Fix return type checking bug due to tuples potentially having untyped types. Also working on down typing untyped.
This commit is contained in:
@@ -154,7 +154,9 @@ gen_string_simple_decl(Allocator *a, Ast_Type *ast, String name){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function B32
|
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;
|
B32 result = true;
|
||||||
if(is_enum(a.type))
|
if(is_enum(a.type))
|
||||||
goto integer;
|
goto integer;
|
||||||
@@ -275,12 +277,12 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
CASE(VALUE, Atom){
|
CASE(VALUE, Atom){
|
||||||
if(is_any(type_of_var)){
|
if(is_any(type_of_var)){
|
||||||
gen("(Any){&");
|
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);
|
gen(", %d}", node->type->type_id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
B32 written = gen_value(node->value);
|
B32 written = gen_value(node->pos, node->value);
|
||||||
if(!written) {
|
if(!written) {
|
||||||
gen("%Q", node->value.intern_val);
|
gen("%Q", node->value.intern_val);
|
||||||
}
|
}
|
||||||
@@ -586,7 +588,7 @@ gen_ast(Ast *ast){
|
|||||||
For(node->scope->decls){
|
For(node->scope->decls){
|
||||||
genln("%Q", it->name);
|
genln("%Q", it->name);
|
||||||
gen(" = ");
|
gen(" = ");
|
||||||
gen_value(it->value);
|
gen_value(it->pos, it->value);
|
||||||
gen(",");
|
gen(",");
|
||||||
}
|
}
|
||||||
global_indent--;
|
global_indent--;
|
||||||
@@ -598,20 +600,20 @@ gen_ast(Ast *ast){
|
|||||||
switch(node->type->kind){
|
switch(node->type->kind){
|
||||||
CASE_FLOAT:{
|
CASE_FLOAT:{
|
||||||
gen("// F64 %Q = ", node->name);
|
gen("// F64 %Q = ", node->name);
|
||||||
gen_value(node->value);
|
// gen_value(node->pos, node->value);
|
||||||
} break;
|
} break;
|
||||||
CASE_INT:{
|
CASE_INT:{
|
||||||
gen("// constant int %Q = ", node->name);
|
gen("// constant int %Q = ", node->name);
|
||||||
gen_value(node->value);
|
// gen_value(node->pos, node->value);
|
||||||
}break;
|
}break;
|
||||||
CASE_STRING:{
|
CASE_STRING:{
|
||||||
assert(is_pointer(node->type) ? node->type == type_pointer_to_char : 1);
|
assert(is_pointer(node->type) ? node->type == type_pointer_to_char : 1);
|
||||||
gen("// const String %Q = ", node->name);
|
gen("// const String %Q = ", node->name);
|
||||||
gen_value(node->value);
|
// gen_value(node->pos, node->value);
|
||||||
}break;
|
}break;
|
||||||
CASE_BOOL:{
|
CASE_BOOL:{
|
||||||
gen("// const Bool %Q = ", node->name);
|
gen("// const Bool %Q = ", node->name);
|
||||||
gen_value(node->value);
|
// gen_value(node->pos, node->value);
|
||||||
}break;
|
}break;
|
||||||
case TYPE_LAMBDA:{
|
case TYPE_LAMBDA:{
|
||||||
gen("// ");
|
gen("// ");
|
||||||
|
|||||||
@@ -516,18 +516,31 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
|
|||||||
CASE(RETURN, Return){ // @todo: need to check if all paths return a value
|
CASE(RETURN, Return){ // @todo: need to check if all paths return a value
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Array<Ast_Type *> types = {scratch};
|
Array<Ast_Type *> 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);
|
types.add(op.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Type *type = type_try_tupling(types, node);
|
Ast_Type *type = type_try_tupling(types, node);
|
||||||
|
if(type && type != ret)
|
||||||
Value value = {}; value.type = type;
|
|
||||||
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: %Q got instead %Q", typestring(ret), typestring(type));
|
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();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -884,6 +897,15 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){
|
|||||||
return resolve_field_access(next, ((Ast_Decl *)type->ast)->scope);
|
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
|
function Operand
|
||||||
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
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);
|
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));
|
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;
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
else if(node->op == TK_Arrow){
|
else if(node->op == TK_Arrow){
|
||||||
|
|||||||
Reference in New Issue
Block a user