Ejemplo n.º 1
0
 public Module(CompileContext context, string name)
 {
     Context = context;
     Name    = name;
 }
Ejemplo n.º 2
0
        public CompileResult Compile()
        {
            CompileContext context = new CompileContext();

            // let's explore each parseresult to gather some top-level info
            // we can do this mostly in parallel, before merging the results of each unit together (we also merge their errors)

            ConcurrentQueue <ParseUnitVisitorResults> results = new ConcurrentQueue <ParseUnitVisitorResults>();
            List <ParseUnitVisitorResults>            units   = new List <ParseUnitVisitorResults>();

            Parallel.ForEach(parseUnits, (unit) =>
            {
                results.Enqueue(ParseUnitVisitor.Visit(unit));
            });

            // gather separate module blocks into modules (each module contains a list of pages, kept separate because we need the imports for each one)
            Dictionary <string, Module> modules = new Dictionary <string, Module>();

            while (results.TryDequeue(out var unit))
            {
                // merge errors
                context.Errors.AddRange(unit.Errors);

                // merge module declarations
                foreach (var page in unit.Modules)
                {
                    if (modules.TryGetValue(page.ModuleID.ToString(), out var m))
                    {
                        m.AddPage(page);
                    }
                    else
                    {
                        var module = new Module(context, page.ModuleID.ToString());
                        module.AddPage(page);
                        modules.Add(page.ModuleID.ToString(), module);
                    }
                }

                units.Add(unit);
            }

            // assign each module to context so we can do module lookups later
            context.Modules = modules;

            Module[] moduleArray = new Module[modules.Count];
            modules.Values.CopyTo(moduleArray, 0);

            // NOTE: we only actually do codegen step if we didn't encounter any errors yet
            if (context.Errors.Count == 0)
            {
                foreach (var m in moduleArray)
                {
                    generator.Add(m);
                }

                foreach (var m in moduleArray)
                {
                    generator.Generate(m);
                }
            }

            context.Errors.AddRange(generator.Errors);

            return(new CompileResult()
            {
                Errors = context.Errors.ToArray(),
                Output = generator.Context
            });
        }