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:
M | fmt/print.ha | | | 29 | +++++++++++++++++++++++------ |
M | math/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);
};