commit e36b9e60ca5f6b0aaeca720137a70109f77025f5
parent cee1c1566cd93830e1d106d3d141c0eb0bffa000
Author: Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com>
Date: Mon, 26 Sep 2016 11:33:40 +0200
[cc2] Fix wafting switches nodes
We need to have all the nodes related to a switch table
together, because otherwise it is impossible to build
a jump table. The code was wrong and it was generating
corrupted statement lists.
Diffstat:
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/cc2/parser.c b/cc2/parser.c
@@ -339,20 +339,36 @@ oreturn(char *token, union tokenop u)
push(np);
}
+/*
+ * Move np (which is a OCASE/ODEFAULT/OESWITCH) to be contigous with
+ * the last switch table. It is a bit ugly to touch directly curstmt
+ * here, but moving this function to node.c is worse, because we are
+ * putting knowledge of how the text is parsed into the node
+ * represtation module.
+ */
static void
waft(Node *np)
{
- Node *p;
+ Node *lastcase, *next;;
struct swtch *cur;
+ extern Node *curstmt;
if (swp == swtbl)
error(EWTACKU);
cur = swp - 1;
- p = cur->last;
- np->next = p->next;
- np->prev = p;
- p->next = np;
+ lastcase = cur->last;
+ next = lastcase->next;
+
+ np->next = next;
+ np->prev = lastcase;
+
+ if (next)
+ next->prev = np;
+ lastcase->next = np;
+
+ if (curstmt == cur->last)
+ curstmt = np;
cur->last = np;
cur->nr++;
}
@@ -361,13 +377,17 @@ static void
bswitch(char *token, union tokenop u)
{
struct swtch *cur;
+ Node *np = newnode(u.op);
if (swp == &swtbl[NR_BLOCK+1])
error(EWTACKO);
cur = swp++;
cur->nr = 0;
- jump(token, u);
- cur->first = cur->last = push(pop());
+
+ eval(strtok(NULL, "\t\n"));
+ np->left = pop();
+
+ push(cur->first = cur->last = np);
}
static void
@@ -379,7 +399,7 @@ eswitch(char *token, union tokenop u)
error(EWTACKU);
jump(token, u);
waft(pop());
- cur = swp--;
+ cur = --swp;
cur->first->u.i = cur->nr;
}