diff options
| -rw-r--r-- | bootstrap/all.h | 1 | ||||
| -rw-r--r-- | bootstrap/cgen.c | 8 | ||||
| -rw-r--r-- | bootstrap/parse.c | 26 | ||||
| -rw-r--r-- | src/main.cff | 4 |
4 files changed, 39 insertions, 0 deletions
diff --git a/bootstrap/all.h b/bootstrap/all.h index d1d58d9..6a0de81 100644 --- a/bootstrap/all.h +++ b/bootstrap/all.h @@ -410,6 +410,7 @@ enum stmttype { Sdecl, Sifelse, Swhile, + Sdowhile, Sfor, Siswitch, Sreturn, diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c index 9a28829..f79e112 100644 --- a/bootstrap/cgen.c +++ b/bootstrap/cgen.c @@ -347,6 +347,12 @@ genstmt(struct stmt *stmt) { genblock(stmt->loop.body); pri("_cont%d:;} _brk%d:;\n", stmt->loop.id, stmt->loop.id); break; + case Sdowhile: + pri("do {"); + genblock(stmt->loop.body); + pri("_cont%d:;} while (%e); _brk%d:;\n", + stmt->loop.id, &stmt->loop.test, stmt->loop.id); + break; case Sfor: pri("{\n"); for (int i = 0; i < stmt->loop.ini.n; ++i) @@ -566,6 +572,8 @@ liftnested(struct stmt *stmt) { liftnested(blocktostmt(stmt->ifelse.t)); break; case Swhile: + case Sdowhile: + liftnestedex(&stmt->loop.test); liftnested(blocktostmt(stmt->loop.body)); break; case Sfor: diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 18aa13b..cff303f 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -2223,6 +2223,8 @@ parsestmt(stmt_yielder_t yield, void *yarg, struct parser *P) { label = tok.str; if (lexmatch(P, &tok, TKkw_while)) goto whilel; + else if (lexmatch(P, &tok, TKkw_do)) + goto dowhilel; else if (lexmatch(P, &tok, TKkw_for)) goto forl; else @@ -2249,6 +2251,30 @@ parsestmt(stmt_yielder_t yield, void *yarg, struct parser *P) { free(env.decls); popenv(P); } + } else if (lexmatch(P, &tok, TKkw_do)) { + dowhilel: + st.t = Sdowhile; + st.span = tok.span; + lexexpect(P, '{'); + st.loop.id = P->loopid++; + struct env env = { P->curenv }; + if (label) { + pushenv(P, &env); + putdecl(P, tok.span, &(struct decl) { Dlabel, label, .loopid = st.loop.id }); + } + WITH_TMPCHANGE(int, P->curloop, st.loop.id) + st.loop.body = parseblock(P).block; + if (label) { + free(env.decls); + popenv(P); + } + lexexpect(P, TKkw_while); + st.loop.test = parseexpr(P); + if (st.loop.test.ty->t != TYbool && st.loop.test.ty->t != TYptr) + fatal(P, st.loop.test.span, + "do-while statement condition must be bool or pointer (%t)", + st.loop.test.ty); + lexexpect(P, ';'); } else if (lexmatch(P, &tok, TKkw_for)) { forl: st.span = tok.span; diff --git a/src/main.cff b/src/main.cff index 9280443..9d92612 100644 --- a/src/main.cff +++ b/src/main.cff @@ -15,5 +15,9 @@ extern fn main(argc int, argv **u8) int { foreach(s, i, args->compact(), printf("%d: %s\n", i, s); ) + + do { + printf("hi"); + } while #f; } |