floats iter 5.2: DESIGN.md — Float in primitive types + refreshed builtins list

This commit is contained in:
2026-05-10 16:37:42 +02:00
parent ea8988b529
commit 2d2646afa7
+28 -14
View File
@@ -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`