aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/parse.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-11 07:53:44 +0200
committerlemon <lsof@mailbox.org>2022-08-11 07:53:44 +0200
commitc7961d732e5d67e8ea1b0be05e979bf24361f794 (patch)
tree07604810c980422332e971d436eea1fac62191f0 /bootstrap/parse.c
parent86aa2d6ab3a003652159fa37828c27744a2cb45d (diff)
do-while
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;