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
|
unsigned: Int = -+-+-int_val
|
||||||
|
|
||||||
not: Bool = !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
|
// uns: U64 = -int_val
|
||||||
// int_float: S64 = float_val
|
// int_float: S64 = float_val
|
||||||
|
|||||||
@@ -90,9 +90,11 @@ convert_untyped(Token *pos, Value a, Ast_Resolved_Type *new_type){
|
|||||||
function S64
|
function S64
|
||||||
value_get_int(Value value){
|
value_get_int(Value value){
|
||||||
assert(value.int_val <= S64MAX);
|
assert(value.int_val <= S64MAX);
|
||||||
assert(is_float(value.type) || is_int(value.type));
|
assert(is_numeric(value.type));
|
||||||
S64 result = 0;
|
S64 result = 0;
|
||||||
switch(value.type->kind){
|
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_UNTYPED_FLOAT: result = (S64)value.f64_val; break;
|
||||||
case TYPE_F64: result = (S64)value.f64_val; break;
|
case TYPE_F64: result = (S64)value.f64_val; break;
|
||||||
case TYPE_F32: result = (S64)value.f32_val; break;
|
case TYPE_F32: result = (S64)value.f32_val; break;
|
||||||
@@ -114,9 +116,9 @@ value_get_int(Value value){
|
|||||||
|
|
||||||
function F64
|
function F64
|
||||||
value_get_float(Value value){
|
value_get_float(Value value){
|
||||||
assert(is_float(value.type) || is_int(value.type));
|
assert(is_numeric(value.type));
|
||||||
F64 result = value.f64_val;
|
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);
|
result = (F64)value_get_int(value);
|
||||||
else if(value.type == type_f32)
|
else if(value.type == type_f32)
|
||||||
result = value.f32_val;
|
result = value.f32_val;
|
||||||
@@ -291,7 +293,20 @@ eval_unary(Token *pos, Token_Kind op, Value a){
|
|||||||
S64 left_int = value_get_int(a);
|
S64 left_int = value_get_int(a);
|
||||||
F64 left_float = value_get_float(a);
|
F64 left_float = value_get_float(a);
|
||||||
|
|
||||||
|
// @todo: bools go right through
|
||||||
switch(op){
|
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:{
|
case TK_Sub:{
|
||||||
left_int = -left_int;
|
left_int = -left_int;
|
||||||
left_float = -left_float;
|
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 {}; }
|
else{ parsing_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; }
|
||||||
}break;
|
}break;
|
||||||
case TK_Dereference:{return operand_lvalue(type_pointer(value.type));}break;
|
case TK_Dereference:{return operand_lvalue(type_pointer(value.type));}break;
|
||||||
|
case TK_Neg:
|
||||||
|
case TK_Not:
|
||||||
|
case TK_Add:
|
||||||
case TK_Sub:{
|
case TK_Sub:{
|
||||||
Operand op = resolve_expr(node->expr);
|
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){
|
if(op.is_const){
|
||||||
Value value = eval_unary(node->pos, node->op, op.value);
|
Value value = eval_unary(node->pos, node->op, op.value);
|
||||||
rewrite_into_const(node, Ast_Unary, 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);
|
return operand_rvalue(op.value.type);
|
||||||
}break;
|
}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 {};
|
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) ||
|
return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) ||
|
||||||
(type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_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