好吧,我又提起一个老话题了。
凭借.NET的开源和生态发展,以及.NET平台本身的优势,可以在.NET上开发一种语言,跨语言使用其他.NET组件。
但是当我在网上搜索时,几乎总是在 2000 年到 2010 年之间:如何在 .NET 上创建一种语言的名人作品。 这些技术和主题太旧了,以至于我尝试过的 api 几乎总是很难在 .NET 5 或新版本上使用。考虑这段代码(仅适用于.NET框架):
目前API中还没有
Save
的方法AssemblyBuilder
,传闻.NET 9之后会支持
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");
}
}
}
我试图看一下boo语言的实现,但不幸的是我不太理解它,它使用了太多的技术栈 java-antlr用作扫描器和解析器,C#用于解析语法树。如果没有开发文档,很难从这么大的项目中获得很多成果。 其实我需要的很简单,就两件事:
至于如何将自己语言的语法树转换为il语法树,这部分我可以自己搞清楚。 token、scanner、parser的流程比较熟悉,但是parser拿到抽象语法树后做什么是平台相关的,我对这部分不是很熟悉
其他谈话
其实我是希望在llvm上构建一门语言,但是llvm有很多问题,包括pc计数器、gc、内存管理、struct声明等。我考虑过它的mir,但是了解后发现mir 是一项很少使用的技术,其实现与许多构建环境问题混合在一起。 cil 拥有托管堆技术,与 llvm ir 相比,我能够在语言运行时节省更多时间
(据我所知)有关如何执行此操作的最新深入教程是 Immo Landwerth 于 2018 年发布的 YouTube 系列 (.NET Core 3.1)。
该项目有一个附带的 github 存储库,拥有超过 1k 颗星。