diff --git a/c_codegen.cpp b/c_codegen.cpp index fbd1582..d44870e 100644 --- a/c_codegen.cpp +++ b/c_codegen.cpp @@ -154,7 +154,9 @@ gen_string_simple_decl(Allocator *a, Ast_Type *ast, String name){ } function B32 -gen_value(Value a){ +gen_value(Token *pos, Value a){ + if(is_untyped(a.type)) compiler_error(pos, "Internal compiler error: Untyped got propagated to the codegen stage"); + B32 result = true; if(is_enum(a.type)) goto integer; @@ -275,12 +277,12 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){ CASE(VALUE, Atom){ if(is_any(type_of_var)){ gen("(Any){&"); - gen("("); gen_simple_decl(node->type); gen("){"); gen_value(node->value); gen("}"); + gen("("); gen_simple_decl(node->type); gen("){"); gen_value(node->pos, node->value); gen("}"); gen(", %d}", node->type->type_id); return true; } - B32 written = gen_value(node->value); + B32 written = gen_value(node->pos, node->value); if(!written) { gen("%Q", node->value.intern_val); } @@ -586,7 +588,7 @@ gen_ast(Ast *ast){ For(node->scope->decls){ genln("%Q", it->name); gen(" = "); - gen_value(it->value); + gen_value(it->pos, it->value); gen(","); } global_indent--; @@ -598,20 +600,20 @@ gen_ast(Ast *ast){ switch(node->type->kind){ CASE_FLOAT:{ gen("// F64 %Q = ", node->name); - gen_value(node->value); + // gen_value(node->pos, node->value); } break; CASE_INT:{ gen("// constant int %Q = ", node->name); - gen_value(node->value); + // gen_value(node->pos, node->value); }break; CASE_STRING:{ assert(is_pointer(node->type) ? node->type == type_pointer_to_char : 1); gen("// const String %Q = ", node->name); - gen_value(node->value); + // gen_value(node->pos, node->value); }break; CASE_BOOL:{ gen("// const Bool %Q = ", node->name); - gen_value(node->value); + // gen_value(node->pos, node->value); }break; case TYPE_LAMBDA:{ gen("// "); diff --git a/typechecking.cpp b/typechecking.cpp index 57ffbf6..3e65271 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -516,18 +516,31 @@ resolve_stmt(Ast *ast, Ast_Type *ret){ CASE(RETURN, Return){ // @todo: need to check if all paths return a value Scratch scratch; Array types = {scratch}; - For(node->expr){ - Operand op = resolve_expr(it, AST_CAN_BE_NULL); + + For_It(node->expr){ + Operand op; + if(is_tuple(ret)){ + Ast_Type *sub_type = ret->agg.members[it.i].type; + op = resolve_expr(*it.it, AST_CAN_BE_NULL, sub_type); + } + else{ + op = resolve_expr(*it.it, AST_CAN_BE_NULL, ret); + op.value = convert_untyped_to_typed(node->pos, op.value, ret); + } + types.add(op.type); } Ast_Type *type = type_try_tupling(types, node); - - Value value = {}; value.type = type; - value = convert_untyped_to_typed(node->pos, value, ret); - if(value.type && value.type != ret) + if(type && type != ret) compiler_error(node->pos, "Return statement has different type then returned value, expecting: %Q got instead %Q", typestring(ret), typestring(type)); - node->resolved_type = value.type; + node->resolved_type = type; + + // @todo down untyping + // For_It(node->expr){ + // Ast_Type *type = + // } + BREAK(); } @@ -884,6 +897,15 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){ return resolve_field_access(next, ((Ast_Decl *)type->ast)->scope); } +function void +try_propagating_resolved_type_to_untyped_literals_one_level_deep(Ast *ast, Ast_Type *type){ + if(ast->kind != AST_VALUE) return; + if(is_untyped(type)) return; + + auto node = (Ast_Atom *)ast; + convert_untyped_to_typed(ast->pos, node->value, type);// @rename: try and this +} + function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {}; @@ -978,6 +1000,9 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ right.value = convert_untyped_to_typed(node->pos, right.value, left.type); if(left.type != right.type) compiler_error(node->pos, "Can't assign value when left is %Q and right is %Q", typestring(left.type), typestring(right.type)); node->resolved_type = right.type; + + try_propagating_resolved_type_to_untyped_literals_one_level_deep(node->left, node->resolved_type); + try_propagating_resolved_type_to_untyped_literals_one_level_deep(node->left, node->resolved_type); return {}; } else if(node->op == TK_Arrow){