[nasm:master] preproc: add %is...() function-like macros

nasm-bot for H. Peter Anvin hpa at zytor.com
Sun Jul 12 06:09:03 PDT 2020


Commit-ID:  d8319155434f3577a2442ad6a27db59e6cfdd4d3
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=d8319155434f3577a2442ad6a27db59e6cfdd4d3
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sat, 11 Jul 2020 20:43:40 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Sun, 12 Jul 2020 06:03:58 -0700

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 at zytor.com>


---
 asm/pptok.pl  |  4 ++++
 asm/preproc.c | 62 +++++++++++++++++++++++++++++++++++++++++++++--------------
 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)


More information about the Nasm-commits mailing list