aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/fold.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-04 10:42:46 +0200
committerlemon <lsof@mailbox.org>2022-08-04 10:42:46 +0200
commit9ea0806f5fff042a20bc0df9798feeebc4a427bf (patch)
tree718c93da22c34adb1c17dda951246f64dedbe90a /bootstrap/fold.c
parentc5d837d2cd9a57e453da9eaab0e41e0c185e084e (diff)
more fold
Diffstat (limited to 'bootstrap/fold.c')
-rw-r--r--bootstrap/fold.c38
1 files changed, 32 insertions, 6 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;
}