コード例 #1
0
        private static void SwitchOnLongargs(CrawlCompilerConfiguration crawlCompilerConfiguration, string longarg)
        {
            string[] parts = longarg.Split('=');
            try
            {
                switch (parts[0])
                {
                case "help":
                    crawlCompilerConfiguration.PrintHelp = true;
                    break;

                case "print-ast":
                    SetStage(crawlCompilerConfiguration, TargetStage.AbstractSyntaxTree);
                    break;

                case "print-pt":
                    SetStage(crawlCompilerConfiguration, TargetStage.ParseTree);
                    break;

                case "typecheck":
                    SetStage(crawlCompilerConfiguration, TargetStage.TypeCheck);
                    break;

                case "optimize":
                    if (parts.Length == 1)
                    {
                        crawlCompilerConfiguration.Optimizations.Add("*");
                    }
                    else
                    {
                        foreach (string optimiaztion in parts[1].Split(','))
                        {
                            crawlCompilerConfiguration.Optimizations.Add(optimiaztion);
                        }
                    }

                    break;

                case "assembly":
                    crawlCompilerConfiguration.Assemblies.Add(parts[1]);
                    break;

                case "output":
                    crawlCompilerConfiguration.OutputFile = parts[1];
                    break;

                case "force-single-thread":
                    crawlCompilerConfiguration.ForceSingleThreaded = true;
                    break;

                default:
                    throw new UnknownOption(parts[0]);
                }
            }
            catch (IndexOutOfRangeException)
            {
                throw new RequiresArgumentException(parts[0]);
            }
        }
コード例 #2
0
        private static void SetStage(CrawlCompilerConfiguration crawlCompilerConfiguration, TargetStage stage)
        {
            if (crawlCompilerConfiguration.TargetStage >= 0)
            {
                throw new MutalExcluseiveOptionsException(crawlCompilerConfiguration.TargetStage.ToString(), stage.ToString());
            }

            crawlCompilerConfiguration.TargetStage = stage;
        }
コード例 #3
0
        public static TextWriter GetPrimaryOutputStream(CrawlCompilerConfiguration configuration)
        {
            if (string.IsNullOrWhiteSpace(configuration.OutputFile))
            {
                return(Console.Out);
            }



            return(new StreamWriter(File.OpenWrite(configuration.OutputFile)));
        }
コード例 #4
0
 internal static void WriteParseTrees(TextWriter output, CrawlCompilerConfiguration configuration)
 {
     foreach (string inputfile in configuration.Files)
     {
         output.WriteLine("Parsing file {0}", inputfile);
         CrawlParser.Translation_unitContext tu = ParseFile(File.OpenRead(inputfile));
         //foreach (string line in Utils.MakeIndents(tu.ToStringTree(CrawlParser.ruleNames)).Split('\n'))
         //{
         //    output.WriteLine(line);
         //}
         output.WriteLine(Utils.MakeIndents(tu.ToStringTree(CrawlParser.ruleNames)));
     }
 }
コード例 #5
0
        private static void SwitchOnCharargs(CrawlCompilerConfiguration crawlCompilerConfiguration, char c)
        {
            switch (c)
            {
            case 'h':
                crawlCompilerConfiguration.PrintHelp = true;
                break;

            case 'p':
                SetStage(crawlCompilerConfiguration, TargetStage.ParseTree);
                break;

            case 'a':
                SetStage(crawlCompilerConfiguration, TargetStage.AbstractSyntaxTree);
                break;

            default:
                throw new UnknownOption(c.ToString());
            }
        }
コード例 #6
0
        public static CrawlCompilerConfiguration Parse(string[] args)
        {
            CrawlCompilerConfiguration configuration = new CrawlCompilerConfiguration();
            TargetStage defaultTargetStage           = configuration.TargetStage;

            configuration.TargetStage = (TargetStage)(-1);
            for (int index = 0; index < args.Length; index++)
            {
                string arg = args[index];
                if (arg.StartsWith("--"))
                {
                    string longarg = arg.Substring(2);
                    SwitchOnLongargs(configuration, longarg);
                }
                else if (arg.StartsWith("-"))
                {
                    string multiargs = arg.Substring(1);
                    foreach (char c in multiargs)
                    {
                        SwitchOnCharargs(configuration, c);
                    }
                }
                else
                {
                    configuration.Files.Add(arg);
                }
            }

            if (configuration.TargetStage < 0)
            {
                configuration.TargetStage = defaultTargetStage;
            }

            if (args.Length == 0)
            {
                configuration.PrintHelp = true;
            }

            return(configuration);
        }
コード例 #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="configuration">Paths to source code, referenced assemblies and compiler directives</param>
        /// <returns>Any resulting errors, logs and executables.</returns>
        public static CompilationResult Compile(CrawlCompilerConfiguration configuration)
        {
            TextWriter output = Utils.GetPrimaryOutputStream(configuration);
            //TraceListners.AssemblyResolverListner =
            //    new System.Diagnostics.TextWriterTraceListener(Utils.GetPrimaryOutputStream(configuration));

            //From referenced files, build list of existing namespaces
            ConcurrentDictionary <string, Namespace> allNamespaces = NamespaceLoader.LoadAll(configuration.Assemblies);

            allNamespaces.MergeInto(Namespace.BuiltinNamespace.AsSingleIEnumerable());

            //Set up logging and status
            SideeffectHelper  sideeffectHelper = new SideeffectHelper();
            CompilationStatus status           = CompilationStatus.Success;

            try
            {
                //single line comments with /* */ are referering to a stage in general_archtechture.md


                bool parallel = !configuration.ForceSingleThreaded;

                //The ConcurrentBag is an unordered, thread safe, collection
                ConcurrentBag <AstData> parsedFiles = Run <AstData, string>(configuration.Files, parallel, sideeffectHelper,
                                                                            (destination, helper) =>
                {
                    //Syntax is slightly wonky, but cannot assign variable to method group.
                    //_Could_ be hidden in ParsePipeline by making them properties instead....

                    //Get the starting transformaton
                    /* Create parse tree */
                    Func <string, SideeffectHelper, ParseTreeData> parsePT = ParsePipeline.ReadFileToPt;

                    //Jump out if we are intrested in earlier stage.
                    if (configuration.TargetStage == TargetStage.ParseTree)
                    {
                        return(parsePT.EndWith(output.WriteLine, helper));
                    }

                    /* Create AST */
                    var parseASt = parsePT
                                   .Then(ParsePipeline.CreateAst); //.Then adds another stage

                    if (configuration.TargetStage == TargetStage.AbstractSyntaxTree)
                    {
                        return(parseASt.EndWith(output.WriteLine, helper));
                    }

                    /* Collect types*/
                    var firstscopepass = parseASt.Then(SemanticAnalysisPipeline.CollectTypes);

                    //.EndWith collects it
                    return(firstscopepass.EndWith(destination.Add, helper));
                }
                                                                            );

                MaybeDie(sideeffectHelper);
                /* Merge type tables */
                foreach (AstData file in parsedFiles)
                {
                    TranslationUnitNode node          = (TranslationUnitNode)file.Tree.RootNode;
                    Namespace           exportedTypes = new Namespace(node.Namespace.Module, node.Code.Scope.Classes());

                    allNamespaces.MergeInto(exportedTypes.AsSingleIEnumerable());
                }

                //TODO: finish Semantic analysis
                ConcurrentBag <AstData> filesWithScope = Run <AstData, AstData>(parsedFiles, parallel, sideeffectHelper,
                                                                                (destination, helper) =>
                {
                    /* Find visible namespace*/
                    //NamespaceDecorator is a hack to pass all namespaces in to the function that finds the relevant ones
                    Func <AstData, SideeffectHelper, AstData> first = new SemanticAnalysisPipeline.NamespaceDecorator(allNamespaces).AddExport;

                    return(first
                           /* Decorate TypeNode */
                           .Then(SemanticAnalysisPipeline.PutTypes)
                           /* Collect remaining scope information */
                           .Then(SemanticAnalysisPipeline.SecondScopePass)
                           /* Finish types */
                           .Then(SemanticAnalysisPipeline.FinishTypes)
                           .EndWith(destination.Add, helper));
                }
                                                                                );

                //TODO: Merge namespaces again with extra (Methods/Variables) from scope. Right now, only classes are visible
                //in other files

                ConcurrentBag <AstData> decoratedAsts = Run <AstData, AstData>(filesWithScope, parallel, sideeffectHelper,
                                                                               (destination, helper) =>
                {
                    /* scope check */
                    Func <AstData, SideeffectHelper, AstData> first = SemanticAnalysisPipeline.DeclerationOrderCheck;
                    var final = first
                                .Then(SemanticAnalysisPipeline.TypeCheck)
                                .EndWith(destination.Add, helper); //Typechecker would be added here or line above

                    return(final);
                }
                                                                               );

                ConcurrentBag <AstData> optimizedAsts = Run <AstData, AstData>(decoratedAsts, parallel, sideeffectHelper,
                                                                               (destination, helper) =>
                {
                    Func <AstData, SideeffectHelper, AstData> first = OptimizationPipeline.FoldConstants;
                    var final = first
                                .Then(OptimizationPipeline.RefWherePossible)
                                .EndWith(destination.Add, helper);

                    return(final);
                }
                                                                               );
                //TODO: Interpeter or code generation

                //Until meaningfull end, print everything

                Execute(decoratedAsts, output.WriteLine, parallel);
                output.WriteLine("\n===Optimized To===>\n");
                Execute(optimizedAsts, output.WriteLine, parallel);

                if (sideeffectHelper.CompilationMessages.Count(message => message.Severity >= MessageSeverity.Error) > 0)
                {
                    status = CompilationStatus.Failure;
                }
            }
            catch (ExitCompilationException)
            { status = CompilationStatus.Failure; }
            catch (Exception e) when(false && !Debugger.IsAttached)
            {
                sideeffectHelper.CompilationMessages.Add(CompilationMessage.CreateNonCodeMessage(MessageCode.InternalCompilerError, e.ToString(), MessageSeverity.Fatal));
                status = CompilationStatus.Failure;
            }

            return(new CompilationResult(status, sideeffectHelper.CompilationMessages));
        }