floats iter 2: JOURNAL — iteration close (surface layer)

This commit is contained in:
2026-05-10 15:14:02 +02:00
parent c619697a76
commit 4ccf1f25c1
+77
View File
@@ -13172,3 +13172,80 @@ milestone:
- DESIGN.md §"Float semantics" subsection (A5 determinism
contract) and line-2033 "supported primitive types" list
update — iter 5.
## 2026-05-10 — Iteration Floats.2: surface layer
Lexer recognises Float literals in form
`<digits>.<digits>(e[+-]?<digits>)?` and `<digits>e[+-]?<digits>`
per spec A2; bare leading/trailing dots, missing fraction-after-
dot, and missing/sign-only exponents reject with
`LexError::InvalidFloat { literal, start }`. Hex floats are
naturally rejected by `f64::from_str` and by the digit-lead caller
arm. The new private `looks_like_float` helper enforces the spec
grammar before delegating the bit-pattern conversion to
`f64::from_str` + `f64::to_bits`. Leading-dot tokens like `.5`
fall through the digit-lead rule (first byte not a digit) and
classify as `Tok::Ident(".5")` — the lexer does not reject them;
downstream stages produce the diagnostic. The 11 new lex tests
pin both the positive grammar (`1.5`, `1.5e3`, `1e10`, `-1.5`,
signed zero, uppercase `E`) and the rejection set (trailing dot,
missing fraction-before-exp, empty exp, sign-only exp, double
dot, leading dot routes to ident).
The new `Tok::Float(u64)` is wired through the parser at two
sites — `parse_term` (atom literal position) and `parse_pat_lit`
(inside `(pat-lit ...)`). The parser ACCEPTS Float in pattern
position even though pattern-matching on Float is semantically
dubious (per spec line 723-735). Typecheck-level rejection is
iter 3's job; the parser-side diagnostic stays a generic "literal
form" error widened to mention float. `tok_label` exhaustiveness
forced the wiring on the same iteration the variant landed —
that's the same enforcement-via-exhaustive-match pattern iter 1
exercised on the AST `Literal` enum.
The two `unimplemented!("Floats milestone iter 2: surface print")`
arms left by iter 1 in `print.rs` are gone. The new
`write_float_lit` helper formats via `f64::to_string` (Grisu3
shortest round-trippable) and appends `.0` if the rendered form
contains neither `.` nor `e`/`E` — preserving the
`lex(print(L)) == L` round-trip property pinned by a new
regression test over six representative bit patterns (`1.5`,
`0.0`, `-0.0`, `10.0`, `-0.375`, `1e10`). Non-finite bits panic;
surface lex cannot produce them, so the only path that would feed
NaN/Inf to the printer is a Form-A direct construction — and the
printer is not a Form-A escape hatch.
Process note from this iteration: the original plan's Step 11
caveat ("`cargo test -p ailang-surface --lib` bypasses parse.rs")
was technically incorrect — `--lib` does compile the whole
library. The implementer caught this and routed Task 1's GREEN
verification through Task 2 instead, where `tok_label`
exhaustiveness gets restored and the lex tests can finally run.
The intent (commit Task 1 with parse.rs broken at exactly one
site, fix in Task 2) was unambiguous and was followed; the
imprecise note in the plan template is queued as a one-line
correction the next plan should not repeat.
Per-task commits:
- `d0c9133` floats iter 2.1: Tok::Float + LexError::InvalidFloat + spec-A2 grammar validator
- `f960e39` floats iter 2.1 fixup: drop task-tags + refresh stale prose + uppercase-E + leading-dot tests
- `f62bff0` floats iter 2.2: parser accepts Tok::Float in term and pat-lit positions
- `c619697` floats iter 2.3: surface print emits shortest round-trippable decimal with .0 fallback
Known debt deliberately deferred to later iterations of this
milestone:
- Typecheck rejection of `Pattern::Lit { lit: Literal::Float
{ .. } }` per spec line 723-735 recommendation (a). The parser
accepts Float patterns; iter 3 surfaces the type error.
- Typecheck widening of `+`/`-`/`*`/`/`/`<`/`<=`/`>`/`>=` from
monomorphic Int to polymorphic-`{Int, Float}` — iter 3.
- Codegen Float lowering paths
(`fadd`/`fsub`/`fmul`/`fdiv`, `fcmp o*`/`une`, `sitofp`,
`@llvm.fptosi.sat.i64.f64`, `fcmp uno`, hex-float constants) —
iter 4.
- Prose round-trip for Float literals — iter 5.
- DESIGN.md §"Float semantics" subsection (A5 determinism
contract) and line-2033 "supported primitive types" list
update — iter 5.