[ Obsolete | The ECLiPSe Built-In Predicates | Reference Manual | Alphabetic Index ]

# define_macro(++TermClass, ++TransPred, ++Options)

Defines a macro transformation for the functor or type specified by TermClass. The transformation predicate is TransPred and Options is a list of options.

TermClass
  Term in the form Atom, Atom/Integer or type(Type).
TransPred
  Term in the form Atom/Integer.
Options
  Possibly empty list of option flags.

### This built-in predicate is obsolete!

## Description

This predicate is used to define a macro transformation on a class of terms. Macro transformation can be performed in two different situations, when a term is read by one of the read predicates (read macros) and when a term is written by one of the write predicates (write macros).

The TermClass specifies to which terms the transformation will be applied:

Name/Arity transform all terms with the specified functor

type(Type) transform all terms of the specified type, where Type is one of compound, string, integer, rational, float, breal, goal, atom, meta.

The +TransPred argument specifies the predicate that will perform the transformation. TransPred must be of arity 2 or 3 and be in the form: trans_function(OldTerm, NewTerm [, Module]):- ... .

At transformation time, the system will call TransPred in the module where define_macro/3 was invoked. The term to transform is passed as the first argument, the second is a free variable which should be bound to the transformed term, and the optional third argument is the module where the term is read or written.

Options is a list which may be empty (in this case the macro defaults to a local read term macro) or contain specifications from the following categories:

* visibility

local: The transformation is only visible in this module (default).

global: The transformation is globally visible.

* mode

read: This is a read macro and shall be applied after reading a term (default).

write: This is a write macro and shall be applied before printing a term.

* type

term: Transform all terms (default).

clause: Transform only if the term is a program clause, i.e. inside compile/1, assert/1 etc. Write macros are applied using the 'C' option in the printf/2 predicate.

goal: Write macros are applied when using the 'G' option in the printf/2 predicate. Note that goal (read) macros are obsolete, please use inline/2 instead.

* additional specification

protect_arg: Disable transformation of subterms (optional).

top_only: Consider only the whole term, not subterms (optional).

A TermClass can have a read and a write macro attached at the same time. By default, macro transformations are local to the module where they were defined. That means, only read/write built-ins that are called from inside this module do these transformations. Local macros hide global ones.

### Modes and Determinism

- define_macro(++, ++, ++) is det

### Exceptions

(4) instantiation fault
  One or more arguments not instantiated.
(5) type error
  TermClass not of form Atom, Atom/Integer or type(Type).
(5) type error
  TransPred not of form Atom/Integer.
(5) type error
  Options not a list or contains invalid flags.
(6) out of range
  Arity of TransPred is not 2 or 3.
(6) out of range
  Illegal flag in Options.
(161) macro transformation already defined in this module
  Transformation already defined in the current module for TermClass

## Examples

    Success:
       % The following example illustrates how a/1 may be
       % transformed into b/2 using the reader.
       [eclipse]: [user].
        trans_a(a(X),b(X,10)).
        :-define_macro(a/1,trans_a/2,[]).

       yes.
       [eclipse]: read(X).
       > a(fred).

       X = b(fred, 10)
       yes.

       %
       % Example showing use of protect_arg
       %
       [eclipse]: [user].
        ?- define_macro(b/1, trb/2, []),
           define_macro(b_protect/1, trb/2, [protect_arg]),
           define_macro(d/0, trd/2, []).
        trb(X, newfunctor(Arg)) :- arg(1, X, Arg).
        trd(d, newd).

       yes.
       [eclipse]: read(X1),read(X2).
       > b(d).
       > b_protect(d).

       X1 = newfunctor(newd)    % d is transformed
       X2 = newfunctor(d)       % d is not transformed
       yes.

       %
       % Example showing use of type macros
       %
        [eclipse 1]: [user].
         tr_int(0, 0).
         tr_int(N, s(S)) :- N > 0, N1 is N-1, tr_int(N1, S).
         :- define_macro(type(integer), tr_int/2, []).

        yes.
        [eclipse 2]: read(X).
        3.

        X = s(s(s(0)))
        yes.

       %
       % Example showing use of write macros
       %
        [eclipse 1]: [user].
         tr_s(0, 0).
         tr_s(s(S), N) :- tr_s(S, N1), N is N1+1.
         :- define_macro(s/1, tr_s/2, [write]).

        yes.
        [eclipse 2]: write(s(s(s(0)))).
        3
        yes.

    Error:
       define_macro(X, trx/2, []).              (Error 4).
       define_macro(a/1, tra/2, [c]).           (Error 6).

## See Also

macro / 3, portray / 3, current_macro / 4, erase_macro / 1, phrase / 2, phrase / 3, inline / 2