hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 8e76e28b20e60367eff21f77ce20ed574ec5c1f2
parent 0074767cf612e6f965a68a95cd9e53a0e0abda50
Author: Sebastian <sebastian@sebsite.pw>
Date:   Sun,  1 Dec 2024 20:25:30 -0500

math: remove generic int functions

Similar to the generic float functions, all supported types can promote
to i64, so the only time the generic functions are useful is when have a
already have a types::integer value which you don't know the type of.
This was the case in fmt::, which now has to match on the value itself.
fmt:: is an exception to the norm though; I doubt most users will have
any issues migrating their code to use the appropriately typed functions
instead.

This is a breaking change.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mfmt/print.ha | 29+++++++++++++++++++++++------
Mmath/ints.ha | 118++++++++++++++++++++-----------------------------------------------------------
2 files changed, 53 insertions(+), 94 deletions(-)

diff --git a/fmt/print.ha b/fmt/print.ha @@ -110,12 +110,29 @@ case let f: types::floating => return strconv::fftosf(out, f, mod.ffmt, if (mod.prec != 0) mod.prec: uint else void, mod.fflags)?; case let i: types::integer => - let neg = match (i) { - case types::unsigned => - yield false; - case let s: types::signed => - i = math::absi(s); - yield math::signi(s) < 0; + let neg = false; + let i: u64 = match (i) { + case let i: i8 => + neg = math::signi8(i) < 0; + yield math::absi8(i); + case let i: i16 => + neg = math::signi16(i) < 0; + yield math::absi16(i); + case let i: i32 => + neg = math::signi32(i) < 0; + yield math::absi32(i); + case let i: i64 => + neg = math::signi64(i) < 0; + yield math::absi64(i); + case let i: int => + neg = math::signi(i) < 0; + yield math::absi(i); + case let i: u8 => yield i; + case let i: u16 => yield i; + case let i: u32 => yield i; + case let i: u64 => yield i; + case let i: uint => yield i; + case let i: size => yield i; }; let sign = if (neg) "-" else { yield switch (mod.neg) { diff --git a/math/ints.ha b/math/ints.ha @@ -4,89 +4,36 @@ use types; // Returns the absolute value of signed integer n. -export fn absi8(n: i8) u8 = { - if (n < 0i8) { - return -n: u8; - } else { - return n: u8; - }; -}; +export fn absi8(n: i8) u8 = if (n < 0) -n: u8 else n: u8; // Returns the absolute value of signed integer n. -export fn absi16(n: i16) u16 = { - if (n < 0i16) { - return -n: u16; - } else { - return n: u16; - }; -}; +export fn absi16(n: i16) u16 = if (n < 0) -n: u16 else n: u16; // Returns the absolute value of signed integer n. -export fn absi32(n: i32) u32 = { - if (n < 0i32) { - return -n: u32; - } else { - return n: u32; - }; -}; +export fn absi32(n: i32) u32 = if (n < 0) -n: u32 else n: u32; // Returns the absolute value of signed integer n. -export fn absi64(n: i64) u64 = { - if (n < 0i64) { - return -n: u64; - } else { - return n: u64; - }; -}; +export fn absi64(n: i64) u64 = if (n < 0) -n: u64 else n: u64; // Returns the absolute value of signed integer n. -export fn absi(n: types::signed) u64 = { - match (n) { - case let n: i8 => - return absi8(n): u64; - case let n: i16 => - return absi16(n): u64; - case let n: i32 => - return absi32(n): u64; - case let n: i64 => - return absi64(n): u64; - case let n: int => - return absi64(n): u64; - }; -}; +export fn absi(n: int) uint = if (n < 0) -n: uint else n: uint; @test fn absi() void = { - // Workaround casting issue where (-types::I8_MIN: u8) has a value not - // equal to (-types::I8_MIN: u16) - let m8 = (-types::I8_MIN: u8); - let m16 = (-types::I16_MIN: u16); - let m32 = (-types::I32_MIN: u32); - let m64 = (-types::I64_MIN: u64); - - assert(absi8(2i8) == 2u8); - assert(absi8(-2i8) == 2u8); - assert(absi8(types::I8_MIN) == m8); - assert(absi16(2i16) == 2u16); - assert(absi16(-2i16) == 2u16); - assert(absi16(types::I16_MIN) == m16); - assert(absi32(2i32) == 2u32); - assert(absi32(-2i32) == 2u32); - assert(absi32(types::I32_MIN) == m32); - assert(absi64(2i64) == 2u64); - assert(absi64(-2i64) == 2u64); - assert(absi64(types::I64_MIN) == m64); - assert(absi(2i8) == 2u64); - assert(absi(-2i8) == 2u64); - assert(absi(types::I8_MIN) == (m8: u64)); - assert(absi(2i16) == 2u64); - assert(absi(-2i16) == 2u64); - assert(absi(types::I16_MIN) == (m16: u64)); - assert(absi(2i32) == 2u64); - assert(absi(-2i32) == 2u64); - assert(absi(types::I32_MIN) == (m32: u64)); - assert(absi(2i64) == 2u64); - assert(absi(-2i64) == 2u64); - assert(absi(types::I64_MIN) == (m64: u64)); + assert(absi8(2) == 2); + assert(absi8(-2) == 2); + assert(absi8(types::I8_MIN) == types::I8_MIN: u8); + assert(absi16(2) == 2); + assert(absi16(-2) == 2); + assert(absi16(types::I16_MIN) == types::I16_MIN: u16); + assert(absi32(2) == 2); + assert(absi32(-2) == 2); + assert(absi32(types::I32_MIN) == types::I32_MIN: u32); + assert(absi64(2) == 2); + assert(absi64(-2) == 2); + assert(absi64(types::I64_MIN) == types::I64_MIN: u64); + assert(absi(2) == 2); + assert(absi(-2) == 2); + assert(absi(types::INT_MIN) == types::INT_MIN: uint); }; // Return 1 if n is positive, -1 if it's negative and 0 if it's 0. @@ -134,19 +81,14 @@ export fn signi64(n: i64) i64 = { }; // Return 1 if n is positive, -1 if it's negative and 0 if it's 0. -export fn signi(n: types::signed) i64 = { - match (n) { - case let n: i8 => - return signi8(n): i64; - case let n: i16 => - return signi16(n): i64; - case let n: i32 => - return signi32(n): i64; - case let n: i64 => - return signi64(n): i64; - case let n: int => - return signi64(n): i64; +export fn signi(n: int) i64 = { + if (n > 0) { + return 1; + }; + if (n < 0) { + return -1; }; + return 0; }; @test fn signi() void = { @@ -162,7 +104,7 @@ export fn signi(n: types::signed) i64 = { assert(signi64(2i64) == 1i64); assert(signi64(-2i64) == -1i64); assert(signi64(0i64) == 0i64); - assert(signi(2i16) == 1i64); - assert(signi(-2i16) == -1i64); - assert(signi(0i16) == 0i64); + assert(signi(2) == 1); + assert(signi(-2) == -1); + assert(signi(0) == 0); };