Iter 14c: ailang-surface ships — form (A) parser + pretty-printer
Strictly additive new crate per Decision 6 architectural pin. JSON-AST stays the source of truth; ailang-surface is one producer/consumer of ailang_core::ast::Module values. ailang-check and ailang-codegen unchanged. Crate contents: - src/lex.rs (~264 LOC): 3-rule lexical core. Whitespace and parens delimit tokens; semicolon to EOL is comment; first-character classifier (digit -> int, " -> string, else -> ident). - src/parse.rs (~1041 LOC): hand-written recursive descent. One Rust fn per EBNF production. No parser-combinator dep. - src/print.rs (~371 LOC): deterministic pretty-printer. Round-trip contract with parse() is the surface's correctness gate. - tests/round_trip.rs (~128 LOC): integration test runs every examples/*.ail.json fixture through print -> parse -> canonical JSON, asserts canonical-byte equality with the original. Two AST-driven form widenings beyond the 14b sketch (both folded into DESIGN.md Decision 6): - lam-term carries (typed name type) params, ret type, and optional effects (Term::Lam has parallel param_tys/ret_ty/ effects fields). - import-clause admits (import name (as alias)?) (Import.alias is Option<String>). Production count ~28, under 30-rule budget. Constraint 1 (formalisable for foreign LLM) intact. Verification: - cargo build --workspace green. - cargo test --workspace: 76 tests green (was 64; +9 surface unit, +2 round-trip integration). All 17 fixtures round-trip byte-identical at canonical level. 3 hand-written .ailx exhibits parse to canonical JSON identical to their .ail.json siblings. - cargo doc --no-deps zero warnings (DESIGN.md item 6 invariant). Manual smoke test (ail parse → ail run): hello, box, list_map_poly all produce expected output through the form-(A) authoring lane end-to-end. CLI: ail parse <file.ailx> [-o <file.ail.json>]. .ail.json remains a first-class input to every existing subcommand. Plan 14d: stdlib (std_list.ailx with length/filter/fold/concat/ reverse/head/tail), authored in form (A) from day one. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,20 +1,21 @@
|
||||
; Iter 14b design exhibit — Decision 6 form (A).
|
||||
; Companion to box.ailx. Same hash-equivalence gate in Iter 14c.
|
||||
; Iter 14b design exhibit, finalised in Iter 14c.
|
||||
; Hash-equivalent to list_map_poly.ail.json (round-trip-tested).
|
||||
|
||||
(module list_map_poly
|
||||
|
||||
(data List (vars a)
|
||||
(doc "Singly-linked polymorphic list.")
|
||||
(doc "Polymorphic singly-linked list.")
|
||||
(ctor Nil)
|
||||
(ctor Cons a (con List a)))
|
||||
|
||||
(fn inc
|
||||
(doc "Add 1 to an Int.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(params x)
|
||||
(body (app + x 1)))
|
||||
|
||||
(fn map
|
||||
(doc "Apply f to every element. Recursive on the tail.")
|
||||
(doc "Polymorphic map: apply f to every element, recursing on the tail.")
|
||||
(type
|
||||
(forall (vars a b)
|
||||
(fn-type
|
||||
@@ -32,6 +33,7 @@
|
||||
(app map f t))))))
|
||||
|
||||
(fn print_list
|
||||
(doc "Print each Int on its own line.")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con List (con Int)))
|
||||
@@ -48,6 +50,7 @@
|
||||
(app print_list t))))))
|
||||
|
||||
(fn main
|
||||
(doc "Map inc over [1,2,3] via polymorphic List, then print: 2,3,4.")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
|
||||
Reference in New Issue
Block a user