diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2026-01-11 15:27:56 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2026-01-11 15:27:56 -0500 |
| commit | 3dc89f2fd1705f03b8838e2afce80f691b709d63 (patch) | |
| tree | 17fafdf1a5723c079c4c42cc3459590abdedb4c7 | |
| parent | bb4c931fc660eca5cc28f637873386bfb3a6b56b (diff) | |
Misc fixes
| -rw-r--r-- | src/compile/assertions.c | 2 | ||||
| -rw-r--r-- | src/compile/optionals.c | 2 | ||||
| -rw-r--r-- | src/environment.c | 4 | ||||
| -rw-r--r-- | src/stdlib/reals.c | 3 | ||||
| -rw-r--r-- | src/stdlib/reals.h | 3 | ||||
| -rw-r--r-- | test/reals.tm | 34 |
6 files changed, 27 insertions, 21 deletions
diff --git a/src/compile/assertions.c b/src/compile/assertions.c index 18531fd9..7cb202e8 100644 --- a/src/compile/assertions.c +++ b/src/compile/assertions.c @@ -13,7 +13,7 @@ public Text_t compile_assertion(env_t *env, ast_t *ast) { ast_t *expr = Match(ast, Assert)->expr; ast_t *message = Match(ast, Assert)->message; - const char *failure = NULL; + const char *failure = "vs"; switch (expr->tag) { case And: { DeclareMatch(and_, expr, And); diff --git a/src/compile/optionals.c b/src/compile/optionals.c index f54d8931..bf8bf4aa 100644 --- a/src/compile/optionals.c +++ b/src/compile/optionals.c @@ -71,6 +71,7 @@ Text_t compile_none(type_t *t) { case PointerType: return Texts("((", compile_type(t), ")NULL)"); case ClosureType: return Text("NONE_CLOSURE"); case FloatType: return Text("nan(\"none\")"); + case RealType: return Text("NONE_REAL"); case StructType: return Texts("((", compile_type(Type(OptionalType, .type = t)), "){.has_value=false})"); case EnumType: { env_t *enum_env = Match(t, EnumType)->env; @@ -91,6 +92,7 @@ Text_t check_none(type_t *t, Text_t value) { else if (t->tag == ClosureType) return Texts("((", value, ").fn == NULL)"); else if (t->tag == FloatType) return Texts(Match(t, FloatType)->bits == TYPE_NBITS64 ? "Float64$isnan(" : "Float32$isnan(", value, ")"); + else if (t->tag == RealType) return Texts("Real$is_none(", value, ")"); else if (t->tag == ListType) return Texts("((", value, ").data == NULL)"); else if (t->tag == TableType) return Texts("((", value, ").entries.data == NULL)"); else if (t->tag == BoolType) return Texts("((", value, ") == NONE_BOOL)"); diff --git a/src/environment.c b/src/environment.c index 1dfeb6bc..7949893f 100644 --- a/src/environment.c +++ b/src/environment.c @@ -308,8 +308,8 @@ env_t *global_env(bool source_mapping) { {"log10", "Real$log10", "func(x:Real -> Real)"}, // {"minus", "Real$minus", "func(x,y:Real -> Real)"}, // {"mix", "Real$mix", "func(amount,x,y:Real -> Real)"}, // - {"mod", "Real$mod", "func(n,modulus:Real -> Real)"}, // - {"mod1", "Real$mod1", "func(n,modulus:Real -> Real)"}, // + {"modulo", "Real$mod", "func(n,modulus:Real -> Real)"}, // + {"modulo1", "Real$mod1", "func(n,modulus:Real -> Real)"}, // {"negative", "Real$negative", "func(x:Real -> Real)"}, // {"parse", "Real$parse", "func(text:Text, remainder:&Text?=none -> Real?)"}, // {"plus", "Real$plus", "func(x,y:Real -> Real)"}, // diff --git a/src/stdlib/reals.c b/src/stdlib/reals.c index 87d1e64a..616fd38d 100644 --- a/src/stdlib/reals.c +++ b/src/stdlib/reals.c @@ -700,7 +700,8 @@ OptionalReal_t Real$parse(Text_t text, Text_t *remainder) { return box_ptr(r, REAL_TAG_RATIONAL); } -static bool Real$is_none(const void *vn, const TypeInfo_t *type) { +public +PUREFUNC bool Real$is_none(const void *vn, const TypeInfo_t *type) { (void)type; Real_t n = *(Real_t *)vn; return is_boxed(n) && get_tag(n) == REAL_TAG_NONE; diff --git a/src/stdlib/reals.h b/src/stdlib/reals.h index 10c071f9..d03e4e5f 100644 --- a/src/stdlib/reals.h +++ b/src/stdlib/reals.h @@ -3,6 +3,7 @@ #include "datatypes.h" #include "types.h" +#include "util.h" // NaN-boxing scheme: use quiet NaN space for pointers // IEEE 754: NaN = exponent all 1s, mantissa non-zero @@ -21,6 +22,7 @@ Int_t Real$as_int(Real_t x, bool truncate); OptionalReal_t Real$parse(Text_t text, Text_t *remainder); +PUREFUNC bool Real$is_none(const void *vn, const TypeInfo_t *type); Real_t Real$abs(Real_t x); Real_t Real$acos(Real_t x); Real_t Real$asin(Real_t x); @@ -49,6 +51,7 @@ Real_t Real$sin(Real_t x); Real_t Real$sqrt(Real_t x); Real_t Real$tan(Real_t x); Real_t Real$times(Real_t x, Real_t y); +Text_t Real$as_text(const void *n, bool colorize, const TypeInfo_t *type); Text_t Real$value_as_text(Real_t x); bool Real$equal(const void *va, const void *vb, const TypeInfo_t *t); bool Real$is_between(Real_t x, Real_t low, Real_t high); diff --git a/test/reals.tm b/test/reals.tm index fc28b474..afb2f5f0 100644 --- a/test/reals.tm +++ b/test/reals.tm @@ -82,18 +82,18 @@ func main() assert (0.5).mix(10., 20.) == 15. # Is between - assert (5.).is_between(1, 10) - assert (1.).is_between(1, 10) - assert (10.).is_between(1, 10) - assert (0.).is_between(1, 10) == no - assert (11.).is_between(1, 10) == no + assert (5.).is_between(1., 10.) + assert (1.).is_between(1., 10.) + assert (10.).is_between(1., 10.) + assert (0.).is_between(1., 10.) == no + assert (11.).is_between(1., 10.) == no # Clamped - assert (5.).clamped(1, 10) == 5 - assert (0.).clamped(1, 10) == 1 - assert (15.).clamped(1, 10) == 10 - assert (1.).clamped(1, 10) == 1 - assert (10.).clamped(1, 10) == 10 + assert (5.).clamped(1., 10.) == 5. + assert (0.).clamped(1., 10.) == 1. + assert (15.).clamped(1., 10.) == 10. + assert (1.).clamped(1., 10.) == 1. + assert (10.).clamped(1., 10.) == 10. # Comparison assert 3. > 2. @@ -107,14 +107,14 @@ func main() assert -(1. / 3.) == -1. / 3. # Power - assert (2.).power(3) == 8 - assert (2.).power(0) == 1 + assert (2.).power(3.) == 8. + assert (2.).power(0.) == 1. # Parsing - assert Real.parse("123") == 123 + assert Real.parse("123") == 123. assert Real.parse("1.5") == 1.5 assert Real.parse("0.3333333333333333") == 0.3333333333333333 - assert Real.parse("-5") == -5 + assert Real.parse("-5") == -5. assert Real.parse("-2.5") == -2.5 # None handling @@ -124,12 +124,12 @@ func main() assert Real.parse("") == none # Large integers - big := (9999999999999999.) - assert big + 1 == (10000000000000000.) + big := (99999999999999999999999999999999.) + assert big + 1. == (100000000000000000000000000000000.) # Mixed operations preserve exactness result := 1. / 3. + 2. / 3. - assert result == 1 + assert result == 1. # Symbolic expressions maintain structure expr := sqrt2 + 1. |
