From cc387af8ed86a7b3a0255a7ef7cda4e394aa3d6c Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 3 Jun 2022 14:57:10 +0200 Subject: [PATCH] Add bit ops to binary --- new_types.kl | 10 +++++--- typecheck.cpp | 64 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/new_types.kl b/new_types.kl index 08dda11..db0a83b 100644 --- a/new_types.kl +++ b/new_types.kl @@ -1,12 +1,12 @@ unary_test :: () - int_val :: 125152553512512512512 // @todo + // int_val :: 125152553512512512512 // @todo bit ints + int_val :: 141 float_val :: 124.42 conversion: F64 = -+int_val float2 := -float_val unsigned: Int = -+-+-int_val - // uns: U64 = -int_val // int_float: S64 = float_val // string :: -"Thing" @@ -16,7 +16,11 @@ unary_test :: () binary_test :: () int_val :: 1000 - add :: int_val + 10 + 2.242 + add :: int_val + 10 + 2.242 + 124 + mul :: 4 * 2 + bit_and :: 3 & 1 + bit_or :: 1 | 4 + bit_xor :: 8 ^ 7 diff --git a/typecheck.cpp b/typecheck.cpp index 6fd70d7..1112f34 100644 --- a/typecheck.cpp +++ b/typecheck.cpp @@ -21,7 +21,7 @@ convert_untyped(Token *pos, Value a, Ast_Resolved_Type *new_type){ switch(new_type->kind){ case TYPE_UNTYPED_INT: break; CASE_CONVERT(pos, a.int_val, a.type->kind, a.s64_val, TYPE_INT, TYPE_INT_MIN, TYPE_INT_MAX) - CASE_CONVERT(pos, a.int_val, a.type->kind, a.u64_val, TYPE_UINT, TYPE_UINT_MIN, TYPE_INT_MAX) + CASE_CONVERT(pos, a.int_val, a.type->kind, a.u64_val, TYPE_UINT, TYPE_UINT_MIN, TYPE_INT_MAX) // @todo big int CASE_CONVERT(pos, a.int_val, a.type->kind, a.s8_val , TYPE_S8 , S8MIN, S8MAX) CASE_CONVERT(pos, a.int_val, a.type->kind, a.s16_val, TYPE_S16, S16MIN, S16MAX) CASE_CONVERT(pos, a.int_val, a.type->kind, a.s32_val, TYPE_S32, S32MIN, S32MAX) @@ -29,7 +29,7 @@ convert_untyped(Token *pos, Value a, Ast_Resolved_Type *new_type){ CASE_CONVERT(pos, a.int_val, a.type->kind, a.u8_val , TYPE_U8 , U8MIN, U8MAX) CASE_CONVERT(pos, a.int_val, a.type->kind, a.u16_val, TYPE_U16, U16MIN, U16MAX) CASE_CONVERT(pos, a.int_val, a.type->kind, a.u32_val, TYPE_U32, U32MIN, U32MAX) - CASE_CONVERT(pos, a.int_val, a.type->kind, a.u64_val, TYPE_U64, U64MIN, U64MAX) + CASE_CONVERT(pos, a.int_val, a.type->kind, a.u64_val, TYPE_U64, U64MIN, U64MAX) // @todo big int invalid_default_case; } } @@ -71,11 +71,11 @@ value_get_int(Value value){ case TYPE_S32:result = value.s32_val; break; case TYPE_S16:result = value.s16_val; break; case TYPE_S8:result = value.s8_val; break; - case TYPE_U64:result = value.u64_val; break;// @todo Need big int + case TYPE_U64:assert(value.u64_val <= S64MAX); result = value.u64_val; break; // @todo big int case TYPE_U32:result = value.u32_val; break; case TYPE_U16:result = value.u16_val; break; case TYPE_U8:result = value.u8_val; break; - case TYPE_UINT:result = value.u64_val; break; + case TYPE_UINT:result = value.u64_val; break; // @todo big int default: invalid_codepath; } return result; @@ -97,10 +97,31 @@ function Value eval_binary(Token *pos, Token_Kind op, Value a, Value b){ if(!(is_numeric(a.type) && is_numeric(b.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)); + Ast_Resolved_Type *final_type = 0; + Value before_conversion; + if(is_int(a.type) && is_int(b.type)) { + before_conversion.type = untyped_int; + final_type = untyped_int; + } + else{ + before_conversion.type = untyped_float; + final_type = untyped_float; + } + + if(is_typed(a.type) && is_typed(b.type)){ + if(a.type != b.type) parsing_error(pos, "Type mismatch in binary operation %s - left: %s right: %s", token_kind_string(op).str, docname(a.type), docname(b.type)); + else final_type = a.type; + } + + else if(is_typed(a.type) || is_typed(b.type)){ + not_implemented; + } + S64 left_int = value_get_int(a); S64 right_int = value_get_int(b); F64 left_float = value_get_float(a); F64 right_float = value_get_float(b); + // @WARNING: When introducing big ints & | ^ will be problematic switch(op){ case TK_Add: { @@ -123,29 +144,26 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b){ left_int = left_int % right_int; left_float = fmod(left_float, right_float); } break; + case TK_BitAnd: { + left_int = left_int & right_int; + if(before_conversion.type == untyped_float) parsing_error(pos, "%s cant be performed on [Untyped_Float]", token_kind_string(op).str); + } break; + case TK_BitOr: { + left_int = left_int | right_int; + if(before_conversion.type == untyped_float) parsing_error(pos, "%s cant be performed on [Untyped_Float]", token_kind_string(op).str); + } break; + case TK_BitXor: { + left_int = left_int ^ right_int; + if(before_conversion.type == untyped_float) parsing_error(pos, "%s cant be performed on [Untyped_Float]", token_kind_string(op).str); + } break; invalid_default_case; } - Ast_Resolved_Type *final_type = 0; - Value before_conversion; - if(is_int(a.type) && is_int(b.type)) { - before_conversion.type = untyped_int; - before_conversion.int_val = left_int; - final_type = untyped_int; - } - else{ - before_conversion.type = untyped_float; + if(before_conversion.type == untyped_float){ before_conversion.f64_val = left_float; - final_type = untyped_float; - } - - if(is_typed(a.type) && is_typed(b.type)){ - if(a.type != b.type) parsing_error(pos, "Type mismatch in binary operation %s - left: %s right: %s", token_kind_string(op).str, docname(a.type), docname(b.type)); - else final_type = a.type; - } - - else if(is_typed(a.type) || is_typed(b.type)){ - not_implemented; + } else { + assert(before_conversion.type == untyped_int); + before_conversion.int_val = left_int; } Value result = convert_untyped(pos, before_conversion, final_type);