Negations and Nots working, more bugs introduced, it's getting quite complex :(

This commit is contained in:
Krzosa Karol
2022-06-03 18:21:47 +02:00
parent 42699034ae
commit 827cad0127
3 changed files with 48 additions and 15 deletions

View File

@@ -8,7 +8,11 @@ unary_test :: ()
unsigned: Int = -+-+-int_val
not: Bool = !int_val
neg: S64 = ~int_val
notf := !float_val
notb := !true
neg64: S64 = ~int_val
neg32: S32 = ~int_val
// big_neg32: U32 = ~41512512 // This doesn't work cause we are negating untyped
// uns: U64 = -int_val
// int_float: S64 = float_val

View File

@@ -90,9 +90,11 @@ convert_untyped(Token *pos, Value a, Ast_Resolved_Type *new_type){
function S64
value_get_int(Value value){
assert(value.int_val <= S64MAX);
assert(is_float(value.type) || is_int(value.type));
assert(is_numeric(value.type));
S64 result = 0;
switch(value.type->kind){
case TYPE_BOOL: result = value.bool_val; break;
case TYPE_UNTYPED_BOOL: result = value.bool_val; break;
case TYPE_UNTYPED_FLOAT: result = (S64)value.f64_val; break;
case TYPE_F64: result = (S64)value.f64_val; break;
case TYPE_F32: result = (S64)value.f32_val; break;
@@ -114,9 +116,9 @@ value_get_int(Value value){
function F64
value_get_float(Value value){
assert(is_float(value.type) || is_int(value.type));
assert(is_numeric(value.type));
F64 result = value.f64_val;
if(is_int(value.type))
if(is_int(value.type) || is_bool(value.type))
result = (F64)value_get_int(value);
else if(value.type == type_f32)
result = value.f32_val;
@@ -291,7 +293,20 @@ eval_unary(Token *pos, Token_Kind op, Value a){
S64 left_int = value_get_int(a);
F64 left_float = value_get_float(a);
// @todo: bools go right through
switch(op){
case TK_Not:{
Value value;
value.type = type_bool;
value.bool_val = is_float(a.type) ? !left_float : !left_int;
return value;
}break;
case TK_Neg:{
left_int = ~left_int;
if(is_float(a.type)) type_error(pos, type_int, a.type, "[~] doesn't work on floating point");
// left_int = int_type_max(a.type) & left_int;
// @todo this doesn't work
}break;
case TK_Sub:{
left_int = -left_int;
left_float = -left_float;
@@ -680,9 +695,12 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
else{ parsing_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; }
}break;
case TK_Dereference:{return operand_lvalue(type_pointer(value.type));}break;
case TK_Neg:
case TK_Not:
case TK_Add:
case TK_Sub:{
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(!is_numeric(op.type)) parsing_error(node->pos, "Unary [%s] cant be applied to value of type %s", token_kind_string(node->op).str, docname(op.type));
if(op.is_const){
Value value = eval_unary(node->pos, node->op, op.value);
rewrite_into_const(node, Ast_Unary, value);
@@ -690,16 +708,6 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
}
return operand_rvalue(op.value.type);
}break;
case TK_Add:{
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){
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;
invalid_default_case; return {};
}

21
types.h
View File

@@ -251,3 +251,24 @@ is_numeric(Ast_Resolved_Type *type){
return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) ||
(type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC);
}
function U64
int_type_max(Ast_Resolved_Type *type){
switch(type->kind){
case TYPE_BOOL: return 1;
case TYPE_UNTYPED_BOOL: return 1;
case TYPE_UNTYPED_INT: return TYPE_INT_MAX;
case TYPE_INT: return TYPE_INT_MAX;
case TYPE_S64: return S64MAX;
case TYPE_S32: return S32MAX;
case TYPE_S16: return S16MAX;
case TYPE_S8: return S8MAX;
case TYPE_UINT: return TYPE_UINT_MAX;
case TYPE_U64: return U64MAX;
case TYPE_U32: return U32MAX;
case TYPE_U16: return U16MAX;
case TYPE_U8: return U8MAX;
invalid_default_case;
}
invalid_return;
}