From 2d2646afa775c2e47147b2405d92c5bf98abd230 Mon Sep 17 00:00:00 2001 From: Brummel Date: Sun, 10 May 2026 16:37:42 +0200 Subject: [PATCH] =?UTF-8?q?floats=20iter=205.2:=20DESIGN.md=20=E2=80=94=20?= =?UTF-8?q?Float=20in=20primitive=20types=20+=20refreshed=20builtins=20lis?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/DESIGN.md | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/docs/DESIGN.md b/docs/DESIGN.md index a5a5a09..02d7aae 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -2031,16 +2031,29 @@ as iterations land; the JOURNAL records when. What **is** supported (and used as the smoke test for the pipeline): -- Int, Bool, Unit, **Str** as primitive types. +- Int, Bool, Unit, **Str**, **Float** as primitive types. - `if`, `let`, function calls, recursion. - Effects on function signatures, with `do op(args)` for direct effect ops (`io/print_int`, `io/print_bool`, `io/print_str`). -- **Builtins.** Arithmetic operators (`+`, `-`, `*`, `/`, `%`) of - type `(Int, Int) -> Int`; ordering operators and `!=` (`!=`, - `<`, `<=`, `>`, `>=`) of type `(Int, Int) -> Bool`; logical - `not : (Bool) -> Bool`; the IO effect ops listed above; - **`==` : forall a. (a, a) -> Bool**; and - **`__unreachable__ : forall a. a`**. +- **Builtins.** Arithmetic operators (`+`, `-`, `*`, `/`) of type + `forall a. (a, a) -> a` (codegen-restricted to `{Int, Float}`); + `%` of type `(Int, Int) -> Int` (Int-only — `fmod` semantics for + Float deferred); ordering operators and `!=` (`!=`, `<`, `<=`, + `>`, `>=`) of type `forall a. (a, a) -> Bool` (codegen-restricted + to `{Int, Float}`); polymorphic `neg : forall a. (a) -> a` + (codegen-restricted to `{Int, Float}`; Float arm uses LLVM + `fneg double` for correct `-0.0` handling); logical + `not : (Bool) -> Bool`; conversions + `int_to_float : (Int) -> Float`, + `float_to_int_truncate : (Float) -> Int` (saturating, NaN → 0), + `float_to_str : (Float) -> Str` (codegen lowering deferred — + symbol installed but errors at codegen pending runtime Str + allocation); inspection `is_nan : (Float) -> Bool` (LLVM + `fcmp uno`); Float bit-pattern constants `nan : Float`, + `inf : Float`, `neg_inf : Float` (resolved as bare values, lower + to direct hex-float `double` SSA constants at use site); the IO + effect ops (`io/print_int|bool|str|float`); **`==` : forall a. + (a, a) -> Bool**; and **`__unreachable__ : forall a. a`**. - **`==` is polymorphic.** The typechecker accepts `==` at any type whose two sides agree (the rigid `a` of the `Forall` is unified by HM at the use site). Codegen @@ -2050,13 +2063,14 @@ What **is** supported (and used as the smoke test for the pipeline): (`@strcmp` is declared in the LLVM IR header alongside `@printf` / `@GC_malloc`); `Unit` → constant `i1 true` (Unit has a single inhabitant; both sides are still - evaluated for any side effects). ADT and `Fn` arg types are - rejected at codegen with a `CodegenError::Internal` - mentioning `==` and the offending type — neither has a - canonical structural-equality scheme yet, and the language - deliberately does not silently elide the check. The other - comparison ops stay Int-only; their codegen path emits - `icmp s{lt,le,gt,ge,ne}` over `i64`. + evaluated for any side effects); `Float` → `fcmp oeq double`. + ADT and `Fn` arg types are rejected at codegen with a + `CodegenError::Internal` mentioning `==` and the offending + type — neither has a canonical structural-equality scheme + yet, and the language deliberately does not silently elide + the check. **`!=` for Float uses `fcmp UNE double` (NOT + `one`)** — `one` is "ordered and not equal" and would return + false for `nan != nan`, violating IEEE-`!=`. - **`__unreachable__`** is a polymorphic bottom value: a use of `__unreachable__` typechecks against any expected type at the use site and codegens to the LLVM `unreachable`