public VisitorSpelializer(VisitorTypeInference visitorTypeInference)
 {
     this.visitorTypeInference = visitorTypeInference;
     specilizedMethods         = new Dictionary <string, MethodDefinition>();
     pendingMethods            = new Dictionary <string, IList <InvocationExpression> >();
     previouslyUnified         = new List <Pair <TypeExpression, TypeExpression> >();
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Runs the application
        /// <param name="directories">A filename : directoryname map</param>
        /// <param name="outputFileName">The output file name. A null value means no executable generation.</param>
        /// <param name="debugFilePath">Path where files with debug info will be created (does not include filename).</param>
        /// <param name="typeTableFileName">Path to file with types table info that will be created (includes filename).</param>
        /// <param name="ilasmFileName">Path to the ilasm.exe executable file (includes filename).</param>
        /// <param name="run">If the program must be executed after compilation</param>
        /// <param name="dynamic">Using "dynamic" to refer to a "dynamic var"</param>
        /// <param name="server">Server option, make use of the DLR</param>
        /// <param name="specialized">Specializing methods with the type information of their arguments</param>
        /// <param name="targetPlatform">The target platform to compile the code</param>
        /// </summary>
        public void Run(IDictionary <string, string> directories, string outputFileName,
                        string debugFilePath, string ilasmFileName, string typeTableFileName, TargetPlatform targetPlatform, bool run, bool dynamic, bool server, bool specialized)
        {
            int previousNumberOfErrors = ErrorManager.Instance.ErrorCount;

            if (entryPointList.Count == 0)
            {
                ErrorManager.Instance.NotifyError(new EntryPointNotFoundError());
            }
            else
            {
                if (entryPointList.Count != 1)
                {
                    for (int i = 0; i < entryPointList.Count; i++)
                    {
                        ErrorManager.Instance.NotifyError(new EntryPointFoundError(entryPointList[i].Location));
                    }
                }
            }

            for (int i = 0; i < this.astList.Count; i++)
            {
                this.astList[i].Accept(new VisitorSSA(), null);
            }

            for (int i = 0; i < this.astList.Count; i++)
            {
                this.astList[i].Accept(new VisitorTypeLoad(), null);
            }

            for (int i = 0; i < this.astList.Count; i++)
            {
                this.astList[i].Accept(new VisitorTypeDefinition(), null);
            }

            for (int i = 0; i < this.astList.Count; i++)
            {
                this.astList[i].Accept(new VisitorSymbolIdentification(directories), null);
            }

            VisitorTypeInference visitorTypeInference = new VisitorTypeInference();

            for (int i = 0; i < this.astList.Count; i++)
            {
                // * The same visitor type inference should be used in the whole process
                this.astList[i].Accept(visitorTypeInference, null);
            }

            //Specialized option
            if (specialized)
            {
                VisitorSpelializer visitorSpecializer = new VisitorSpelializer(visitorTypeInference);
                for (int i = 0; i < this.astList.Count; i++)
                {
                    // * The same visitor type inference should be used in the whole process
                    this.astList[i].Accept(visitorSpecializer, null);
                }
            }

            //for (int i = 0; i < this.astList.Count; i++)
            //    this.astList[i].Accept(new VisitorDebug(new StreamWriter("debug.out")),0);

            // * Code is generated if no error has been found...
            if (ErrorManager.Instance.ErrorCount == previousNumberOfErrors &&
                // * ... and the output file and platform are not null
                outputFileName != null)
            {
                if (entryPointList.Count == 1)
                {
                    // * The same visitor code generation should be used in the whole process
                    string ilFileName = Path.ChangeExtension(outputFileName, ".il");
                    VisitorCodeGenerationBase visitorCodeGeneration = createVisitorCodeGeneration(ilFileName, outputFileName, targetPlatform, server);
                    for (int i = 0; i < this.astList.Count; i++)
                    {
                        this.astList[i].Accept(visitorCodeGeneration, null);
                    }
                    visitorCodeGeneration.AddExceptionCode();
                    visitorCodeGeneration.Close();


                    // If no errors found, the executable file is generated
                    if (previousNumberOfErrors == ErrorManager.Instance.ErrorCount)
                    {
                        switch (targetPlatform)
                        {
                        case TargetPlatform.CLR:
                            assembleAndRun(ilFileName, outputFileName, ilasmFileName, run);
                            break;

                        case TargetPlatform.RRotor:
                            // TODO (assemble and run the IL code in the Rrotor platform)
                            break;

                        default:
                            System.Diagnostics.Debug.Assert(false, "Unknown target platform.");
                            break;
                        }
                    }
                }
            }


#if DEBUG
            // * Dumps the types table
            debug(debugFilePath, typeTableFileName);
#endif

            ClearMemory();
        }