diff options
author | Ori Bernstein <ori@eigenstate.org> | 2017-01-23 00:48:09 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2017-01-23 00:48:09 -0800 |
commit | bccf958a86c52a27db9fab3f85f159ddc34629e8 (patch) | |
tree | 757922486ca8aec55ac42412047ff1d8d579fe7b /mi | |
parent | 2c4eeb399845785a1dc317e4f2e3cb3c3c7c5370 (diff) | |
download | mc-bccf958a86c52a27db9fab3f85f159ddc34629e8.tar.gz |
Fix decrement in while loop.
Fixes #70
Diffstat (limited to 'mi')
-rw-r--r-- | mi/flatten.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/mi/flatten.c b/mi/flatten.c index 25d35ed..2da6435 100644 --- a/mi/flatten.c +++ b/mi/flatten.c @@ -216,7 +216,7 @@ static void flattencond(Flattenctx *s, Node *n, Node *ltrue, Node *lfalse) } } -/* flattenlifies +/* flatten * a || b * to * if a || b @@ -239,6 +239,7 @@ static Node *flattenlazy(Flattenctx *s, Node *n) /* flatten the conditional */ flattencond(s, n, ltrue, lfalse); + /* if true */ append(s, ltrue); u = mkexpr(n->loc, Olit, mkbool(n->loc, 1), NULL); @@ -570,10 +571,13 @@ static void flattenloop(Flattenctx *s, Node *n) { Node *lbody; Node *lend; + Node *ldec; Node *lcond; Node *lstep; + size_t i; lbody = genlbl(n->loc); + ldec = genlbl(n->loc); lcond = genlbl(n->loc); lstep = genlbl(n->loc); lend = genlbl(n->loc); @@ -588,8 +592,16 @@ static void flattenloop(Flattenctx *s, Node *n) flatten(s, lstep); /* test lbl */ flatten(s, n->loopstmt.step); /* step */ flatten(s, lcond); /* test lbl */ - flattencond(s, n->loopstmt.cond, lbody, lend); /* repeat? */ - flatten(s, lend); /* exit */ + flattencond(s, n->loopstmt.cond, ldec, lend); /* repeat? */ + flatten(s, ldec); /* drain decrements */ + for (i = 0; i < s->nqueue; i++) + append(s, s->incqueue[i]); + jmp(s, lbody); /* goto test */ + flatten(s, lend); /* exit */ + + for (i = 0; i < s->nqueue; i++) + append(s, s->incqueue[i]); + lfree(&s->incqueue, &s->nqueue); s->nloopstep--; s->nloopexit--; @@ -601,6 +613,7 @@ static void flattenif(Flattenctx *s, Node *n, Node *exit) { Node *l1, *l2, *l3; Node *iftrue, *iffalse; + size_t i; l1 = genlbl(n->loc); l2 = genlbl(n->loc); @@ -614,9 +627,15 @@ static void flattenif(Flattenctx *s, Node *n, Node *exit) flattencond(s, n->ifstmt.cond, l1, l2); flatten(s, l1); + for (i = 0; i < s->nqueue; i++) + append(s, s->incqueue[i]); + /* goto test */ flatten(s, iftrue); jmp(s, l3); flatten(s, l2); + for (i = 0; i < s->nqueue; i++) + append(s, s->incqueue[i]); + lfree(&s->incqueue, &s->nqueue); /* because lots of bunched up end labels are ugly, * coalesce them by handling 'elif'-like constructs * separately */ |