scheme: Phase 11 — test.sh + scoreboard
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s
lib/scheme/test.sh — single-process test runner. Loads parser/eval/
runtime + lib/guest/reflective/env.sx once, then for each test
suite loads its file and calls its (*-tests-run!) function. Parses
the {:passed N :failed N ...} dict output and aggregates.
Usage:
bash lib/scheme/test.sh # summary
bash lib/scheme/test.sh -v # per-suite breakdown
Output: "ok 296/296 scheme-on-sx tests passed (9 suites)"
lib/scheme/scoreboard.md — per-suite passing counts, phase status,
deferred items, reflective-kit consumption ledger.
The scoreboard documents the chisel value of the Scheme port:
three reflective kits unlocked (env.sx — already extracted with
Scheme as third consumer; evaluator.sx + quoting.sx — second-
consumer-ready for extraction whenever a follow-up commit is run).
Loop status: 11 phases done (1, 2, 3, 3.5, 4, 5abc, 6ab, 7, 8, 9,
10, 11). Two deferred (6c hygiene, full call/cc-wind interaction).
296 tests, 1830 LoC of Scheme implementation. Zero substrate fixes
required across the loop.
This commit is contained in:
83
lib/scheme/scoreboard.md
Normal file
83
lib/scheme/scoreboard.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Scheme-on-SX Scoreboard
|
||||
|
||||
**All tests pass: 296 / 296 across 9 suites.**
|
||||
|
||||
## Per-suite breakdown
|
||||
|
||||
| Suite | Passing | Covers |
|
||||
|-------------|--------:|--------|
|
||||
| parse | 62 | R7RS lexer: numbers, strings, chars, vectors, lists, quote/quasi/unquote, line/block/datum comments |
|
||||
| eval | 23 | Self-evaluating literals, symbol lookup, quote, primitive application |
|
||||
| syntax | 49 | if/define/set!/begin/lambda/closures + let/let*/cond/when/unless/and/or |
|
||||
| runtime | 78 | Standard env: variadic arithmetic, type predicates, list/string/char/vector ops, higher-order combinators |
|
||||
| control | 25 | call/cc (escape), raise/guard/with-exception-handler, dynamic-wind |
|
||||
| macros | 20 | define-syntax / syntax-rules incl. tail-rest ellipsis |
|
||||
| reflection | 23 | eval / interaction-environment / null-environment / scheme-report-environment + quasiquote runtime |
|
||||
| records | 9 | define-record-type with constructor / predicate / accessor / mutator |
|
||||
| modules | 7 | define-library + import (minimal — no cond-expand / include / rename) |
|
||||
|
||||
## Phases implemented
|
||||
|
||||
- [x] Phase 1 — Parser
|
||||
- [x] Phase 2 — Evaluator + env.sx **third consumer**
|
||||
- [x] Phase 3 — Syntactic operators (if/lambda/define/set!/begin)
|
||||
- [x] Phase 3.5 — let/let*/cond/when/unless/and/or
|
||||
- [x] Phase 4 — Standard environment + set! cond-bugfix
|
||||
- [x] Phase 5a — call/cc
|
||||
- [x] Phase 5b — exceptions (raise/guard/with-exception-handler/error)
|
||||
- [x] Phase 5c — dynamic-wind (basic, no call/cc-escape tracking)
|
||||
- [x] Phase 6a — define-syntax + syntax-rules (no ellipsis)
|
||||
- [x] Phase 6b — syntax-rules ellipsis (tail-rest, single variable)
|
||||
- [x] Phase 7 — eval / interaction-environment **second consumer for evaluator.sx**
|
||||
- [x] Phase 8 — define-library + import (minimal)
|
||||
- [x] Phase 9 — define-record-type
|
||||
- [x] Phase 10 — quasiquote runtime **second consumer for quoting.sx**
|
||||
- [x] Phase 11 — test.sh + scoreboard
|
||||
|
||||
## Deferred
|
||||
|
||||
- **Phase 6c — hygiene** (scope-set / lifted-symbol Dybvig-style algorithm).
|
||||
Would be the second consumer for the deferred `lib/guest/reflective/hygiene.sx`
|
||||
research-grade kit. Current macros work for common patterns but can capture
|
||||
caller bindings if a macro introduces same-named identifiers.
|
||||
|
||||
- **Nested quasiquote depth tracking** — `` `\`x\` `` is not properly depth-aware;
|
||||
matches Kernel's deferred state.
|
||||
|
||||
- **R7RS module rich features**: cond-expand, include, include-library-declarations,
|
||||
`(only ...)` / `(except ...)` / `(prefix ...)` / `(rename ...)` import sets.
|
||||
|
||||
- **Dotted-pair `(a b . rest)` syntax** at the parser level. Lambda rest-args
|
||||
currently use the `(lambda args ...)` form (bare symbol) instead.
|
||||
|
||||
- **Full call/cc + dynamic-wind interaction**: re-entry/re-exit of dynamic
|
||||
extents via continuations is not tracked. Pure-eval programs work; call/cc-
|
||||
heavy code with dynamic-wind interleaving doesn't.
|
||||
|
||||
## Reflective-kit consumption (chisel ledger)
|
||||
|
||||
This Scheme port unlocks three reflective-kit extractions from the kernel-on-sx
|
||||
loop's original six-candidate list:
|
||||
|
||||
| Kit | Status |
|
||||
|----------------------|---------------------------------------------|
|
||||
| env.sx | **Extracted** (third consumer; no adapter) |
|
||||
| class-chain.sx | n/a (no OO in Scheme) |
|
||||
| evaluator.sx | **Unblocked** (second consumer ready) |
|
||||
| quoting.sx | **Unblocked** (second consumer ready) |
|
||||
| hygiene.sx | Awaiting Phase 6c (research-grade) |
|
||||
| combiner.sx | n/a (no fexprs in Scheme) |
|
||||
| short-circuit.sx | n/a (Scheme `and`/`or` are syntactic, not operative) |
|
||||
|
||||
The kit-extraction commits themselves are follow-on work — kit code is staged
|
||||
in the proposed sections of `plans/kernel-on-sx.md`; Scheme's consumer code
|
||||
satisfies the two-consumer rule for `evaluator.sx` and `quoting.sx`.
|
||||
|
||||
## Substrate stats
|
||||
|
||||
- parser.sx — 281 LoC
|
||||
- eval.sx — ~970 LoC
|
||||
- runtime.sx — ~580 LoC
|
||||
- Tests — ~1500 LoC across 9 files
|
||||
|
||||
Total Scheme implementation ≈ 1830 LoC.
|
||||
92
lib/scheme/test.sh
Executable file
92
lib/scheme/test.sh
Executable file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env bash
|
||||
# Scheme-on-SX test runner — runs all tests in one sx_server process.
|
||||
#
|
||||
# Usage:
|
||||
# bash lib/scheme/test.sh # run all suites
|
||||
# bash lib/scheme/test.sh -v # verbose (list each suite)
|
||||
|
||||
set -uo pipefail
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
SX_SERVER="${SX_SERVER:-hosts/ocaml/_build/default/bin/sx_server.exe}"
|
||||
if [ ! -x "$SX_SERVER" ]; then
|
||||
SX_SERVER="/root/rose-ash/hosts/ocaml/_build/default/bin/sx_server.exe"
|
||||
fi
|
||||
if [ ! -x "$SX_SERVER" ]; then
|
||||
echo "ERROR: sx_server.exe not found." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERBOSE="${1:-}"
|
||||
|
||||
# Suites: NAME RUNNER-FN PATH
|
||||
SUITES=(
|
||||
"parse scm-tests-run! lib/scheme/tests/parse.sx"
|
||||
"eval scm-eval-tests-run! lib/scheme/tests/eval.sx"
|
||||
"syntax scm-syn-tests-run! lib/scheme/tests/syntax.sx"
|
||||
"runtime scm-rt-tests-run! lib/scheme/tests/runtime.sx"
|
||||
"control scm-ctl-tests-run! lib/scheme/tests/control.sx"
|
||||
"macros scm-mac-tests-run! lib/scheme/tests/macros.sx"
|
||||
"reflection scm-ref-tests-run! lib/scheme/tests/reflection.sx"
|
||||
"records scm-rec-tests-run! lib/scheme/tests/records.sx"
|
||||
"modules scm-mod-tests-run! lib/scheme/tests/modules.sx"
|
||||
)
|
||||
|
||||
TMPFILE=$(mktemp); trap "rm -f $TMPFILE" EXIT
|
||||
EPOCH=1
|
||||
|
||||
emit_load () { echo "(epoch $EPOCH)"; echo "(load \"$1\")"; EPOCH=$((EPOCH+1)); }
|
||||
emit_eval () { echo "(epoch $EPOCH)"; echo "(eval \"$1\")"; EPOCH=$((EPOCH+1)); }
|
||||
|
||||
{
|
||||
emit_load "lib/guest/lex.sx"
|
||||
emit_load "lib/guest/reflective/env.sx"
|
||||
emit_load "lib/scheme/parser.sx"
|
||||
emit_load "lib/scheme/eval.sx"
|
||||
emit_load "lib/scheme/runtime.sx"
|
||||
for SUITE in "${SUITES[@]}"; do
|
||||
read -r _NAME _RUNNER FILE <<< "$SUITE"
|
||||
emit_load "$FILE"
|
||||
emit_eval "($_RUNNER)"
|
||||
done
|
||||
} > "$TMPFILE"
|
||||
|
||||
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>&1 || true)
|
||||
|
||||
# Final 9 outputs are the suite results. Parse each "{:passed N :failed N ..}".
|
||||
TOTAL_PASS=0
|
||||
TOTAL_FAIL=0
|
||||
FAILED_SUITES=()
|
||||
|
||||
# Walk the output; for each suite, extract the {:passed ...} line.
|
||||
# The dict format from sx_server is {:passed N :failed N :total N :fails (...)}.
|
||||
LAST_DICT_LINES=$(echo "$OUTPUT" | grep -E '^\{:' || true)
|
||||
|
||||
I=0
|
||||
while read -r LINE; do
|
||||
[ -z "$LINE" ] && continue
|
||||
P=$(echo "$LINE" | grep -oE ':passed [0-9]+' | awk '{print $2}')
|
||||
F=$(echo "$LINE" | grep -oE ':failed [0-9]+' | awk '{print $2}')
|
||||
[ -z "$P" ] && P=0
|
||||
[ -z "$F" ] && F=0
|
||||
SUITE_INFO="${SUITES[$I]}"
|
||||
SUITE_NAME=$(echo "$SUITE_INFO" | awk '{print $1}')
|
||||
TOTAL_PASS=$((TOTAL_PASS + P))
|
||||
TOTAL_FAIL=$((TOTAL_FAIL + F))
|
||||
if [ "$F" -gt 0 ]; then
|
||||
FAILED_SUITES+=("$SUITE_NAME: $P/$((P+F))")
|
||||
printf 'X %-12s %d/%d\n' "$SUITE_NAME" "$P" "$((P+F))"
|
||||
elif [ "$VERBOSE" = "-v" ]; then
|
||||
printf 'ok %-12s %d passed\n' "$SUITE_NAME" "$P"
|
||||
fi
|
||||
I=$((I+1))
|
||||
done <<< "$LAST_DICT_LINES"
|
||||
|
||||
TOTAL=$((TOTAL_PASS + TOTAL_FAIL))
|
||||
if [ $TOTAL_FAIL -eq 0 ]; then
|
||||
echo "ok $TOTAL_PASS/$TOTAL scheme-on-sx tests passed (${#SUITES[@]} suites)"
|
||||
else
|
||||
echo "FAIL $TOTAL_PASS/$TOTAL passed, $TOTAL_FAIL failed:"
|
||||
for S in "${FAILED_SUITES[@]}"; do echo " $S"; done
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user