From 49f2124df0f644e183f0570dd047493678eaf9f1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 29 Jul 2018 10:22:17 +0100 Subject: [PATCH] Support larger integer literals to work with the new BigInt system --- core/bits/bits.odin | 32 +++++++++++++-------------- src/big_int.cpp | 53 ++++++++++++++++++++++++++++----------------- src/exact_value.cpp | 7 +++--- 3 files changed, 53 insertions(+), 39 deletions(-) diff --git a/core/bits/bits.odin b/core/bits/bits.odin index a67813c53..38a639efa 100644 --- a/core/bits/bits.odin +++ b/core/bits/bits.odin @@ -2,25 +2,25 @@ package bits import "core:os" -U8_MIN :: u8(0); -U16_MIN :: u16(0); -U32_MIN :: u32(0); -U64_MIN :: u64(0); +U8_MIN :: 0; +U16_MIN :: 0; +U32_MIN :: 0; +U64_MIN :: 0; -U8_MAX :: ~u8(0); -U16_MAX :: ~u16(0); -U32_MAX :: ~u32(0); -U64_MAX :: ~u64(0); +U8_MAX :: 1 << 8 - 1; +U16_MAX :: 1 << 16 - 1; +U32_MAX :: 1 << 32 - 1; +U64_MAX :: 1 << 64 - 1; -I8_MIN :: i8( ~u8(0) >> 1); -I16_MIN :: i16(~u16(0) >> 1); -I32_MIN :: i32(~u32(0) >> 1); -I64_MIN :: i64(~u64(0) >> 1); +I8_MIN :: - 1 << 7; +I16_MIN :: - 1 << 15; +I32_MIN :: - 1 << 31; +I64_MIN :: - 1 << 63; -I8_MAX :: -I8_MIN - 1; -I16_MAX :: -I16_MIN - 1; -I32_MAX :: -I32_MIN - 1; -I64_MAX :: -I64_MIN - 1; +I8_MAX :: 1 << 7 - 1; +I16_MAX :: 1 << 15 - 1; +I32_MAX :: 1 << 31 - 1; +I64_MAX :: 1 << 63 - 1; foreign { @(link_name="llvm.ctpop.i8") count_ones8 :: proc(i: u8) -> u8 --- diff --git a/src/big_int.cpp b/src/big_int.cpp index 9e18fb783..f7f51df6a 100644 --- a/src/big_int.cpp +++ b/src/big_int.cpp @@ -36,6 +36,11 @@ void global_big_int_init(void) { #endif } +// IMPORTANT NOTE LEAK(bill): This entire BigInt library leaks memory like there is no tomorrow +// However, this isn't really a problem as the vast majority of BigInt operations will not use +// more than 1 word. +// I could track how much this does leaks because I use an arena_allocator but I doubt I will require +// it any time soon gb_inline gbAllocator big_int_allocator(void) { return arena_allocator(&global_big_int_arena); } @@ -55,6 +60,13 @@ void big_int_from_i64(BigInt *dst, i64 x); void big_int_init (BigInt *dst, BigInt const *src); void big_int_from_string(BigInt *dst, String const &s); +void big_int_dealloc(BigInt *dst) { + if (dst->len > 1) { + gb_free(big_int_allocator(), dst->d.words); + } + gb_zero_item(dst); +} + BigInt big_int_make(BigInt const *b, bool abs=false); BigInt big_int_make_abs(BigInt const *b); BigInt big_int_make_u64(u64 x); @@ -246,6 +258,10 @@ BigInt big_int_make_i64(i64 x) { void big_int_from_string(BigInt *dst, String const &s) { +#if 0 + u64 u = u64_from_string(s); + big_int_from_u64(dst, u); +#else u64 base = 10; bool has_prefix = false; if (s.len > 2 && s[0] == '0') { @@ -266,28 +282,24 @@ void big_int_from_string(BigInt *dst, String const &s) { len -= 2; } - BigInt result = {}; - BigInt val = {}; BigInt b = {}; big_int_from_u64(&b, base); - val.len = 1; - val.d.word = 100000000ull; + big_int_init(dst, &BIG_INT_ZERO); - // for (isize i = 0; i < len; i++) { - // Rune r = cast(Rune)text[i]; - // if (r == '_') { - // continue; - // } - // u64 v = u64_digit_value(r); - // if (v >= base) { - // break; - // } - // val.d.word = v; - - // big_int_mul_eq(&result, &b); - // big_int_add_eq(&result, &val); - // } - *dst = result; + for (isize i = 0; i < len; i++) { + Rune r = cast(Rune)text[i]; + if (r == '_') { + continue; + } + u64 v = u64_digit_value(r); + if (v >= base) { + break; + } + BigInt val = big_int_make_u64(v); + big_int_mul_eq(dst, &b); + big_int_add_eq(dst, &val); + } +#endif } @@ -1291,6 +1303,8 @@ void big_int_not(BigInt *dst, BigInt const *x, u64 bit_count, bool is_signed) { return; } + // TODO(bill): Is this fast enough? + dst->neg = false; u64 const *xd = big_int_ptr(x); if (bit_count <= 64) { @@ -1361,7 +1375,6 @@ char digit_to_char(u8 digit) { String big_int_to_string(gbAllocator allocator, BigInt const *x, u64 base) { GB_ASSERT(base <= 16); - if ((x->len == 0) && (x->len == 1 && x->d.word == 0)) { u8 *buf = gb_alloc_array(allocator, u8, 1); buf[0] = '0'; diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 4d455c8e2..30d4fd649 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -135,9 +135,10 @@ ExactValue exact_value_procedure(Ast *node) { } -ExactValue exact_value_integer_from_string(String string) { - u64 u = u64_from_string(string); - return exact_value_u64(u); +ExactValue exact_value_integer_from_string(String const &string) { + ExactValue result = {ExactValue_Integer}; + big_int_from_string(&result.value_integer, string); + return result; } f64 float_from_string(String string) {