aboutsummaryrefslogtreecommitdiffstats
path: root/asm
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2020-07-11 20:43:40 -0700
committerH. Peter Anvin <hpa@zytor.com>2020-07-12 06:03:58 -0700
commitd8319155434f3577a2442ad6a27db59e6cfdd4d3 (patch)
treef22658eea5dac1e80bae24c48c87d15721d5729c /asm
parent80e1774b909a36a620dec14b702b622939c6ee08 (diff)
downloadnasm-d8319155434f3577a2442ad6a27db59e6cfdd4d3.tar.gz
nasm-d8319155434f3577a2442ad6a27db59e6cfdd4d3.tar.xz
nasm-d8319155434f3577a2442ad6a27db59e6cfdd4d3.zip
preproc: add %is...() function-like macros
Add the first "preprocessor functions". These are simply "magic" single-line macros with a suitable expansion function. The first application is functions equal to the %if directives, e.g. %ifdef blah == %if %isdef(blah) except can be used anywhere (not just in %if statements like defined() in C.) Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'asm')
-rwxr-xr-xasm/pptok.pl4
-rw-r--r--asm/preproc.c62
2 files changed, 52 insertions, 14 deletions
diff --git a/asm/pptok.pl b/asm/pptok.pl
index 47924897..f40cb58e 100755
--- a/asm/pptok.pl
+++ b/asm/pptok.pl
@@ -124,9 +124,11 @@ if ($what eq 'h') {
print OUT "enum preproc_token {\n";
$n = 0;
+ my $maxlen = 0;
foreach $pt (@pptok) {
if (defined($pt)) {
printf OUT " %-24s = %3d,\n", "PP_\U$pt\E", $n;
+ $maxlen = length($pt) if (length($pt) > $maxlen);
}
$n++;
}
@@ -143,6 +145,8 @@ if ($what eq 'h') {
printf OUT "#define PP_HAS_CASE(x) ((x) >= PP_%s)\n",
uc($pptok[$first_itoken]);
print OUT "#define PP_INSENSITIVE(x) ((x) & 1)\n";
+ # The +1 here is for the initial % sign
+ printf OUT "#define PP_TOKLEN_MAX %d\n", $maxlen+1;
print OUT "\n";
foreach $ct (@cctok) {
diff --git a/asm/preproc.c b/asm/preproc.c
index 8fb9dfbb..63d40e61 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -3050,8 +3050,10 @@ static SMacro *define_smacro(const char *mname, bool casesense,
smac->params = tmpl->params;
smac->alias = tmpl->alias;
smac->greedy = tmpl->greedy;
- if (tmpl->expand)
- smac->expand = tmpl->expand;
+ if (tmpl->expand) {
+ smac->expand = tmpl->expand;
+ smac->expandpvt = tmpl->expandpvt;
+ }
}
if (list_option('s')) {
list_smacro_def((smac->alias ? PP_DEFALIAS : PP_DEFINE)
@@ -5543,8 +5545,8 @@ static SMacro *expand_one_smacro(Token ***tpp)
/* Note: we own the expansion this returns. */
t = m->expand(m, params, nparam);
- tafter = tline->next; /* Skip past the macro call */
- tline->next = NULL; /* Truncate list at the macro call end */
+ tafter = tline->next; /* Skip past the macro call */
+ tline->next = NULL; /* Truncate list at the macro call end */
tline = tafter;
tup = NULL;
@@ -6634,33 +6636,65 @@ stdmac_ptr(const SMacro *s, Token **params, int nparams)
}
}
+static Token *
+stdmac_is(const SMacro *s, Token **params, int nparams)
+{
+ int retval;
+ struct Token *pline = params[0];
+
+ (void)nparams;
+
+ params[0] = NULL; /* Don't free this later */
+
+ retval = if_condition(pline, s->expandpvt.u) == COND_IF_TRUE;
+ return make_tok_num(NULL, retval);
+}
+
/* Add magic standard macros */
struct magic_macros {
const char *name;
int nparam;
ExpandSMacro func;
};
-static const struct magic_macros magic_macros[] =
-{
- { "__?FILE?__", 0, stdmac_file },
- { "__?LINE?__", 0, stdmac_line },
- { "__?BITS?__", 0, stdmac_bits },
- { "__?PTR?__", 0, stdmac_ptr },
- { NULL, 0, NULL }
-};
-
static void pp_add_magic_stdmac(void)
{
+ static const struct magic_macros magic_macros[] = {
+ { "__?FILE?__", 0, stdmac_file },
+ { "__?LINE?__", 0, stdmac_line },
+ { "__?BITS?__", 0, stdmac_bits },
+ { "__?PTR?__", 0, stdmac_ptr },
+ { NULL, 0, NULL }
+ };
const struct magic_macros *m;
SMacro tmpl;
+ enum preproc_token pt;
+ char name_buf[PP_TOKLEN_MAX+1];
+ /* Simple standard magic macros */
nasm_zero(tmpl);
-
for (m = magic_macros; m->name; m++) {
tmpl.nparam = m->nparam;
tmpl.expand = m->func;
define_smacro(m->name, true, NULL, &tmpl);
}
+
+ /* %is...() macro functions */
+ tmpl.nparam = 1;
+ tmpl.greedy = true;
+ tmpl.expand = stdmac_is;
+ name_buf[0] = '%';
+ name_buf[1] = 'i';
+ name_buf[2] = 's';
+ for (pt = PP_IF; pt < PP_IFN; pt++) {
+ if (pp_directives[pt]) {
+ nasm_new(tmpl.params);
+
+ tmpl.params[0].flags = SPARM_GREEDY;
+ strcpy(name_buf+3, pp_directives[pt]+3);
+ tmpl.expandpvt.u = pt;
+ define_smacro(name_buf, false, NULL, &tmpl);
+ }
+ }
}
static void pp_reset_stdmac(enum preproc_mode mode)