Multiple return values working!

This commit is contained in:
Krzosa Karol
2022-06-16 12:42:43 +02:00
parent 5345894e3e
commit c262e7e491
3 changed files with 43 additions and 12 deletions

View File

@@ -139,6 +139,7 @@ struct Ast_Builtin: Ast_Expr{
//
struct Ast_Return: Ast{
Ast_Type *resolved_type;
Array<Ast_Expr *> expr;
};

View File

@@ -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);
@@ -382,10 +395,17 @@ gen_ast(Ast *ast){
CASE(RETURN, Return){
gen("return ");
For(node->expr){
gen(" ");
gen_expr(it); // @todo multiple_returns
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();
}

View File

@@ -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();
}