aboutsummaryrefslogtreecommitdiff
path: root/tests/test_win.ps1
diff options
context:
space:
mode:
authorGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
committerGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
commitecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch)
tree70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /tests/test_win.ps1
a
Diffstat (limited to 'tests/test_win.ps1')
-rw-r--r--tests/test_win.ps1258
1 files changed, 258 insertions, 0 deletions
diff --git a/tests/test_win.ps1 b/tests/test_win.ps1
new file mode 100644
index 0000000..aee60e8
--- /dev/null
+++ b/tests/test_win.ps1
@@ -0,0 +1,258 @@
+# TinyVM Windows test suite (PowerShell implementation of test.sh)
+$ErrorActionPreference = "Stop"
+
+# detect compiler (prioritizing LLVM-MinGW with UCRT headers)
+$llvmMinGW = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages\MartinStorsjo.LLVM-MinGW*\llvm-mingw*\bin" -ErrorAction SilentlyContinue
+if ($llvmMinGW) {
+ $env:Path = "$($llvmMinGW[0].FullName);$env:Path"
+ $cc = "clang"
+} elseif (Get-Command clang -ErrorAction SilentlyContinue) {
+ $cc = "clang"
+} elseif (Get-Command gcc -ErrorAction SilentlyContinue) {
+ $cc = "gcc"
+} else {
+ Write-Error "No C compiler (clang or gcc) found in PATH."
+ exit 1
+}
+
+Write-Host "===============================================================================" -ForegroundColor Cyan
+Write-Host " TinyVM Windows Automated Test Suite " -ForegroundColor Cyan
+Write-Host "===============================================================================" -ForegroundColor Cyan
+Write-Host "Compiler: $cc"
+Write-Host ""
+
+$tempDir = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "tinyvm_test_" + [System.Guid]::NewGuid().ToString("N"))
+New-Item -ItemType Directory -Path "$tempDir\s0", "$tempDir\s1" -Force | Out-Null
+
+$totalPassed = 0
+$totalFailed = 0
+
+function Report-Result($success, $name, $detail = "") {
+ if ($success) {
+ $script:totalPassed++
+ Write-Host " [OK] $name" -ForegroundColor Green
+ } else {
+ $script:totalFailed++
+ Write-Host " [FAIL] $name $detail" -ForegroundColor Red
+ }
+}
+
+try {
+ # --- 1. bootstrap & fixpoint ---
+ Write-Host "=== 1. Bootstrap and Fixpoint Verification ===" -ForegroundColor Yellow
+ & $cc -fwrapv -O1 -w src\tools\zc0.c -Isrc/core -o "$tempDir\zc0.exe"
+ & $cc -fwrapv -O1 -w src\tools\mkgenome.c -Isrc/core -o "$tempDir\mkgenome.exe"
+
+ Copy-Item src\core\core.c, src\core\io_win.c, src\core\memmap.h, src\core\fops.h, src\core\bops.h, src\core\stack.h -Destination "$tempDir\s0"
+ Copy-Item src\core\core.c, src\core\io_win.c, src\core\memmap.h, src\core\fops.h, src\core\bops.h, src\core\stack.h -Destination "$tempDir\s1"
+
+ cmd.exe /c "(type src\runtime\rt.zc & type src\compiler\compiler.zc) | $tempDir\zc0.exe > $tempDir\s0\genome.h"
+ & $cc -fwrapv -O2 -w -DJTYPE=int "$tempDir\s0\core.c" "$tempDir\s0\io_win.c" -o "$tempDir\zy0.exe"
+
+ $bzc = [IO.File]::ReadAllText("src\tools\build.zc")
+ $rt = [IO.File]::ReadAllText("src\runtime\rt.zc")
+ $cp = [IO.File]::ReadAllText("src\compiler\compiler.zc")
+ $combined = $bzc + [char]96 + $rt + $cp
+ [IO.File]::WriteAllBytes("$tempDir\in.tmp", [Text.Encoding]::ASCII.GetBytes($combined))
+
+ $p1 = Start-Process -FilePath "$tempDir\zy0.exe" -NoNewWindow -PassThru -RedirectStandardInput "$tempDir\in.tmp" -RedirectStandardOutput "$tempDir\g1.bin" -Wait
+ cmd.exe /c "$tempDir\mkgenome.exe < $tempDir\g1.bin > $tempDir\s1\genome.h"
+
+ & $cc -fwrapv -O2 -w -DJTYPE=int "$tempDir\s1\core.c" "$tempDir\s1\io_win.c" -o "$tempDir\zy1.exe"
+ $p2 = Start-Process -FilePath "$tempDir\zy1.exe" -NoNewWindow -PassThru -RedirectStandardInput "$tempDir\in.tmp" -RedirectStandardOutput "$tempDir\g2.bin" -Wait
+
+ $g1 = [IO.File]::ReadAllBytes("$tempDir\g1.bin")
+ $g2 = [IO.File]::ReadAllBytes("$tempDir\g2.bin")
+ $isFixpoint = [System.Linq.Enumerable]::SequenceEqual($g1, $g2)
+ Report-Result $isFixpoint "Fixpoint: compiler compiles itself to identical $($g1.Length / 8) words"
+
+ $ghRepo = (Get-FileHash "src\core\genome.h").Hash
+ $ghGen = (Get-FileHash "$tempDir\s1\genome.h").Hash
+ Report-Result ($ghRepo -eq $ghGen) "genome.h is up to date"
+
+ # --- 2. compile test executables ---
+ Write-Host "`n=== 2. Compiling Test Executables ===" -ForegroundColor Yellow
+ & $cc -fwrapv -O2 -w -DJTYPE=int src\core\core.c src\core\io_win.c -Isrc/core -o "$tempDir\zy.exe"
+ & $cc -fwrapv -O2 -w src\micro\micro.c src\micro\port_win.c -Isrc/core -Isrc/micro -o "$tempDir\zym.exe"
+ & $cc -fwrapv -O2 -w src\tools\genmap.c -Isrc/core -o "$tempDir\genmap.exe"
+
+ # --- 3. feature tests on zy.exe ---
+ Write-Host "`n=== 3. Running Feature Tests on VM Core (zy.exe) ===" -ForegroundColor Yellow
+ $featureTests = @(
+ @{ name = "hello"; file = "examples\hello.zc"; expect = "hello, world!" },
+ @{ name = "factorial"; file = "examples\fact.zc"; expect = "1101110101111100000000`n3628800`n" },
+ @{ name = "self-patching code"; file = "examples\selfpatch.zc"; expect = "ABC" },
+ @{ name = "ownership frees everything"; file = "examples\lists.zc"; expect = "[0 1 4 9 16 25]`nlive: 7`nafter the block: 0`n" },
+ @{ name = "typed example"; file = "examples\typed.zc"; expect = "last: 4`npoint is 2 words: x int, y int`nvec<point*> is 3 words: len int, cap int, items point**`npush is bool(vec<T>*, T.d)`nthe heap says v is a vec<point*>, and v.items[0] is a point`n" },
+ @{ name = "enhancement example"; file = "examples\wiring.zc"; expect = "16 1234 25 4/9" },
+ @{ name = "o3 prime sieve"; file = "examples\primes.zc"; expect = "widest gap: 72, after 31397" },
+ @{ name = "language basics"; file = "tests\programs\basics.zc"; expect = "285 610 42 512`nhey 65 -3 -2 1024 -8`n12456`n757`n9 100-101`n5`nok`n" },
+ @{ name = "u m d lifetimes"; file = "tests\programs\umd.zc"; expect = "100 6 0 15 99 5 5" },
+ @{ name = "u, m and d names"; file = "tests\programs\names.zc"; expect = "12 1 8" },
+ @{ name = "mark-sweep collector"; file = "tests\programs\gc.zc"; expect = "1000 1 900 1 199900" },
+ @{ name = "parse words and operator tables"; file = "tests\programs\meta.zc"; expect = "1024 19`nunless ok`nrrr`n15 42`n7`n42`n7`n144`n" },
+ @{ name = "compile-time eval and mnemonics"; file = "tests\programs\misc.zc"; expect = "45`n54321`nok`n" },
+ @{ name = "types, generics, reflection"; file = "tests\programs\types.zc"; expect = "12 5 2 15 56 42 7 14 3`nrect rect* list<int>* list<T>*.u(int) T(list<T>*) fn(word.d)`na:point@0 b:point@2 tag:int@4 `npoint 1 1`n" },
+ @{ name = "typechecker accepts valid program"; file = "tests\programs\typeok.zc"; expect = "14" },
+ @{ name = "typechecker off by default"; file = "tests\programs\typeoff.zc"; expect = "6" },
+ @{ name = "virtual enhancements"; file = "tests\programs\enhance.zc"; expect = "100 0 343 3,2 5 -2 0" },
+ @{ name = "joins and paths"; file = "tests\programs\joins.zc"; expect = "0 0 5 80 8 3 9 0" },
+ @{ name = "buddy allocator"; file = "tests\programs\buddy.zc"; expect = "131072 262144 1 0" },
+ @{ name = "borrow move"; file = "tests\programs\borrowmove.zc"; expect = "6" },
+ @{ name = "alias tracking"; file = "tests\programs\alias.zc"; expect = "11 22 4 8" },
+ @{ name = "quarantine stale alias"; file = "tests\programs\quarantine.zc"; expect = "0 1234" },
+ @{ name = "recycle dropped block"; file = "tests\programs\recycle.zc"; expect = "1 0 1" },
+ @{ name = "roots collector mark"; file = "tests\programs\roots.zc"; expect = "1 0" },
+ @{ name = "bump arena"; file = "tests\programs\arena.zc"; expect = "4 7 0 1 1" },
+ @{ name = "do/while, enum, cast"; file = "tests\programs\csyn.zc"; expect = "13 0 5 6 0" },
+ @{ name = "include and string helpers"; file = "tests\programs\use_std.zc"; expect = "42 -7 1" },
+ @{ name = "stdlib arena and byte buffer"; file = "tests\programs\stdbuf.zc"; expect = "4 1 266 8" },
+ @{ name = "64-bit shifts"; file = "tests\programs\wide.zc"; expect = "1099511627776 1 1 1 -1" },
+ @{ name = "floating point"; file = "tests\programs\float.zc"; expect = "4.000000 4.500000 3.000000 2.500000 2.500000 0.001500 0.100000 -0.125000 inf -inf nan 1 1 1 0 0 3 -3 3.000000 -2.000000 2" },
+ @{ name = "negative zero is false"; file = "tests\programs\ftruth.zc"; expect = "00111000110107" },
+ @{ name = "float types"; file = "tests\programs\ftype.zc"; expect = "3.500000 10.500000 3.500000 4.250000 5.250000 4.250000 6.500000 2 4 4.250000 8.500000 1 4" },
+ @{ name = "o3 lifts float ops"; file = "tests\programs\fo3.zc"; expect = "5997 5997 4.000000 nan 0 3.250000 1 0 0" },
+ @{ name = "float formatting"; file = "tests\programs\ftext.zc"; expect = "1e+308 1e-10 -0 inf -inf nan 0.1 1.50 1.250e+0 100000000000000000000.000000 1e+40 1111111111" },
+ @{ name = "byte addressing"; file = "tests\programs\bytes.zc"; expect = "17 34 43981 16909060 1 205 171 -3674937295934316015 1108152156331 0 0 30768`nABC" },
+ @{ name = "byte strings"; file = "tests\programs\strings.zc"; expect = "hi! 3 3 104 i! 1 1 1 -42 42 -42 11 1 -9223372036854775808 0 1 3 10 1 1 1 W ab" },
+ @{ name = "shared cons cells"; file = "tests\programs\share.zc"; expect = "1 2 1 4 1 1 1 1 42 1 1 1 6 0" },
+ @{ name = "memdebug shared cell"; file = "tests\programs\share_dbg.zc"; expect = "7 1" },
+ @{ name = "growable and fixed arrays"; file = "tests\programs\arrays.zc"; expect = "100 128 9801 9801 99 3 4 12 19 8 19 28`n0`n" },
+ @{ name = "o3 regions"; file = "tests\programs\o3.zc"; expect = "3142 42 43 9 57 98781 520625 10192 -18782 1152" },
+ @{ name = "o3 scopes"; file = "tests\programs\o3scopes.zc"; expect = "116" },
+ @{ name = "o3 fat data"; file = "tests\programs\o3fat.zc"; expect = "node node 3 box node [0]int" },
+ @{ name = "o3 direct calls"; file = "tests\programs\o3call.zc"; expect = "0 0 4 23 55 node" },
+ @{ name = "bounds check optimization"; file = "tests\programs\bounds.zc"; expect = "55 55 8" }
+ )
+
+ foreach ($t in $featureTests) {
+ $out = (cmd.exe /c "$tempDir\zy.exe < $($t.file) 2>&1") -join "`n"
+ $normOut = $out.Trim().Replace("`r`n", "`n")
+ $normExp = $t.expect.Trim().Replace("`r`n", "`n")
+ $match = ($normOut -eq $normExp) -or ($normOut.Contains($normExp))
+ Report-Result $match $t.name
+ }
+
+ # --- 4. microcore tests ---
+ Write-Host "`n=== 4. Running Microcore Tests (zym.exe) ===" -ForegroundColor Yellow
+ $microTests = @(
+ @{ name = "microcore: hello"; file = "examples\hello.zc"; expect = "hello, world!" },
+ @{ name = "microcore: factorial"; file = "examples\fact.zc"; expect = "3628800" },
+ @{ name = "microcore: primes"; file = "examples\primes.zc"; expect = "widest gap: 72" },
+ @{ name = "microcore: basics"; file = "tests\programs\basics.zc"; expect = "ok" },
+ @{ name = "microcore: umd"; file = "tests\programs\umd.zc"; expect = "100 6 0 15 99 5 5" }
+ )
+ foreach ($t in $microTests) {
+ $out = (cmd.exe /c "$tempDir\zym.exe < $($t.file) 2>&1") -join "`n"
+ $normOut = $out.Trim().Replace("`r`n", "`n")
+ $match = $normOut.Contains($t.expect)
+ Report-Result $match $t.name
+ }
+
+ # --- 5. error rejection suites ---
+ Write-Host "`n=== 5. Error Rejection Suites ===" -ForegroundColor Yellow
+ foreach ($suite in @(@{ dir = "tests\errors"; name = "Lifetime errors" },
+ @{ dir = "tests\typeerrors"; name = "Typechecker errors" },
+ @{ dir = "tests\langerrors"; name = "Language/o3 errors" })) {
+ $files = Get-ChildItem "$($suite.dir)\*.zc"
+ $pass = 0
+ $fail = 0
+ foreach ($f in $files) {
+ $want = ((Get-Content $f.FullName -TotalCount 1) -replace '^// expect:\s*').Trim()
+ $got = (Get-Content $f.FullName -Raw | & "$tempDir\zy.exe" 2>&1 | Select-Object -First 1)
+ if ($got -and $got.Contains($want)) {
+ $pass++
+ } else {
+ $fail++
+ Write-Host " Failed $($f.Name): got [$got], want [$want]" -ForegroundColor DarkYellow
+ }
+ }
+ Report-Result ($fail -eq 0) "$($suite.name): $pass rejected as expected"
+ }
+
+ # --- 6. tool verification ---
+ Write-Host "`n=== 6. Memory Map Tool Verification (genmap.exe) ===" -ForegroundColor Yellow
+ cmd.exe /c "`"$tempDir\genmap.exe`" --preset default --check >nul 2>nul"
+ Report-Result ($LASTEXITCODE -eq 0) "genmap default preset check passed"
+
+ cmd.exe /c "`"$tempDir\genmap.exe`" --preset small -o `"$tempDir\small`" >nul 2>nul"
+ Report-Result ($LASTEXITCODE -eq 0) "genmap small preset generated"
+
+ # --- 7. ZC language server (zclsp.exe) ---
+ Write-Host "`n=== 7. ZC Language Server (zclsp.exe) ===" -ForegroundColor Yellow
+ # the server is the real compiler in check mode plus src\lsp\server.zc, on its own map
+ $lspDir = "$tempDir\lsp"
+ New-Item -ItemType Directory -Force "$lspDir\src" | Out-Null
+ # two passes: compile once to learn the genome length, then lay the map out again for that length
+ $lspSrc = "(type `"$lspDir\map\rt.zc`" & type `"$lspDir\map\compiler.zc`" & type src\lsp\server.zc)"
+ cmd.exe /c "`"$tempDir\genmap.exe`" --preset lsp --grow -o `"$lspDir\map`" >nul 2>nul"
+ & $cc -fwrapv -O1 -w src\tools\zc0.c "-I$lspDir\map" -Isrc/core -o "$lspDir\zc0.exe"
+ cmd.exe /c "$lspSrc | `"$lspDir\zc0.exe`" > `"$lspDir\genome.h`""
+ $glen = [int]((Select-String -Path "$lspDir\genome.h" -Pattern '#define\s+GLEN\s+(\d+)' | Select-Object -First 1).Matches[0].Groups[1].Value)
+ $slot = [int]([math]::Ceiling($glen / 4096.0) * 4096)
+ Remove-Item -Recurse -Force "$lspDir\map"
+ cmd.exe /c "`"$tempDir\genmap.exe`" --preset lsp --grow --genome $slot -o `"$lspDir\map`" >nul 2>nul"
+ & $cc -fwrapv -O1 -w src\tools\zc0.c "-I$lspDir\map" -Isrc/core -o "$lspDir\zc0.exe"
+ cmd.exe /c "$lspSrc | `"$lspDir\zc0.exe`" > `"$lspDir\src\lsp_genome.h`""
+ foreach ($f in 'core.c','io_win.c','fops.h','bops.h','stack.h') { Copy-Item "src\core\$f" "$lspDir\src\" }
+ Copy-Item "$lspDir\map\memmap.h" "$lspDir\src\"
+ & $cc -fwrapv -O2 -w -DJTYPE=int -DUSE_LSP_GENOME "-I$lspDir\src" "$lspDir\src\core.c" "$lspDir\src\io_win.c" -o "$lspDir\zclsp.exe"
+ Report-Result (Test-Path "$lspDir\zclsp.exe") "zclsp.exe compiled"
+
+ # CLI check: a clean file
+ $lspHello = (cmd.exe /c "`"$lspDir\zclsp.exe`" < examples\hello.zc 2>&1") -join "`n"
+ Report-Result ($lspHello.Trim() -eq "no errors") "zclsp: a clean program (hello.zc)"
+
+ # CLI check: the compiler's own message
+ $lspErr = (cmd.exe /c "`"$lspDir\zclsp.exe`" < tests\errors\back_to_m.zc 2>&1") -join "`n"
+ Report-Result ($lspErr.Contains("can't be recast back to m")) "zclsp: lifetime error detection (back_to_m.zc)"
+
+ # CLI check: the compiler's optimization hints
+ $lspOpt = (cmd.exe /c "`"$lspDir\zclsp.exe`" < examples\opt_test.zc 2>&1") -join "`n"
+ $hints = @("is never read", "is never reassigned; make it a const", "is a shift; write << 3", "the number 1234 has no name", "new inside a loop", "stack buffer", "handed off once")
+ foreach ($h in $hints) { Report-Result ($lspOpt.Contains($h)) "zclsp hint: $h" }
+
+ # methods with this, and closures, check clean
+ $lspStruct = (cmd.exe /c "`"$lspDir\zclsp.exe`" < examples\struct_closure_opt.zc 2>&1") -join "`n"
+ Report-Result (-not $lspStruct.Contains(": error:")) "zclsp: methods and closures check clean"
+
+ # protocol and corpus tests
+ if (Get-Command node -ErrorAction SilentlyContinue) {
+ $lspOut = (node tests\drivers\lsp_test.js "$lspDir\zclsp.exe" 2>&1) -join "`n"
+ $lspCode = $LASTEXITCODE
+ Report-Result ($lspCode -eq 0) "zclsp: protocol and corpus tests"
+ if ($lspCode -ne 0) { Write-Host $lspOut }
+ } else {
+ Write-Host " [SKIP] Node.js not detected in PATH, skipping lsp protocol tests." -ForegroundColor DarkYellow
+ }
+
+ # --- 8. JavaScript / TypeScript vm runtime (src/js/tinyvm.js) ---
+ Write-Host "`n=== 8. JavaScript VM Runtime (node src/js/tinyvm.js) ===" -ForegroundColor Yellow
+ $nodeCmd = Get-Command node -ErrorAction SilentlyContinue
+ if ($nodeCmd) {
+ $jsHello = (node src\js\tinyvm.js examples\hello.zc 2>&1) -join "`n"
+ Report-Result ($jsHello.Trim() -eq "hello, world!") "JS VM: hello.zc"
+
+ $jsFact = (node src\js\tinyvm.js examples\fact.zc 2>&1) -join "`n"
+ Report-Result ($jsFact.Contains("3628800")) "JS VM: fact.zc"
+
+ $jsPrimes = (node src\js\tinyvm.js examples\primes.zc 2>&1) -join "`n"
+ Report-Result ($jsPrimes.Contains("widest gap: 72")) "JS VM: primes.zc"
+
+ $jsMandel = (node src\js\tinyvm.js examples\mandel.zc 2>&1) -join "`n"
+ Report-Result ($jsMandel.Contains("*") -or $jsMandel.Contains(".")) "JS VM: mandel.zc (custom fmul enhancement)"
+ } else {
+ Write-Host " [SKIP] Node.js not detected in PATH, skipping JS tests." -ForegroundColor DarkYellow
+ }
+}
+finally {
+ Start-Sleep -Milliseconds 200
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $tempDir
+}
+
+Write-Host "`n===============================================================================" -ForegroundColor Cyan
+$summaryColor = if ($totalFailed -eq 0) { "Green" } else { "Red" }
+Write-Host "Test Results: $totalPassed passed, $totalFailed failed" -ForegroundColor $summaryColor
+Write-Host "===============================================================================" -ForegroundColor Cyan
+
+if ($totalFailed -gt 0) { exit 1 } else { exit 0 }