Search code examples
metaprogrammingdslnemerle

Infix format for Nemerle macro


Say I need some very special multiplication operator. It may be implemented in following macro:

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

And I can use it like

def val = 2 <<! 3

And its work.

But what I really want is some 'english'-like operator for the DSL Im developing now:

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

and if I try to use it like

def val = 2 multiply 3

compiler fails with 'expected ;' error

What is the problem? How can I implement this infix-format macro?


Solution

  • Straight from the compiler source code:

    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 ]>
      }
    

    You need to sprinkle OperatorAttributes around and it will work. Btw, OperatorAttribute is defined as follows:

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