From 575d4289c9b1fb47774cb79764a24899a69a8d52 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 6 Oct 2010 00:25:55 +0400 Subject: [PATCH] preproc.c: Support multiple matches in paste_tokens In mmacro params head TOK_NUM should be concat'ed with tail TOK_NUM only, otherwise the weird construction like %define id1 1 %define idid1 2 %define TOK_NUM 1 %define TOK_ID id %macro m 2 mov eax, 1%1id%2 ; this expands to 1idid1 ; where idid1 expands to 2 ; and then to 12 %endmacro m TOK_ID, TOK_NUM issue error. N.B. I've checked nasm-0.98.39 and it compiles this macro perfectly well, for the record. Reported-by: nasm64developer@users.sf.net Signed-off-by: Cyrill Gorcunov --- preproc.c | 115 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 47 deletions(-) diff --git a/preproc.c b/preproc.c index eb7902a8..ea3efc54 100644 --- a/preproc.c +++ b/preproc.c @@ -214,6 +214,11 @@ enum pp_token_type { #define PP_CONCAT_MASK(x) (1 << (x)) +struct tokseq_match { + int mask_head; + int mask_tail; +}; + struct Token { Token *next; char *text; @@ -3639,13 +3644,14 @@ static int find_cc(Token * t) return i; } -static bool paste_tokens(Token **head, int mask_head, int mask_tail, - bool handle_paste_tokens) +static bool paste_tokens(Token **head, const struct tokseq_match *m, + int mnum, bool handle_paste_tokens) { Token **tail, *t, *tt; Token **paste_head; bool did_paste = false; char *tmp; + int i; /* Now handle token pasting... */ paste_head = NULL; @@ -3696,44 +3702,48 @@ static bool paste_tokens(Token **head, int mask_head, int mask_tail, /* * Concatenation of tokens might look nontrivial * but in real it's pretty simple -- the caller - * prepares the masks of tokens to be concatenated + * prepares the masks of token types to be concatenated * and we simply find matched sequences and slip * them together */ - if (PP_CONCAT_MASK(t->type) & mask_head) { - size_t len = 0; - char *tmp, *p; + for (i = 0; i < mnum; i++) { + if (PP_CONCAT_MASK(t->type) & m[i].mask_head) { + size_t len = 0; + char *tmp, *p; - while (tt && (PP_CONCAT_MASK(tt->type) & mask_tail)) { - len += strlen(tt->text); - tt = tt->next; - } + while (tt && (PP_CONCAT_MASK(tt->type) & m[i].mask_tail)) { + len += strlen(tt->text); + tt = tt->next; + } - /* - * Now tt points to the first token after - * the potential paste area... - */ - if (tt != t->next) { - /* We have at least two tokens... */ - len += strlen(t->text); - p = tmp = nasm_malloc(len+1); - while (t != tt) { - strcpy(p, t->text); - p = strchr(p, '\0'); - t = delete_Token(t); + /* + * Now tt points to the first token after + * the potential paste area... + */ + if (tt != t->next) { + /* We have at least two tokens... */ + len += strlen(t->text); + p = tmp = nasm_malloc(len+1); + while (t != tt) { + strcpy(p, t->text); + p = strchr(p, '\0'); + t = delete_Token(t); + } + t = *tail = tokenize(tmp); + nasm_free(tmp); + while (t->next) { + tail = &t->next; + t = t->next; + } + t->next = tt; /* Attach the remaining token chain */ + did_paste = true; } - t = *tail = tokenize(tmp); - nasm_free(tmp); - while (t->next) { - tail = &t->next; - t = t->next; - } - t->next = tt; /* Attach the remaining token chain */ - did_paste = true; + paste_head = tail; + tail = &t->next; + break; } - paste_head = tail; - tail = &t->next; - } else { + } + if (i >= mnum) { /* no match */ tail = &t->next; if (!tok_type_(t->next, TOK_WHITESPACE)) paste_head = tail; @@ -3981,14 +3991,21 @@ static Token *expand_mmac_params(Token * tline) *tail = NULL; if (changed) { - int mask_head = PP_CONCAT_MASK(TOK_ID) | - PP_CONCAT_MASK(TOK_NUMBER) | - PP_CONCAT_MASK(TOK_FLOAT); - int mask_tail = PP_CONCAT_MASK(TOK_ID) | - PP_CONCAT_MASK(TOK_NUMBER) | - PP_CONCAT_MASK(TOK_FLOAT) | - PP_CONCAT_MASK(TOK_OTHER); - paste_tokens(&thead, mask_head, mask_tail, false); + const struct tokseq_match t[] = { + { + PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_FLOAT), /* head */ + PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_NUMBER) | + PP_CONCAT_MASK(TOK_FLOAT) | + PP_CONCAT_MASK(TOK_OTHER) /* tail */ + }, + { + PP_CONCAT_MASK(TOK_NUMBER), /* head */ + PP_CONCAT_MASK(TOK_NUMBER) /* tail */ + } + }; + paste_tokens(&thead, t, ARRAY_SIZE(t), false); } return thead; @@ -4301,12 +4318,16 @@ again: * them (without white spaces in between). */ if (expanded) { - int mask_head = PP_CONCAT_MASK(TOK_ID) | - PP_CONCAT_MASK(TOK_PREPROC_ID); - int mask_tail = PP_CONCAT_MASK(TOK_ID) | - PP_CONCAT_MASK(TOK_PREPROC_ID) | - PP_CONCAT_MASK(TOK_NUMBER); - if (paste_tokens(&thead, mask_head, mask_tail, true)) { + const struct tokseq_match t[] = { + { + PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_PREPROC_ID), /* head */ + PP_CONCAT_MASK(TOK_ID) | + PP_CONCAT_MASK(TOK_PREPROC_ID) | + PP_CONCAT_MASK(TOK_NUMBER) /* tail */ + } + }; + if (paste_tokens(&thead, t, ARRAY_SIZE(t), true)) { /* * If we concatenated something, *and* we had previously expanded * an actual macro, scan the lines again for macros...