From feeb86d046d55d197040c7061e39198c80373ecb Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 15 Aug 2022 14:52:15 +0200 Subject: #when --- bootstrap/parse.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'bootstrap/parse.c') diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 0d9ab16..1848caf 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -394,6 +394,8 @@ lex(struct parser *P) { tok.t = '##'; } else if (!strcmp(s, "#len")) { tok.t = '#len'; + } else if (!strcmp(s, "#when")) { + tok.t = TKhwhen; } else if (!strcmp(s, "#tag")) { tok.t = '#tag'; } else if (!strcmp(s, "#?")) { @@ -3073,6 +3075,31 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) { struct attr attr = {0}; decl.container = P->container; + while (lexmatch(P, &tok, TKhwhen)) { + struct expr test = parseexpr(P); + if (!fold(&test) || test.ty->t != TYbool) + fatal(P, test.span, "#when test is not a constant bool expression"); + assert(test.t == Eboolit); + lexexpect(P, '{'); + if (test.i) { + while (!lexmatch(P, &tok, '}')) + parsedecl(yield, yarg, P, toplevel); + } else { + int pabal = 0, // ( ) parens balance + bkbal = 0, // [ ] brackets .. + bcbal = 1; // { } braces .. + + while (pabal || bkbal || bcbal) { + tok = lex(P); + switch (tok.t) { + case '[': ++bkbal; break; case ']': --bkbal; break; + case '{': ++bcbal; break; case '}': --bcbal; break; + case '(': ++pabal; break; case ')': --pabal; break; + } + } + } + } + if (lexmatch(P, &tok, '#')) { lexexpect(P, '['); while (!lexmatch(P, NULL, ']')) { -- cgit v1.2.3