From dbec90cefd6e2cf6a432b963929698cd90fb41eb Mon Sep 17 00:00:00 2001 From: Brummel Date: Sun, 10 May 2026 15:43:31 +0200 Subject: [PATCH] =?UTF-8?q?floats=20iter=203:=20JOURNAL=20=E2=80=94=20iter?= =?UTF-8?q?ation=20close=20(typecheck=20+=20builtins)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/JOURNAL.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/docs/JOURNAL.md b/docs/JOURNAL.md index bdb8c92..30b18af 100644 --- a/docs/JOURNAL.md +++ b/docs/JOURNAL.md @@ -13249,3 +13249,104 @@ milestone: - DESIGN.md §"Float semantics" subsection (A5 determinism contract) and line-2033 "supported primitive types" list update — iter 5. + +## 2026-05-10 — Iteration Floats.3: typecheck + builtins + +Widened the existing arithmetic and comparison builtins (`+`, `-`, +`*`, `/`, `!=`, `<`, `<=`, `>`, `>=`) from monomorphic +`(Int, Int) -> {Int,Bool}` to polymorphic `forall a. (a, a) -> a` +(resp. `... -> Bool`). Same shape `==` already had since iter 16e. +The `{Int, Float}` filter is enforced at codegen (iter 4); typecheck +accepts any matching pair, mirroring how `==` works today. `%` stays +monomorphic-Int (no fmod yet — `%` semantics for Float require an +explicit decision on sign-of-result and ±0/±Inf edge cases that has +not been made). The widening is type-side only; codegen lowering for +`+` etc. continues to use the monomorphic-Int `synth::builtin_binop` +table (iter 4 converts that to type-dispatched). The lockstep partner +table at `crates/ailang-codegen/src/synth.rs::builtin_ail_type` was +widened in the same commit so no codegen call site sees an +out-of-date polymorphic shape. + +Stale comment caught and corrected during the iter-3.1 quality +review: the `==` install block carried "the other comparison ops +(`<`, `<=`, `>`, `>=`, `!=`) stay Int-only" since iter 16e. +Replaced with the actual current shape — and the same comment now +documents the codegen-dispatch table's Float arm that lands in +iter 4 (`Float → fcmp oeq double`), so the future-state pointer +sits next to the typecheck-side install rather than only in the +spec. + +Five new Float builtins installed: `neg : forall a. (a) -> a` +(polymorphic; parallel to widened `+`), `int_to_float : (Int) -> +Float`, `float_to_int_truncate : (Float) -> Int`, `float_to_str : +(Float) -> Str`, `is_nan : (Float) -> Bool`. The polymorphic `neg` +rationale: spec section A3 calls out that the `(- 0.0 x)` desugar +is wrong for `-0.0` (returns `+0.0` per IEEE rounding), so Float +negation needs its own builtin name. Reusing the `forall a. (a) -> a` +shape lets Int negation share the symbol. + +Three Float bit-pattern constants installed as bare values +(parallel to `__unreachable__` but with concrete `Type::float()` +rather than `forall a. a`): `nan`, `inf`, `neg_inf`. Reference site +is `(var nan)`, not `(app nan)`. Codegen emits `double 0x7FF8...` / +`double 0x7FF0...` / `double 0xFFF0...` at the use site in iter 4. + +One new effect op installed: `io/print_float : (Float) -> Unit !IO`. +Mirrors `io/print_int|bool|str`. Codegen lowering through runtime C +glue `@ail_print_float` lands in iter 4. + +Pattern-matching on Float literals is now typecheck-rejected via the +new `CheckError::FloatPatternNotAllowed` variant per spec line +723-735 recommendation (a). The surface lex / parser still ACCEPT +Float patterns (iter 2 left this open); the typecheck diagnostic +fires at the `Pattern::Lit { lit }` arm in +`crates/ailang-check/src/lib.rs`. The error message points the +LLM-author to the documented alternative — ordering operators and +`is_nan` for Float discrimination. The variant gets a parallel arm +in `CheckError::code()` returning `"float-pattern-not-allowed"` — +mechanical compile-completeness driven by the variant addition. + +`ail builtins` reflects all twelve new entries (4 widened arithmetic +display strings + 5 Float fn builtins + 3 Float constants + 1 +io/print_float effect op) via the refreshed `list()` table. + +Per-task commits: + +- `0981804` floats iter 3.1: widen +/-/*/// and !=//>= to polymorphic forall a +- `6890aa2` floats iter 3.1 fixup: correct stale ==-comparison comment + asymmetric Float test args + drop spec-section reference +- `60a4c68` floats iter 3.2: install neg/int_to_float/float_to_int_truncate/float_to_str/is_nan +- `fd3f74c` floats iter 3.3: install Float constants nan/inf/neg_inf + io/print_float effect op +- `d6da5c2` floats iter 3.4: typecheck rejects Pattern::Lit Float with FloatPatternNotAllowed + +Process note: the Floats milestone keeps centralising the lockstep +between `crates/ailang-check/src/builtins.rs::install` and +`crates/ailang-codegen/src/synth.rs::{builtin_ail_type, +builtin_effect_op_ret}`. After iter 3 these two tables carry four +near-identical `Forall { vars: ["a"], …, body: Fn { params, ret, … } }` +constructions per crate. The two-table convention is established and +deliberate (different crates, no `ailang-core` dependency in `synth.rs` +on `ailang-check`-style helpers), but if the duplication crosses a +fifth pair of entries in iter 4 a small `ailang-core::ast::poly_a_a_to_a` +constructor starts to earn its keep. Queued as a roadmap item, not +fix-now. + +Known debt deliberately deferred to later iterations of this +milestone: + +- Codegen LOWERING for the widened `+`/`-`/`*`/`/` etc. — iter 4 + converts the monomorphic-Int `synth::builtin_binop` table to + type-dispatched; emits `fadd double` / `fcmp olt double` / `fcmp + une double` (for `!=`!) / etc. for the Float arm. +- Codegen LOWERING for `neg` (Int → `sub i64 0, %x`, Float → + `fneg double %x`) — iter 4. The `fneg` instruction (LLVM 8+) is + needed for correct `-0.0` handling. +- Codegen LOWERING for `int_to_float` (`sitofp`), + `float_to_int_truncate` (`@llvm.fptosi.sat.i64.f64`), + `float_to_str` (runtime C glue), `is_nan` (`fcmp uno`) — iter 4. +- Codegen LOWERING for `nan`/`inf`/`neg_inf` constants (LLVM + hex-float literals at the use site) — iter 4. +- Codegen LOWERING for `io/print_float` (parallel to + `io/print_int`, runtime glue `@ail_print_float`) — iter 4. +- Prose round-trip for Float literals — iter 5. +- DESIGN.md §"Float semantics" subsection (A5 determinism contract) + and the line-2033 "supported primitive types" list update — iter 5.