diff options
| author | 2026-10-12 08:46:23 +0330 | |
|---|---|---|
| committer | 2026-10-12 08:46:23 +0330 | |
| commit | ecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch) | |
| tree | 70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /docs/history/17-o3-boundaries/code/test.sh | |
a
Diffstat (limited to 'docs/history/17-o3-boundaries/code/test.sh')
| -rwxr-xr-x | docs/history/17-o3-boundaries/code/test.sh | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/docs/history/17-o3-boundaries/code/test.sh b/docs/history/17-o3-boundaries/code/test.sh new file mode 100755 index 0000000..533042d --- /dev/null +++ b/docs/history/17-o3-boundaries/code/test.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# full check: bootstraps the compiler from zc0, verifies the fixpoint, then runs +# the examples and tests on the portable interpreter (host), the arm64 jit under +# qemu, and the llvm backend. needs gcc; the jit half needs aarch64-linux-gnu-gcc +# and qemu-aarch64, the llvm half needs llvm-config and libLLVM (each is skipped +# if missing). +cd "$(dirname "$0")"; T=$(mktemp -d); trap 'rm -rf $T' EXIT +ok=0; bad=0 +chk(){ if [ "$1" = "$2" ]; then echo "ok $3"; ok=$((ok+1)); else echo "FAIL $3: got [$1]"; bad=$((bad+1)); fi; } +src(){ cat src/rt.zc src/compiler.zc; } +selfc(){ (cat tools/build.zc; printf '`'; src) | $1 > $2; } + +# bootstrap: zc0 (c) -> g0, g0 compiles compiler.zc -> g1, g1 compiles it -> g2 +gcc -O1 -w zc0.c -o $T/zc0 && gcc -O1 -w mkgenome.c -o $T/mkg || exit 1 +mkdir $T/s0 $T/s1 +cp core.c io_linux.c $T/s0/; cp core.c io_linux.c $T/s1/ +src | $T/zc0 > $T/s0/genome.h || exit 1 +gcc -O2 -w -DJTYPE=int $T/s0/core.c $T/s0/io_linux.c -o $T/zy0 +selfc $T/zy0 $T/g1.bin; $T/mkg < $T/g1.bin > $T/s1/genome.h +gcc -O2 -w -DJTYPE=int $T/s1/core.c $T/s1/io_linux.c -o $T/zy1 +selfc $T/zy1 $T/g2.bin +cmp -s $T/g1.bin $T/g2.bin && chk 1 1 "fixpoint: the compiler compiles itself to the same $(($(stat -c %s $T/g1.bin) / 4)) words" || chk 0 1 "fixpoint" +cmp -s $T/s1/genome.h genome.h && chk 1 1 "genome.h is up to date" || chk 0 1 "genome.h is stale (cp the bootstrap output over it)" + +run(){ # $1 = vm command, $2 = label + local vm="$1" l="$2" + chk "$($vm < examples/hello.zc)" "hello, world!" "$l hello" + chk "$($vm < examples/fact.zc | tr '\n' '/')" "1101110101111100000000/3628800/" "$l factorial" + chk "$( (cat examples/echo.zc; printf '`abc\n') | $vm)" "abc" "$l echo after the backtick" + chk "$($vm < examples/selfpatch.zc)" "ABC" "$l self-patching code" + chk "$($vm < examples/lists.zc | tr '\n' '/')" "[0 1 4 9 16 25]/live: 7/after the block: 0/" "$l ownership frees everything" + chk "$( (cat examples/repl.zc; printf '`fn sq(x) { return x * x; }`putn(sq(7)); putc(10);`puts("hi\\n");') | $vm | tr '\n' '/')" "49/hi/" "$l repl on the resident compiler" + chk "$($vm < examples/typed.zc | tr '\n' '/')" "last: 4/point is 2 words: x int, y int/vec<*point> is 3 words: len int, cap int, items **point/push is bool(*vec<T>, T.d)/the heap says v is a vec<T>, and v.items[0] is a point/" "$l typed example" + chk "$($vm < examples/wiring.zc)" "16 1234 25 4/9" "$l enhancement example" + chk "$($vm < tests/basics.zc | tr '\n' '/')" "285 610 42 512/hey 65 -3 -2 1024 -8/12456/757/9 100-101/5/ok/" "$l language basics" + chk "$($vm < tests/umd.zc)" "100 6 0 15 99 5 5" "$l u m d lifetimes" + chk "$($vm < tests/gc.zc)" "1000 1 900 1 199900" "$l mark-sweep collector" + chk "$($vm < tests/meta.zc | tr '\n' '/')" "1024 19/unless ok/rrr/15 42/7/42/7/144/" "$l parse words, quote, eval, load, operator tables" + chk "$($vm < tests/misc.zc | tr '\n' '/')" "45/54321/ok/" "$l compile-time eval, patched mnemonics, unchecked" + chk "$($vm < tests/types.zc | tr '\n' '/')" "12 5 2 15 56 42 7 14 3/rect *rect *list<int> *list<T>.u(int) T(*list<T>) fn(word.d)/a:point@0 b:point@2 tag:int@4 /point 1 1/" "$l types, generics, reflection" + chk "$($vm < tests/typeok.zc)" "14" "$l a program the typechecker accepts" + chk "$($vm < tests/typeoff.zc)" "6" "$l the typechecker is off by default" + chk "$($vm < tests/enhance.zc)" "100 0 343 3,2 5 -2 0" "$l virtual enhancements" + chk "$($vm < tests/joins.zc)" "0 0 5 80 8 3 9 0" "$l joins free what one path gave away; switch, ?:, no prototypes" + chk "$($vm < tests/buddy.zc)" "131072 262144 1 0" "$l buddy allocator merges freed blocks" + chk "$($vm < tests/borrowmove.zc)" "6" "$l storing into a borrowed object moves it" + chk "$($vm < tests/manyerrors.zc | tr '\n' '/')" "zc: line 3: expected an expression/zc: line 4: x: m object is never used/zc: line 5: type error: initializer: expected *char, got int/zc: line 6: expected ;/zc: 4 errors/" "$l several errors in one run" + chk "$($vm < tests/overflow_return.zc 2>&1)" "zy: return stack overflow" "$l return stack overflow is caught" + chk "$($vm < tests/overflow_data.zc 2>&1)" "zy: data stack overflow" "$l data stack overflow is caught" + chk "$($vm < tests/overflow_frame.zc 2>&1)" "zy: frame stack overflow" "$l frame stack overflow is caught" + chk "$($vm < examples/mandel.zc 2>&1 | md5sum | cut -c1-32)" "f41aecbf2c844168050413cfa832db0e" "$l example: mandelbrot with a fixed-point enhancement" + chk "$($vm < examples/bf.zc 2>&1 | md5sum | cut -c1-32)" "223570983752b17f7ece32e93d5e19e4" "$l example: brainfuck compiled at runtime" + chk "$($vm < examples/dump.zc 2>&1 | md5sum | cut -c1-32)" "757774b00f6b3cd0bfbcba66448a8619" "$l example: struct printer through reflection" + chk "$($vm < examples/tree.zc 2>&1 | md5sum | cut -c1-32)" "b86a2e4e9e31acc294a4ddf86be863f2" "$l example: owning tree frees itself" + chk "$($vm < examples/lang.zc 2>&1 | md5sum | cut -c1-32)" "aa1a18c78b5200129c7c2b315f163d28" "$l example: pipe operator, unless, assert, times" + chk "$($vm < examples/staged.zc 2>&1 | md5sum | cut -c1-32)" "6f790a125c48b0cc7a897cee73ee5627" "$l example: staged code compiled while running" + chk "$($vm < examples/quine.zc 2>&1 | md5sum | cut -c1-32)" "c868ecb9dd7b05224a1bd8a4c32ae788" "$l example: quine" + chk "$($vm < examples/primes.zc 2>&1 | md5sum | cut -c1-32)" "814faffc70dad0ae520c0671c33e73d4" "$l example: o3 prime sieve" + chk "$($vm < examples/life.zc 2>&1 | md5sum | cut -c1-32)" "aefb036b6f9ad1dadfc3e6bb47a6885d" "$l example: game of life" + chk "$($vm < tests/arrays.zc | tr '\n' '/')" "100 128 9801 9801 99 3 4 12 19 8 19 28/0/" "$l growable and fixed arrays" + chk "$($vm < tests/o3.zc)" "3142 42 43 9 57 98781 520625 10192 -18782 1152" "$l o3 regions: loops, calls, recursion, switch, arrays, more vars than registers" + chk "$($vm < tests/o3scopes.zc)" "116" "$l o3 registers shared by scopes, cached fixed arrays" + chk "$($vm < tests/o3fat.zc)" "node node 3 box node [0]int" "$l o3 data gets fattened on the way out" + chk "$($vm < tests/o3_bounds.zc 2>&1)" "zy: index 7 out of range (length 5)" "$l o3 bounds check" + local r; r=$(tests/runerr.sh "$vm" tests/errors | tail -1) + chk "$r" "rejected: $(ls tests/errors/*.zc | wc -l) passed, 0 failed" "$l analyzer rejects every bad program" + r=$(tests/runerr.sh "$vm" tests/typeerrors | tail -1) + chk "$r" "rejected: $(ls tests/typeerrors/*.zc | wc -l) passed, 0 failed" "$l typechecker rejects every bad program" + r=$(tests/runerr.sh "$vm" tests/langerrors | tail -1) + chk "$r" "rejected: $(ls tests/langerrors/*.zc | wc -l) passed, 0 failed" "$l o3 and array misuse is rejected" +} +gcc -O2 -w -DJTYPE=int core.c io_linux.c -o $T/zy +run $T/zy "interp" +chk "$(ZYTRACE=1 $T/zy < tests/o3.zc 2>&1 | grep -c 'micro-ops$')" "8" "every o3 region lifts" +if command -v aarch64-linux-gnu-gcc >/dev/null && command -v qemu-aarch64 >/dev/null; then + aarch64-linux-gnu-gcc -O2 -w -DJTYPE=int -static core.c io_linux.c -o $T/zyj || exit 1 + printf '#!/bin/sh\nexec qemu-aarch64 %s "$@"\n' $T/zyj > $T/jit; chmod +x $T/jit + run $T/jit "jit" + chk "$(ZYTRACE=1 $T/jit < tests/o3.zc 2>&1 | grep -c 'bytes of arm64')" "8" "jit compiles every o3 region to arm64" + selfc $T/jit $T/gj.bin; cmp -s $T/g1.bin $T/gj.bin && chk 1 1 "jit self-compile matches" || chk 0 1 "jit self-compile matches" +else echo "skip jit (no aarch64 toolchain or qemu)"; fi +if command -v llvm-config >/dev/null; then + gcc -O2 -w -DJTYPE=int -DZYLLVM $(llvm-config --cflags) core.c io_linux.c -o $T/zyl $(llvm-config --ldflags --libs) || exit 1 + run $T/zyl "llvm" + chk "$(ZYTRACE=1 $T/zyl < tests/o3.zc 2>&1 | grep -c 'compiled by llvm')" "8" "llvm compiles every o3 region" + printf '#!/bin/sh\nZYHOT=1 exec %s "$@"\n' $T/zyl > $T/llall; chmod +x $T/llall + chk "$($T/llall < tests/types.zc | md5sum)" "$($T/zy < tests/types.zc | md5sum)" "llvm compiling every block agrees" + selfc $T/zyl $T/gl.bin; cmp -s $T/g1.bin $T/gl.bin && chk 1 1 "llvm self-compile matches" || chk 0 1 "llvm self-compile matches" +else echo "skip llvm (no llvm-config)"; fi +echo "$ok passed, $bad failed"; [ $bad = 0 ] |
