shithub: mc

Download patch

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 */