aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-15 14:52:15 +0200
committerlemon <lsof@mailbox.org>2022-08-15 14:52:15 +0200
commitfeeb86d046d55d197040c7061e39198c80373ecb (patch)
tree733d4da08ec979eb8f6b9b91d39c655e7fd4847b /bootstrap
parentf906d0b350b0b4ceb747669c9a9845d11bd0e486 (diff)
#when
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/all.h1
-rw-r--r--bootstrap/dump.c4
-rw-r--r--bootstrap/parse.c27
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, ']')) {