Commit Graph

7 Commits

Author SHA1 Message Date
Brummel 12e9a9c0cc Iter 14h: cross-module parameterised-ADT import (15a unblocked)
The 15a tester surfaced a real compiler limitation: cross-module
type and ctor references were not implemented. Iter 5b only
carried fns + consts via module_globals; types/ctors stayed
module-local with an explicit DESIGN comment. This iter completes
the cross-module mechanism using the Iter-5b convention:
qualified-only access via module.Name.

Implementation:
- ailang-check: Env.module_types populated by build_module_types.
  Qualified resolution in Type::Con, Term::Ctor, with cross-module
  fallback for pat-ctor (local wins, multi-import collision -> new
  ambiguous-ctor diagnostic). Four new unit tests.
- ailang-codegen: workspace-level module_ctor_index replaces
  per-Emitter table. lookup_ctor_by_type / lookup_ctor_in_pattern
  thread qualified type names through box-tag and field-type
  resolution.
- examples/std_maybe_demo.{ailx,ail.json}: type-name slots now
  qualified (std_maybe.Maybe).
- New e2e test cross_module_maybe_demo asserts the demo prints
  ["7","99","true","true","42"].

Net diff ~550 LOC. Tests 80 -> 85. All Iter 14a regressions
(parameterised_box_round_trip, parameterised_maybe_match,
list_map_poly_inc_then_prints, polymorphic_id_at_int_and_bool)
verified green — the 14h derive_substitution change (default
unpinned forall vars to Unit for monomorphiser) sits on a
different layer than 14a's $u-wildcard fix and they coexist.

Hash invariance: all five std_maybe def hashes unchanged. All
80-test-suite fixtures retain bit-identical hashes — cross-module
support is purely additive at the language level.

Process note: the std_maybe.ailx file landed in the 14g commit
via a sloppy git-add-A; should have spotted it before staging.
Not a correctness issue but a hygiene one.

Implementer flagged Unit-default monomorphisation as wasteful-
but-correct; rethink if stdlib grows toward overload-resolution-
style cases needing distinct unconstrained instantiations.

std_maybe stdlib effectively ships: module + four combinators +
e2e-tested consumer demo. Plan 15b: std_list importing std_maybe,
exercising Maybe-returning head/tail and tail-call-marked
fold_left.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:08:56 +02:00
Brummel d64031c234 Iter 14e: explicit, verified tail calls
Decision 8 ships. Term::App and Term::Do gain tail: bool with
serde-default false and skip-when-false serialisation. New
typecheck pass verify_tail_positions enforces tail-position rules
(Scheme-style propagation through match arms, seq.rhs, let body,
lam body). Codegen emits musttail call for marked App calls.

Hash invariance verified: only the two migrated print_list defs
(list_map_poly.print_list, sort.print_list) changed hashes; all
other defs across all 18 fixtures kept bit-identical hashes —
confirms the skip-when-false serialisation rule works.

Tests 76 -> 79: tail_call_in_non_tail_position_is_rejected,
tail_call_in_tail_position_is_accepted, plus an IR-grep e2e test
asserting that print_list's recursive call site emits musttail
in the lowered IR. Existing 25 e2e tests unchanged in behaviour
(map -> [2,3,4], sort -> sorted list).

IR evidence at the recursive site:
  %v7 = musttail call i8 @ail_list_map_poly_print_list(ptr %v6)
  ret i8 %v7

Two deviations called out in the implementer report and JOURNAL:
1. tail-do uses tail call, not musttail. Cross-type return
   (runtime helpers return i32, AILang Unit is i8) would have
   LLVM reject musttail. Path is implemented but not exercised
   by any current fixture; proper fix is runtime-helper signature
   change, punted.
2. block_terminated flag in codegen so tail-call emit
   (musttail call + ret) doesn't get a duplicate trailing ret
   from surrounding code (match-arm phi, fn-body, lambda thunk).
   Internal plumbing; required for IR well-formedness.

Form (A) productions now at ~30, exactly the constraint-1
budget. Future surface additions need to retire something or
explicit-budget-rebalance in DESIGN.md.

GC notes from implementer survey land in JOURNAL:
- Allocations cluster in lower_ctor; every term-ctor does
  malloc(8+8n).
- Tail recursion does not reduce alloc pressure, only stack.
  For map-style ctor-blocked recursions, allocation IS the
  bottleneck.
- Per-fn arena is sound only when fn return type contains no
  boxed ADT. Most current fixtures violate this.

Plan 14f: Boehm conservative GC (GC_malloc, -lgc) as a first
cut. Single-iter integration, no AST/schema change. Stress
test: build a 100k Cons list, observe RSS doesn't blow up.

After 14f the language is feature-complete enough for stdlib
work (15a).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:16:28 +02:00
Brummel d8727d5bdb Iter 13e: rustdoc polish for ailang-check
Second docwriter mission. Pure rustdoc additions (no API or
behaviour change) across the typechecker crate:

- builtins.rs: module root expanded; EffectOpSig (struct + 3
  fields) and install() got /// strings.
- diagnostic.rs: Severity (+ both variants), Diagnostic (+
  severity/code/message fields) and the error/with_def/with_ctx
  helpers got /// strings; super:: link rewritten to crate::.
- lib.rs: CheckError + every variant, to_diagnostic, CheckedModule
  (+ symbols), check, Env (+ globals/effect_ops/types/
  module_globals/current_module), CtorRef (+ type_name) got ///
  strings; crate-root prose upgraded with intra-doc link to
  check_module.

Verification: cargo doc --no-deps zero warnings; cargo build
--workspace green; cargo test --workspace 64/64 + 3 ignored
doctests green. Diff is 188 LOC, all in /// or //! lines (verified
by filtering).

Findings (not fixed; orchestrator-deferred):
- Env is pub but only privately constructable.
- CheckError::CtorArity and ::ArityMismatch share the public
  diagnostic code "arity-mismatch" by design.
- Diagnostic / Severity reachable via two paths because the
  diagnostic module is pub.

JOURNAL.md updated with the Iter 13e entry. 13f (ailang-codegen
+ ail) and 14a (List a rewrite) remain queued.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:13:03 +02:00
Brummel c90926dbba Iter 13d: rustdoc polish for ailang-core + new docwriter agent
Adds ailang-docwriter to /agents/ — a recurring role for keeping
crate-, module-, and pub-item-level rustdoc accurate. First mission:
ailang-core. Crate root, every module root, every pub item documented;
intra-doc links throughout; Iter-13a additions (TypeDef.vars, Type::Con.args)
get an explicit backwards-compat note. Two stale broken-link warnings in
ailang-check fixed in passing. cargo doc --no-deps now warning-free across
the workspace; promoted to verification invariant 6 in DESIGN.md.
2026-05-07 15:02:35 +02:00
Brummel 7577ab8a90 Translate project content to English
Make English the project-wide language: all comments, string literals,
CLI help text, design docs, journal, agent prompts, and README. Only
CLAUDE.md (the user's own instruction file) stays German, and the live
conversation between user and Claude continues in German.

Adds a new "Project language: English" section to docs/DESIGN.md as
the durable convention. No logic changes — translation only. Four
internal error strings in the typechecker were retranslated; no
test asserts on their wording.

Verified: cargo test --workspace passes (44/44).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 12:17:48 +02:00
Brummel b2878fe655 Iter 5b: Cross-Module-Typcheck mit qualifizierten Verweisen
Neue API check_workspace(&Workspace) -> Vec<Diagnostic>; check_module
hebt das Modul intern in einen Trivial-Workspace. Term::Var mit genau
einem Punkt im Namen ist ein qualifizierter Verweis <prefix>.<def>,
aufgelöst über Import-Map (alias-oder-modulname → echter Modulname).
Drei neue Diagnostic-Codes: unknown-module, unknown-import,
invalid-def-name. ail check lädt jetzt immer via load_workspace;
Loader-Fehler werden im JSON-Modus zu strukturierten Diagnostics
(module-not-found, module-cycle, …). DESIGN.md und JOURNAL.md
dokumentieren die Konvention. Hash-Stabilität: alle ir_snapshot_*-
Tests bitidentisch grün, kein neuer AST-Knoten.
2026-05-07 11:31:57 +02:00
Brummel 93fe7237e3 Iter 4a: ail check --json mit strukturierten Diagnostics
Neue Top-Level-API check_module(&Module) -> Vec<Diagnostic> in
ailang-check, plus stabile Codes (unbound-var, type-mismatch,
arity-mismatch, non-exhaustive-match, unknown-ctor-in-pattern,
duplicate-def, …). CLI bekommt --json-Flag für maschinenlesbares
Output, Exit 1 bei Errors. Text-Modus unverändert. E2E-Test
check_json_unbound_var sichert das Format ab.
2026-05-07 11:07:36 +02:00