Extracted the duplicated conformance plumbing into a single driver:
- lib/guest/conformance.sx — two helper fns that emit (gc-result NAME P F T)
lines for the bash side to grep: gc-dict-result for runners returning
a {:passed :failed :total} dict, and gc-counters-result for guests that
bump a global pass/fail counter from a test file load.
- lib/guest/conformance.sh — config-driven bash driver. Sources a per-lang
conf, locates sx_server, runs sx_server in either single-session "dict"
mode (one preload + many suite evals) or per-suite "counters" mode
(fresh sx_server per suite, with shared preloads). Aggregates and writes
scoreboard.{json,md} via per-lang emit_scoreboard_* functions.
- Ported lib/prolog/conformance.sh and lib/haskell/conformance.sh down to
one-line wrappers that exec the shared driver against their .conf file.
Verification:
- Prolog: 590/590 — diff vs baseline is timestamp-only.
- Haskell: 156/156 — significantly higher than the 0/18 in baseline. The
old conformance.sh was buggy (its `(ok-len 3 ...)` grep never matched,
defaulting every program to 0 pass / 1 fail). Updated baseline to the
true count; no actual test regressed. Plan baseline cell updated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
77 lines
2.5 KiB
Plaintext
77 lines
2.5 KiB
Plaintext
# Haskell-on-SX conformance config — sourced by lib/guest/conformance.sh.
|
|
|
|
LANG_NAME=haskell
|
|
MODE=counters
|
|
COUNTERS_PASS=hk-test-pass
|
|
COUNTERS_FAIL=hk-test-fail
|
|
TIMEOUT_PER_SUITE=120
|
|
|
|
PRELOADS=(
|
|
lib/haskell/tokenizer.sx
|
|
lib/haskell/layout.sx
|
|
lib/haskell/parser.sx
|
|
lib/haskell/desugar.sx
|
|
lib/haskell/runtime.sx
|
|
lib/haskell/match.sx
|
|
lib/haskell/eval.sx
|
|
lib/haskell/testlib.sx
|
|
)
|
|
|
|
SUITES=(
|
|
"fib:lib/haskell/tests/program-fib.sx"
|
|
"sieve:lib/haskell/tests/program-sieve.sx"
|
|
"quicksort:lib/haskell/tests/program-quicksort.sx"
|
|
"nqueens:lib/haskell/tests/program-nqueens.sx"
|
|
"calculator:lib/haskell/tests/program-calculator.sx"
|
|
"collatz:lib/haskell/tests/program-collatz.sx"
|
|
"palindrome:lib/haskell/tests/program-palindrome.sx"
|
|
"maybe:lib/haskell/tests/program-maybe.sx"
|
|
"fizzbuzz:lib/haskell/tests/program-fizzbuzz.sx"
|
|
"anagram:lib/haskell/tests/program-anagram.sx"
|
|
"roman:lib/haskell/tests/program-roman.sx"
|
|
"binary:lib/haskell/tests/program-binary.sx"
|
|
"either:lib/haskell/tests/program-either.sx"
|
|
"primes:lib/haskell/tests/program-primes.sx"
|
|
"zipwith:lib/haskell/tests/program-zipwith.sx"
|
|
"matrix:lib/haskell/tests/program-matrix.sx"
|
|
"wordcount:lib/haskell/tests/program-wordcount.sx"
|
|
"powers:lib/haskell/tests/program-powers.sx"
|
|
)
|
|
|
|
emit_scoreboard_json() {
|
|
local n=${#GC_NAMES[@]} i sep date_only
|
|
date_only=$(date '+%Y-%m-%d')
|
|
printf '{\n'
|
|
printf ' "date": "%s",\n' "$date_only"
|
|
printf ' "total_pass": %d,\n' "$GC_TOTAL_PASS"
|
|
printf ' "total_fail": %d,\n' "$GC_TOTAL_FAIL"
|
|
printf ' "programs": {\n'
|
|
for ((i=0; i<n; i++)); do
|
|
sep=","; [ $i -eq $((n-1)) ] && sep=""
|
|
printf ' "%s": {"pass": %d, "fail": %d}%s\n' \
|
|
"${GC_NAMES[$i]}" "${GC_PASS[$i]}" "${GC_FAIL[$i]}" "$sep"
|
|
done
|
|
printf ' }\n'
|
|
printf '}\n'
|
|
}
|
|
|
|
emit_scoreboard_md() {
|
|
local n=${#GC_NAMES[@]}
|
|
local i status p f t prog_pass=0 prog_total=$n date_only
|
|
date_only=$(date '+%Y-%m-%d')
|
|
for ((i=0; i<n; i++)); do
|
|
[ "${GC_FAIL[$i]}" -eq 0 ] && prog_pass=$((prog_pass + 1))
|
|
done
|
|
printf '# Haskell-on-SX Scoreboard\n\n'
|
|
printf 'Updated %s · Phase 6 (prelude extras + 18 programs)\n\n' "$date_only"
|
|
printf '| Program | Tests | Status |\n'
|
|
printf '|---------|-------|--------|\n'
|
|
for ((i=0; i<n; i++)); do
|
|
p=${GC_PASS[$i]}; f=${GC_FAIL[$i]}; t=${GC_TOTAL_S[$i]}
|
|
[ "$f" -eq 0 ] && status="✓" || status="✗"
|
|
printf '| %s.hs | %d/%d | %s |\n' "${GC_NAMES[$i]}" "$p" "$t" "$status"
|
|
done
|
|
printf '| **Total** | **%d/%d** | **%d/%d programs** |\n' \
|
|
"$GC_TOTAL_PASS" "$GC_TOTAL" "$prog_pass" "$prog_total"
|
|
}
|