/* * Expand MMacro-local things: parameter references (%0, %n, %+n, * %-n) and MMacro-local identifiers (%%foo). */ static Token *expand_mmac_params(Token * tline) ...{ Token *t, *tt, **tail, *thead;
/**//* thead 是链表头,tail 指向链表尾部 */ tail = &thead; thead = NULL;
/**//* 如果是可以扩展的宏参数,则扩展,或则照旧 */ while (tline) ...{ if (tline->type == TOK_PREPROC_ID && (((tline->text[1] == '+' || tline->text[1] == '-') /**//* %+- num/space */ && tline->text[2]) || tline->text[1] == '%' /**//* %% */ || (tline->text[1] >= '0' && tline->text[1] <= '9'))) /**//* %num */ ...{ char *text = NULL; int type = 0, cc; /**//* type = 0 to placate optimisers */ char tmpbuf[30]; int n, i; MMacro *mac;
t = tline; tline = tline->next;
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]) ...{ /**//* * We have to make a substitution of one of the * forms %1, %-1, %+1, %%foo, %0. */ case '0': /**//* 有几个参数 */ type = TOK_NUMBER; snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam); text = nasm_strdup(tmpbuf); break; case '%': /**//* 假设变量名是Local, 则结果是..@XLoacal, 其中X是mac->unique * 通过修改变量名来是他成为唯一的变量, C/C++也是这样子 */ type = TOK_ID; snprintf(tmpbuf, sizeof(tmpbuf), "..@%lu.", mac->unique); text = nasm_strcat(tmpbuf, t->text + 2); break; case '-': /**//* 处理条件宏定义 */ n = atoi(t->text + 2) - 1; /**//* %-num */ if (n >= mac->nparam) /**//* 验证要求的参数是否超出提供的范围 */ tt = NULL; else ...{ if (mac->nparam > 1) n = (n + mac->rotate) % mac->nparam; /**//* %rotate宏定义 */ tt = mac->params[n]; /**//* 取出第几个参数,从0开始计数 */ } 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); } else ...{ *tail = t; tail = &t->next; t->type = type; nasm_free(t->text); t->text = text; t->mac = NULL; } continue; } else ...{ t = *tail = tline; tline = tline->next; t->mac = NULL; tail = &t->next; } } *tail = NULL; t = thead; for (; t && (tt = t->next) != NULL; t = t->next) ...{ switch (t->type) ...{ case TOK_WHITESPACE: if (tt->type == TOK_WHITESPACE) ...{ /**//* 删除空格Token */ t->next = delete_Token(tt); } break; case TOK_ID: if (tt->type == TOK_ID || tt->type == TOK_NUMBER) ...{ char *tmp = nasm_strcat(t->text, tt->text); nasm_free(t->text); t->text = tmp; t->next = delete_Token(tt); } break; case TOK_NUMBER: if (tt->type == TOK_NUMBER) ...{ char *tmp = nasm_strcat(t->text, tt->text); nasm_free(t->text); t->text = tmp; t->next = delete_Token(tt); } break; } }
return thead; }
|