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