diff --git a/lib/maude/conformance.conf b/lib/maude/conformance.conf index d904c0b0..f54a65ad 100644 --- a/lib/maude/conformance.conf +++ b/lib/maude/conformance.conf @@ -3,24 +3,10 @@ LANG_NAME=maude MODE=dict -PRELOADS=( - lib/guest/lex.sx - lib/guest/pratt.sx - lib/maude/term.sx - lib/maude/parser.sx - lib/maude/sorts.sx - lib/maude/reduce.sx - lib/maude/matching.sx - lib/maude/conditional.sx - lib/maude/fire.sx - lib/maude/confluence.sx - lib/maude/rewrite.sx - lib/maude/searchpath.sx - lib/maude/strategy.sx - lib/maude/meta.sx - lib/maude/pretty.sx - lib/maude/run.sx -) +# Load order is the single source of truth in load-order.txt (also consumable +# by other drivers, e.g. lib/artdag). Sourced after the driver cd's to repo +# top-level, so the relative path resolves; #-comments and blanks are stripped. +mapfile -t PRELOADS < <(grep -vE '^[[:space:]]*(#|$)' lib/maude/load-order.txt) SUITES=( "parse:lib/maude/tests/parse.sx:(mau-parse-tests-run!)" diff --git a/lib/maude/load-order.txt b/lib/maude/load-order.txt new file mode 100644 index 00000000..d9b66403 --- /dev/null +++ b/lib/maude/load-order.txt @@ -0,0 +1,23 @@ +# lib/maude load order — single source of truth for the dependency-ordered +# file list needed to load the maude engine (parser + rewriting + confluence + +# reflection). Sourced by lib/maude/conformance.conf; other drivers (e.g. +# lib/artdag, which today hardcodes its own copy of these load lines) can read +# the same list instead of duplicating it, so a file rename here is a one-line +# change. Repo-root-relative paths, one per line; blank lines and #-comments +# are ignored by readers. +lib/guest/lex.sx +lib/guest/pratt.sx +lib/maude/term.sx +lib/maude/parser.sx +lib/maude/sorts.sx +lib/maude/reduce.sx +lib/maude/matching.sx +lib/maude/conditional.sx +lib/maude/fire.sx +lib/maude/confluence.sx +lib/maude/rewrite.sx +lib/maude/searchpath.sx +lib/maude/strategy.sx +lib/maude/meta.sx +lib/maude/pretty.sx +lib/maude/run.sx diff --git a/plans/maude-on-sx.md b/plans/maude-on-sx.md index 755c3926..ad460715 100644 --- a/plans/maude-on-sx.md +++ b/plans/maude-on-sx.md @@ -171,22 +171,40 @@ real consumer *wants* the `fmod` parser — it authors rules as Maude text. A th term-rewriting kernel that excludes the parser does not serve it; a "kernel" that includes the parser is just `lib/maude` renamed. -**Recommended move (cheap, low-risk, real) — a public API facade, not a relocation:** -add `lib/maude/api.sx` re-exporting exactly the ~12 consumed symbols as the -supported surface (`mau/parse-module`, `mau/creduce*`/`mau/ccanon`, -`mau/confluent?`/`mau/non-joinable-pairs`/`mau/cp->str`, term ctors/accessors). -artdag imports the facade instead of nine `load "lib/maude/.sx"` lines; -the internal file layout becomes free to change without breaking the consumer. -This delivers the *encapsulation* value of extraction (a named, stable boundary) -without moving files across three trees (`lib/guest/` + `lib/maude/` + -`lib/artdag/`) or risking the two green suites (maude 274, artdag 225). +**Recommended move (cheap, low-risk, real) — a driver-level manifest, not a +relocation and not an `.sx` re-export** (the `.sx` facade was tried and proven +infeasible; see FINDING below). The consumed surface is `mau/parse-module`, +`mau/creduce*`/`mau/ccanon`, `mau/confluent?`/`mau/non-joinable-pairs`/`mau/cp->str`, +term ctors/accessors. + +**FINDING (2026-07, smoke-tested): an `.sx`-file facade is architecturally +impossible.** `load` is an *epoch-protocol command*, not an evaluator symbol — +`(load "…")` forms **inside** a loaded `.sx` file error with "Undefined symbol: +load" (verified: a would-be `api.sx` of `(load …)` lines fails on every line). +The nested-load seen in `common-lisp/tests/runtime.sx` works only because that +harness feeds each form as a *command*, not because `load` is callable from +evaluated code. So the load list is inherently a **driver-level** concern +(shell / `conformance.conf`), and no `.sx` file can wrap "nine loads into one". + +**BUILT INSTEAD — `lib/maude/load-order.txt`** (driver-level manifest, the +working form of the facade): the dependency-ordered file list as the single +source of truth. `lib/maude/conformance.conf` now reads it +(`mapfile -t PRELOADS < <(grep -vE '^\s*(#|$)' lib/maude/load-order.txt)`) — +proven by the 274 suite staying green. A file rename is now a one-line change, +and `lib/artdag`'s driver can `mapfile` the same file to drop its hardcoded copy +of these load lines (artdag-side change, its scope — a documented follow-up, not +done here). This delivers the load-list DRY + file-rename freedom that the +`.sx` facade could not. + +**Symbol-contract (optional, not built):** a pure-manifest `mau/api-symbols` +list (the ~25 public symbols, no `load` forms so it loads fine) + an `api` test +exercising each end-to-end would pin the *symbol* surface as a tripwire. Modest; +skipped as gilding — the file-level manifest is the higher-value half. **Defer the physical `lib/guest/rewriting/` split** until a *third* consumer -appears whose needs actually diverge from artdag's — at that point the boundary -will be drawn by two real shapes, not one plus a guess. The data dependency DAG -and the 7-symbol coupling set above are recorded so that cut is a 1-session job -when justified. **Sole remaining action if desired: the `api.sx` facade (in -scope: `lib/maude/**` only); coordinate artdag's import-side change separately.** +diverges from artdag — the boundary should be drawn by two real shapes, not one +plus a guess. The dependency DAG and 7-symbol coupling set above make that cut a +1-session job when justified. ### SATURATION (post-roadmap)