From b6b75a1e166c6ce5f18a2854e1c594b6bebd7049 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 24 Sep 2019 14:28:23 -0400 Subject: bug fixes; no non-void if without else --- parse.c | 1 + test.toc | 18 ++++++++---------- types.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/parse.c b/parse.c index 49b13e8..a753bda 100644 --- a/parse.c +++ b/parse.c @@ -1007,6 +1007,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (token_is_kw(t->token, KW_LBRACE)) { /* it's a block */ + e->kind = EXPR_BLOCK; if (!parse_block(p, &e->block)) return false; if (t->token != end) { tokr_err(t, "Expression continues after end of block."); /* TODO: improve this err message */ diff --git a/test.toc b/test.toc index 788cdcd..94e8ff7 100644 --- a/test.toc +++ b/test.toc @@ -1,13 +1,11 @@ main @= fn() { - //x := 1; - /*foo := if x { - 9 - } elif 7-3 { - 5 - } elif main { - 3 - } else {7 };*/ - - bar := if 1 { 9 }; + { + i := 0; + asdf := if (fn(i: i64) i64 { i - 1024 })(i) { + i = i * 2; + i + } else { 0 }; + } + (fn(){})(); }; diff --git a/types.c b/types.c index 8c42d7e..7e9e929 100644 --- a/types.c +++ b/types.c @@ -374,8 +374,8 @@ static bool type_of_expr(Typer *tr, Expression *e) { } } - if (!has_else && t->kind == TYPE_VOID) { - err_print(e->where, "non-void if block with no else"); + if (!has_else && t->kind != TYPE_VOID) { + err_print(e->where, "Non-void if block with no else."); return false; } } break; @@ -583,26 +583,46 @@ static bool type_of_expr(Typer *tr, Expression *e) { } static bool types_block(Typer *tr, Block *b) { - bool ret = true; + bool success = true; Block *prev_block = tr->block; tr->block = b; if (!block_enter(b, &b->stmts)) return false; arr_foreach(&b->stmts, Statement, s) { - if (!types_stmt(tr, s)) ret = false; + if (!types_stmt(tr, s)) success = false; } - if (b->ret_expr) + if (!success) return false; + if (b->ret_expr) { if (!types_expr(tr, b->ret_expr)) - ret = false; + return false; + if (b->ret_expr->type.kind == TYPE_VOID) { + err_print(b->ret_expr->where, "Cannot return void value."); + return false; + } + } + block_exit(b, &b->stmts); tr->block = prev_block; - return ret; + return true; } -/* does descend into blocks, unlike type_of_expr. */ +/* does descend into functions, unlike type_of_expr. */ /* TODO: you still need to descend into other things */ static bool types_expr(Typer *tr, Expression *e) { if (!type_of_expr(tr, e)) return false; switch (e->kind) { + case EXPR_UNARY_OP: + if (!types_expr(tr, e->unary.of)) return false; + break; + case EXPR_BINARY_OP: + if (!types_expr(tr, e->binary.lhs)) return false; + if (!types_expr(tr, e->binary.rhs)) return false; + break; + case EXPR_CALL: + if (!types_expr(tr, e->call.fn)) return false; + arr_foreach(&e->call.args, Expression, arg) { + if (!types_expr(tr, arg)) return false; + } + break; case EXPR_FN: { assert(e->type.kind == TYPE_FN); FnExpr *f = e->fn; @@ -631,7 +651,18 @@ static bool types_expr(Typer *tr, Expression *e) { return false; } } break; - default: break; + case EXPR_IF: { + IfExpr *i = &e->if_; + if (i->cond && !types_expr(tr, i->cond)) return false; + + } break; + case EXPR_DIRECT: + case EXPR_BLOCK: + case EXPR_IDENT: + case EXPR_LITERAL_INT: + case EXPR_LITERAL_FLOAT: + case EXPR_LITERAL_STR: + break; } return true; } -- cgit v1.2.3