.\" -------------------- seca0.t -------------------- .sh 1 "Macros" .pp SB-Prolog features a facility for the definition and expansion of macros that is fully compatible with the runtime system. Its basic mechanism is a simple partial evaluator. It is called by both \fIconsult\fR and \fIcompile\fR, so that macro expansion occurs independently of whether the code is interpreted or compiled (but not when asserted). Moreover, the macro definitions av%retained as clauses at runtime, so that invocation of macros via \fIcall\fR/1 at runtime (or from asserted clauses) does not pose a problem. This means, however, that if the same macro is used in many different files, it will be loaded more than once, thus leading to wasetd space. This ought to be thought about and fixed. .pp The source for the macro expander is in the SB-Prolog system file \fImodlib/src/$mac.P\fR. .sh 2 "Defining Macros" .pp `Macros', or predicates to be evaluated at compile-time, are defined by clauses of the form .(l Head ::\- Body .)l where facts have `true' as their body. .(x b (P) ::\-/2 .)x The partial evaluator will expand any call to a predicate defined by ::\-/2 that unifies with the head of only one clause in ::\-/2. If a call unifies with the head of more than one clause in ::\-/2, it will not be expanded Notice that this is not a fundamental restriction, since `;' is permitted in the body of a clause. The partial evaluator also converts each definition of the form .(l Head ::\- Body. .)l to a clause of the form .(l Head :\- Body. .)l and adds this second clause to the other ``normal'' clauses that were read from the file. This ensures that calls to the macro at runtime, e.g. through \fIcall\fR/1 or from unexpanded calls in the program do not cause any problems. .pp The partial evaluator is actually a Prolog interpreter written `purely' in Prolog, i.e., variable assignments are explicitly handled. This is necessary to be able to handle impure constructs such as `var(X), X=a'. As a result this is a \fIvery slow\fR Prolog evaluator. .pp Since naive partial evaluation can go into an infinite loop, SB-Prolog's partial evaluator maintains a depth-bound and will not expand recursive calls deeper than that. The depth is determined by the globalset predicate \fI$mac_\|depth\fR. The default value for \fI$mac_\|depth\fR is 50 This can be changed to some other value \fIn\fR by executing .(l | ?- globalset($mac_\|depth(\fIn\fR)). .)l. .sh 2 "Macro Expander Options" .lp The following options are recognized by the macro expander: .ip \fBd\fR Dumps all clauses to the user after expansion. Useful for debugging. .ip \fBe\fR Expand macros. If omitted, the expander simply converts each ::\-/2 clause to a normal :\-/2 clause. .ip \fBv\fR ``Verbose'' mode. Prints macros that are/are not being expanded. .\" -------------------- end of section seca0.t --------------------