diff options
-rw-r--r-- | eval.c | 5 | ||||
-rw-r--r-- | parse.c | 28 | ||||
-rw-r--r-- | test.toc | 6 | ||||
-rw-r--r-- | types.c | 9 |
4 files changed, 42 insertions, 6 deletions
@@ -136,8 +136,9 @@ static bool eval_expr(Expression *e, Value *v) { case EXPR_FN: v->fn = *e->fn; return true; - case EXPR_IF: { - err_print(e->where, "compile time if not supported yet."); /* TODO */ + case EXPR_IF: + case EXPR_WHILE: { + err_print(e->where, "compile time if/while not supported yet."); /* TODO */ } break; case EXPR_CALL: err_print(e->where, "Compile time function calling not supported yet."); /* TODO */ @@ -68,6 +68,7 @@ typedef enum { EXPR_BINARY_OP, EXPR_UNARY_OP, EXPR_IF, + EXPR_WHILE, EXPR_FN, EXPR_CALL, EXPR_BLOCK, @@ -106,6 +107,11 @@ typedef struct { Block body; } IfExpr; +typedef struct { + struct Expression *cond; + Block body; +} WhileExpr; + #define EXPR_FLAG_FOUND_TYPE 0x01 typedef struct Expression { @@ -130,6 +136,7 @@ typedef struct Expression { DirectExpr direct; Identifier ident; IfExpr if_; + WhileExpr while_; struct FnExpr *fn; Block block; }; @@ -799,7 +806,21 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { return true; } case KW_WHILE: { - /* TODO */ + e->kind = EXPR_WHILE; + WhileExpr *w = &e->while_; + t->token++; + Token *cond_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE, NULL); + if (!cond_end) return false; + if (!token_is_kw(cond_end, KW_LBRACE)) { + t->token = cond_end; + tokr_err(t, "Expected { to open while body."); + return false; + } + Expression *cond = parser_new_expr(p); + w->cond = cond; + if (!parse_expr(p, cond, cond_end)) + return false; + if (!parse_block(p, &w->body)) return false; return true; } default: break; @@ -1429,6 +1450,11 @@ static void fprint_expr(FILE *out, Expression *e) { if (e->if_.next_elif) fprint_expr(out, e->if_.next_elif); break; + case EXPR_WHILE: + fprintf(out, "while "); + fprint_expr(out, e->while_.cond); + fprint_block(out, &e->while_.body); + break; case EXPR_CALL: fprint_expr(out, e->call.fn); fprint_args(out, &e->call.args); @@ -1,10 +1,10 @@ main @= fn() { { - i := 0; - asdf := if (fn(i: i64) i64 { i - 1024 })(i) { + i := 1; + asdf := while (fn(i: i64) i64 { i - 1024 })(i) { i = i * 2; i - } else { 0 }; + }; } (fn(){})(); }; @@ -379,6 +379,15 @@ static bool type_of_expr(Typer *tr, Expression *e) { return false; } } break; + case EXPR_WHILE: { + WhileExpr *w = &e->while_; + if (!types_block(tr, &w->body)) + return false; + if (!type_of_expr()) { + /* TODO: is type_of_expr really necessary? why not just never descend into fns unless it's a decl? */ + } + *t = w->body.ret_expr->type; + } break; case EXPR_CALL: { CallExpr *c = &e->call; Expression *f = c->fn; |