//! AILang authoring surface — form (A) S-expression projection. //! //! This crate is **one of potentially many** producers / consumers of //! [`ailang_core::ast::Module`] values. The JSON-AST in `ailang-core` //! remains the canonical, hashable, content-addressed source of truth; //! form (A) is the AI-authoring projection optimised for token-efficient //! production by LLMs (see `docs/DESIGN.md` Decision 6). //! //! ## Modules //! //! - [`mod@lex`] — hand-written lexer for the 3-rule lexical core //! (whitespace / parens / comments delimit tokens; first character //! classifies into integer / string / ident). //! - [`mod@parse`] — hand-written recursive-descent parser. One Rust //! function per EBNF production, line-by-line auditable. No //! parser-combinator dependency. //! - [`mod@print`] — deterministic pretty-printer that emits form (A). //! Round-trip with the parser is the contract that gates the //! surface (see the integration test `tests/round_trip.rs`). //! //! ## Round-trip contract //! //! For every well-formed [`ailang_core::ast::Module`] value `m`, //! [`parse()`] applied to [`print()`]`(m)` produces a module whose //! canonical JSON bytes equal those of `m`. This is enforced by the //! integration test against every `examples/*.ail.json` fixture. //! //! ## Architectural pin //! //! No new AST nodes, no schema changes, no new hashable form. //! `ailang-check` and `ailang-codegen` are projection-agnostic — they //! consume `Module` values regardless of which front-end produced them. pub mod lex; pub mod parse; pub mod print; pub use parse::{parse, parse_term, ParseError}; pub use print::{print, term_to_form_a, type_to_form_a};