aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
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
parentb348c470ff065400ff149da6ccefa8fd8f22e9be (diff)
constant defs
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/all.h2
-rw-r--r--bootstrap/cgen.c4
-rw-r--r--bootstrap/dump.c2
-rw-r--r--bootstrap/parse.c32
-rw-r--r--bootstrap/test2.cff4
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);