|
From: Cyrill G. <gor...@gm...> - 2010-10-05 20:51:57
|
On Fri, Oct 01, 2010 at 10:24:34AM -0700, H. Peter Anvin wrote:
> On 10/01/2010 10:23 AM, Cyrill Gorcunov wrote:
> >>
> >> NASM 0.98 only supported implicit concatenation (mmac), with
> >> three simple rules:
> >>
> >> - TOK_WHITE + TOK_WHITE
> >> - TOK_ID + {TOK_ID,TOK_NUMBER}
> >> - TOK_NUMBER + TOK_NUMBER
> >>
This last TOK_NUMBER + TOK_NUMBER seems to be not handled properly
at the moment (as being pointed by nasm64developer in different
form). So say the code
%define id1 1
%define idid1 2
%define TOK_NUM 1
%define TOK_ID id
%macro m 2
mov eax, 1%1id%2 ; this exapnds to 1idid1
; where idid1 expands to 2
; and then to 12
%endmacro
m TOK_ID, TOK_NUM
do not proceed properly. I've fixed it via array of masks
such as the commit I've not pushed out yet looks like one
below. Comments? I would like to push it out for rc2.
Actually I tested this code on 0.98.39 and it compiles as
well to same results.
---
>From 97342233762c06440f32931853eb78558bb6bd54 Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gor...@gm...>
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
Do not proceed.
Reported-by: nas...@us...
Signed-off-by: Cyrill Gorcunov <gor...@gm...>
---
preproc.c | 117 ++++++++++++++++++++++++++++++++++++-------------------------
1 files changed, 69 insertions(+), 48 deletions(-)
diff --git a/preproc.c b/preproc.c
index eb7902a..ea3efc5 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;
-
- while (tt && (PP_CONCAT_MASK(tt->type) & 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);
+ 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) & m[i].mask_tail)) {
+ len += strlen(tt->text);
+ tt = tt->next;
}
- t = *tail = tokenize(tmp);
- nasm_free(tmp);
- while (t->next) {
- tail = &t->next;
- t = t->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);
+ }
+ 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->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...
--
1.7.3
|