diff --git a/ast.cpp b/ast.cpp index 89d65f5..c1ada89 100644 --- a/ast.cpp +++ b/ast.cpp @@ -139,6 +139,7 @@ struct Ast_Builtin: Ast_Expr{ // struct Ast_Return: Ast{ + Ast_Type *resolved_type; Array expr; }; diff --git a/ccodegen.cpp b/ccodegen.cpp index bcfbf68..5a4c4f9 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -30,7 +30,7 @@ string_scope_name(Allocator *a, Ast_Scope *scope){ String string = {}; if(!should_gen_scope_name) return string; if(scope->parent_scope) string = string_scope_name(a, scope->parent_scope); - if(scope->name.str) string_fmt(a, "%Q%Q_", string, scope->name); + if(scope->name.str) string = string_fmt(a, "%Q%Q_", string, scope->name); return string; } @@ -41,6 +41,18 @@ gen_scope_name(Ast_Scope *scope){ gen("%.*s", (int)string.len, string.str); } +function String +unique_name(Allocator *allocator, Ast *ast){ + Scratch scratch; + B32 temp = should_gen_scope_name; + should_gen_scope_name = true; + String result = string_scope_name(scratch, ast->parent_scope); + should_gen_scope_name = temp; + assert(result.len); + result = string_fmt(allocator, "%Q%d", result, ast->pos->line); + return result; +} + // @todo: Gen complicated decl //array 10 ( pointer (pointer array 5 int a)) // int (*(*(a[5])))[10] @@ -68,6 +80,10 @@ string_simple_decl_prefix(Allocator *a, Ast_Type *ast, bool scope_names){ string = string_fmt(a, "Slice%llu ", ast->type_id); return string; }break; + case TYPE_TUPLE:{ + String string = string_fmt(a, "Tuple%llu ", ast->type_id); + return string; + }break; case TYPE_STRUCT: { auto constant = (Ast_Decl *)ast->ast; auto name = constant->name; @@ -213,10 +229,7 @@ gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){ if(name == pctx->intern("main"_s) || name == pctx->intern("WinMain"_s)){ is_foreign = true; } - if(lambda->resolved_type->func.ret->kind == TYPE_TUPLE){ - gen("TUPLE "); - } - else gen_simple_decl(lambda->resolved_type->func.ret, name, lambda->parent_scope, !is_foreign); + gen_simple_decl(lambda->resolved_type->func.ret, name, lambda->parent_scope, !is_foreign); gen("("); For(lambda->args){ gen_var(it, DONT_EMIT_VALUE, true); @@ -381,11 +394,18 @@ gen_ast(Ast *ast){ } CASE(RETURN, Return){ - gen("return"); - For(node->expr){ - gen(" "); - gen_expr(it); // @todo multiple_returns + gen("return "); + if(is_tuple(node->resolved_type)) { + gen("("); + gen_simple_decl(node->resolved_type); + gen("){"); } + For(node->expr){ + gen_expr(it); // @todo multiple_returns + if(!node->expr.is_last(&it)) + gen(", "); + } + if(is_tuple(node->resolved_type)) gen("}"); gen(";"); BREAK(); } @@ -528,11 +548,20 @@ gen_ast(Ast *ast){ } CASE(VAR_UNPACK, Var_Unpack){ - For(node->vars) { - gen_ast(it); - } + For(node->vars) {gen_ast(it);} + + Scratch scratch; + gen_simple_decl(node->resolved_type); + String var_name = unique_name(scratch, node); + gen("%Q", var_name); gen(" = "); gen_expr(node->expr); + gen(";"); + + int i = 0; + For(node->vars) { + gen("%Q = %Q.m%d;", it->name, var_name, i); + } BREAK(); } diff --git a/typechecking.cpp b/typechecking.cpp index 37f7996..5b458bf 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -435,6 +435,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){ value = convert_untyped_to_typed(node->pos, value, ret); if(value.type && value.type != ret) compiler_error(node->pos, "Return statement has different type then returned value, expecting: %s got instead %s", docname(ret), docname(type)); + node->resolved_type = value.type; BREAK(); }