From 041d9ff133a944580bc39ba42d053379df33330c Mon Sep 17 00:00:00 2001 From: Andrew Yourtchenko Date: Tue, 26 Nov 2019 01:35:09 +0100 Subject: [PATCH] Implement "%rdefine", which aims to help with symbolic references to registers. The usage is as follows: %rdefine foo_test ax mov foo_test, 1 %rdefine bar_test ax mov bar_test, 2 the result will generate: mov ax, 1 mov ax, 2 however, uncommenting either of the commented above lines will cause error. Under the hood, rdefine defines an additional macro rdefine_, which refers back to the name of the rdefine argument - this way we can track which rdefines refer to which registers, and undefine them automatically as needed. --- asm/pptok.dat | 1 + asm/preproc.c | 22 ++++++++++++++++++++++ test/rdefine.asm | 6 ++++++ 3 files changed, 29 insertions(+) create mode 100644 test/rdefine.asm diff --git a/asm/pptok.dat b/asm/pptok.dat index b6285c36..bb0b7cec 100644 --- a/asm/pptok.dat +++ b/asm/pptok.dat @@ -61,6 +61,7 @@ %!assign %!defalias %!define +%!rdefine %!defstr %!deftok %!macro diff --git a/asm/preproc.c b/asm/preproc.c index 41a7c6fb..a9d06c3f 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -4049,6 +4049,7 @@ issue_error: break; case PP_DEFINE: + case PP_RDEFINE: case PP_XDEFINE: case PP_DEFALIAS: { @@ -4101,6 +4102,27 @@ issue_error: * carefully re-terminated after chopping off the expansion * from the end). */ + if (op == PP_RDEFINE) { + const char *target = tok_text(macro_start); + int sz = strlen(target)+1+strlen("rdefine_"); + char *rdef_name = nasm_malloc(sz); + SMacro *rdef_defn = 0; + Token *t = make_tok_qstr(NULL, mname); + SMacro tmpl2; + + /* fprintf(stderr, "RDEFINE %s %s\n", mname, target); */ + snprintf(rdef_name, sz, "rdefine_%s", target); + if (smacro_defined(NULL, rdef_name, 0, &rdef_defn, casesense, 0)) { + const char *expansion = unquote_token(rdef_defn->expansion); + /* fprintf(stderr, "Already defined %s as %s\n", rdef_name, expansion); */ + /* fprintf(stderr, "undefining %s\n", expansion); */ + undef_smacro(expansion, false); + /* fprintf(stderr, "undefining %s\n", rdef_name); */ + undef_smacro(expansion, false); + } + nasm_zero(tmpl2); + define_smacro(rdef_name, casesense, t, &tmpl2); + } define_smacro(mname, casesense, macro_start, &tmpl); break; } diff --git a/test/rdefine.asm b/test/rdefine.asm new file mode 100644 index 00000000..c888392a --- /dev/null +++ b/test/rdefine.asm @@ -0,0 +1,6 @@ +%rdefine foobar_test ax + mov foobar_test, 1 +# mov foobar2_test, 2 +%rdefine foobar2_test ax +# mov foobar_test, 3 + mov foobar2_test, 4 -- 2.17.1