编写.net的编译器 - IL或字节码?

Mic*_*tum 27 .net compiler-construction cil

我目前正在深入研究.net的内部运作,这意味着IL.作为练习,我想为.net构建一个brainf..k编译器(是的,它们已经存在,但正如所说的那样是为了学习目的).

目前我只是编写了一些包含.il的文本文件,并使用ilasm编译它们.但我想知道我是否可以/应该更深入一级并直接写字节码?

我的"关注点"是编译EXE时的Windows PE Stuff - 而不是ilasm我需要某种Bytecode链接器来获取我的MSIL/CIL字节码并为它生成PE Stuff?

或者编译器"只"将他们的语言编译成IL并执行ilasm?是否有我可以从编译器调用/嵌入的托管版本?

ang*_*son 27

为什么不简单地使用Reflection.Emit api生成带有编译代码的内存中程序集,然后将其保存到磁盘?应该比写出.IL文件容易得多.

链接:

如果你想要走这条路,如果你在这里问更具体的问题上SO你会得到很多例子,如何定义一个动态组装,并将其保存到磁盘.

这是一个例子:

using System;
using System.Reflection.Emit;
using System.Reflection;

namespace SO2598958
{
    class Program
    {
        static void Main()
        {
            AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(
                new AssemblyName("TestOutput"),
                AssemblyBuilderAccess.RunAndSave);

            ModuleBuilder mod = asm.DefineDynamicModule("TestOutput.exe",
                "TestOutput.exe");
            TypeBuilder type = mod.DefineType("Program", TypeAttributes.Class);

            MethodBuilder main = type.DefineMethod("Main",
                MethodAttributes.Public | MethodAttributes.Static);
            ILGenerator il = main.GetILGenerator();
            il.Emit(OpCodes.Ldstr, "Hello world!");
            il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
                BindingFlags.Public | BindingFlags.Static,
                null, new Type[] { typeof(String) }, null));
            il.Emit(OpCodes.Ret);

            type.CreateType();
            asm.SetEntryPoint(main);
            asm.Save("TestOutput.exe");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以从此处下载测试解决方案文件.这里有解决方案直接链接到zip文件.

如果您首先编译并运行此程序,它将在磁盘上生成一个名为TestOutput的新exe文件,然后您可以执行该文件以获得"Hello World!".打印在控制台上.

  • 如果您指的是SO2598958命名空间,那只是我为答案创建解决方案并将其提交到我的存储库这一事实的工件,因此很容易找回问题的正确文件夹.我所有的StackOverflow回答我已经为我保留的代码生成了一些代码:http://svn.vkarlsen.no:81/public/listing.php?update = StackOverflow& (4认同)