diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-03 20:29:22 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-03 20:29:22 -0400 |
commit | 39b4b36741bb63fe1bd6da945fc5553ff648d97a (patch) | |
tree | 4c361b86c79373e119f4bd95923166c67322e4ea | |
parent | d960aa2d2eca0f0efbbcf2440955266ebb5369b8 (diff) |
a bit more eval but there are bugs
-rw-r--r-- | eval.c | 56 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | test.toc | 3 |
3 files changed, 61 insertions, 0 deletions
@@ -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); + } +} @@ -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 @@ -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; |