summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2014-01-04 14:02:01 -0500
committerOri Bernstein <ori@eigenstate.org>2014-01-04 14:02:01 -0500
commit92e25d24edc4cd7c954ecb2b0bd88956566cbe22 (patch)
tree85d2deda69582f5aa1c799c551667afad2f8c121
parentb194f947b512b1791e614a5941ebc785cdd28730 (diff)
downloadmc-92e25d24edc4cd7c954ecb2b0bd88956566cbe22.tar.gz
Fix bug preventing complex exprs on 'for in' loops
'for in' loops had a bug where we would try to evaluate the sequence for the loop every time, instead of doing it once. This also caused the side effect of expecting lvalues instead of rvalues for the index expressions. This change fixes it.
-rw-r--r--6/simp.c7
-rw-r--r--test/subrangefor.myr8
-rw-r--r--test/tests1
3 files changed, 13 insertions, 3 deletions
diff --git a/6/simp.c b/6/simp.c
index 61de96c..82a1b62 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -505,7 +505,7 @@ static void simploop(Simp *s, Node *n)
static void simpiter(Simp *s, Node *n)
{
Node *lbody, *lstep, *lcond, *lmatch, *lend;
- Node *idx, *len, *dcl, *val, *done;
+ Node *idx, *len, *dcl, *seq, *val, *done;
Node *zero;
lbody = genlbl();
@@ -517,6 +517,7 @@ static void simpiter(Simp *s, Node *n)
zero = mkintlit(n->line, 0);
zero->expr.type = tyintptr;
+ seq = rval(s, n->iterstmt.seq, NULL);
idx = gentemp(s, n, tyintptr, &dcl);
declarelocal(s, dcl);
@@ -531,11 +532,11 @@ static void simpiter(Simp *s, Node *n)
simp(s, assign(s, idx, addk(idx, 1)));
/* condition */
simp(s, lcond);
- len = seqlen(s, n->iterstmt.seq, tyintptr);
+ len = seqlen(s, seq, tyintptr);
done = mkexpr(n->line, Olt, idx, len, NULL);
cjmp(s, done, lmatch, lend);
simp(s, lmatch);
- val = load(idxaddr(s, n->iterstmt.seq, idx));
+ val = load(idxaddr(s, seq, idx));
umatch(s, n->iterstmt.elt, val, val->expr.type, lbody, lstep);
simp(s, lend);
}
diff --git a/test/subrangefor.myr b/test/subrangefor.myr
new file mode 100644
index 0000000..0a3acc4
--- /dev/null
+++ b/test/subrangefor.myr
@@ -0,0 +1,8 @@
+use std
+
+const main = {
+ for i in [1,2,3,4][:2]
+ std.put("%i", i)
+ ;;
+ std.put("\n")
+}
diff --git a/test/tests b/test/tests
index 516f69a..460986e 100644
--- a/test/tests
+++ b/test/tests
@@ -56,6 +56,7 @@ B callbig E 42
B nestfn E 42
# B closure E 55 ## BUGGERED
B loop E 45
+B subrangefor P 12
B patiter P 23512
B condiftrue E 7
B condiffalse E 9