2.1.4. Macro functions

You can also define a macro function. The expansion rules are: the body is not expanded during definition. At the point of call, the arguments are expanded and then substituted into the body, then the body is expanded.

WARNING: macro function definitions need a semi-colon at the end. This is because the RHS is universally treated as an expression.

Start felix section to tut/macros/mac-2.01.04-0.flx[1 /1 ]
     1: #line 323 "./lpsrc/flx_tut_macro.pak"
     2: #import <flx.flxh>
     3: 
     4: // a basic expression macro without parameters
     5: macro fun x() =  {print 1; endl;};
     6: x;
     7: 
     8: // an expression macro with one argument
     9: macro fun h(z) = z + z;
    10: print (h 1); endl;
    11: 
    12: // an expression macro denoting a procedure
    13: macro fun f(a) = { print a; endl; };
    14: f 1;
    15: f 2;
    16: 
    17: // nastier example of rescanning
    18: macro fun a() = b c;
    19: macro fun b(x) = f;
    20: a() 1;
    21: // (b c) 1;
    22: // f 1;
    23: // { print 1; endl; };
    24: // call {print 1; endl; } ();
    25: 
    26: // finally: recursion
    27: macro fun j(i) =
    28:    if(i>0) then i + j(i-1)
    29:    else 0 endif;
    30: print  (j 5); // 5 + 4 + 3 + 2 + 1 = 16
    31: endl;
    32: 
    33: val q=1;
    34: macro fun z(q) = q;
    35: print (z q); endl;
End felix section to tut/macros/mac-2.01.04-0.flx[1]
Start data section to tut/macros/mac-2.01.04-0.expect[1 /1 ]
     1: 1
     2: 2
     3: 1
     4: 2
     5: 1
     6: 15
     7: 1
End data section to tut/macros/mac-2.01.04-0.expect[1]
It is vital to understand that macros cannot break syntactically established precedence rules. In the last example, a 1 expands to (b c) 1, which expands to f 1. Substitutions are implemented by manipulation of the abstract syntax tree (AST), not token pasting or string manipulation.