summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-10-03 20:29:22 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-10-03 20:29:22 -0400
commit39b4b36741bb63fe1bd6da945fc5553ff648d97a (patch)
tree4c361b86c79373e119f4bd95923166c67322e4ea
parentd960aa2d2eca0f0efbbcf2440955266ebb5369b8 (diff)
a bit more eval but there are bugs
-rw-r--r--eval.c56
-rw-r--r--main.c2
-rw-r--r--test.toc3
3 files changed, 61 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 337b7e8..cb4f41a 100644
--- a/eval.c
+++ b/eval.c
@@ -1,3 +1,5 @@
+static void eval_block(Evaluator *ev, Block *b, Value *v);
+
static void evalr_create(Evaluator *ev) {
allocr_create(&ev->allocr);
}
@@ -273,6 +275,7 @@ static void val_cast(Value *vin, Type *from, Value *vout, Type *to) {
}
}
+
static void eval_expr(Evaluator *ev, Expression *e, Value *v) {
/* WARNING: macros ahead */
#define eval_unary_op_one(low, up, op) \
@@ -405,6 +408,35 @@ static void eval_expr(Evaluator *ev, Expression *e, Value *v) {
assert(0);
}
break;
+ case EXPR_IF: {
+ IfExpr *i = &e->if_;
+ if (i->cond) {
+ Value cond;
+ eval_expr(ev, i->cond, &cond);
+ if (val_truthiness(&cond, &i->cond->type)) {
+ eval_block(ev, &i->body, v);
+ } else if (i->next_elif) {
+ eval_expr(ev, i->next_elif, v);
+ return;
+ }
+ } else {
+ eval_block(ev, &i->body, v);
+ }
+ } break;
+ case EXPR_WHILE: {
+ Value cond;
+ WhileExpr *w = &e->while_;
+ bool looped_once = false;
+ while (1) {
+ eval_expr(ev, w->cond, &cond);
+ if (!val_truthiness(&cond, &w->cond->type))
+ break;
+ eval_block(ev, &w->body, v);
+ }
+ } break;
+ case EXPR_BLOCK:
+ eval_block(ev, &e->block, v);
+ break;
case EXPR_LITERAL_BOOL:
v->boolv = e->booll;
break;
@@ -421,3 +453,27 @@ static void eval_expr(Evaluator *ev, Expression *e, Value *v) {
} break;
}
}
+
+static void eval_stmt(Evaluator *ev, Statement *stmt) {
+ switch (stmt->kind) {
+ case STMT_DECL:
+ /* TODO */
+ break;
+ case STMT_EXPR: {
+ Value unused;
+ eval_expr(ev, &stmt->expr, &unused);
+ } break;
+ case STMT_RET:
+ /* TODO */
+ break;
+ }
+}
+
+static void eval_block(Evaluator *ev, Block *b, Value *v) {
+ arr_foreach(b->stmts, Statement, stmt) {
+ eval_stmt(ev, stmt);
+ }
+ if (b->ret_expr) {
+ eval_expr(ev, b->ret_expr, v);
+ }
+}
diff --git a/main.c b/main.c
index 2fd777d..9cca0f2 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,9 @@
/*
TODO:
+whiles should not return values, unless they have no condition
call fns at compile time
finish evaluator
+improve casting: do you really need "as"?
fix void fn type
re-do cgen
any odd number of "s for a string
diff --git a/test.toc b/test.toc
index be9340c..09471ae 100644
--- a/test.toc
+++ b/test.toc
@@ -7,6 +7,9 @@ main @= fn() {
bar := foo(3);
+ a238674 : [if 5 - 5 { 12 } else { 6 }]int;
+ a2394823 : [{ 3; 7 }]int;
+ gfdsdgf : [ while 3 { 5 }]int;
// arr1 : ['a' as u8]int;
// arr2 : [main as u64]int;
// arr3 : [main as i64]int;