aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/parse.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-07 17:23:35 +0200
committerlemon <lsof@mailbox.org>2022-08-07 17:23:35 +0200
commit855834ed40250f35fe5de5e304173ec69059e2fc (patch)
tree093435fcaff9d62bdca0f8a169460b58eb64830b /bootstrap/parse.c
parentb348c470ff065400ff149da6ccefa8fd8f22e9be (diff)
constant defs
Diffstat (limited to 'bootstrap/parse.c')
-rw-r--r--bootstrap/parse.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index 912a346..7b2e007 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -1055,6 +1055,8 @@ pexprimary(struct parser *P) {
ex.ty = decl->var.ty;
} else if (decl->t == Dstatic) {
ex.ty = decl->var.ty;
+ } else if (decl->t == Ddef) {
+ ex = *decl->var.ini;
} else if (decl->t == Dfn) {
if (!decl->fn.selfty)
((struct decl *)decl)->fn.selfty = fntype(&decl->fn);
@@ -1934,7 +1936,7 @@ isdecltokt(int tokt) {
switch (tokt)
case TKkw_extern: case TKkw_fn: case TKkw_typedef:
case TKkw_defmacro: case TKkw_static: case TKkw_enum:
- case TKkw_struct: case TKkw_union:
+ case TKkw_struct: case TKkw_union: case TKkw_def:
return 1;
return 0;
}
@@ -2617,6 +2619,28 @@ staticvaryield(struct decl *decl, void *arg) {
a->yield(decl, a->yarg);
}
+struct defyarg {
+ struct parser *P;
+ struct span espan;
+ decl_yielder_t yield;
+ void *yarg;
+};
+
+static void
+defyield(struct decl *decl, void *arg) {
+ struct defyarg *a = arg;
+ decl->t = Ddef;
+ decl->span = a->espan;
+ assert(decl->name);
+ if (!decl->var.ini)
+ fatal(a->P, decl->span, "def must have a value");
+ if (!fold(decl->var.ini))
+ fatal(a->P, decl->var.ini->span, "def initializer must be constant expression");
+ putdecl(a->P, decl->span, decl);
+ if (a->yield)
+ a->yield(decl, a->yarg);
+}
+
static void
parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) {
struct tok tok = { .span = P->tokspan };
@@ -2646,6 +2670,12 @@ parsedecl(decl_yielder_t yield, void *yarg, struct parser *P, bool toplevel) {
P, externp, toplevel, tok.span, yield, yarg
}, P, 0, externp);
return;
+ } else if (lexmatch(P, &tok, TKkw_def)) {
+ if (externp) fatal(P, tok.span, "def cannot be `extern'");
+ parsevardecl(defyield, &(struct defyarg) {
+ P, tok.span, yield, yarg
+ }, P, 0, 0);
+ return;
} else if (lexmatch(P, &tok, TKkw_typedef)) {
if (externp) fatal(P, tok.span, "typedef cannot be `extern'");
decl.t = Dtype;