More work on conversions and constant evaluation
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user