scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
Mcc2/parser.c | 36++++++++++++++++++++++++++++--------
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; }