More work on conversions and constant evaluation

This commit is contained in:
Krzosa Karol
2022-06-03 14:13:45 +02:00
parent e200a006a2
commit c2f501bf36
2 changed files with 36 additions and 43 deletions

View File

@@ -1,11 +1,13 @@
unary_test :: ()
int_val :: 1251525
uns: U64 = -int_val
float_val :: 124.42
conversion: F64 = -+int_val
float2 := -float_val
unsigned: Int = -+-+-int_val
// int_float: S64 = float_val
// string :: -"Thing"
// boolean :: -true

View File

@@ -151,52 +151,40 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b){
}
function Value
eval_unary(Token *pos, Token_Kind op, Value v){
eval_unary(Token *pos, Token_Kind op, Value a){
if(!is_numeric(a.type)) parsing_error(pos, "Constant application of binary %s on values of type %s is not allowed", token_kind_string(op).str, docname(a.type));
S64 left_int = value_get_int(a);
F64 left_float = value_get_float(a);
switch(op){
case TK_Sub:{
switch(v.type->kind){
// @todo: Bounds checking for conversion from negative to positive
// it's, positive is 2147483647 negative is -2147483648
case TYPE_UNTYPED_INT: v.int_val = -v.int_val;break;
case TYPE_UNTYPED_FLOAT: v.f64_val = -v.f64_val;break;
case TYPE_INT: v.s64_val = -v.int_val;break;
case TYPE_S64: v.s64_val = -v.s64_val;break;
case TYPE_S32: v.s32_val = -v.s32_val;break;
case TYPE_S16: v.s16_val = -v.s16_val;break;
case TYPE_S8: v.s8_val = -v.s8_val; break;
case TYPE_F32: v.f32_val = -v.f32_val;break;
case TYPE_F64: v.f64_val = -v.f64_val;break;
case TYPE_U64:
case TYPE_U32:
case TYPE_U16:
case TYPE_U8:
case TYPE_UINT: parsing_error(pos, "Application of unary [-] on type %s results in overflow", docname(v.type));break;
default: parsing_error(pos, "Constant application of unary [-] on type of %s is unsupported", docname(v.type));break;
}
left_int = -left_int;
left_float = -left_float;
}break;
case TK_Add:{
switch(v.type->kind){
case TYPE_UNTYPED_INT: v.int_val = +v.int_val;break;
case TYPE_UNTYPED_FLOAT: v.f64_val = +v.f64_val;break;
case TYPE_INT: v.s64_val = +v.int_val;break;
case TYPE_S64: v.s64_val = +v.int_val;break;
case TYPE_S32: v.s32_val = +v.int_val;break;
case TYPE_S16: v.s16_val = +v.int_val;break;
case TYPE_S8: v.s8_val = +v.int_val;break;
case TYPE_F32: v.f32_val = +v.f32_val;break;
case TYPE_F64: v.f64_val = +v.f64_val;break;
case TYPE_U64: v.u64_val = +v.u64_val;break;
case TYPE_U32: v.u32_val = +v.u32_val;break;
case TYPE_U16: v.u16_val = +v.u16_val;break;
case TYPE_U8: v.u8_val = +v.u8_val;break;
case TYPE_UINT: v.u64_val = +v.u64_val;break;
default: parsing_error(pos, "Constant application of unary [+] on type of %s is unsupported", docname(v.type));break;
}
left_int = +left_int;
left_float = +left_float;
}break;
default: invalid_codepath;
invalid_default_case;
}
// case TYPE_UINT: parsing_error(pos, "Application of unary [-] on type %s results in overflow", docname(v.type));break;
// default: parsing_error(pos, "Constant application of unary [-] on type of %s is unsupported", docname(v.type));break;
// default: parsing_error(pos, "Constant application of unary [+] on type of %s is unsupported", docname(v.type));break;
Value before_conversion;
if(is_int(a.type)){
before_conversion.type = untyped_int;
before_conversion.int_val = left_int;
}
else{
assert(is_float(a.type));
before_conversion.type = untyped_float;
before_conversion.f64_val = left_float;
}
return v;
Value result = convert_untyped(pos, before_conversion, a.type);
return result;
}
#define rewrite_into_const(ast,T,s) _rewrite_into_const(ast,sizeof(T),s)
@@ -578,8 +566,9 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
Operand op = resolve_expr(node->expr);
if(!is_numeric(op.type)) parsing_error(node->pos, "Unary [-] cant be applied to value of type %s", docname(op.type));
if(op.is_const){
rewrite_into_const(node, Ast_Unary, eval_unary(node->pos, node->op, op.value));
return operand_const_rvalue(op.value);
Value value = eval_unary(node->pos, node->op, op.value);
rewrite_into_const(node, Ast_Unary, value);
return operand_const_rvalue(value);
}
return operand_rvalue(op.value.type);
}break;
@@ -587,8 +576,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
Operand op = resolve_expr(node->expr);
if(!is_numeric(op.type)) parsing_error(node->pos, "Unary [+] cant be applied to value of type %s", docname(op.type));
if(op.is_const){
rewrite_into_const(node, Ast_Unary, eval_unary(node->pos, node->op, op.value));
return operand_const_rvalue(op.value);
Value value = eval_unary(node->pos, node->op, op.value);
rewrite_into_const(node, Ast_Unary, value);
return operand_const_rvalue(value);
}
return operand_rvalue(op.type);
}break;