summaryrefslogtreecommitdiff
path: root/mi
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-01-23 00:48:09 -0800
committerOri Bernstein <ori@eigenstate.org>2017-01-23 00:48:09 -0800
commitbccf958a86c52a27db9fab3f85f159ddc34629e8 (patch)
tree757922486ca8aec55ac42412047ff1d8d579fe7b /mi
parent2c4eeb399845785a1dc317e4f2e3cb3c3c7c5370 (diff)
downloadmc-bccf958a86c52a27db9fab3f85f159ddc34629e8.tar.gz
Fix decrement in while loop.
Fixes #70
Diffstat (limited to 'mi')
-rw-r--r--mi/flatten.c25
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 */