aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2019-05-16 12:57:50 -0700
committerMichael Forney <mforney@mforney.org>2019-05-16 12:59:04 -0700
commit52bf506762f2d04ba37701af41b7b06c0d6dc7f9 (patch)
tree08c2e3a25cb8bfa2eb8baee08902c9aba770a2ea
parent1b1092f3246eed96c796b1f74f814cb594be8768 (diff)
stmt: continue in do-loop should evaluate controlling expression
-rw-r--r--stmt.c12
-rw-r--r--test/do-loop.c9
-rw-r--r--test/do-loop.qbe31
3 files changed, 47 insertions, 5 deletions
diff --git a/stmt.c b/stmt.c
index c53c969..8d45e3c 100644
--- a/stmt.c
+++ b/stmt.c
@@ -177,24 +177,26 @@ stmt(struct func *f, struct scope *s)
next();
label[0] = mkblock("do_body");
- label[1] = mkblock("do_join");
+ label[1] = mkblock("do_cond");
+ label[2] = mkblock("do_join");
s = mkscope(s);
s = mkscope(s);
- s->continuelabel = label[0];
- s->breaklabel = label[1];
+ s->continuelabel = label[1];
+ s->breaklabel = label[2];
funclabel(f, label[0]);
stmt(f, s);
s = delscope(s);
expect(TWHILE, "after 'do' statement");
expect(TLPAREN, "after 'while'");
+ funclabel(f, label[1]);
e = expr(s);
expect(TRPAREN, "after expression");
v = funcexpr(f, e);
- funcjnz(f, v, label[0], label[1]); // XXX: compare to 0
- funclabel(f, label[1]);
+ funcjnz(f, v, label[0], label[2]); // XXX: compare to 0
+ funclabel(f, label[2]);
s = delscope(s);
expect(TSEMICOLON, "after 'do' statement");
break;
diff --git a/test/do-loop.c b/test/do-loop.c
new file mode 100644
index 0000000..2189a67
--- /dev/null
+++ b/test/do-loop.c
@@ -0,0 +1,9 @@
+int main(void) {
+ int x = 2, y = 0;
+ do {
+ if (x == 1)
+ continue;
+ ++y;
+ } while (x--);
+ return y != 2;
+}
diff --git a/test/do-loop.qbe b/test/do-loop.qbe
new file mode 100644
index 0000000..c13b8fe
--- /dev/null
+++ b/test/do-loop.qbe
@@ -0,0 +1,31 @@
+export
+function w $main() {
+@start.1
+ %.1 =l alloc4 4
+ %.3 =l alloc4 4
+@body.2
+ %.2 =l add %.1, 0
+ storew 2, %.2
+ %.4 =l add %.3, 0
+ storew 0, %.4
+@do_body.3
+ %.5 =w loadsw %.1
+ %.6 =w ceqw %.5, 1
+ %.7 =w cnew %.6, 0
+ jnz %.7, @if_true.6, @if_false.7
+@if_true.6
+ jmp @do_cont.4
+@if_false.7
+ %.8 =w loadsw %.3
+ %.9 =w add %.8, 1
+ storew %.9, %.3
+@do_cont.4
+ %.10 =w loadsw %.1
+ %.11 =w sub %.10, 1
+ storew %.11, %.1
+ jnz %.10, @do_body.3, @do_join.5
+@do_join.5
+ %.12 =w loadsw %.3
+ %.13 =w cnew %.12, 2
+ ret %.13
+}