代码之家  ›  专栏  ›  技术社区  ›  Tamas Czinege

将.NET表达式树链接到新程序集中

  •  5
  • Tamas Czinege  · 技术社区  · 15 年前

    为了更好地理解编译器的工作原理,我正在尝试编写自己的玩具——我的玩具语言——MSIL编译器。我得到了解析和词法分析的工作,我构建了表达式树,使用system.linq.expressions表达式树API,我有一个工作的解释器。现在我想发出一些真正的MSIL程序集。

    问题是,我不知道如何实际构建这些程序集。这个 MethodBuilder 类只接受原始的msil方法体,因此我必须获取表达式树的原始msil。打电话 Expression.Compile() 返回一个工作委托,但我无法获取其基础MSIL。打电话 MethodInfo.GetMethodBody() 引发InvalidOperationException,因为它未在该特定子类中实现。

    如何将该委托链接到新程序集中?

    2 回复  |  直到 15 年前
        1
  •  3
  •   Tamas Czinege    15 年前

    刚刚找到。lambdaexpression的DLR版本公开了一个compileToMethod方法,它完全满足我的需要。

    lambdaExpression.CompileToMethod(myMethodBuilder);
    
        2
  •  0
  •   Ilya Khaprov    15 年前

    为了发出原始IL,您需要定义自己的AST。需要先获取assemblybuilder,然后获取modulebuilder,然后才能定义模块级方法,或者获取新的typebuilder,现在是methodbuilder来定义类级方法。

    你说你已经有了lexer和parser。这意味着你可以建立AST。所以只需遍历解析的表达式并发出您的IL。

    即使您得到(通过编译)代码,您也不能用它做一些有用的事情,因为生成的代码依赖于基础结构。例如,如果需要编译闭包,那么应该为词法变量等创建类或其他存储(如非词法控件传输,它需要在.NET中使用异常)。