
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.



Arguments
   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.

Type
   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 --- One or more arguments not instantiated.
     5 --- TermClass not of form Atom, Atom/Integer or type(Type).
     5 --- TransPred not of form Atom/Integer.
     5 --- Options not a list or contains invalid flags.
     6 --- Arity of TransPred is not 2 or 3.
     6 --- Illegal flag in Options.
   161 --- 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
