aboutsummaryrefslogtreecommitdiff
path: root/tests/test_win.ps1
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 07:28:39 +0000
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 07:28:39 +0000
commit7451eb090d890fb5ea5e4d40627a1b4df15a49de (patch)
tree357bdf4b528e860bffa688865306f656b788d2c2 /tests/test_win.ps1
parentanalyzer: close the ownership gaps that stopped the compiler compiling itself (diff)
build: embed images with #embed, keep everything generated in build/
the cores take their genome in with c23 #embed through src/core/genome.h, so images are plain little-endian word files (genome.bin) instead of generated c headers. zc0 writes that format, mkgenome checks an image against its map and shows a compiler's diagnostics when it gets them, and the javascript vm and the editor's vm host read the same files. src/tools/findcc.sh picks a compiler with #embed (clang 19 or gcc 15). zc gets an embed declaration, embed "file" as [type] name, for globals and locals: a byte string by default, char*, numbers read little-endian, and arrays of numbers. the compiler and language server carry their library and source texts through it, so embed.sh and the text it spliced into compiler.zc are gone. make writes executables to build/bin, the default map to build/core/map, the web page to build/web and the extension staging to build/vsix, and the genome now rebuilds when its sources change. the test suite lays out its own map and bootstrap and reads nothing from build/. also: rt.put_s of a byte string in zc0 images, retained function sources no longer count as live objects, a missing include no longer cascades into undefined-name errors, consecutive comment lines join into one hover paragraph, and stale test fixtures follow the include format.
Diffstat (limited to 'tests/test_win.ps1')
-rw-r--r--tests/test_win.ps1134
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 {