Multiple return values working!
This commit is contained in:
1
ast.cpp
1
ast.cpp
@@ -139,6 +139,7 @@ struct Ast_Builtin: Ast_Expr{
|
|||||||
//
|
//
|
||||||
|
|
||||||
struct Ast_Return: Ast{
|
struct Ast_Return: Ast{
|
||||||
|
Ast_Type *resolved_type;
|
||||||
Array<Ast_Expr *> expr;
|
Array<Ast_Expr *> expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
51
ccodegen.cpp
51
ccodegen.cpp
@@ -30,7 +30,7 @@ string_scope_name(Allocator *a, Ast_Scope *scope){
|
|||||||
String string = {};
|
String string = {};
|
||||||
if(!should_gen_scope_name) return string;
|
if(!should_gen_scope_name) return string;
|
||||||
if(scope->parent_scope) string = string_scope_name(a, scope->parent_scope);
|
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;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +41,18 @@ gen_scope_name(Ast_Scope *scope){
|
|||||||
gen("%.*s", (int)string.len, string.str);
|
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
|
// @todo: Gen complicated decl
|
||||||
//array 10 ( pointer (pointer array 5 int a))
|
//array 10 ( pointer (pointer array 5 int a))
|
||||||
// int (*(*(a[5])))[10]
|
// 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);
|
string = string_fmt(a, "Slice%llu ", ast->type_id);
|
||||||
return string;
|
return string;
|
||||||
}break;
|
}break;
|
||||||
|
case TYPE_TUPLE:{
|
||||||
|
String string = string_fmt(a, "Tuple%llu ", ast->type_id);
|
||||||
|
return string;
|
||||||
|
}break;
|
||||||
case TYPE_STRUCT: {
|
case TYPE_STRUCT: {
|
||||||
auto constant = (Ast_Decl *)ast->ast;
|
auto constant = (Ast_Decl *)ast->ast;
|
||||||
auto name = constant->name;
|
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)){
|
if(name == pctx->intern("main"_s) || name == pctx->intern("WinMain"_s)){
|
||||||
is_foreign = true;
|
is_foreign = true;
|
||||||
}
|
}
|
||||||
if(lambda->resolved_type->func.ret->kind == TYPE_TUPLE){
|
gen_simple_decl(lambda->resolved_type->func.ret, name, lambda->parent_scope, !is_foreign);
|
||||||
gen("TUPLE ");
|
|
||||||
}
|
|
||||||
else gen_simple_decl(lambda->resolved_type->func.ret, name, lambda->parent_scope, !is_foreign);
|
|
||||||
gen("(");
|
gen("(");
|
||||||
For(lambda->args){
|
For(lambda->args){
|
||||||
gen_var(it, DONT_EMIT_VALUE, true);
|
gen_var(it, DONT_EMIT_VALUE, true);
|
||||||
@@ -382,10 +395,17 @@ gen_ast(Ast *ast){
|
|||||||
|
|
||||||
CASE(RETURN, Return){
|
CASE(RETURN, Return){
|
||||||
gen("return ");
|
gen("return ");
|
||||||
For(node->expr){
|
if(is_tuple(node->resolved_type)) {
|
||||||
gen(" ");
|
gen("(");
|
||||||
gen_expr(it); // @todo multiple_returns
|
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(";");
|
gen(";");
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
@@ -528,11 +548,20 @@ gen_ast(Ast *ast){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(VAR_UNPACK, Var_Unpack){
|
CASE(VAR_UNPACK, Var_Unpack){
|
||||||
For(node->vars) {
|
For(node->vars) {gen_ast(it);}
|
||||||
gen_ast(it);
|
|
||||||
}
|
Scratch scratch;
|
||||||
|
gen_simple_decl(node->resolved_type);
|
||||||
|
String var_name = unique_name(scratch, node);
|
||||||
|
gen("%Q", var_name);
|
||||||
gen(" = ");
|
gen(" = ");
|
||||||
gen_expr(node->expr);
|
gen_expr(node->expr);
|
||||||
|
gen(";");
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
For(node->vars) {
|
||||||
|
gen("%Q = %Q.m%d;", it->name, var_name, i);
|
||||||
|
}
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -435,6 +435,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
|||||||
value = convert_untyped_to_typed(node->pos, value, ret);
|
value = convert_untyped_to_typed(node->pos, value, ret);
|
||||||
if(value.type && value.type != 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));
|
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();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user