diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-08-13 02:51:10 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-08-13 02:51:10 -0400 |
| commit | 2c4f6536a34cb55a5dcaf73908b7ea056da802a9 (patch) | |
| tree | 27de91078ac6c0c286b8d769d4b6a4b79d1d7b28 | |
| parent | f4011eb489d97bbf3170c81a985a09568bfc0dd7 (diff) | |
Fix Int->Num promotions
| -rw-r--r-- | builtins/integers.c | 8 | ||||
| -rw-r--r-- | builtins/integers.h | 1 | ||||
| -rw-r--r-- | compile.c | 5 |
3 files changed, 14 insertions, 0 deletions
diff --git a/builtins/integers.c b/builtins/integers.c index eaaae660..b50d61c2 100644 --- a/builtins/integers.c +++ b/builtins/integers.c @@ -36,6 +36,14 @@ public Int_t Int$from_num(double n) return Int$from_mpz(result); } +public double Int$as_num(Int_t i) +{ + if (__builtin_expect(i.small & 1, 1)) + return (double)(i.small >> 2); + + return mpz_get_d(*i.big); +} + public CORD Int$as_text(const Int_t *i, bool colorize, const TypeInfo *type) { (void)type; if (!i) return "Int"; diff --git a/builtins/integers.h b/builtins/integers.h index 33df2f89..218d8d23 100644 --- a/builtins/integers.h +++ b/builtins/integers.h @@ -79,6 +79,7 @@ Int_t Int$abs(Int_t x); #define Int$as_i64(i) (((i).small & 1) ? (int64_t)((i).small >> 2) : mpz_get_si(*(i).big)) Int_t Int$from_i64(int64_t i); Int_t Int$from_num(double n); +double Int$as_num(Int_t i); #define I(i) ((int64_t)(i) == (int32_t)(i) ? ((Int_t){.small=((uint64_t)(i)<<2)|1}) : Int$from_i64(i)) Int_t Int$plus(Int_t x, Int_t y); @@ -36,6 +36,11 @@ static bool promote(env_t *env, CORD *code, type_t *actual, type_t *needed) return true; } + if (actual->tag == IntType && Match(actual, IntType)->bits == 0 && needed->tag == NumType) { + *code = CORD_all("Int$as_num(", *code, ")"); + return true; + } + if (actual->tag == IntType || actual->tag == NumType) return true; |
