aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstrap/fold.c38
-rw-r--r--bootstrap/test.cff2
2 files changed, 33 insertions, 7 deletions
diff --git a/bootstrap/fold.c b/bootstrap/fold.c
index 8f080a0..6a62359 100644
--- a/bootstrap/fold.c
+++ b/bootstrap/fold.c
@@ -58,7 +58,7 @@ numcast(struct expr *ex, const struct type *to) {
}
static void
-unary(struct expr *ex) {
+funary(struct expr *ex) {
struct expr *r = ex->unop.child;
const struct type *ty = ex->ty;
@@ -96,7 +96,7 @@ unary(struct expr *ex) {
}
static void
-binop(struct expr *ex) {
+fbinop(struct expr *ex) {
struct expr *l = ex->binop.lhs;
struct expr *r = ex->binop.rhs;
const struct type *ty = ex->ty,
@@ -159,7 +159,7 @@ binop(struct expr *ex) {
}
static void
-cond(struct expr *ex) {
+fcond(struct expr *ex) {
struct expr *test = ex->cond.test,
*t = ex->cond.t,
*f = ex->cond.f;
@@ -180,6 +180,28 @@ cond(struct expr *ex) {
free(f);
}
+static void
+findex(struct expr *ex) {
+ struct expr *ty = ex->ty,
+ *l = ex->index.lhs,
+ *r = ex->index.rhs;
+
+ if (!fold(l) || !fold(r))
+ return;
+
+ if (l->t == Estrlit) {
+ if (r->u > l->strlit.n)
+ return;
+ ex->t = Eintlit;
+ ex->i = l->strlit.d[r->u];
+ } else {
+ assert(0);
+ }
+
+ free(l);
+ free(r);
+}
+
int
fold(struct expr *ex) {
switch (ex->t) {
@@ -189,13 +211,17 @@ fold(struct expr *ex) {
case Estrlit:case Enullit:
return 1;
case Eprefix:
- unary(ex);
+ funary(ex);
break;
case Ebinop:
- binop(ex);
+ fbinop(ex);
break;
case Econd:
- cond(ex);
+ fcond(ex);
+ break;
+ case Eindex:
+ findex(ex);
+ break;
default:
break;
}
diff --git a/bootstrap/test.cff b/bootstrap/test.cff
index 1f426b8..ba47c6d 100644
--- a/bootstrap/test.cff
+++ b/bootstrap/test.cff
@@ -1,4 +1,4 @@
-typedef v3f [-(-1 * 2) + -(-8/~~5)]f32;
+typedef v3f ["!"[~-1] - 30]f32;
extern fn main (argc int, argv **u8) void {
extern fn printf(fmt *const u8, ...) int;