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
convert_untyped_to_typed(Token *pos, Value a, Ast_Type *new_type){
function void
convert_untyped_to_typed(Token *pos, Value *a, Ast_Type *new_type){
assert(new_type);
if(a.type == 0) return a;
if(is_typed(a.type)) return a;
if(a->type == 0) return;
if(is_typed(a->type)) return;
if(is_int(a.type) && is_int(new_type))
assert(a.type == untyped_int);
else if(is_int(a.type) && is_enum(new_type))
if(is_int(a->type) && is_int(new_type))
assert(a->type == untyped_int);
else if(is_int(a->type) && is_enum(new_type))
;
else if(is_int(a.type) && is_float(new_type))
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_float(new_type))
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_float(a.type) && is_float(new_type))
else if(is_float(a->type) && is_float(new_type))
; // 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
else if(is_string(a.type) && is_string(new_type))
else if(is_string(a->type) && is_string(new_type))
; // 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;
check_value_bounds(pos, &a);
return a;
a->type = new_type;
check_value_bounds(pos, 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
@@ -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)){
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)){
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)){
*a = value_float(a->big_int_val);
@@ -324,7 +331,7 @@ eval_unary(Token *pos, Token_Kind op, Operand *operand){
}
function void
try_converting_untyped_to_typed(Value *op){
try_converting_untyped_to_default_type(Value *op){
if(is_untyped(op->type)){
switch(op->type->kind){
case TYPE_UNTYPED_INT: op->type = type_s64; break;
@@ -337,8 +344,8 @@ try_converting_untyped_to_typed(Value *op){
}
function void
try_converting_untyped_to_typed(Operand *op){
try_converting_untyped_to_typed(&op->value);
try_converting_untyped_to_default_type(Operand *op){
try_converting_untyped_to_default_type(&op->value);
}
FLAG32(Typecheck_Flag){
@@ -358,7 +365,7 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ
if(!type){
assert(is_flag_set(debug_flag, TYPE_CAN_BE_NULL));
assert(expr->type);
try_converting_untyped_to_typed(expr);
try_converting_untyped_to_default_type(expr);
}
else if(!expr->type){
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;
}
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)){
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;
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;
}
@@ -484,19 +491,18 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_
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);
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);
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;
node->resolved_type = convert_untyped_to_typed(ast->pos, node->resolved_type, 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);
BREAK();
@@ -509,8 +515,7 @@ try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_
}
CASE(UNARY, Unary){
Value value = {}; value.type = node->resolved_type; // @cleanup
node->resolved_type = convert_untyped_to_typed(ast->pos, value, type).type;
node->resolved_type = convert_untyped_to_typed(ast->pos, node->resolved_type, type);
try_propagating_resolved_type_to_untyped_literals(node->expr, type);
BREAK();
}
@@ -588,7 +593,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
}
else{
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);
@@ -804,7 +809,7 @@ resolve_cast(Ast_Binary *node){
else goto failure;
} break;
CASE_UNTYPED: {
expr.value = convert_untyped_to_typed(node->pos, expr.value, type);
convert_untyped_to_typed(node->pos, &expr.value, type);
} break;
CASE_UINT:
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");
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));
node->resolved_type = right.type;