From 6068a746896407b5ef33bca72a8be6fced14439b Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 11 Jan 2026 19:08:32 -0500 Subject: Implement some missing logic for reals --- src/compile/comparisons.c | 3 +++ src/compile/expressions.c | 5 ++++- src/stdlib/reals.c | 34 ++++++++++++++++++++++------------ src/stdlib/reals.h | 2 ++ 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/compile/comparisons.c b/src/compile/comparisons.c index afb5dc15..99f220e3 100644 --- a/src/compile/comparisons.c +++ b/src/compile/comparisons.c @@ -50,6 +50,8 @@ Text_t compile_comparison(env_t *env, ast_t *ast) { switch (operand_t->tag) { case BigIntType: return Texts(ast->tag == Equals ? EMPTY_TEXT : Text("!"), "Int$equal_value(", lhs, ", ", rhs, ")"); + case RealType: + return Texts(ast->tag == Equals ? EMPTY_TEXT : Text("!"), "Real$equal_values(", lhs, ", ", rhs, ")"); case BoolType: case ByteType: case IntType: @@ -94,6 +96,7 @@ Text_t compile_comparison(env_t *env, ast_t *ast) { const char *op = comparison_operator(ast->tag); switch (operand_t->tag) { case BigIntType: return Texts("(Int$compare_value(", lhs, ", ", rhs, ") ", op, " 0)"); + case RealType: return Texts("(Real$compare_values(", lhs, ", ", rhs, ") ", op, " 0)"); case BoolType: case ByteType: case IntType: diff --git a/src/compile/expressions.c b/src/compile/expressions.c index e2c1d68a..321f5f9f 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -85,6 +85,7 @@ Text_t compile_empty(type_t *t) { case FloatType: { return Match(t, FloatType)->bits == TYPE_NBITS32 ? Text("F32(0.0f)") : Text("F64(0.0)"); } + case RealType: return Text("Real$from_float64(0.0)"); case StructType: return compile_empty_struct(t); case EnumType: return compile_empty_enum(t); default: return EMPTY_TEXT; @@ -157,7 +158,7 @@ Text_t compile(env_t *env, ast_t *ast) { return Texts(b->code, "(", compile_arguments(env, ast, fn->args, new (arg_ast_t, .value = value)), ")"); } - if (t->tag == IntType || t->tag == FloatType) return Texts("-(", compile(env, value), ")"); + if (t->tag == IntType || t->tag == FloatType || t->tag == RealType) return Texts("-(", compile(env, value), ")"); code_err(ast, "I don't know how to get the negative value of type ", type_to_text(t)); } @@ -213,6 +214,8 @@ Text_t compile(env_t *env, ast_t *ast) { if (key_t->tag == BigIntType) comparison = Texts("(Int$compare_value(", lhs_key, ", ", rhs_key, ")", (ast->tag == Min ? "<=" : ">="), "0)"); + else if (key_t->tag == RealType) + comparison = Texts("(Real$compare_values(", lhs_key, ", ", rhs_key, ")", (ast->tag == Min ? "<=" : ">="), "0)"); else if (key_t->tag == IntType || key_t->tag == FloatType || key_t->tag == BoolType || key_t->tag == PointerType || key_t->tag == ByteType) comparison = Texts("((", lhs_key, ")", (ast->tag == Min ? "<=" : ">="), "(", rhs_key, "))"); diff --git a/src/stdlib/reals.c b/src/stdlib/reals.c index 824401c7..e9a6b2ef 100644 --- a/src/stdlib/reals.c +++ b/src/stdlib/reals.c @@ -291,7 +291,7 @@ Real_t Real$times(Real_t a, Real_t b) { return sa->left; } // Also check if arguments are equal values (not just pointers) - if (Real$equal(&sa->left, &sb->left, NULL)) { + if (Real$equal_values(sa->left, sb->left)) { return sa->left; } } @@ -414,13 +414,13 @@ Real_t Real$mix(Real_t amount, Real_t x, Real_t y) { public bool Real$is_between(Real_t x, Real_t low, Real_t high) { - return Real$compare(&low, &x, NULL) <= 0 && Real$compare(&x, &high, NULL) <= 0; + return Real$compare_values(low, x) <= 0 && Real$compare_values(x, high) <= 0; } public Real_t Real$clamped(Real_t x, Real_t low, Real_t high) { - if (Real$compare(&x, &low, NULL) <= 0) return low; - if (Real$compare(&x, &high, NULL) >= 0) return high; + if (Real$compare_values(x, low) <= 0) return low; + if (Real$compare_values(x, high) >= 0) return high; return x; } @@ -814,10 +814,7 @@ PUREFUNC bool Real$is_none(const void *vn, const TypeInfo_t *type) { // Equality check (may be undecidable for some symbolics) public -bool Real$equal(const void *va, const void *vb, const TypeInfo_t *t) { - (void)t; - Real_t a = *(Real_t *)va; - Real_t b = *(Real_t *)vb; +bool Real$equal_values(Real_t a, Real_t b) { if (!Real$is_boxed(a) && !Real$is_boxed(b)) return a.d == b.d; if (Real$is_boxed(a) != Real$is_boxed(b)) return 0; @@ -833,6 +830,14 @@ bool Real$equal(const void *va, const void *vb, const TypeInfo_t *t) { return fabs(da - db) < 1e-15; } +public +bool Real$equal(const void *va, const void *vb, const TypeInfo_t *t) { + (void)t; + Real_t a = *(Real_t *)va; + Real_t b = *(Real_t *)vb; + return Real$equal_values(a, b); +} + public uint64_t Real$hash(const void *vr, const TypeInfo_t *type) { (void)type; @@ -842,10 +847,7 @@ uint64_t Real$hash(const void *vr, const TypeInfo_t *type) { // Comparison: -1 (less), 0 (equal), 1 (greater) public -int32_t Real$compare(const void *va, const void *vb, const TypeInfo_t *t) { - (void)t; - Real_t a = *(Real_t *)va; - Real_t b = *(Real_t *)vb; +int32_t Real$compare_values(Real_t a, Real_t b) { if (!Real$is_boxed(a) && !Real$is_boxed(b)) { return (a.d > b.d) - (a.d < b.d); } @@ -861,6 +863,14 @@ int32_t Real$compare(const void *va, const void *vb, const TypeInfo_t *t) { return (da > db) - (da < db); } +public +int32_t Real$compare(const void *va, const void *vb, const TypeInfo_t *t) { + (void)t; + Real_t a = *(Real_t *)va; + Real_t b = *(Real_t *)vb; + return Real$compare_values(a, b); +} + // Unary negation public Real_t Real$negative(Real_t a) { diff --git a/src/stdlib/reals.h b/src/stdlib/reals.h index 6d30063e..e6d47f5c 100644 --- a/src/stdlib/reals.h +++ b/src/stdlib/reals.h @@ -57,10 +57,12 @@ 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$equal_values(Real_t a, Real_t b); bool Real$get_rational(Real_t x, int64_t *num, int64_t *den); bool Real$is_between(Real_t x, Real_t low, Real_t high); double Real$as_float64(Real_t n, bool truncate); int32_t Real$compare(const void *va, const void *vb, const TypeInfo_t *t); +int32_t Real$compare_values(Real_t a, Real_t b); int Real$test(); -- cgit v1.2.3