Exemplo n.º 1
0
        static void EmitMain(string programName, Assembly[] assemblies, Tracer tracer, IReadOnlyList <ImmutableRootSyntaxNode> rootNodes)
        {
            var createdAssembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(programName), AssemblyBuilderAccess.RunAndSave);
            var createdModule   = createdAssembly.DefineDynamicModule(programName, programName + ".exe");

            var emitModuleBuilder = new EmitModuleBuilder(createdModule, assemblies);

            var codeGenerator = new NewCodeGenerator(emitModuleBuilder, tracer);

            var entryPoint = codeGenerator.GenerateAssembly(rootNodes);

            //            System.Console.Out.WriteLine("Hello World from Out!");


            if (entryPoint == null)
            {
                throw new InvalidOperationException("Entry point must be null");
            }

            createdAssembly.SetEntryPoint(((EmitMethodInfo)entryPoint).MethodInfo);

            createdAssembly.Save(programName + ".exe");

            tracer.AddEpoch("Code Generation");
        }
Exemplo n.º 2
0
        public IMethodInfo?GenerateAssembly(IReadOnlyList <ImmutableRootSyntaxNode> rootNodes)
        {
            if (rootNodes == null)
            {
                throw new ArgumentNullException(nameof(rootNodes));
            }

            var store = new CodeGenerationStore();

            IType voidType;

            (delegateConstructorTypes, voidType, baseConstructorInfo) = moduleBuilder.BuiltInTypeProvider.GenerateAssemblyTypes(store);

            typeChecker = new SimpleTypeChecker(voidType);

            tracer.AddEpoch("Dependent Type Load");

            var toGenerate = CreateTypesToGenerate(rootNodes, store);

            tracer.AddEpoch("Generate Types");

            GenerateDelegates(toGenerate, store);

            tracer.AddEpoch("Generate Delegates");

            IMethodInfo?methodInfo = null;

            GenerateClassPlaceholders(toGenerate, store, ref methodInfo);

            tracer.AddEpoch("Generate Class Definitions");

            GenerateMethods(toGenerate, store);

            tracer.AddEpoch("Generate Class Methods");

            GenerateConstructors(toGenerate, store);

            tracer.AddEpoch("Generate Class Constructors");

            foreach (var type in store.Types.Values)
            {
                if (type is ITypeBuilder tb)
                {
                    tb.CreateTypeInfo();
                }
            }

            tracer.AddEpoch("Create Type Infos");

            return(methodInfo);
        }
Exemplo n.º 3
0
        static void IlAsmMain(string programName, Assembly[] assemblies, Tracer tracer, IReadOnlyList <ImmutableRootSyntaxNode> rootNode)
        {
            var emitModuleBuilder = new AsmModuleBuilder(programName, assemblies);

            var codeGenerator = new NewCodeGenerator(emitModuleBuilder, tracer);

            var entryPoint = codeGenerator.GenerateAssembly(rootNode);


            if (entryPoint == null)
            {
                throw new InvalidOperationException("Entry point must be null");
            }

            var asm = emitModuleBuilder.Emitter.Finalize();

            File.WriteAllLines($"{programName}.il", asm);

            tracer.AddEpoch("Code Generation");
        }
Exemplo n.º 4
0
        static void Main(string?programName = null, string[]?args = null)
        {
            var tracer = new Tracer();

            tracer.Restart();

            if (args == null)
            {
                throw new InvalidOperationException("You must pass in a file");
            }

            var libraries = args.Where(x =>
            {
                var ext = Path.GetExtension(x);
                return(ext == ".exe" || ext == ".dll");
            }).ToArray();

            args = args.Except(libraries).ToArray();

            if (args.Length == 0)
            {
                throw new InvalidOperationException("You must pass in a file to actually compile");
            }

#pragma warning disable CS8619 // Nullability of reference types in value doesn't match target type.
            Assembly[] assemblies = libraries.Select(x =>
            {
                try
                {
                    return(Assembly.LoadFrom(x));
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch
#pragma warning restore CA1031 // Do not catch general exception types
                {
                    return(null);
                }
            }).Where(x => x != null).Append(typeof(object).Assembly).ToArray();
#pragma warning restore CS8619 // Nullability of reference types in value doesn't match target type.

            if (programName == null)
            {
                programName = Path.GetFileNameWithoutExtension(args[0]);
            }

            tracer.AddEpoch("Initialization");

            var tokenizer = new SimpleTokenizer();
            var parser    = new SimpleParser();

            var rootNodes = new List <ImmutableRootSyntaxNode>();

            foreach (var file in args)
            {
                var code       = File.ReadAllText(file);
                var fileTokens = tokenizer.EnumerateTokens(code.AsSpan());
                tracer.AddEpoch($"Tokenizing {file}");
                var immutableNode = parser.ParseTokens(fileTokens);
                rootNodes.Add(immutableNode);
                tracer.AddEpoch($"Parsing {file}");
            }

            EmitMain(programName + "Emit", assemblies, tracer, rootNodes);

            // Skip the ilasm backend for demonstation.
            IlAsmMain(programName, assemblies, tracer, rootNodes);



            tracer.PrintEpochs();
            Console.WriteLine("Compilation Complete!");
        }