Negations and Nots working, more bugs introduced, it's getting quite complex :(
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
21
types.h
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user