From 827cad01271b252b241d52b471c1c26d4edb4a25 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 3 Jun 2022 18:21:47 +0200 Subject: [PATCH] Negations and Nots working, more bugs introduced, it's getting quite complex :( --- new_types.kl | 6 +++++- typecheck.cpp | 36 ++++++++++++++++++++++-------------- types.h | 21 +++++++++++++++++++++ 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/new_types.kl b/new_types.kl index dc48902..eacf6b4 100644 --- a/new_types.kl +++ b/new_types.kl @@ -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 diff --git a/typecheck.cpp b/typecheck.cpp index c306965..0c19dcb 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -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 {}; } diff --git a/types.h b/types.h index f6b2213..a17ad38 100644 --- a/types.h +++ b/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; +} \ No newline at end of file