| GPP(1) | General Commands Manual | GPP(1) |
NAME¶
GPP - Generic PreprocessorSYNOPSIS¶
gpp [-{o|O} outfile] [-I/include/path] [-Dname=val ...]
[-z|+z] [-x] [-m] [-C|-T|-H|-X|-P|-U ... [-M ...]]
[-n|+n] [+c <n> str1 str2] [+s<n> str1 str2 c]
[-c str1] [--nostdinc] [--nocurinc]
[--curdirinclast] [--warninglevel n]
[--includemarker str] [--include file]
[ infile]
gpp --help
gpp --version
DESCRIPTION¶
GPP is a general-purpose preprocessor with customizable syntax, suitable for a wide range of preprocessing tasks. Its independence from any programming language makes it much more versatile than cpp, while its syntax is lighter and more flexible than that of m4.OPTIONS¶
GPP recognizes the following command-line switches and options. Note that the -nostdinc, -nocurinc, -curdirinclast, -warninglevel, and -includemarker options from version 2.1 and earlier are deprecated and should not be used. Use the "long option" variants instead (--nostdinc, etc.).- -h --help
- Print a short help message.
- --version
- Print version information.
- -o outfile
- Specify a file to which all output should be sent (by default, everything is sent to standard output).
- -O outfile
- Specify a file to which all output should be sent; output is simultanously sent to stdout.
- -I/include/path
- Specify a path where the #include meta-macro will look for include files if they are not present in the current directory. The default is /usr/include if no -I option is specified. Multiple -I options may be specified to look in several directories.
- -Dname=val
- Define the user macro name as equal to val. This is strictly equivalent to using the #define meta-macro, but makes it possible to define macros from the command-line. If val makes references to arguments or other macros, it should conform to the syntax of the mode specified on the command-line. Starting with version 2.1, macro argument naming is allowed on the command-line. The syntax is as follows: -D macro(arg1,...)=definition. The arguments are specified in C-style syntax, without any whitespace, but the definition should still conform to the syntax of the mode specified on the command-line.
- +z
- Set text mode to Unix mode (LF terminator). Any CR character in the input is systematically discarded. This is the default under Unix systems.
- -z
- Set text mode to DOS mode (CR-LF terminator). In this mode all CR characters are removed from the input, and all output LF characters are converted to CR-LF. This is the default if GPP is compiled with the WIN_NT option.
- -x
- Enable the use of the #exec meta-macro. Since #exec includes the output of an arbitrary shell command line, it may cause a potential security threat, and is thus disabled unless this option is specified.
- -m
- Enable automatic mode switching to the cpp compatibility mode if the name of an included file ends in `.h' or `.c'. This makes it possible to include C header files with only minor modifications.
- -n
- Prevent newline or whitespace characters from being removed from the input when they occur as the end of a macro call or of a comment. By default, when a newline or whitespace character forms the end of a macro or a comment it is parsed as part of the macro call or comment and therefore removed from output. Use the -n option to keep the last character in the input stream if it was whitespace or a newline. This is activated in cpp and Prolog modes.
- +n
- The opposite of -n. This is the default in all modes except cpp and Prolog. Note that +n must be placed after -C or -P in order to have any effect.
- -U arg1 ... arg9
- User-defined mode. The nine following command-line arguments are taken to be respectively the macro start sequence, the macro end sequence for a call without arguments, the argument start sequence, the argument separator, the argument end sequence, the list of characters to stack for argument balancing, the list of characters to unstack, the string to be used for referring to an argument by number, and finally the quote character (if there is none an empty string should be provided). These settings apply both to user macros and to meta-macros, unless the -M option is used to define other settings for meta-macros. See the section on syntax specification for more details.
- -M arg1 ... arg7
- User-defined mode specifications for meta-macros. This option can only be used together with -M. The seven following command-line arguments are taken to be respectively the macro start sequence, the macro end sequence for a call without arguments, the argument start sequence, the argument separator, the argument end sequence, the list of characters to stack for argument balancing, and the list of characters to unstack. See below for more details.
- (default mode)
- The default mode is a vaguely cpp-like mode, but it does
not handle comments, and presents various incompatibilities with cpp.
Typical meta-macros and user macros look like this:
#define x y
macro(arg,...)This mode is equivalent to
-U "" "" "(" "," ")" "(" ")" "#" "\\"
-M "#" "\n" " " " " "\n" "(" ")"
- -C
- cpp compatibility mode. This is the mode where GPP's
behavior is the closest to that of cpp. Unlike in the default mode,
meta-macro expansion occurs only at the beginning of lines, and C comments
and strings are understood. This mode is equivalent to
-n -U "" "" "(" "," ")" "(" ")" "#" ""
-M "\n#\w" "\n" " " " " "\n" "" ""
+c "/*" "*/" +c "//" "\n" +c "\\\n" ""
+s "\"" "\"" "\\" +s "'" "'" "\\"
- -T
- TeX-like mode. In this mode, typical meta-macros and user
macros look like this:
\define{x}{y}
\macro{arg}{...}No comments are understood. This mode is equivalent to
-U "\\" "" "{" "}{" "}" "{" "}" "#" "@"
- -H
- HTML-like mode. In this mode, typical meta-macros and user
macros look like this:
<#define x|y>
<#macro arg|...>No comments are understood. This mode is equivalent to
-U "<#" ">" "\B" "|" ">" "<" ">" "#" "\\"
- -X
- XHTML-like mode. In this mode, typical meta-macros and user
macros look like this:
<#define x|y/>
<#macro arg|.../>No comments are understood. This mode is equivalent to
-U "<#" "/>" "\B" "|" "/>" "<" ">" "#" "\\"
- -P
- Prolog-compatible cpp-like mode. This mode differs from the
cpp compatibility mode by its handling of comments, and is equivalent to
-n -U "" "" "(" "," ")" "(" ")" "#" ""
-M "\n#\w" "\n" " " " " "\n" "" ""
+ccss "\!o/*" "*/" +ccss "%" "\n" +ccii "\\\n" ""
+s "\"" "\"" "" +s "\!#'" "'" ""
- +c<n> str1 str2
- Specify comments. Any unquoted occurrence of str1 will be interpreted as the beginning of a comment. All input up to the first following occurrence of str2 will be discarded. This option may be used multiple times to specify different types of comment delimiters. The optional parameter <n> can be specified to alter the behavior of the comment and, e.g., turn it into a string or make it ignored under certain circumstances, see below.
- -c str1
- Un-specify comments or strings. The comment/string specification whose start sequence is str1 is removed. This is useful to alter the built-in comment specifications of a standard mode -- e.g., the cpp compatibility mode.
- +s<n> str1 str2 c
- Specify strings. Any unquoted occurrence of str1 will be interpreted as the beginning of a string. All input up to the first following occurrence of str2 will be output as is without any evaluation. The delimiters themselves are output. If c is non-empty, its first character is used as a string-quote character -- i.e., a character whose presence immediately before an occurrence of str2 prevents it from terminating the string. The optional parameter <n> can be specified to alter the behavior of the string and, e.g., turn it into a comment, enable macro evaluation inside the string, or make the string specification ignored under certain circumstances. See below.
- -s str1
- Un-specify comments or strings. Identical to -c.
- --include file
- Process file before infile
- --nostdinc
- Do not look for include files in the standard directory /usr/include.
- --nocurinc
- Do not look for include files in the current directory.
- --curdirinclast
- Look for include files in the current directory after the directories specified by -I rather than before them.
- --warninglevel n
- Set warning level to n (0, 1 or 2). Default is 2 (most verbose).
- --includemarker str
- keep track of #include directives by inserting a marker in the output stream. The format of the marker is determined by str, which must contain three occurrences of the character % (or equivalently ?). The first occurrence is replaced with the line number, the second with the file name, and the third with 1, 2 or blank. When this option is specified in default, cpp or Prolog mode, GPP does its best to ensure that line numbers are the same in the output as in the input by inserting blank lines in the place of definitions or comments.
- infile
- Specify an input file from which GPP reads its input. If no
input file is specified, input is read from standard input.
SYNTAX SPECIFICATION¶
The syntax of a macro call is as follows: it must start with a sequence of characters matching the macro start sequence as specified in the current mode, followed immediately by the name of the macro, which must be a valid identifier -- i.e., a sequence of letters, digits, or underscores ("_"). The macro name must be followed by a short macro end sequence if the macro has no arguments, or by a sequence of arguments initiated by an argument start sequence. The various arguments are then separated by an argument separator, and the macro ends with a long macro end sequence.- i
- disable the comment/string specification.
- c
- comment (neither evaluated nor output).
- s
- string (the string and its delimiter sequences are output as-is).
- q
- quoted string (the string is output as-is, without the delimiter sequences).
- C
- evaluated comment (macros are evaluated, but output is discarded).
- S
- evaluated string (macros are evaluated, delimiters are output).
- Q
- evaluated quoted string (macros are evaluated, delimiters
are not output).
- b
- matches any sequence of one or more spaces or tab characters (`\b' is identical to ` ').
- w
- matches any sequence of zero or more spaces or tab characters.
- B
- matches any sequence of one or more spaces, tabs or newline characters.
- W
- matches any sequence of zero or more spaces, tabs or newline characters.
- a
- an alphabetic character (`a' to `z' and `A' to `Z').
- A
- an alphabetic character, or a space, tab or newline.
- #
- a digit (`0' to `9').
- i
- an identifier character. The set of matched characters is customizable using the #mode charset id command. The default setting matches alphanumeric characters and underscores (`a' to `z', `A' to `Z', `0' to `9' and `_').
- t
- a tab character.
- n
- a newline character.
- o
- an operator character. The set of matched characters is customizable using the #mode charset op command. The default setting matches all characters in "+-*/\^<>=`~:.?@#&!%|", except in Prolog mode where `!', `%' and `|' are not matched.
- O
- an operator character or a parenthesis character. The set
of additional matched characters in comparison with `\o' is customizable
using the #mode charset par command. The default setting is to have
the characters in "()[]{}" as parentheses.
EVALUATION RULES¶
Input is read sequentially and interpreted according to the rules of the current mode. All input text is first matched against the specified comment/string start sequences of the current mode (except those which are disabled by the 'i' modifier), unless the body being evaluated is the contents of a comment/string whose modifier enables macro evaluation. The most recently defined comment/string specifications are checked for first. Important note: comments may not appear between the name of a macro and its arguments (doing so results in undefined behavior).META-MACROS¶
These macros are always predefined. Their actual calling sequence depends on the current mode; here we use cpp-like notation.- #define x y
- This defines the user macro x as y. y
can be any valid GPP input, and may for example refer to other macros.
x must be an identifier ( i.e., a sequence of alphanumeric
characters and '_'), unless named arguments are specified. If x is
already defined, the previous definition is overwritten. If no second
argument is given, x will be defined as a macro that outputs
nothing. Neither x nor y are evaluated; the macro definition
is only evaluated when it is called, not when it is declared.
It is also possible to name the arguments in a macro definition: in that case, the argument x should be a user-macro call whose arguments are all identifiers. These identifiers become available as user-macros inside the macro definition; these virtual macros must be called without arguments, and evaluate to the corresponding macro parameter.
- #defeval x y
- This acts in a similar way to #define, but the second argument y is evaluated immediately. Since user macro definitions are also evaluated each time they are called, this means that the macro y will undergo two successive evaluations. The usefulness of #defeval is considerable as it is the only way to evaluate something more than once, which may be needed to force evaluation of the arguments of a meta-macro that normally doesn't perform any evaluation. However since all argument references evaluated at define-time are understood as the arguments of the body in which the macro is being defined and not as the arguments of the macro itself, usually one has to use the quote character to prevent immediate evaluation of argument references.
- #undef x
- This removes any existing definition of the user macro x.
- #ifdef x
- This begins a conditional block. Everything that follows is evaluated only if the identifier x is defined, and until either a #else or a #endif statement is reached. Note, however, that the commented text is still scanned thoroughly, so its syntax must be valid. It is in particular legal to have the #else or #endif statement ending the conditional block appear only as the result of a user-macro expansion and not explicitly in the input.
- #ifndef x
- This begins a conditional block. Everything that follows is evaluated only if the identifier x is not defined.
- #ifeq x y
- This begins a conditional block. Everything that follows is evaluated only if the results of the evaluations of x and y are identical as character strings. Any leading or trailing whitespace is ignored for the comparison. Note that in cpp-mode any unquoted whitespace character is understood as the end of the first argument, so it is necessary to be careful.
- #ifneq x y
- This begins a conditional block. Everything that follows is evaluated only if the results of the evaluations of x and y are not identical (even up to leading or trailing whitespace).
- #else
- This toggles the logical value of the current conditional block. What follows is evaluated if and only if the preceding input was commented out.
- #endif
- This ends a conditional block started by a #if... meta-macro.
- #include file
- This causes GPP to open the specified file and evaluate its
contents, inserting the resulting text in the current output. All defined
user macros are still available in the included file, and reciprocally all
macros defined in the included file will be available in everything that
follows. The include file is looked for first in the current directory,
and then, if not found, in one of the directories specified by the
-I command-line option (or /usr/include if no directory was
specified). Note that, for compatibility reasons, it is possible to put
the file name between "" or <>.
The order in which the various directories are searched for include files is affected by the -nostdinc, -nocurinc and -curdirinclast command-line options.Upon including a file, GPP immediately saves a copy of the current operating mode onto the mode stack, and restores the operating mode at the end of the included file. The included file may override this behavior by starting with a #mode restore call and ending with a #mode push call. Additionally, when the -m command line option is specified, GPP will automatically switch to the cpp compatibility mode upon including a file whose name ends with either '.c' or '.h'.
- #exec command
- This causes GPP to execute the specified command line and include its standard output in the current output. Note that, for security reasons, this meta-macro is disabled unless the -x command line flag was specified. If use of #exec is not allowed, a warning message is printed and the output is left blank. Note that the specified command line is evaluated before being executed, thus allowing the use of macros in the command-line. However, the output of the command is included verbatim and not evaluated. If you need the output to be evaluated, you must use #defeval (see above) to cause a double evaluation.
- #eval expr
- The #eval meta-macro attempts to evaluate
expr first by expanding macros (normal GPP evaluation) and then by
performing arithmetic evaluation and/or wildcard matching. The syntax and
operator precedence for arithmetic expressions are the same as in C; the
only missing operators are <<, >>, ?:, and the assignment
operators.
POSIX-style wildcard matching ('globbing') is available only on POSIX implementations and can be invoked with the =~ operator. In brief, a '?' matches any single character, a '*' matches any string (including the empty string), and '[...]' matches any one of the characters enclosed in brackets. A '[...]' class is complemented when the first character in the brackets is '!'. The characters in a '[...]' class can also be specified as a range using the '-' character -- e.g., '[F-N]' is equivalent to '[FGHIJKLMN]'.If unable to assign a numerical value to the result, the returned text is simply the result of macro expansion without any arithmetic evaluation. The only exceptions to this rule are the comparison operators ==, !=, <, >, <=, and >= which, if one of the sides does not evaluate to a number, perform string comparison instead (ignoring trailing and leading spaces). Additionally, the length(...) arithmetic operator returns the length in characters of its evaluated argument.Inside arithmetic expressions, the defined(...) special user macro is also available: it takes only one argument, which is not evaluated, and returns 1 if it is the name of a user macro and 0 otherwise.
- #if expr
- This meta-macro invokes the arithmetic/globbing evaluator in the same manner as #eval and compares the result of evaluation with the string "0" in order to begin a conditional block. In particular note that the logical value of expr is always true when it cannot be evaluated to a number.
- #elif expr
- This meta-macro can be used to avoid nested #if conditions. #if ... #elif ... #endif is equivalent to #if ... #else #if ... #endif #endif.
- #mode keyword ...
- This meta-macro controls GPP's operating mode. See below for a list of #mode commands.
- #line
- This meta-macro evaluates to the line number of the current input file.
- #file
- This meta-macro evaluates to the filename of the current input file as it appears on the command line or in the argument to #include. If GPP is reading its input from stdin, then #file evaluates to `stdin'.
- #date fmt
- This meta-macro evaluates to the current date and time as formatted by the specified format string fmt. See the section DATE AND TIME CONVERSION SPECIFIERS below.
- #error msg
- This meta-macro causes an error message with the current filename and line number, and with the text msg, to be printed to the standard error device. Subsequent processing is then aborted.
- #warning msg
- This meta-macro causes a warning message with the current
filename and line number, and with the text msg, to be printed to
the standard error device. Subsequent processing is then resumed.
- #mode save / #mode push
- Push the current mode specification onto the mode stack.
- #mode restore / #mode pop
- Pop mode specification from the mode stack.
- #mode standard name
- Select one of the standard modes. The only argument must be one of: default (default mode); cpp, C (cpp mode); tex, TeX (tex mode); html, HTML (html mode); xhtml, XHTML (xhtml mode); prolog, Prolog (prolog mode). The mode name must be given directly, not as a C string.
- #mode user "s1" ... "s9"
- Specify user macro syntax. The 9 arguments, all of them C strings, are the mode specification for user macros (see the -U command-line option and the section on syntax specification). The meta-macro specification is not affected.
- #mode meta {user | "s1" ... "s7"}
- Specify meta-macro syntax. Either the only argument is user (not as a string), and the user-macro mode specifications are copied into the meta-macro mode specifications, or there must be seven string arguments, whose significance is the same as for the -M command-line option (see section on syntax specification).
- #mode quote ["c"]
- With no argument or "" as argument, removes the quote character specification and disables the quoting functionality. With one string argument, the first character of the string is taken to be the new quote character. The quote character can be neither alphanumeric nor '_', nor can it be one of the special matching sequences.
- #mode comment [xxx] "start" "end" ["c" ["c"]]
- Add a comment specification. Optionally a first argument consisting of three characters not enclosed in " " can be used to specify a comment/string modifier (see the section on syntax specification). The default modifier is ccc. The first two string arguments are used as comment start and end sequences respectively. The third string argument is optional and can be used to specify a string-quote character. (If it is "", the functionality is disabled.) The fourth string argument is optional and can be used to specify a string delimitation warning character. (If it is "", the functionality is disabled.)
- #mode string [xxx] "start" "end" ["c" ["c"]]
- Add a string specification. Identical to #mode comment except that the default modifier is sss.
- #mode nocomment / #mode nostring ["start"]
- With no argument, remove all comment/string specifications. With one string argument, delete the comment/string specification whose start sequence is the argument.
- #mode preservelf { on | off | 1 | 0 }
- Equivalent to the -n command-line switch. If the argument is on or 1, any newline or whitespace character terminating a macro call or a comment/string is left in the input stream for further processing. If the argument is off or 0 this feature is disabled.
- #mode charset { id | op | par } "string"
- Specify the character sets to be used for matching the \o,
\O and \i special sequences. The first argument must be one of id
(the set matched by \i), op (the set matched by \o) or par
(the set matched by \O in addition to the one matched by \o).
"string" is a C string which lists all characters to put
in the set. It may contain only the special matching sequences \a, \A, \b,
\B, and \# (the other sequences and the negated sequences are not
allowed). When a '-' is found inbetween two non-special characters this
adds all characters inbetween (e.g. "A-Z" corresponds to all
uppercase characters). To have '-' in the matched set, either put it in
first or last position or place it next to a \x sequence.
DATE AND TIME CONVERSION SPECIFIERS¶
Ordinary characters placed in the format string are copied to without conversion. Conversion specifiers are introduced by a `%' character, and are replaced as follows:- %a
- The abbreviated weekday name according to the current locale.
- %A
- The full weekday name according to the current locale.
- %b
- The abbreviated month name according to the current locale.
- %B
- The full month name according to the current locale.
- %c
- The preferred date and time representation for the current locale.
- %d
- The day of the month as a decimal number (range 01 to 31).
- %F
- Equivalent to %Y-%m-%d (the ISO 8601 date format).
- %H
- The hour as a decimal number using a 24-hour clock (range 00 to 23).
- %I
- The hour as a decimal number using a 12-hour clock (range 01 to 12).
- %j
- The day of the year as a decimal number (range 001 to 366).
- %m
- The month as a decimal number (range 01 to 12).
- %M
- The minute as a decimal number (range 00 to 59).
- %p
- Either `AM' or `PM' according to the given time value, or the corresponding strings for the current locale. Noon is treated as `pm' and midnight as `am'.
- %R
- The time in 24-hour notation (%H:%M).
- %S
- The second as a decimal number (range 00 to 61).
- %U
- The week number of the current year as a decimal number, range 00 to 53, starting with the first Sunday as the first day of week 01.
- %w
- The day of the week as a decimal, range 0 to 6, Sunday being 0.
- %W
- The week number of the current year as a decimal number, range 00 to 53, starting with the first Monday as the first day of week 01.
- %x
- The preferred date representation for the current locale without the time.
- %X
- The preferred time representation for the current locale without the date.
- %y
- The year as a decimal number without a century (range 00 to 99).
- %Y
- The year as a decimal number including the century.
- %Z
- The time zone or name or abbreviation.
- %%
- A literal `%' character.
EXAMPLES¶
Here is a basic self-explanatory example in standard or cpp mode:#define FOO This is
#define BAR a message.
#define concat #1 #2
concat(FOO,BAR)
#ifeq (concat(foo,bar)) (foo bar)
This is output.
#else
This is not output.
#endif
#define concat(x,y) x y
\define{FOO}{This is}
\define{BAR}{a message.}
\define{\concat{x}{y}}{\x \y}
\concat{\FOO}{\BAR}
\ifeq{\concat{foo}{bar}}{foo bar}
This is output.
\else
This is not output.
\endif
<#define FOO|This is>
<#define BAR|a message.>
<#define concat|#1 #2>
<#concat <#FOO>|<#BAR>>
<#ifeq <#concat foo|bar>|foo bar>
This is output.
<#else>
This is not output.
<#endif>
#define FOO This is \
a multiline definition.
#define BLAH(x) My argument is x
BLAH(urf)
\BLAH(urf)
#define BLAH foo
BLAH "BLAH" /* BLAH */
'It\'s a /*string*/ !'
<#ifeq <#exec echo blah>|blah
> #exec allowed <#else> #exec not allowed <#endif>
#ifeq (#exec echo blah
) (blah
)
\#exec allowed
#else
\#exec not allowed
#endif
#mode string QQQ "$" "$"
#ifeq $#exec echo blah
$ $blah
$
\#exec allowed
#else
\#exec not allowed
#endif
#ifeq blah #exec echo -n blah
\#exec allowed
#else
\#exec not allowed
#endif
#define DUP(x) x x
#define FOO and I said: DUP
FOO(blah)
<#define APPLY|<#defeval TEMP|<\##1 \#1>><#TEMP #2>>
<#define <#foo x>|<#x> and <#x>>
<#APPLY foo|BLAH>
#define BALANCE(x) x
#define APPLY(f,v) BALANCE(#defeval TEMP f
TEMP(v))
#define foo(x) x and x
APPLY(\foo,BLAH)
#define x 4
The answer is:
#eval x*x + 2*(16-x) + 1998%x
#if defined(x)&&!(3*x+5>17)
This should be output.
#endif
#mode push
#define f(x) x x
#mode standard tex
\f{blah}
\mode{string}{"$" "$"}
\mode{comment}{"/*" "*/"}
$\f{urf}$ /* blah */
\define{FOO}{bar/* and some more */}
\mode{pop}
f($FOO$)
#define blah(x) "and he said: x"
blah(foo)
#mode push
#mode nostring "\""
#define blah(x) "and he said: x"
#mode pop
#mode quote "`"
#define blah(x) `"and he said: x`"
#mode string QQQ "$$" "$$"
#define blah(x) $$"and he said: x"$$
#define myeval #eval #1
#define x 1
#defeval x #eval x+1
ADVANCED EXAMPLES¶
Here are some examples of advanced constructions using GPP. They tend to be pretty awkward and should be considered as evidence of GPP's limitations.\define{countdown}{
\if{#1}
#1...
\define{loop}{\countdown}
\else
Done.
\define{loop}{}
\endif
\loop{\eval{#1-1}}
}
\countdown{10}
#mode string QQQ "$" "$"
#define triangle(x,y) y \
$#if length(y)<x$ $#define iter triangle$ $#else$ \
$#define iter$ $#endif
$ iter(x,*y)
triangle(20)
#mode string "`" "`" "\\"
#define ASIS(x) x
#define SILENT(x) ASIS()
#define EVAL(x,f,v) SILENT(
#mode string QQQ "`" "`" "\\"
#defeval TEMP0 x
#defeval TEMP1 (
\#define \TEMP2(TEMP0) f
)
TEMP1
)TEMP2(v)
#define LAMBDA(x,f,v) SILENT(
#ifneq (v) ()
#define TEMP3(a,b,c) EVAL(a,b,c)
#else
#define TEMP3(a,b,c) \LAMBDA(a,b)
#endif
)TEMP3(x,f,v)
#define EVALAMBDA(x,y) SILENT(
#defeval TEMP4 x
#defeval TEMP5 y
)
#define APPLY(f,v) SILENT(
#defeval TEMP6 ASIS(\EVA)f
TEMP6
)EVAL(TEMP4,TEMP5,v)
LAMBDA(z,z+z)
=> LAMBDA(z,z+z)
LAMBDA(z,z+z,2)
=> 2+2
#define f LAMBDA(y,y*y)
f
=> LAMBDA(y,y*y)
APPLY(f,blah)
=> blah*blah
APPLY(LAMBDA(t,t t),(t t))
=> (t t) (t t)
LAMBDA(x,APPLY(f,(x+x)),urf)
=> (urf+urf)*(urf+urf)
APPLY(APPLY(LAMBDA(x,LAMBDA(y,x*y)),foo),bar)
=> foo*bar
#define test LAMBDA(y,`#ifeq y urf
y is urf#else
y is not urf#endif
`)
APPLY(test,urf)
=> urf is urf
APPLY(test,foo)
=> foo is not urf