floats iter 2: JOURNAL — iteration close (surface layer)
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user