metaprogrammingnemerle

How to construct a macro emitting arbitrary number of possible matches?


Let's say I would like to create a macro of this kind:

m(1, k) would produce:

match(k)
{
  | 1 => 2
  | _ => 0
}

m(2, k) would produce:

match(k)
{
  | 1 => 2
  | 2 => 3
  | _ => 0
}

and so on. Although construction like <[ $i => $(i + 1) ]> for the possible match is accepted, I do not know how to create match expression consisting of these. The example is of course contrived ;)


Solution

  • public macro m(to, k)
    {
      def toInteger(literal)
      {
         | <[ $(i : int) ]> => i
         | _ => Message.Error(literal.Location, $"'$literal' integer literal expected"); 0;
      }
    
      def to = toInteger(to);
    
      def createCases(i) 
      {
         | i when (i > 0) => <[case: | $i => $(i + 1)  ]> :: createCases(i - 1);
         | _ => [ <[case: | _ => 0 ]> ]
      }
    
      <[
        match ($k)
        {
          ..$(createCases(to))
        }
      ]>
    }
    

    http://nemerle.org/Macros_tutorial#Matching_match-cases