ref: bccf958a86c52a27db9fab3f85f159ddc34629e8
parent: 2c4eeb399845785a1dc317e4f2e3cb3c3c7c5370
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jan 22 19:48:09 EST 2017
Fix decrement in while loop. Fixes #70
--- a/mi/flatten.c
+++ b/mi/flatten.c
@@ -216,7 +216,7 @@
}
}
-/* flattenlifies
+/* flatten
* a || b
* to
* if a || b
@@ -239,6 +239,7 @@
/* 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 @@
{
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,9 +592,17 @@
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 @@
{
Node *l1, *l2, *l3;
Node *iftrue, *iffalse;
+ size_t i;
l1 = genlbl(n->loc);
l2 = genlbl(n->loc);
@@ -614,9 +627,15 @@
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 */