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