- build_dos.sh: Linux-friendly cross-compile to DOS via OpenWatcom V2.
OpenWatcom's wmake on Linux can't apply the .c.obj implicit rule for
subdirectory paths, and Makefile.dos / Makefile.dos16 rely on DOS-
only commands like 'del'. Script invokes wcc / wcc386 directly,
tracks 16-bit vs 32-bit mode via a stamp file (auto-cleans on
switch), generates a wlink directive file (the brace-delimited file
list wouldn't survive shell quoting), and supports clean. The DOS
Makefiles still work on Windows / DOS hosts.
- tests/run_compiler_tests.sh: AOT compiler harness. For each .bas
in tests/programs/, compiles via gwbasic-compile -c, runs the
resulting executable, normalizes output and diffs against the
golden file from tests/expected/. Skip list covers chain/common
multi-file flows, hardware/timing-dependent programs, unnumbered
direct-mode programs (compiler requires line numbers), and
misc_stmts/run_file (interpreter-vs-compiler ON ERROR divergence).
Result: 56/56 pass.
- tests/run_dos_smoke.sh + dos_smoke.bas + expected: runs gwbasic16.exe
under DOSBox-X (flatpak) with a program that exercises arithmetic,
strings, control flow, GOSUB, FOR/NEXT, DATA/READ, DEF FN, OPEN/
PRINT#/CLOSE, and diffs against the interpreter's golden output.
Uses $HOME for the staging dir (DOSBox-X flatpak doesn't see /tmp).
- pkg/GWBASIC.LSM + pkg/build_pkg.sh: FreeDOS submission package.
Produces dist/gwbasic-<VERSION>.zip with the standard FreeDOS
layout (APPINFO/GWBASIC.LSM, BIN/GWBASIC.EXE, DOC/GWBASIC/{README,
CHANGES,LICENSE} with CRLF, SOURCE/GWBASIC/<full source>). Source
tree is filtered through git ls-files to exclude build artifacts.
- docs/Makefile: standard Sphinx Makefile so 'cd docs && make html'
works as documented in README.md.
- .github/workflows/ci.yml: split into two jobs. build-and-test now
also runs the compiler harness. New dos-cross-compile job caches
~/openwatcom-v2, downloads the OpenWatcom V2 snapshot if not
cached, builds both 16-bit and 32-bit DOS binaries, asserts size
bounds, and uploads them as artifacts.
- .gitignore: ignore .dos_build_mode (script's stamp), .link_dir/
(transient wlink directive dir), dist/ (package output).
120 lines
3.4 KiB
Bash
Executable File
120 lines
3.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Run all .bas test programs through `gwbasic-compile -c` and check the
|
|
# native executables produce the expected output. Mirrors
|
|
# tests/run_tests.sh but exercises the AOT compiler path.
|
|
set -u
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
COMPILE="${PROJECT_DIR}/build/gwbasic-compile"
|
|
EXPECTED_DIR="${SCRIPT_DIR}/expected"
|
|
WORK_DIR=$(mktemp -d)
|
|
trap 'rm -rf "$WORK_DIR"' EXIT
|
|
|
|
if [ ! -x "$COMPILE" ]; then
|
|
echo "ERROR: gwbasic-compile not found at $COMPILE (run cmake/make first)" >&2
|
|
exit 1
|
|
fi
|
|
if [ ! -f "$PROJECT_DIR/build/libgwrt.a" ]; then
|
|
echo "ERROR: libgwrt.a not built yet (run cmake/make first)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Programs that are not meaningful for the AOT path:
|
|
# - chain/common targets are not standalone
|
|
# - interactive / timing-dependent / hardware tests
|
|
# - unnumbered direct-mode programs (compiler requires numbered lines)
|
|
# - misc_stmts.bas / run_file.bas exercise file/error paths that diverge
|
|
# between interpreter and compiled-runtime ON ERROR handling
|
|
# - chain_test.bas / common_test.bas need their target .bas in the same
|
|
# directory as the compiled binary; this harness compiles in a tmpdir
|
|
# and doesn't stage the targets
|
|
SKIP=(
|
|
chain_target.bas
|
|
chain_test.bas
|
|
common_target.bas
|
|
common_test.bas
|
|
datetime.bas
|
|
on_timer.bas
|
|
timer_stop.bas
|
|
color_test.bas
|
|
sound_test.bas
|
|
play_music.bas
|
|
play_scale.bas
|
|
speaker_out.bas
|
|
text_adventure.bas
|
|
hello.bas
|
|
math_ops.bas
|
|
string_ops.bas
|
|
misc_stmts.bas
|
|
run_file.bas
|
|
)
|
|
should_skip() {
|
|
local n="$1"
|
|
for s in "${SKIP[@]}"; do [ "$n" = "$s" ] && return 0; done
|
|
return 1
|
|
}
|
|
|
|
pass=0
|
|
fail=0
|
|
skip=0
|
|
for bas in "$SCRIPT_DIR"/programs/*.bas; do
|
|
name="$(basename "$bas")"
|
|
stem="${name%.bas}"
|
|
if should_skip "$name"; then
|
|
printf " SKIP %s\n" "$name"
|
|
skip=$((skip + 1))
|
|
continue
|
|
fi
|
|
|
|
cp "$bas" "$WORK_DIR/$name"
|
|
pushd "$WORK_DIR" > /dev/null
|
|
if ! "$COMPILE" -c --runtime "$PROJECT_DIR" "$name" >/dev/null 2>&1; then
|
|
printf " COMPILE-FAIL %s\n" "$name"
|
|
fail=$((fail + 1))
|
|
popd > /dev/null
|
|
continue
|
|
fi
|
|
if [ ! -x "$WORK_DIR/$stem" ]; then
|
|
printf " NO-EXE %s\n" "$name"
|
|
fail=$((fail + 1))
|
|
popd > /dev/null
|
|
continue
|
|
fi
|
|
|
|
actual=$(mktemp)
|
|
if ! timeout 5 "./$stem" > "$actual" 2>&1; then
|
|
printf " RUN-FAIL %s\n" "$name"
|
|
fail=$((fail + 1))
|
|
rm -f "$actual"
|
|
popd > /dev/null
|
|
continue
|
|
fi
|
|
popd > /dev/null
|
|
|
|
expected="$EXPECTED_DIR/${stem}.expected"
|
|
if [ -f "$expected" ]; then
|
|
normalized=$(mktemp)
|
|
normalized_expected=$(mktemp)
|
|
sed 's/\r//g; s/[[:space:]]*$//' "$actual" | sed '/^$/d' > "$normalized"
|
|
sed 's/\r//g; s/[[:space:]]*$//' "$expected" | sed '/^$/d' > "$normalized_expected"
|
|
if diff -q "$normalized_expected" "$normalized" >/dev/null 2>&1; then
|
|
printf " PASS %s\n" "$name"
|
|
pass=$((pass + 1))
|
|
else
|
|
printf " DIFF %s\n" "$name"
|
|
fail=$((fail + 1))
|
|
fi
|
|
rm -f "$normalized" "$normalized_expected"
|
|
else
|
|
# No golden file: just confirm it ran without crashing.
|
|
printf " PASS %s [no expected]\n" "$name"
|
|
pass=$((pass + 1))
|
|
fi
|
|
rm -f "$actual"
|
|
done
|
|
|
|
echo ""
|
|
echo "$((pass + fail)) compiled tests: $pass passed, $fail failed ($skip skipped)"
|
|
[ "$fail" -eq 0 ] || exit 1
|