Trying to change untyped to typed in the typechecking phase

This commit is contained in:
Krzosa Karol
2022-06-22 13:16:49 +02:00
parent 40557b083b
commit 35daeade20
2 changed files with 110 additions and 25 deletions

View File

@@ -167,13 +167,17 @@ gen_value(Token *pos, Value a){
const char *string = bigint_to_error_string(scratch, &a.big_int_val, 10);
gen("%s", string);
}break;
CASE_STRING:
if(is_pointer(a.type)){
assert(a.type == type_pointer_to_char);
case TYPE_POINTER:{
if(a.type == type_pointer_to_char){
gen("\"%Q\"", a.intern_val);
} else{
gen("(String){(U8 *)\"%Q\", %d}", a.intern_val, a.intern_val.len);
}
else{
U64 pointer_value = bigint_as_unsigned(&a.big_int_val);
gen("0x%llx", pointer_value);
}
}break;
case TYPE_STRING:
gen("(String){(U8 *)\"%Q\", %d}", a.intern_val, a.intern_val.len);
break;
CASE_BOOL: a.bool_val ? gen("true"):gen("false"); break;
CASE_FLOAT: gen("%f", a.f64_val); break;

View File

@@ -456,6 +456,67 @@ insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
scope->decls.add(decl);
}
//
// Booleans are special in that untyped boolean appears from every comparison
// and children of that comparison don't have to be booleans so we have to
// propagate values of resolved children to each other
//
// int == untyped_int => bool
// need to propagate int to untyped_int
//
function void
try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_Type *additional_not_bool_type = 0){
if(!ast) return;
if(is_untyped(type)) return;
if(!is_bool(type)){
if(ast->kind != AST_VALUE) return;
auto node = (Ast_Atom *)ast;
node->value = convert_untyped_to_typed(ast->pos, node->value, type);// @rename: try and this
return;
}
switch(ast->kind){
CASE(IDENT, Atom){
type = additional_not_bool_type ? additional_not_bool_type : type;
node->value = convert_untyped_to_typed(ast->pos, node->value, type);
BREAK();
}
CASE(VALUE, Atom){
type = additional_not_bool_type ? additional_not_bool_type : type;
node->value = convert_untyped_to_typed(ast->pos, node->value, type);
BREAK();
}
CASE(BINARY, Binary){
Value value = {}; value.type = node->resolved_type; // @cleanup
node->resolved_type = convert_untyped_to_typed(ast->pos, value, type).type;
// memes: int = 10
// thing: Bool = int == (20 + 10)
try_propagating_resolved_type_to_untyped_literals(node->left, type, node->right->resolved_type);
try_propagating_resolved_type_to_untyped_literals(node->right, type, node->left->resolved_type);
BREAK();
}
CASE(CALL, Call){
if(is_untyped(node->resolved_type))
compiler_error(node->pos, "Internal compiler error: Resolved type of a call is marked as untyped");
BREAK();
}
CASE(UNARY, Unary){
Value value = {}; value.type = node->resolved_type; // @cleanup
node->resolved_type = convert_untyped_to_typed(ast->pos, value, type).type;
try_propagating_resolved_type_to_untyped_literals(node->expr, type);
BREAK();
}
}
}
function Ast_Type *
resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = 0){
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL))
@@ -536,10 +597,12 @@ resolve_stmt(Ast *ast, Ast_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 = type;
// @todo down untyping
// For_It(node->expr){
// Ast_Type *type =
// }
For_It(node->expr){
Ast_Type *sub_type = type;
if(is_tuple(type)) sub_type = type->agg.members[it.i].type;
try_propagating_resolved_type_to_untyped_literals(*it.it, sub_type);
}
BREAK();
}
@@ -561,6 +624,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
CASE(RUNTIME_ASSERT, Builtin){
resolve_and_require_bool("Assert condition is not boolean", node->expr, AST_CAN_BE_NULL);
try_propagating_resolved_type_to_untyped_literals(node->expr, type_bool);
BREAK();
}
@@ -597,6 +661,9 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
else if(!is_bool(op.type)){
compiler_error(node->pos, "Invalid type of for loop condition %Q, required [Bool]", typestring(op.type));
}
else{
try_propagating_resolved_type_to_untyped_literals(node->cond, type_bool);
}
}
resolve_expr(node->iter, AST_CAN_BE_NULL);
@@ -609,6 +676,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
resolve_stmt(it->init, ret);
// @todo: maybe add else kind ?? and then make sure other then else are AST_CANT_BE_NULL
resolve_and_require_bool("Conditional in a if condition", it->expr, AST_CAN_BE_NULL);
try_propagating_resolved_type_to_untyped_literals(it->expr, type_bool);
For_Named(it->scope->stmts, jt)
resolve_stmt(jt, ret);
}
@@ -684,6 +752,7 @@ resolve_lambda_type(Ast_Lambda *lambda){
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL, type);
make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
it->type = type;
try_propagating_resolved_type_to_untyped_literals(it->expr, it->type);
}
args.add(it->type);
@@ -794,6 +863,7 @@ resolve_compound_array(Ast_Call *node, Ast_Type *type){
Operand item = resolve_expr(it->item, AST_CANT_BE_NULL, item_type);
make_sure_value_is_compatible_with_type(it->pos, &item, item_type, TYPE_AND_EXPR_REQUIRED);
it->resolved_type = item_type;
try_propagating_resolved_type_to_untyped_literals(it->item, it->resolved_type);
}
}
@@ -849,6 +919,7 @@ resolve_compound_struct(Ast_Call *node, Ast_Type *type){
make_sure_value_is_compatible_with_type(it->pos, &item, item_type, TYPE_AND_EXPR_REQUIRED);
it->resolved_type = item_type;
try_propagating_resolved_type_to_untyped_literals(it->item, it->resolved_type);
}
For(type->agg.members) it.visited = false;
@@ -897,15 +968,6 @@ 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,11 +1040,20 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
}
node->index_original_type = left.type;
assert(left.type);
// @todo: type_architecture?
try_propagating_resolved_type_to_untyped_literals(node->index, type_s64);
if(!left.type)
compiler_error(node->expr->pos, "Internal compiler error: type of array is null somehow");
if(is_untyped(left.type))
compiler_error(node->expr->pos, "Internal compiler error: type of array is marked as untyped somehow");
if(is_string(left.type)){
return operand_lvalue(type_u8);
}
else if(!is_array(left.type) && !is_pointer(left.type) && !is_slice(left.type)){
if(!is_array(left.type) && !is_pointer(left.type) && !is_slice(left.type)){
compiler_error(node->pos, "Indexing variable that is not an [Array] or [Pointer], it's of type %Q instead", typestring(left.type));
}
@@ -999,10 +1070,10 @@ 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);
node->resolved_type = right.type;
try_propagating_resolved_type_to_untyped_literals(node->left, node->resolved_type, node->right->resolved_type);
try_propagating_resolved_type_to_untyped_literals(node->right, node->resolved_type, node->left->resolved_type);
return {};
}
else if(node->op == TK_Arrow){
@@ -1020,12 +1091,18 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
Operand right = resolve_expr(node->right, AST_CANT_BE_NULL);
B32 is_const = left.is_const && right.is_const;
Value value = eval_binary(node->pos, node->op, left.value, right.value, is_const);
node->resolved_type = value.type;
if(is_const){
// We don't need to propagte deeps for const values cause we are rewritting them
rewrite_into_const(node, Ast_Binary, value);
return operand_const_rvalue(value);
}
else return operand_rvalue(value.type);
else {
try_propagating_resolved_type_to_untyped_literals(node->left, value.type);
try_propagating_resolved_type_to_untyped_literals(node->right, value.type);
return operand_rvalue(value.type);
}
}
BREAK();
}
@@ -1119,6 +1196,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
CASE(LENGTH_OF, Builtin){
Operand name = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
node->resolved_type = type_s64;
if(name.type == type_type){
if(is_array(name.type_val)){
Value value = value_int(name.type_val->arr.size);
@@ -1187,6 +1265,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
item->resolved_type = lambda_arg->type;
}
try_propagating_resolved_type_to_untyped_literals(item->item, item->resolved_type);
item->resolved_index = lambda->args.get_index(&lambda_arg);
items.add(item);
}
@@ -1206,6 +1285,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
}
node->exprs = items.tight_copy(pctx->perm);
node->resolved_type = name.type->func.ret;
// @note: check if all arguments are included and cleanup
For(node->exprs){
@@ -1297,6 +1377,7 @@ resolve_decl(Ast_Decl *ast){
if(node->expr) compiler_error(node->pos, "#foreign variable shouldn't have value");
}
try_propagating_resolved_type_to_untyped_literals(node->expr, node->type);
BREAK();
}