【问题标题】:Infix format for Nemerle macroNemerle 宏的中缀格式
【发布时间】:2008-10-21 21:23:37
【问题描述】:

假设我需要一些非常特殊的乘法运算符。它可以在以下宏中实现:

macro @<<!(op1, op2)
{
    <[ ( $op1 * $op2 ) ]>
}

我可以像这样使用它

def val = 2 <<! 3

还有它的工作。

但我真正想要的是一些类似于“英语”的运算符,用于正在开发的 DSL:

macro @multiply(op1, op2)
{
    <[ ( $op1 * $op2 ) ]>
}

如果我尝试像这样使用它

def val = 2 multiply 3

编译器因 'expected ;' 而失败错误

有什么问题?如何实现这个中缀格式的宏?

【问题讨论】:

    标签: metaprogramming dsl nemerle


    【解决方案1】:

    直接来自编译器源代码:

    namespace Nemerle.English
    {
      [assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.English", "and", false, 160, 161)]
      [assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.English", "or", false, 150, 151)]
      [assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.English", "not", true, 181, 180)]  
    
      macro @and (e1, e2) {
        <[ $e1 && $e2 ]>
      }
    
      macro @or (e1, e2) {
        <[ $e1 || $e2 ]>
      }
    
      macro @not (e) {
        <[ ! $e ]>
      }
    

    你需要在周围撒上 OperatorAttributes,它就会起作用。顺便说一句,OperatorAttribute 定义如下:

    public class OperatorAttribute : NemerleAttribute
    {
      public mutable env : string;
      public mutable name : string;
      public mutable IsUnary : bool;
      public mutable left : int;
      public mutable right : int;
    }
    

    【讨论】:

      【解决方案2】:

      像往常一样,我比社区响应更快地找到答案 :) 因此,解决方案是简单地使用特殊的组装级别属性,将宏指定为二元运算符:

      namespace TestMacroLib
      {
        [assembly: Nemerle.Internal.OperatorAttribute ("TestMacroLib", "multiply", false, 160, 161)]
        public macro multiply(op1, op2)
        {
          <[ ( $op1 * $op2 ) ]>
        }
      }
      

      【讨论】:

      猜你喜欢
      • 2013-05-23
      • 1970-01-01
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多