<!--
  - Authors:
  -   Denys Duchier     <duchier@ps.uni-sb.de>
  -
  - Copyright:
  -   Denys Duchier, 1999
  -
  - Last change:
  -   $Date$ by $$
  -   $Revision$
  -
  - This file is part of Mozart, an implementation
  - of Oz 3
  -    http://www.mozart-oz.org
  -
  - See the file "LICENSE" or
  -    http://www.mozart-oz.org/LICENSE.html
  - for information on usage and redistribution
  - of this file, and for a DISCLAIMER OF ALL
  - WARRANTIES.
  -
  -->

<chapter id=chapter.macro>
  <title>Macro Facility</title>
  <p>A new macro facility has now been integrated into the Mozart
system.  This is <em/not/ a preprocessing facility: preprocessors such
as <name/CPP/ or <name/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.</p>
  <section id=section.call.and.define>
    <title/Invoking And Defining Macros/
    <p>Oz macros are invoked with the following new syntax:
    <code display>&lt;&lt;repeat 5 {Show hello}&gt;&gt;</code>
    angle brackets delimit a sequence of phrases (expressions and
    statements).  The first element should be an atom (here
    <code/repeat/) and names the macro to be invoked.</p>
    <p>When the compiler encounters a macro, it invokes the
macro-expansion facility.  The latter eventually returns a syntactic
representation that is guaranteed to no longer contain any macro
invocation.</p>
    <p>A macro is implemented by a <em/macro expander/.  This is a
function of two arguments: (1) a macro form (a syntactic
representation), (2) a macro environment.  It returns a transformed
syntactic representation.  Syntactic representations of Oz code use
the <q/Syntax Tree Format/ which is described in <ptr.extern
to="ozdoc:compiler" key="appendix.syntax">.</p>
    <p>Let's define a very simple macro:
<code display>&lt;&lt;unless B S1 S2 S3&gt;&gt;</code>
which executes the body <code/S1 S2 S3/ iff <code/B/ evaluates to false.
&ie; it is precisely equivalent to:
<code display>if B then skip else S1 S2 S3 end</code>
Here is the code for the expander:
<code display>
declare
fun {UnlessExpander fMacro(M|B|L C) Env}
   fBoolCase(
      B
      fSkip(unit)
      {Macro.listToSequence L}
      C)
end
</code>
The first argument <code/fMacro(M|B|L C)/ is the macro call form.
<code/M/ is the representation of the atom which is the first element of the
macro invocation (here <code/fAtom(unless C2)/, where <code/C2/ is a
<em/coordinate/ indicating the provenance and location of the token in
the input). <code/B/ is the 2nd element of the macro call and
represents the boolean condition. <code/L/ is the list of the
remainder of the macro call and represents the body.  <code/C/ is also
a coordinate. <code/Env/ is a macro environment and can usually be
ignored.</p>
    <p><code/{Macro.listToSequence L}/ turns the list <code/L/ of
instructions into the syntactic representation of a sequence.  Module
<code/Macro/ is described in <ptr to=section.macro.module>.
    <p>We must now globally register the macro expander:
<code display>{Macro.defmacro unless UnlessExpander}</code>
Here is a test:
<code display>
declare
proc {DO X Y}
   &lt;&lt;unless X&lt;Y {Show X} {Show Y}&gt;&gt;
end
</code>
<code/{DO 2 5}/ prints nothing while <code/{DO 5 2}/ prints 5 then 2.</p>
    <p>A common mistake while using the interactive development
environment is to feed a buffer that contains both macro definitions
and uses of these macros.  This cannot work: when the code in the
buffer is being compiled the macros are not yet defined.  They become
defined only after execution of the code.  Thus you must first feed
your macro definitions, and only then feed any code that makes use of
them.</p>
  </section>
  <section id=section.macro.module>
    <title/<code/Macro/ Module/
    <p>
<list>
	<entry/<code/macroExpand//
	<synopsis/<code display/{Macro.macroExpand ?+{X} ?+{Env} ??{Y}}//
	<item><code/X/ is a term representing Oz code using
<em/Syntax Tree Format/.  This performs full macro expansion on
<code/X/ with respect to macro environment <code/Env/ and returns
<code/Y/ which is guaranteed to no longer contain any macro
invocation.  A macro environment maps macro names to expanders.
<code/Env/ may also be <code/unit/ in which case the global macro
environment is used which contains all the macros registered using
<code/Macro.defmacro/.</item>
	<entry/<code/defmacro//
	<synopsis/<code display/{Macro.defmacro ?+{A} ?+{F}}//
	<item><code/A/ should be an atom.  A new global macro is
defined which is invoked using atom <code/A/ and implemented using
macro expander <code/F/.</item>
	<entry/<code/makeVar//
	<entry/<code/makeNamedVar//
	<synopsis/<code display/{Macro.makeVar ??{X}}//
	<synopsis/<code display/{Macro.makeNamedVar ?+{A} ??{X}}//
	<item>This is very useful to create on the fly new
representations of variables that are guaranteed not to conflict with
those in user code.  With <code/Macro.makeNamedVar/, you supply an
atom that provides the variable with a more meaningful name.  This can
be helpful for debugging.  For example:
<code display>X = {Macro.makeNamedVar 'Tail'}</code>
creates a new variable representation, guaranteed to be distinct from
any other variable representation, and whose print name is
<code/Tail/.</item>
	<entry/<code/sequenceToList//
	<synopsis/<code display/{Macro.sequenceToList ?+{X} ??{L}}//
	<item>Converts the syntactic representation of a sequence to a
list</item>
	<entry/<code/listToSequence//
	<synopsis/<code display/{Macro.listToSequence ?+{L} ??{X}}//
	<item>Converts a list to the syntactic representation of a
sequence</item>
</list></p>
  </section>
  <section id=section.backquote.macro>
    <title/Backquote Macro/
    <p>Writing macros using only the <em/Syntax Tree Format/ can be
quite difficult.  The backquote macro makes some of it a little bit
easier.  The Mozart backquote macro was inspired by the classical Lisp
backquote macro.  However, it is not quite as nice and easy as in
Lisp: in Lisp all source code is represented by lists, which makes
syntactic manipulation quite uniform and simple.  Oz, on the other
hand, is a language that makes heavy use of keywords and special
notations.  Its natural representation is the <em/Syntax Tree Format/
described in <ptr.extern to="ozdoc:compiler" key="appendix.syntax">
which is more structured and does not lend itself quite as easily to
uniform processing.  Nonetheless, if you ever write macros, you will
find the backquote facility of great convenience, even if it only gets
you part of the way.</p>
    <p>The idea of the backquote facility is that it gives you
convenient first class access to syntactic representation of code.
For example:
<code display/declare U = &lt;&lt;'`' if {F X} then X+1 end&gt;&gt;/
Causes <code/U/ to be bound to the <em/Syntax Tree Format/
representation of the code <code/if {F X} then X+1 end/.</p>
    <p>Furthermore, within the scope of a backquote macro, you can
invoke the <q/comma/ macro to insert a piece of syntactic
representation.
<code display/declare V = &lt;&lt;'`' local X = 7 in &lt;&lt;',' U&gt;&gt; end&gt;&gt;/
<code/V/ is now bound to the syntactic representation of
<code display/local X = 7 in if {F X} then X+1 end end/
The limits of this technique are simply the limits of the Oz syntax:
each macro invocation must represent one <q/phrase/ in the
language.</p>
  </section>
  <section>
    <title/Compiling functors that use macros/
    <p>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 <code
proglang=sh/--include/ or <code proglang=sh/--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 <code proglang=sh/--environment/.</p>
    <p>First we create a functor that defines new macros.  It exports
nothing, but just registers the macros.  Suppose we write file
<file/unless.oz/ containing:
<code display>
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
</code>
We compile it as usual:
<code display proglang=sh>ozc -c unless.oz</code>
Now we write file <file/do.oz/ that makes use of this macro:
<code display>
functor
import System(show:Show)
export Do
define
   proc {Do X Y}
      &lt;&lt;unless X&lt;Y {Show X} {Show Y}&gt;&gt;
   end
end
</code>
The trick is to compile it as follows:
<code display proglang=sh>ozc -l 'Bogus=unless.ozf' -c do.oz</code>
When the compiler processes option <code proglang=sh/-l/ it links in the
new module <code/Bogus/ using functor <file/unless.ozf/.  Module
<code/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.</p>
  </section>
</chapter>

<!--
Local Variables:
mode: sgml
mode: auto-fill
sgml-default-dtd-file: "chapter.ced"
sgml-auto-activate-dtd: t
adaptive-fill-mode: nil
End:
-->
