aboutsummaryrefslogtreecommitdiff
path: root/tests/test_win.ps1
diff options
context:
space:
mode:
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 {