1 Macro Facility

A new macro facility has now been integrated into the Mozart system. This is not a preprocessing facility: preprocessors such as CPP or M4 are widely available and can be used for preprocessing arbitrary files. You could easily use them to preprocess files of Oz code. This is not what we discuss here. The Mozart macro facility is closer in spirit to that of Lisp.



1.4 Compiling functors that use macros

It doesn't work to write a functor that both defines macros and uses them: when the functor is being compiled the macros have not yet been defined. The trick is to take advantage of compiler options --include or --environment to get the compiler to execute code defining your macros before going on to compile your functor. We now describe how to achieve the desired effect using option --environment.

First we create a functor that defines new macros. It exports nothing, but just registers the macros. Suppose we write file unless.oz containing:

functor 
import Macro
define 
   fun {UnlessExpander fMacro(M|B|L C) Env}
      fBoolCase(
         B
         fSkip(unit)
         {Macro.listToSequence L}
         C)
   end 
   {Macro.defmacro unless UnlessExpander}
end

We compile it as usual:

ozc -c unless.oz

Now we write file do.oz that makes use of this macro:

functor 
import System(show:Show)
export Do
define 
   proc {Do X Y}
      <<unless X<Y {Show X} {Show Y}>> 
   end 
end

The trick is to compile it as follows:

ozc -l 'Bogus=unless.ozf' -c do.oz

When the compiler processes option -l it links in the new module Bogus using functor unless.ozf. Module Bogus is in itself uninteresting; only the side-effects resulting from linking it are really what we are after, namely to define and register new macros.


Denys Duchier
Version 1.4.0 (20100209)