diff options
| author | 2022-08-07 17:23:35 +0200 | |
|---|---|---|
| committer | 2022-08-07 17:23:35 +0200 | |
| commit | 855834ed40250f35fe5de5e304173ec69059e2fc (patch) | |
| tree | 093435fcaff9d62bdca0f8a169460b58eb64830b /bootstrap | |
| parent | b348c470ff065400ff149da6ccefa8fd8f22e9be (diff) | |
constant defs
Diffstat (limited to 'bootstrap')
| -rw-r--r-- | bootstrap/all.h | 2 | ||||
| -rw-r--r-- | bootstrap/cgen.c | 4 | ||||
| -rw-r--r-- | bootstrap/dump.c | 2 | ||||
| -rw-r--r-- | bootstrap/parse.c | 32 | ||||
| -rw-r--r-- | bootstrap/test2.cff | 4 |
5 files changed, 41 insertions, 3 deletions
diff --git a/bootstrap/all.h b/bootstrap/all.h index 8c61d5e..5302a07 100644 --- a/bootstrap/all.h +++ b/bootstrap/all.h @@ -35,6 +35,7 @@ struct span { _(break) \ _(case) \ _(const) \ + _(def) \ _(defmacro) \ _(do) \ _(else) \ @@ -229,6 +230,7 @@ enum decltype { Dfn, Dlet, Dstatic, + Ddef, Dmacro, Dtepl, }; diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c index 587f546..3bd6710 100644 --- a/bootstrap/cgen.c +++ b/bootstrap/cgen.c @@ -303,7 +303,7 @@ genstmt(struct stmt *stmt) { if (decl.externp) genstatic(1, decl.name, &decl.var); break; - case Dtype: case Dmacro: case Dtepl: + case Ddef: case Dtype: case Dmacro: case Dtepl: break; } break; @@ -550,7 +550,7 @@ gendecl(struct decl *decl, bool toplevel) { case Dlet: assert(!toplevel); break; - case Dtype: case Dtepl: case Dmacro: + case Ddef: case Dtype: case Dtepl: case Dmacro: break; } } diff --git a/bootstrap/dump.c b/bootstrap/dump.c index dae457a..047e77b 100644 --- a/bootstrap/dump.c +++ b/bootstrap/dump.c @@ -403,6 +403,8 @@ dumpdecl(const struct decl *decl, int ws) { epri(" = %e", decl->var.ini); epri("\n"); break; + case Ddef: + epri("<def> %t = %e", decl->var.ty, decl->var.ini); case Dfn: epri("<%sfn> (", decl->externp ? "extern " : ""); for (int i = 0; i < decl->fn.params.n; ++i) 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; diff --git a/bootstrap/test2.cff b/bootstrap/test2.cff index 7a61f28..3532f4a 100644 --- a/bootstrap/test2.cff +++ b/bootstrap/test2.cff @@ -12,11 +12,15 @@ struct Bit<T> { fn neg(x T) T { return ~x; } } +def X = 7 + 2, + Y = 3.3; + extern fn main() void { let n Node<int> = {#null, 0}; let n Node<int> = {&n, 1}; let x int #?; + x = X + 1 + Y; printf("n %d\n", n.value); printf("n link %d\n", n.link.value); |