diff options
Diffstat (limited to 'tests/test_win.ps1')
| -rw-r--r-- | tests/test_win.ps1 | 134 |
1 files changed, 76 insertions, 58 deletions
diff --git a/tests/test_win.ps1 b/tests/test_win.ps1 index 0edc86c..953e875 100644 --- a/tests/test_win.ps1 +++ b/tests/test_win.ps1 @@ -1,17 +1,29 @@ # TinyVM Windows test suite (PowerShell implementation of test.sh) $ErrorActionPreference = "Stop" -# detect compiler (prioritizing LLVM-MinGW with UCRT headers) +# the suite reads nothing from build\: it lays out the default map, bootstraps the +# compiler and builds every executable in its own temporary directory. the cores +# take their genome in with c23 #embed, so the compiler must be clang 19 or gcc 15. +$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", "$tempDir\probe" -Force | Out-Null +[IO.File]::WriteAllText("$tempDir\probe\probe.bin", "ab") +[IO.File]::WriteAllText("$tempDir\probe\probe.c", "static const unsigned char probe[] = {`n#embed `"probe.bin`"`n};`nint main(void) { return sizeof probe == 2 ? 0 : 1; }`n") +function Test-Embed($compiler) { + & $compiler -w "--embed-dir=$tempDir\probe" "$tempDir\probe\probe.c" -o "$tempDir\probe\probe.exe" 2>$null | Out-Null + return $LASTEXITCODE -eq 0 +} +# detect a compiler with #embed (CC first, then LLVM-MinGW with UCRT headers, then PATH) +$cc = $null +$candidates = @() +if ($env:CC) { $candidates += $env:CC } $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." +if ($llvmMinGW) { $candidates += "$($llvmMinGW[0].FullName)\clang.exe" } +$candidates += @("clang", "gcc", "$env:ProgramFiles\LLVM\bin\clang.exe") +foreach ($c in $candidates) { + if ((Get-Command $c -ErrorAction SilentlyContinue) -and (Test-Embed $c)) { $cc = $c; break } +} +if (-not $cc) { + Write-Error "No C compiler with #embed support (clang 19 or gcc 15 and later) was found." exit 1 } @@ -21,9 +33,6 @@ Write-Host "==================================================================== 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 @@ -40,41 +49,41 @@ function Report-Result($success, $name, $detail = "") { 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" + # the default map, as make writes it, and the tools built against it + & $cc -fwrapv -O2 -w src\tools\genmap.c -o "$tempDir\genmap.exe" + cmd.exe /c "`"$tempDir\genmap.exe`" --preset default --check -o `"$tempDir\map`" >nul 2>nul" + Report-Result ($LASTEXITCODE -eq 0) "genmap default preset matches the sources" + $map = "$tempDir\map" + & $cc -fwrapv -O1 -w src\tools\zc0.c -Isrc/core "-I$map" -o "$tempDir\zc0.exe" + & $cc -fwrapv -O1 -w src\tools\mkgenome.c "-I$map" -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" + cmd.exe /c "(type src\runtime\rt.zc & type src\core\core.zc & type src\compiler\compiler.zc) | `"$tempDir\zc0.exe`" > `"$tempDir\s0\g0.bin`"" + cmd.exe /c "`"$tempDir\mkgenome.exe`" < `"$tempDir\s0\g0.bin`" > `"$tempDir\s0\genome.bin`"" + & $cc -fwrapv -O2 -w -DJTYPE=int src\core\core.c src\core\io_win.c -Isrc/core "-I$map" "--embed-dir=$tempDir\s0" -o "$tempDir\zy0.exe" $bzc = [IO.File]::ReadAllText("src\tools\build.zc") $rt = [IO.File]::ReadAllText("src\runtime\rt.zc") + $core = [IO.File]::ReadAllText("src\core\core.zc") $cp = [IO.File]::ReadAllText("src\compiler\compiler.zc") - $combined = $bzc + [char]96 + $rt + $cp + $combined = $bzc + [char]96 + $rt + $core + $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" + cmd.exe /c "`"$tempDir\mkgenome.exe`" < `"$tempDir\g1.bin`" > `"$tempDir\s1\genome.bin`"" + Report-Result ($LASTEXITCODE -eq 0) "the compiler compiles its own source" - & $cc -fwrapv -O2 -w -DJTYPE=int "$tempDir\s1\core.c" "$tempDir\s1\io_win.c" -o "$tempDir\zy1.exe" + & $cc -fwrapv -O2 -w -DJTYPE=int src\core\core.c src\core\io_win.c -Isrc/core "-I$map" "--embed-dir=$tempDir\s1" -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 "build\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 --- + # --- 2. compile test executables, each carrying the fixpoint genome --- 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" + & $cc -fwrapv -O2 -w -DJTYPE=int src\core\core.c src\core\io_win.c -Isrc/core "-I$map" "--embed-dir=$tempDir\s1" -o "$tempDir\zy.exe" + & $cc -fwrapv -O2 -w src\micro\micro.c src\micro\port_win.c -Isrc/core "-I$map" "--embed-dir=$tempDir\s1" -Isrc/micro -o "$tempDir\zym.exe" # --- 3. feature tests on zy.exe --- Write-Host "`n=== 3. Running Feature Tests on VM Core (zy.exe) ===" -ForegroundColor Yellow @@ -158,7 +167,7 @@ try { $pass = 0 $fail = 0 foreach ($f in $files) { - $want = ((Get-Content $f.FullName -TotalCount 1) -replace '^// expect:\s*').Trim() + $want = ((Get-Content $f.FullName | Where-Object { $_ -match '^// expect:' } | Select-Object -First 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++ @@ -172,9 +181,6 @@ try { # --- 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" @@ -182,21 +188,28 @@ try { 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) + New-Item -ItemType Directory -Force "$lspDir" | Out-Null + # the steps of src/tools/automap.sh lsp with DOCS=1: compile once to learn the genome + # length, lay the map out for it, then again with the documentation the hovers read + function Build-LspImage($slot, $define, $out) { + if (Test-Path "$lspDir\map") { Remove-Item -Recurse -Force "$lspDir\map" } + $genomeOption = if ($slot) { "--genome $slot" } else { "" } + cmd.exe /c "`"$tempDir\genmap.exe`" --preset lsp --grow $genomeOption -o `"$lspDir\map`" >nul 2>nul" + & $cc -fwrapv -O1 -w $define src\tools\zc0.c "-I$lspDir\map" -Isrc/core -o "$lspDir\zc0.exe" + & $cc -fwrapv -O1 -w src\tools\mkgenome.c "-I$lspDir\map" -o "$lspDir\mkgenome.exe" + cmd.exe /c "(type `"$lspDir\map\rt.zc`" & type src\core\core.zc & type `"$lspDir\map\compiler.zc`" & type src\lsp\server.zc) | `"$lspDir\zc0.exe`" > `"$lspDir\raw.bin`"" + cmd.exe /c "`"$lspDir\mkgenome.exe`" < `"$lspDir\raw.bin`" > `"$lspDir\$out`"" + return [int]((Get-Item "$lspDir\$out").Length / 8) + } + # ZC0PLAIN defines nothing zc0 reads; it stands in for "no documentation" as one argument + $glen = Build-LspImage $null "-DZC0PLAIN" "image.bin" + $slot = [int]([math]::Ceiling($glen / 4096.0) * 4096) + $glen = Build-LspImage ($slot + 65536) "-DZC0DOCS" "image.bin" $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" + $final = Build-LspImage $slot "-DZC0DOCS" "lsp_genome.bin" + Report-Result ($final -eq $glen) "the LSP genome keeps its length on its sized map" + Copy-Item "$lspDir\map\memmap.h" "$lspDir\" + & $cc -fwrapv -O2 -w -DJTYPE=int -DZY_SANDBOX -DUSE_LSP_GENOME src\core\core.c src\core\io_win.c -Isrc/core "-I$lspDir" "--embed-dir=$lspDir" -o "$lspDir\zclsp.exe" Report-Result (Test-Path "$lspDir\zclsp.exe") "zclsp.exe compiled" # CLI check: a clean file @@ -209,7 +222,7 @@ try { # 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") + $hints = @("is never read", "is never reassigned; make it a const", "is a shift; write << 3", "unannotated numeric literal 1234", "new inside a loop", "stack buffer") foreach ($h in $hints) { Report-Result ($lspOpt.Contains($h)) "zclsp hint: $h" } # methods with this, and closures, check clean @@ -226,23 +239,28 @@ try { Write-Host " [SKIP] Node.js not detected in PATH, skipping lsp protocol tests." -ForegroundColor DarkYellow } - # --- 8. JavaScript / TypeScript vm runtime (build/js/tinyvm.js) --- - Write-Host "`n=== 8. JavaScript VM Runtime (node build/js/tinyvm.js) ===" -ForegroundColor Yellow + # --- 8. JavaScript / TypeScript vm runtime, built as make js builds it --- + Write-Host "`n=== 8. JavaScript VM Runtime (node tinyvm.js) ===" -ForegroundColor Yellow $nodeCmd = Get-Command node -ErrorAction SilentlyContinue - if ($nodeCmd) { - $jsHello = (node build\js\tinyvm.js examples\hello.zc 2>&1) -join "`n" + $tscCmd = Get-Command tsc -ErrorAction SilentlyContinue + if ($nodeCmd -and $tscCmd) { + $jsDir = "$tempDir\js" + node src\js\mklayout.js --map "$map\memmap.h" --out $jsDir | Out-Null + Copy-Item "$tempDir\s1\genome.bin" "$jsDir\genome.bin" + tsc src\js\tinyvm.ts --target es2020 --lib es2020,dom --module commonjs --outDir $jsDir + $jsHello = (node $jsDir\tinyvm.js examples\hello.zc 2>&1) -join "`n" Report-Result ($jsHello.Trim() -eq "hello, world!") "JS VM: hello.zc" - $jsFact = (node build\js\tinyvm.js examples\fact.zc 2>&1) -join "`n" + $jsFact = (node $jsDir\tinyvm.js examples\fact.zc 2>&1) -join "`n" Report-Result ($jsFact.Contains("3628800")) "JS VM: fact.zc" - $jsPrimes = (node build\js\tinyvm.js examples\primes.zc 2>&1) -join "`n" + $jsPrimes = (node $jsDir\tinyvm.js examples\primes.zc 2>&1) -join "`n" Report-Result ($jsPrimes.Contains("widest gap: 72")) "JS VM: primes.zc" - $jsMandel = (node build\js\tinyvm.js examples\mandel.zc 2>&1) -join "`n" + $jsMandel = (node $jsDir\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 + Write-Host " [SKIP] Node.js or tsc not detected in PATH, skipping JS tests." -ForegroundColor DarkYellow } } finally { |
