From bc3a8286ea4033931940742a8dc0b944747e1ce5 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Thu, 8 Apr 2010 03:46:43 +0000 Subject: [PATCH] NASM preproc: Add basic support for %{x:y} parameter list expansion. Contributed by: Mathieu Monnier nasm64developer has a more advanced 3-parameter version that will take some time to integrate, so for now just provide the simpler version. svn path=/trunk/yasm/; revision=2312 --- modules/preprocs/nasm/nasm-pp.c | 207 ++++++++++++++++++++------------ 1 file changed, 128 insertions(+), 79 deletions(-) diff --git a/modules/preprocs/nasm/nasm-pp.c b/modules/preprocs/nasm/nasm-pp.c index 211eca2e..b892a64a 100644 --- a/modules/preprocs/nasm/nasm-pp.c +++ b/modules/preprocs/nasm/nasm-pp.c @@ -3858,105 +3858,51 @@ expand_mmac_params(Token * tline) char *text = NULL; int type = 0, cc; /* type = 0 to placate optimisers */ char tmpbuf[30]; + char *second_text = NULL; int n, i; MMacro *mac; t = tline; tline = tline->next; + second_text = strchr(t->text, ':'); + mac = istk->mstk; while (mac && !mac->name) /* avoid mistaking %reps for macros */ mac = mac->next_active; if (!mac) error(ERR_NONFATAL, "`%s': not in a macro call", t->text); else - switch (t->text[1]) + { + if (second_text) { - /* - * We have to make a substitution of one of the - * forms %1, %-1, %+1, %%foo, %0. - */ - case '0': - type = TOK_NUMBER; - sprintf(tmpbuf, "%ld", mac->nparam); - text = nasm_strdup(tmpbuf); - break; - case '%': - type = TOK_ID; - sprintf(tmpbuf, "..@%lu.", mac->unique); - text = nasm_strcat(tmpbuf, t->text + 2); - break; - case '-': - n = atoi(t->text + 2) - 1; - if (n >= mac->nparam) + int end = atoi(second_text+1)-1; + int is_fst = 1; + int k; + n = atoi(t->text + 1)-1; + if (end < 0) + end += mac->nparam; + + for (k = n; k <= end; k++) + { + if (k >= mac->nparam) tt = NULL; else { if (mac->nparam > 1) - n = (n + mac->rotate) % mac->nparam; - tt = mac->params[n]; - } - cc = find_cc(tt); - if (cc == -1) - { - error(ERR_NONFATAL, - "macro parameter %d is not a condition code", - n + 1); - text = NULL; + k = (k + mac->rotate) % mac->nparam; + tt = mac->params[k]; } - else + if (tt) { - type = TOK_ID; - if (inverse_ccs[cc] == -1) + if (!is_fst && mac->paramlen[k]) { - error(ERR_NONFATAL, - "condition code `%s' is not invertible", - conditions[cc]); - text = NULL; + *tail = new_Token(NULL, TOK_OTHER, ",", 0); + tail = &(*tail)->next; } - else - text = - nasm_strdup(conditions[inverse_ccs - [cc]]); - } - break; - case '+': - n = atoi(t->text + 2) - 1; - if (n >= mac->nparam) - tt = NULL; - else - { - if (mac->nparam > 1) - n = (n + mac->rotate) % mac->nparam; - tt = mac->params[n]; - } - cc = find_cc(tt); - if (cc == -1) - { - error(ERR_NONFATAL, - "macro parameter %d is not a condition code", - n + 1); - text = NULL; - } - else - { - type = TOK_ID; - text = nasm_strdup(conditions[cc]); - } - break; - default: - n = atoi(t->text + 1) - 1; - if (n >= mac->nparam) - tt = NULL; - else - { - if (mac->nparam > 1) - n = (n + mac->rotate) % mac->nparam; - tt = mac->params[n]; - } - if (tt) - { - for (i = 0; i < mac->paramlen[n]; i++) + if (mac->paramlen[k]) + is_fst = 0; + for (i = 0; i < mac->paramlen[k]; i++) { *tail = new_Token(NULL, tt->type, tt->text, @@ -3966,8 +3912,111 @@ expand_mmac_params(Token * tline) } } text = NULL; /* we've done it here */ - break; + } + } + else + { + switch (t->text[1]) + { + /* + * We have to make a substitution of one of the + * forms %1, %-1, %+1, %%foo, %0. + */ + case '0': + type = TOK_NUMBER; + sprintf(tmpbuf, "%ld", mac->nparam); + text = nasm_strdup(tmpbuf); + break; + case '%': + type = TOK_ID; + sprintf(tmpbuf, "..@%lu.", mac->unique); + text = nasm_strcat(tmpbuf, t->text + 2); + break; + case '-': + n = atoi(t->text + 2) - 1; + if (n >= mac->nparam) + tt = NULL; + else + { + if (mac->nparam > 1) + n = (n + mac->rotate) % mac->nparam; + tt = mac->params[n]; + } + cc = find_cc(tt); + if (cc == -1) + { + error(ERR_NONFATAL, + "macro parameter %d is not a condition code", + n + 1); + text = NULL; + } + else + { + type = TOK_ID; + if (inverse_ccs[cc] == -1) + { + error(ERR_NONFATAL, + "condition code `%s' is not invertible", + conditions[cc]); + text = NULL; + } + else + text = + nasm_strdup(conditions[inverse_ccs + [cc]]); + } + break; + case '+': + n = atoi(t->text + 2) - 1; + if (n >= mac->nparam) + tt = NULL; + else + { + if (mac->nparam > 1) + n = (n + mac->rotate) % mac->nparam; + tt = mac->params[n]; + } + cc = find_cc(tt); + if (cc == -1) + { + error(ERR_NONFATAL, + "macro parameter %d is not a condition code", + n + 1); + text = NULL; + } + else + { + type = TOK_ID; + text = nasm_strdup(conditions[cc]); + } + break; + default: + n = atoi(t->text + 1) - 1; + if (n >= mac->nparam) + tt = NULL; + else + { + if (mac->nparam > 1) + n = (n + mac->rotate) % mac->nparam; + tt = mac->params[n]; + } + if (tt) + { + for (i = 0; i < mac->paramlen[n]; i++) + { + *tail = + new_Token(NULL, tt->type, tt->text, + 0); + tail = &(*tail)->next; + tt = tt->next; + } + } + text = NULL; /* we've done it here */ + break; + } } + } + if (!text) { delete_Token(t); -- 2.40.0