diff options
| author | 2022-08-15 14:52:15 +0200 | |
|---|---|---|
| committer | 2022-08-15 14:52:15 +0200 | |
| commit | feeb86d046d55d197040c7061e39198c80373ecb (patch) | |
| tree | 733d4da08ec979eb8f6b9b91d39c655e7fd4847b /bootstrap/parse.c | |
| parent | f906d0b350b0b4ceb747669c9a9845d11bd0e486 (diff) | |
#when
Diffstat (limited to 'bootstrap/parse.c')
| -rw-r--r-- | bootstrap/parse.c | 27 |
1 files changed, 27 insertions, 0 deletions
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, ']')) { |