diff --git a/lambdas.kl b/lambdas.kl index f1f8275..f6d3303 100644 --- a/lambdas.kl +++ b/lambdas.kl @@ -5,16 +5,16 @@ pointer_type :: *S64 if_stmt :: (cond: S64): type CONSTANT :: 10 thing := 10 - if i := thing + cond, cond + CONSTANT + if i := thing + cond, cond > CONSTANT return i + CONSTANT - else if cond - CONSTANT + else if cond < CONSTANT return i - CONSTANT else return CONSTANT for_stmt :: () - for i := 0, i + 10, i+=1 + for i := 0, i < 10, i+=1 pass add_10 :: (size: S64): S64 diff --git a/new_types.kl b/new_types.kl index 67edeb3..eed0ae7 100644 --- a/new_types.kl +++ b/new_types.kl @@ -79,7 +79,7 @@ compounds :: () for pass - for i := 0, i, i+=1 + for i := 0, i == 4, i+=1 pass for j:=0, j < 10 diff --git a/typecheck.cpp b/typecheck.cpp index 638067d..21899c0 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -349,6 +349,39 @@ resolve_typespec(Ast_Expr *ast, B32 ast_can_be_null){ return resolved.type_val; } +function Operand +require_const_int(Ast_Expr *expr, B32 ast_can_be_null){ + Operand op = resolve_expr(expr); + + if(expr == 0 && ast_can_be_null) + return op; + else if(expr == 0) + parsing_error(expr->pos, "This field cannot be null"); + + if(!op.is_const) + parsing_error(expr->pos, "Expected a const value"); + if(!is_int(op.type)) + parsing_error(expr->pos, "Expected a constant integer got instead %s", docname(op.type)); + + return op; +} + +function Operand +resolve_and_require_bool(const char *error, Ast_Expr *expr, B32 ast_can_be_null = AST_CANT_BE_NULL){ + if(!expr){ + if(ast_can_be_null) + return {}; + else parsing_error(0, "Compiler error: Null expression"); + } + + Operand op = resolve_expr(expr); + if(!is_bool(op.type)){ + type_error(expr->pos, type_bool, op.type, "%s", error); + } + + return op; +} + // @note: Ret is return value of function passed down the stack // to check if type matches function void @@ -390,11 +423,13 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ } S64 scope = scope_open(); + { resolve_expr(node->init, ret); - resolve_expr(node->cond, ret); + resolve_and_require_bool("Conditional in a for loop condition", node->cond, AST_CAN_BE_NULL); resolve_expr(node->iter, ret); For(node->block->stmts) resolve_stmt(it, ret); + } scope_close(scope); BREAK(); } @@ -403,9 +438,12 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ For(node->ifs){ resolve_stmt(it->init, ret); S64 scope = scope_open(); - resolve_expr(it->expr); // @todo: typechecking + { + // @todo: maybe add else kind ?? and then make sure other then else are AST_CANT_BE_NULL + resolve_and_require_bool("Conditional in a if condition", it->expr, AST_CAN_BE_NULL); For_It(it->block->stmts, jt) resolve_stmt(jt, ret); + } scope_close(scope); } BREAK(); @@ -421,23 +459,6 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ } } -function Operand -require_const_int(Ast_Expr *expr, B32 ast_can_be_null){ - Operand op = resolve_expr(expr); - - if(expr == 0 && ast_can_be_null) - return op; - else if(expr == 0) - parsing_error(expr->pos, "This field cannot be null"); - - if(!op.is_const) - parsing_error(expr->pos, "Expected a const value"); - if(!is_int(op.type)) - parsing_error(expr->pos, "Expected a constant integer got instead %s", docname(op.type)); - - return op; -} - function Operand resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){ Scratch scratch;