spec

Software for Diffraction

2.4.4.3. - Macro Arguments



Within ordinary macros (not macro functions), the symbols $1, $2, ..., are replaced by the arguments with which the macro is invoked. Arguments are defined as strings of characters separated by spaces. Also,
$0 is replaced with the macro name,
$* is replaced with all the arguments,
$@  is replaced with arguments delimited by \a,
$# is replaced with the number of arguments,
$$ is a literal $.
A macro argument is a string of characters delimited by spaces. Use quotes to include spaces within a single argument. Use \" or \' to pass literal quotes. Arguments can be continued over more than one line by putting a backslash at the end of the line.

When a macro defined without arguments is invoked, only the macro name is replaced with the definition.

When a macro defined with arguments is invoked, all characters on the input line up to a ;, a { or the end of the line are eaten up, whether or not the macro uses them as arguments.

When numbered arguments are referred to in the macro definition, but are missing when the macro is invoked, they are replaced with zeros. If $* is used in the definition and there are no arguments, no characters are substituted.

Argument substitution occurs very early in the input process, before the substituted text is sent to the parser. It is not possible to use variables or expressions to specify the argument number.

It is often useful when parsing macro arguments, particularly when the macro is called with a variable number of arguments, to use the split() function to place the arguments into an associative array. Typical syntax is:
{
   local ac, av[]
   ac = split("$*", av)
}
Note, that usage does not respect quoted arguments, since $* removes quotation marks when concatenating the macro arguments.

The sequence $@ is replaced with the concatenated arguments delimited by the special character \a (the audible bell, ^G , ASCII 7). The string can then be split as follows:
{
   local ac, av[]
   ac = split("$!", av, "\a")
}
The elements of av[] will respect the quoted arguments in the macro invocation. There is no syntax to escape the \a. .up

There are no limits on the length of macro definitions, the number of macro arguments or on the total combined size of all macro definitions.

Beware of unwanted side affects when referencing the same argument more than once. For example,
def test 'a = $1; b = 2 * $1'
invoked as test i++, would be replaced with a = i++; b = 2 * i++, with the result that i is incremented twice, even though that action is not apparent to the user. The previous definition also would cause problems if invoked as test 2+3, as that would be replaced with a = 2+3; b = 2 * 2+3. The latter expression evaluates to 7, not 10, as might have been intended by the user. Use of parenthesis to surround arguments used in arithmetic expressions in macro definitions will avoid such problems, as in b = 2 * ($1).