diff options
Diffstat (limited to 'bootstrap')
| -rw-r--r-- | bootstrap/all.h | 1 | ||||
| -rw-r--r-- | bootstrap/dump.c | 4 | ||||
| -rw-r--r-- | bootstrap/parse.c | 27 |
3 files changed, 31 insertions, 1 deletions
diff --git a/bootstrap/all.h b/bootstrap/all.h index b86e7f6..77f4577 100644 --- a/bootstrap/all.h +++ b/bootstrap/all.h @@ -77,6 +77,7 @@ enum toktype { TKexpr, TKlabel, TKstrify, + TKhwhen, TKeof, }; diff --git a/bootstrap/dump.c b/bootstrap/dump.c index 91832fd..0cf5670 100644 --- a/bootstrap/dump.c +++ b/bootstrap/dump.c @@ -148,8 +148,10 @@ tok2str(struct tok tok) { return "<type parameter>"; } else if (tok.t == TKexpr) { return "<const parameter>"; + } else if (tok.t == TKhwhen) { + return "`#when'"; } else if (tok.t == TKstrify) { - return "#strify"; + return "`#strify'"; } else if (tok.t < NUM_KEYWORDS) { snprintf(buf, sizeof buf - 1, "`%s'", keyword2str[tok.t]); } else if (tok.t > 0xFF) { 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, ']')) { |