aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap/parse.c')
-rw-r--r--bootstrap/parse.c26
1 files changed, 26 insertions, 0 deletions
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;