diff options
| author | 2022-08-07 17:23:35 +0200 | |
|---|---|---|
| committer | 2022-08-07 17:23:35 +0200 | |
| commit | 855834ed40250f35fe5de5e304173ec69059e2fc (patch) | |
| tree | 093435fcaff9d62bdca0f8a169460b58eb64830b /bootstrap/parse.c | |
| parent | b348c470ff065400ff149da6ccefa8fd8f22e9be (diff) | |
constant defs
Diffstat (limited to 'bootstrap/parse.c')
| -rw-r--r-- | bootstrap/parse.c | 32 |
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; |