mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-07-24 10:25:42 -04:00
preproc, %map(): require second colon, update documentation
Require the second colon before the grouped parameter count; otherwise the syntax is ambiguous since an expression can start with (. Update/complete the documentation and the examples. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
cb96db9b70
commit
9f83c383e4
@ -7455,14 +7455,13 @@ stdmac_map(const SMacro *s, Token **params, int nparam)
|
|||||||
|
|
||||||
fixargs = NULL;
|
fixargs = NULL;
|
||||||
fixparams = 0;
|
fixparams = 0;
|
||||||
|
mparams = 1;
|
||||||
t = skip_white(t->next);
|
t = skip_white(t->next);
|
||||||
if (tok_is(t, ':')) {
|
if (tok_is(t, ':')) {
|
||||||
fixargs = t->next;
|
fixargs = t->next;
|
||||||
fixparams = count_smacro_args(fixargs, &t);
|
fixparams = count_smacro_args(fixargs, &t);
|
||||||
if (fixparams)
|
|
||||||
t = skip_white(t->next);
|
t = skip_white(t->next);
|
||||||
}
|
|
||||||
mparams = 1;
|
|
||||||
if (tok_is(t, ':')) {
|
if (tok_is(t, ':')) {
|
||||||
struct ppscan pps;
|
struct ppscan pps;
|
||||||
struct tokenval tokval;
|
struct tokenval tokval;
|
||||||
@ -7492,6 +7491,7 @@ stdmac_map(const SMacro *s, Token **params, int nparam)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nparam--;
|
nparam--;
|
||||||
params++;
|
params++;
|
||||||
|
@ -2959,22 +2959,60 @@ argument to the conditional using \c{\{\}}:
|
|||||||
\S{f_map} \i\c{%map()} Function
|
\S{f_map} \i\c{%map()} Function
|
||||||
|
|
||||||
The \c{%map()} function takes as its first parameter the name of a
|
The \c{%map()} function takes as its first parameter the name of a
|
||||||
single-line macro, optionally followed by a colon and an integer
|
single-line macro, followed by up to two optional colon-separated
|
||||||
expression (default 1), specifying the number of parameter to the
|
subparameters:
|
||||||
macro, \e{n}.
|
|
||||||
|
|
||||||
The following parameters are then passed as parameters to the given
|
\b The first subparameter, if present, should be a list of macro
|
||||||
macro for expansion, in groups of \e{n}, and the results turned into a
|
parameters enclosed in parentheses. Note that \c{()} represents a
|
||||||
comma-separated list.
|
one-argument list containing an empty parameter; omit the parentheses
|
||||||
|
to specify no parameters.
|
||||||
|
|
||||||
|
\b The second subparameter, if present, represent the number of
|
||||||
|
group size for additional parameters to the macro (default 1).
|
||||||
|
|
||||||
|
Further parameters, if any, are then passed as additional parameters to the
|
||||||
|
given macro for expansion, in sets given by the specified group size,
|
||||||
|
and the results turned into a comma-separated list. If no additional
|
||||||
|
parameters are given, \c{%map()} expands to nothing.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
\c %define alpha(&x) x
|
||||||
\c %define alpha(&x,y) y dup (x)
|
\c %define alpha(&x,y) y dup (x)
|
||||||
\c db %map(alpha:2,foo,bar,baz,quux)
|
\c %define alpha(s,&x,y) y dup (x,s)
|
||||||
|
\c ; 0 fixed + 1 grouped parameters per call, calls alpha(&x)
|
||||||
|
\c db %map(alpha,foo,bar,baz,quux)
|
||||||
|
\c ; 0 fixed + 2 grouped parameters per call, calls alpha(&x,y)
|
||||||
|
\c db %map(alpha::2,foo,bar,baz,quux)
|
||||||
|
\c ; 1 fixed + 2 grouped parameters per call, calls alpha(s,&x,y)
|
||||||
|
\c db %map(alpha:("!"):2,foo,bar,baz,quux)
|
||||||
|
|
||||||
... expands to:
|
... expands to:
|
||||||
|
|
||||||
\c db bar dup ("foo"),quux dup ("baz")
|
\c db 'foo','bar','baz','quux'
|
||||||
|
\c db bar dup ('foo'),quux dup ('baz')
|
||||||
|
\c db bar dup ('foo',"!"),quux dup ('baz',"!")
|
||||||
|
|
||||||
|
As a more complex example, a macro that joins quoted strings together
|
||||||
|
with a user-specified delimiter string:
|
||||||
|
|
||||||
|
\c %define join(sep) '' ; handle the case of zero strings
|
||||||
|
\c %define _join(sep,str) sep,str ; helper macro
|
||||||
|
\c %define join(sep,s1,sn+) %strcat(s1, %map(_join:(sep) %, sn))
|
||||||
|
\c
|
||||||
|
\c db join(':')
|
||||||
|
\c db join(':','a')
|
||||||
|
\c db join(':','a','b')
|
||||||
|
\c db join(':','a','b','c')
|
||||||
|
\c db join(':','a','b','c','d')
|
||||||
|
|
||||||
|
... expands to:
|
||||||
|
|
||||||
|
\c db ''
|
||||||
|
\c db 'a'
|
||||||
|
\c db 'a:b'
|
||||||
|
\c db 'a:b:c'
|
||||||
|
\c db 'a:b:c:d'
|
||||||
|
|
||||||
|
|
||||||
\S{f_num} \i\c{%num()} Function
|
\S{f_num} \i\c{%num()} Function
|
||||||
|
14
test/map.asm
14
test/map.asm
@ -1,7 +1,15 @@
|
|||||||
%define foo(x) (x+1)
|
%define foo(x) (x+1)
|
||||||
%define bar(=x,y) (x*y)
|
%define bar(=x,y) (x*y)
|
||||||
%define baz(x+) %(x)
|
%define baz(x+) %(x)
|
||||||
|
|
||||||
dw %map(foo,1,2,3,4)
|
dw %map(foo,1,2,3,4)
|
||||||
dw %map(bar:2,1+2,3+4,5+6,7+8)
|
dw %map(bar::2,1+2,3+4,5+6,7+8)
|
||||||
dw %map(baz:2,1+2,3+4,5+6,7+8)
|
dw %map(baz::2,1+2,3+4,5+6,7+8)
|
||||||
|
|
||||||
|
bar equ 8
|
||||||
|
quux equ 4
|
||||||
|
%define alpha(&x) x
|
||||||
|
%define alpha(&x,y) y dup (x)
|
||||||
|
%define alpha(s,&x,y) y dup (x,s)
|
||||||
|
db %map(alpha,foo,bar,baz,quux)
|
||||||
|
db %map(alpha::2,foo,bar,baz,quux)
|
||||||
|
db %map(alpha:("!"):2,foo,bar,baz,quux)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user