Extracted the data-half of Pratt-style precedence parsing: the operator table format and lookup. The climbing loop stays per-language because the two canaries use opposite conventions (lua: higher prec = tighter; prolog: lower prec = tighter, with xfx/xfy/yfx assoc tags) — forcing one shared loop adds callback indirection that obscures more than it shares. The brief's literal ask is "Grammar is a dict, not hardcoded cond" and that's what gets shared. Entry shape: (NAME PREC ASSOC). Three accessors: pratt-op-name / pratt-op-prec / pratt-op-assoc. One traversal: pratt-op-lookup. Ported lua/parser.sx — replaced 18-clause cond and the lua-binop-right? hardcoded `or` with a 15-entry lua-op-table, now queried via pratt-op-lookup. Ported prolog/parser.sx — pl-op-find (linear walk reimpl) deleted; pl-op-lookup wraps pratt-op-lookup; pl-token-op simplified to return the entry directly. Verification: - lua/test.sh: 185/185 = baseline. - prolog/conformance.sh: 590/590 = baseline (timestamp-only diff). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
82 lines
3.6 KiB
Plaintext
82 lines
3.6 KiB
Plaintext
# Prolog conformance config — sourced by lib/guest/conformance.sh.
|
|
|
|
LANG_NAME=prolog
|
|
MODE=dict
|
|
|
|
PRELOADS=(
|
|
lib/guest/pratt.sx
|
|
lib/prolog/tokenizer.sx
|
|
lib/prolog/parser.sx
|
|
lib/prolog/runtime.sx
|
|
lib/prolog/query.sx
|
|
lib/prolog/compiler.sx
|
|
lib/prolog/hs-bridge.sx
|
|
)
|
|
|
|
SUITES=(
|
|
"parse:lib/prolog/tests/parse.sx:(pl-parse-tests-run!)"
|
|
"unify:lib/prolog/tests/unify.sx:(pl-unify-tests-run!)"
|
|
"clausedb:lib/prolog/tests/clausedb.sx:(pl-clausedb-tests-run!)"
|
|
"solve:lib/prolog/tests/solve.sx:(pl-solve-tests-run!)"
|
|
"operators:lib/prolog/tests/operators.sx:(pl-operators-tests-run!)"
|
|
"dynamic:lib/prolog/tests/dynamic.sx:(pl-dynamic-tests-run!)"
|
|
"findall:lib/prolog/tests/findall.sx:(pl-findall-tests-run!)"
|
|
"term_inspect:lib/prolog/tests/term_inspect.sx:(pl-term-inspect-tests-run!)"
|
|
"append:lib/prolog/tests/programs/append.sx:(pl-append-tests-run!)"
|
|
"reverse:lib/prolog/tests/programs/reverse.sx:(pl-reverse-tests-run!)"
|
|
"member:lib/prolog/tests/programs/member.sx:(pl-member-tests-run!)"
|
|
"nqueens:lib/prolog/tests/programs/nqueens.sx:(pl-nqueens-tests-run!)"
|
|
"family:lib/prolog/tests/programs/family.sx:(pl-family-tests-run!)"
|
|
"atoms:lib/prolog/tests/atoms.sx:(pl-atom-tests-run!)"
|
|
"query_api:lib/prolog/tests/query_api.sx:(pl-query-api-tests-run!)"
|
|
"iso_predicates:lib/prolog/tests/iso_predicates.sx:(pl-iso-predicates-tests-run!)"
|
|
"meta_predicates:lib/prolog/tests/meta_predicates.sx:(pl-meta-predicates-tests-run!)"
|
|
"list_predicates:lib/prolog/tests/list_predicates.sx:(pl-list-predicates-tests-run!)"
|
|
"meta_call:lib/prolog/tests/meta_call.sx:(pl-meta-call-tests-run!)"
|
|
"set_predicates:lib/prolog/tests/set_predicates.sx:(pl-set-predicates-tests-run!)"
|
|
"char_predicates:lib/prolog/tests/char_predicates.sx:(pl-char-predicates-tests-run!)"
|
|
"io_predicates:lib/prolog/tests/io_predicates.sx:(pl-io-predicates-tests-run!)"
|
|
"assert_rules:lib/prolog/tests/assert_rules.sx:(pl-assert-rules-tests-run!)"
|
|
"string_agg:lib/prolog/tests/string_agg.sx:(pl-string-agg-tests-run!)"
|
|
"advanced:lib/prolog/tests/advanced.sx:(pl-advanced-tests-run!)"
|
|
"compiler:lib/prolog/tests/compiler.sx:(pl-compiler-tests-run!)"
|
|
"cross_validate:lib/prolog/tests/cross_validate.sx:(pl-cross-validate-tests-run!)"
|
|
"integration:lib/prolog/tests/integration.sx:(pl-integration-tests-run!)"
|
|
"hs_bridge:lib/prolog/tests/hs_bridge.sx:(pl-hs-bridge-tests-run!)"
|
|
)
|
|
|
|
emit_scoreboard_json() {
|
|
local n=${#GC_NAMES[@]} i sep
|
|
printf '{\n'
|
|
printf ' "total_passed": %d,\n' "$GC_TOTAL_PASS"
|
|
printf ' "total_failed": %d,\n' "$GC_TOTAL_FAIL"
|
|
printf ' "total": %d,\n' "$GC_TOTAL"
|
|
printf ' "suites": {'
|
|
for ((i=0; i<n; i++)); do
|
|
sep=","; [ $i -eq $((n-1)) ] && sep=""
|
|
printf '"%s":{"passed":%d,"total":%d,"failed":%d}%s' \
|
|
"${GC_NAMES[$i]}" "${GC_PASS[$i]}" "${GC_TOTAL_S[$i]}" "${GC_FAIL[$i]}" "$sep"
|
|
done
|
|
printf '},\n'
|
|
printf ' "generated": "%s"\n' "$(date -Iseconds 2>/dev/null || date)"
|
|
printf '}\n'
|
|
}
|
|
|
|
emit_scoreboard_md() {
|
|
local n=${#GC_NAMES[@]} i status when
|
|
when="$(date -Iseconds 2>/dev/null || date)"
|
|
printf '# Prolog scoreboard\n\n'
|
|
printf '**%d / %d passing** (%d failure(s)).\n' \
|
|
"$GC_TOTAL_PASS" "$GC_TOTAL" "$GC_TOTAL_FAIL"
|
|
printf 'Generated %s.\n\n' "$when"
|
|
printf '| Suite | Passed | Total | Status |\n'
|
|
printf '|-------|--------|-------|--------|\n'
|
|
for ((i=0; i<n; i++)); do
|
|
status="ok"; [ "${GC_FAIL[$i]}" -gt 0 ] && status="FAIL"
|
|
printf '| %s | %d | %d | %s |\n' \
|
|
"${GC_NAMES[$i]}" "${GC_PASS[$i]}" "${GC_TOTAL_S[$i]}" "$status"
|
|
done
|
|
printf '\nRun `bash lib/prolog/conformance.sh` to refresh. Override the binary\n'
|
|
printf 'with `SX_SERVER=path/to/sx_server.exe bash …`.\n'
|
|
}
|