2.2. Constant Expression Folding

The Felix macro processor also performs constant folding; that is, evaluation of certain expressions involving only literals. The following operations are folded:
opdescr
+int
-int
int+int
int-int
int*int
int/int
int%int
int<int
int>int
int<=int
int>=int
int==int
int!=int
string+string
string==string
string!=string
string*intcat n copies
string stringcat
string intcat ISO10646
not bool
bool && bool
bool or bool
bool == bool
bool != bool
if bool then expr1 else expr2 endif

The critical operation here is that a conditional with a constant first argument is replaced by one of the two expressions, and the other is elided. See the example for an application: the implication is that the elided expression, whilst it must be well formed syntactically, does not need to be type correct, nor do symbols in it need to be defined.

Note that the fold uses compiler intrinsic operations on integers, bools, and strings: user defined functions are not applied and do not need to be defined. Consequently, the result may disagree with a user defined function applied at run time. If necessary, constant folding can be blocked with the noexpand mark 'noexpand'.

Note: the expressions

  "" 999
  u"" 999
are semantically, but not physically equivalent. The first operation is the UTF-8 representation of 999, whilst the second is the UCS-32 value 999.

Start felix section to tut/macros/mac-2.02-0.flx[1 /1 ]
     1: #line 433 "./lpsrc/flx_tut_macro.pak"
     2: #import <flx.flxh>
     3: header '''
     4: #define flx_unix 0
     5: #define flx_windows 0
     6: #define testhook 1
     7: #if flx_unix
     8: #include <dlopen.h>
     9: #elif flx_windows
    10: #include <windows.h>
    11: #else
    12: #include <stdio.h>
    13: #endif
    14: ''';
    15: macro val Unix = case 0 of 2;
    16: macro val Windows = case 0 of 2;
    17: 
    18: fun dlopen:string -> address = 'dlopen($1.data())';
    19: fun LoadLibrary:string -> int = 'LoadLibrary($.data())';
    20: fun testhook:string -> int = 'printf("LoadTheLibrary(%s)\\n",$1.data())';
    21: 
    22: macro val openlib =
    23:   if Unix then dlopen
    24:   elif Windows then LoadLibrary
    25:   else testhook endif
    26: ;
    27: 
    28: macro val ext =
    29:   if Unix then ".so"
    30:   elif Windows then ".DLL"
    31:   else ".lib_ext" endif
    32: ;
    33: // conditional compilation
    34: C_hack::ignore(openlib ("MyLibrary" ext));
End felix section to tut/macros/mac-2.02-0.flx[1]
Start data section to tut/macros/mac-2.02-0.expect[1 /1 ]
     1: LoadTheLibrary(MyLibrary.lib_ext)
End data section to tut/macros/mac-2.02-0.expect[1]