0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-10-10 00:25:06 -04:00

preproc: add a %selbits() function

Although one can implement this "manually" in terms of %sel(), this
function is *really* useful for making multi-mode tests and allows for
better error checking.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin
2025-10-07 09:17:59 -07:00
parent e4044cfc48
commit f1b6d3188c
3 changed files with 73 additions and 23 deletions

View File

@@ -7738,9 +7738,9 @@ stdmac_tok(const SMacro *s, Token **params, int nparams)
return reverse_tokens(tokenize(unquote_token_cstr(params[0])));
}
/* %cond() or %sel() */
/* %sel() */
static Token *
stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
stdmac_sel(const SMacro *s, Token **params, int nparams)
{
int64_t which;
@@ -7749,29 +7749,57 @@ stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
*/
which = get_tok_num(params[0], NULL);
if (s->expandpvt.u) {
/* Booleanize (for %cond): true -> 1, false -> 2 (else) */
which = which ? 1 : 2;
if (which >= nparams) {
/* false, and no else clause */
return NULL;
}
} else {
if (unlikely(which < 1)) {
nasm_warn(WARN_PP_SEL_RANGE,
"%s(%"PRId64") is not a valid selector", s->name, which);
return NULL;
} else if (unlikely(which >= nparams)) {
nasm_warn(WARN_PP_SEL_RANGE,
"%s(%"PRId64") exceeds the number of arguments",
s->name, which);
return NULL;
}
if (unlikely(which < 1)) {
nasm_warn(WARN_PP_SEL_RANGE,
"%s(%"PRId64") is not a valid selector", s->name, which);
return NULL;
} else if (unlikely(which >= nparams)) {
nasm_warn(WARN_PP_SEL_RANGE,
"%s(%"PRId64") exceeds the number of arguments",
s->name, which);
return NULL;
}
return new_Token(NULL, tok_smac_param(which), "", 0);
}
/* %cond() */
static Token *
stdmac_cond(const SMacro *s, Token **params, int nparams)
{
int64_t which;
(void)s;
(void)params;
/*
* params[0] will have been generated by make_tok_num.
*/
which = get_tok_num(params[0], NULL);
/* Booleanize: true -> 1, false -> 2 (else) */
which = which ? 1 : 2;
if (which >= nparams) {
/* false, and no else clause */
return NULL;
}
return new_Token(NULL, tok_smac_param(which), "", 0);
}
/* %selbits() */
static Token *
stdmac_selbits(const SMacro *s, Token **params, int nparams)
{
int which = ilog2_32(globl.bits)-4;
(void)s;
(void)params;
if (nparams <= which)
which = nparams - 1;
return new_Token(NULL, tok_smac_param(which), "", 0);
}
/* %count() function */
static Token *
stdmac_count(const SMacro *s, Token **params, int nparams)
@@ -8173,6 +8201,7 @@ static void pp_add_magic_simple(void)
{ "%null", false, 1, SPARM_GREEDY, stdmac_null },
{ "%pathsearch", false, 1, SPARM_PLAIN, stdmac_pathsearch },
{ "%realpath", false, 1, SPARM_PLAIN, stdmac_realpath },
{ "%selbits", false, 1, SPARM_PLAIN|SPARM_VARADIC, stdmac_selbits },
{ "%str", false, 1, SPARM_GREEDY|SPARM_STR, stdmac_join },
{ "%strcat", false, 1, SPARM_STR|SPARM_CONDQUOTE|SPARM_VARADIC, stdmac_strcat },
{ "%strlen", false, 1, SPARM_STR|SPARM_CONDQUOTE, stdmac_strlen },
@@ -8268,15 +8297,16 @@ static void pp_add_magic_miscfunc(void)
/* %sel() function */
nasm_zero(tmpl);
tmpl.nparam = 2;
tmpl.expand = stdmac_cond_sel;
tmpl.expand = stdmac_sel;
nasm_newn(tmpl.params, tmpl.nparam);
tmpl.params[0].flags = SPARM_EVAL;
tmpl.params[1].flags = SPARM_VARADIC;
define_magic("%sel", false, &tmpl);
/* %cond() function, a variation on %sel */
/* %cond() function */
nasm_zero(tmpl);
tmpl.nparam = 3;
tmpl.expandpvt.u = 1; /* Booleanize */
tmpl.expand = stdmac_cond;
nasm_newn(tmpl.params, tmpl.nparam);
tmpl.params[0].flags = SPARM_EVAL;
tmpl.params[1].flags = 0;