This commit is contained in:
Krzosa Karol
2022-06-22 13:25:07 +02:00
parent 33ba44989b
commit b0872e2303

View File

@@ -77,31 +77,38 @@ check_value_bounds(Token *pos, Value *a){
} }
} }
function Value function void
convert_untyped_to_typed(Token *pos, Value a, Ast_Type *new_type){ convert_untyped_to_typed(Token *pos, Value *a, Ast_Type *new_type){
assert(new_type); assert(new_type);
if(a.type == 0) return a; if(a->type == 0) return;
if(is_typed(a.type)) return a; if(is_typed(a->type)) return;
if(is_int(a.type) && is_int(new_type)) if(is_int(a->type) && is_int(new_type))
assert(a.type == untyped_int); assert(a->type == untyped_int);
else if(is_int(a.type) && is_enum(new_type)) else if(is_int(a->type) && is_enum(new_type))
; ;
else if(is_int(a.type) && is_float(new_type)) else if(is_int(a->type) && is_float(new_type))
a.f64_val = bigint_as_float(&a.big_int_val); // @leak bigint a->f64_val = bigint_as_float(&a->big_int_val); // @leak bigint
else if(is_int(a.type) && is_pointer(new_type)) else if(is_int(a->type) && is_pointer(new_type))
; ;
else if(is_float(a.type) && is_float(new_type)) else if(is_float(a->type) && is_float(new_type))
; // nothing to do ; // nothing to do
else if(is_bool(a.type) && is_bool(new_type)) else if(is_bool(a->type) && is_bool(new_type))
; // nothing to do ; // nothing to do
else if(is_string(a.type) && is_string(new_type)) else if(is_string(a->type) && is_string(new_type))
; // nothing to do ; // nothing to do
else compiler_error(pos, "Type mismatch when converting from %Q to %Q", typestring(a.type), typestring(new_type)); else compiler_error(pos, "Type mismatch when converting from %Q to %Q", typestring(a->type), typestring(new_type));
a.type = new_type; a->type = new_type;
check_value_bounds(pos, &a); check_value_bounds(pos, a);
return a; }
function Ast_Type *
convert_untyped_to_typed(Token *pos, Ast_Type *type, Ast_Type *new_type){
Value value = {};
value.type = type;
convert_untyped_to_typed(pos, &value, new_type);
return value.type;
} }
function void function void
@@ -120,11 +127,11 @@ make_sure_types_are_compatible_for_constant_evaluation(Token *pos, Value *a, Val
if(is_untyped(a->type) && is_typed(b->type)){ if(is_untyped(a->type) && is_typed(b->type)){
assert(is_typed(b->type)); assert(is_typed(b->type));
*a = convert_untyped_to_typed(pos, *a, b->type); convert_untyped_to_typed(pos, a, b->type);
} }
else if(is_typed(a->type) && is_untyped(b->type)){ else if(is_typed(a->type) && is_untyped(b->type)){
assert(is_typed(a->type)); assert(is_typed(a->type));
*b = convert_untyped_to_typed(pos, *b, a->type); convert_untyped_to_typed(pos, b, a->type);
} }
else if(is_int(a->type) && is_float(b->type)){ else if(is_int(a->type) && is_float(b->type)){
*a = value_float(a->big_int_val); *a = value_float(a->big_int_val);
@@ -324,7 +331,7 @@ eval_unary(Token *pos, Token_Kind op, Operand *operand){
} }
function void function void
try_converting_untyped_to_typed(Value *op){ try_converting_untyped_to_default_type(Value *op){
if(is_untyped(op->type)){ if(is_untyped(op->type)){
switch(op->type->kind){ switch(op->type->kind){
case TYPE_UNTYPED_INT: op->type = type_s64; break; case TYPE_UNTYPED_INT: op->type = type_s64; break;
@@ -337,8 +344,8 @@ try_converting_untyped_to_typed(Value *op){
} }
function void function void
try_converting_untyped_to_typed(Operand *op){ try_converting_untyped_to_default_type(Operand *op){
try_converting_untyped_to_typed(&op->value); try_converting_untyped_to_default_type(&op->value);
} }
FLAG32(Typecheck_Flag){ FLAG32(Typecheck_Flag){
@@ -358,7 +365,7 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ
if(!type){ if(!type){
assert(is_flag_set(debug_flag, TYPE_CAN_BE_NULL)); assert(is_flag_set(debug_flag, TYPE_CAN_BE_NULL));
assert(expr->type); assert(expr->type);
try_converting_untyped_to_typed(expr); try_converting_untyped_to_default_type(expr);
} }
else if(!expr->type){ else if(!expr->type){
assert(is_flag_set(debug_flag, EXPR_CAN_BE_NULL)); assert(is_flag_set(debug_flag, EXPR_CAN_BE_NULL));
@@ -375,7 +382,7 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ
expr->type = type; expr->type = type;
} }
else if(is_untyped(expr->type)){ else if(is_untyped(expr->type)){
expr->value = convert_untyped_to_typed(pos, expr->value, type); convert_untyped_to_typed(pos, &expr->value, type);
} }
else if(is_slice(type) && is_array(expr->type)){ else if(is_slice(type) && is_array(expr->type)){
if(type->arr.slice_hash == expr->type->arr.slice_hash) if(type->arr.slice_hash == expr->type->arr.slice_hash)
@@ -476,7 +483,7 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_
if(ast->kind != AST_VALUE) return; if(ast->kind != AST_VALUE) return;
auto node = (Ast_Atom *)ast; auto node = (Ast_Atom *)ast;
node->value = convert_untyped_to_typed(ast->pos, node->value, type);// @rename: try and this convert_untyped_to_typed(ast->pos, &node->value, type);
return; return;
} }
@@ -484,19 +491,18 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_
switch(ast->kind){ switch(ast->kind){
CASE(IDENT, Atom){ CASE(IDENT, Atom){
type = additional_not_bool_type ? additional_not_bool_type : type; type = additional_not_bool_type ? additional_not_bool_type : type;
node->value = convert_untyped_to_typed(ast->pos, node->value, type); convert_untyped_to_typed(ast->pos, &node->value, type);
BREAK(); BREAK();
} }
CASE(VALUE, Atom){ CASE(VALUE, Atom){
type = additional_not_bool_type ? additional_not_bool_type : type; type = additional_not_bool_type ? additional_not_bool_type : type;
node->value = convert_untyped_to_typed(ast->pos, node->value, type); convert_untyped_to_typed(ast->pos, &node->value, type);
BREAK(); BREAK();
} }
CASE(BINARY, Binary){ CASE(BINARY, Binary){
Value value = {}; value.type = node->resolved_type; // @cleanup node->resolved_type = convert_untyped_to_typed(ast->pos, node->resolved_type, type);
node->resolved_type = convert_untyped_to_typed(ast->pos, value, type).type;
try_propagating_resolved_type_to_untyped_literals(node->left, type, node->right->resolved_type); 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); try_propagating_resolved_type_to_untyped_literals(node->right, type, node->left->resolved_type);
BREAK(); BREAK();
@@ -509,8 +515,7 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_
} }
CASE(UNARY, Unary){ CASE(UNARY, Unary){
Value value = {}; value.type = node->resolved_type; // @cleanup node->resolved_type = convert_untyped_to_typed(ast->pos, node->resolved_type, type);
node->resolved_type = convert_untyped_to_typed(ast->pos, value, type).type;
try_propagating_resolved_type_to_untyped_literals(node->expr, type); try_propagating_resolved_type_to_untyped_literals(node->expr, type);
BREAK(); BREAK();
} }
@@ -588,7 +593,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
} }
else{ else{
op = resolve_expr(*it.it, AST_CAN_BE_NULL, ret); op = resolve_expr(*it.it, AST_CAN_BE_NULL, ret);
op.value = convert_untyped_to_typed(node->pos, op.value, ret); convert_untyped_to_typed(node->pos, &op.value, ret);
} }
types.add(op.type); types.add(op.type);
@@ -804,7 +809,7 @@ resolve_cast(Ast_Binary *node){
else goto failure; else goto failure;
} break; } break;
CASE_UNTYPED: { CASE_UNTYPED: {
expr.value = convert_untyped_to_typed(node->pos, expr.value, type); convert_untyped_to_typed(node->pos, &expr.value, type);
} break; } break;
CASE_UINT: CASE_UINT:
CASE_SINT:{ CASE_SINT:{
@@ -1061,7 +1066,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
if(!left.is_lvalue) compiler_error(node->pos, "Assigning to rvalue"); if(!left.is_lvalue) compiler_error(node->pos, "Assigning to rvalue");
Operand right = resolve_expr(node->right, AST_CANT_BE_NULL); Operand right = resolve_expr(node->right, AST_CANT_BE_NULL);
right.value = convert_untyped_to_typed(node->pos, right.value, left.type); 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;