|
- # E02-S01: build the source-reader test PRG and a fresh D81 holding it plus
- # generated PETSCII fixtures. Writes build/source-test/expected.json with the
- # results the host computes independently of the C128 code.
- [CmdletBinding()]
- param()
-
- $ErrorActionPreference = "Stop"
- $project = Split-Path $PSScriptRoot -Parent
- Import-Module (Join-Path $PSScriptRoot "lib\Nova128Test.psm1") -Force
- $out = Join-Path $project "build\source-test"
- New-Item -ItemType Directory -Force -Path $out | Out-Null
-
- $link = Invoke-Nova128Link -Name "source-test" -BuildDir $out `
- -Config (Join-Path $project "cfg\compiler.cfg") -Sources @(
- (Join-Path $project "src\compiler\mmu.s"),
- (Join-Path $project "src\compiler\diskio.s"),
- (Join-Path $project "src\compiler\source.s"),
- (Join-Path $project "tests\source\source-test.s"))
- if ((Get-Nova128Label $link.Labels "test_entry") -ne 0x1C0D) { throw "test_entry is not at `$1C0D" }
-
- # ---------------------------------------------------------------- fixtures
- function Get-Lines([byte[]]$bytes) {
- # Split exactly as src_next_line does: $0D ends a line; trailing bytes
- # without $0D form a last line.
- $lines = New-Object System.Collections.Generic.List[byte[]]
- $start = 0
- for ($i = 0; $i -lt $bytes.Length; $i++) {
- if ($bytes[$i] -eq 13) {
- if ($i -gt $start) { $lines.Add([byte[]]$bytes[$start..($i - 1)]) }
- else { $lines.Add([byte[]]@()) }
- $start = $i + 1
- }
- }
- if ($start -lt $bytes.Length) { $lines.Add([byte[]]$bytes[$start..($bytes.Length - 1)]) }
- return ,$lines
- }
-
- function Get-Fletcher([byte[]]$bytes) {
- $s1 = 0; $s2 = 0
- foreach ($line in (Get-Lines $bytes)) {
- foreach ($b in (@($line) + 13)) {
- $s1 = ($s1 + $b) % 255
- $s2 = ($s2 + $s1) % 255
- }
- }
- return @($s1, $s2)
- }
-
- function New-Line([int]$length, [int]$seed) {
- # Mixed case so both PETSCII letter ranges appear.
- $alphabet = "abcdefghijKLMNOPQRST0123456789 =+()"
- $chars = for ($i = 0; $i -lt $length; $i++) { $alphabet[($i + $seed) % $alphabet.Length] }
- return (-join $chars)
- }
-
- $fixtures = [ordered]@{}
- $decls = ConvertTo-Nova128Petscii (Get-Content -Raw (Join-Path $project "tests\grammar\accepted\decls.n8"))
- if ($decls[-1] -ne 13) { throw "decls.n8 should end with a newline" }
- $fixtures["decls.n8"] = $decls
- $fixtures["nofinal.n8"] = [byte[]]$decls[0..($decls.Length - 2)]
-
- $edge = New-Object System.Text.StringBuilder
- [void]$edge.Append((New-Line 80 0) + "`n") # exactly the line limit
- for ($i = 0; $i -lt 598; $i++) {
- $len = if ($i -lt 380) { 31 } else { 30 } # totals exactly 18,999 bytes
- [void]$edge.Append((New-Line $len $i) + "`n")
- }
- $fixtures["edge.n8"] = ConvertTo-Nova128Petscii $edge.ToString()
-
- $long = "a = 1`nb = 2`n" + (New-Line 81 3) + "`nc = 3`n"
- $fixtures["longln.n8"] = ConvertTo-Nova128Petscii $long
-
- $many = (1..600 | ForEach-Object { "x = $_" }) -join "`n"
- $fixtures["manyln.n8"] = ConvertTo-Nova128Petscii ($many + "`n")
-
- $big = (1..500 | ForEach-Object { New-Line 37 $_ }) -join "`n"
- $fixtures["big.n8"] = ConvertTo-Nova128Petscii ($big + "`n")
-
- # Boundary sanity: these are the facts the expectations below rely on.
- $edgeLines = Get-Lines $fixtures["edge.n8"]
- if ($fixtures["edge.n8"].Length -ne 18999 -or $edgeLines.Count -ne 599 -or $edgeLines[0].Length -ne 80) {
- throw "edge.n8 is not at the exact limits"
- }
- if ($fixtures["big.n8"].Length -ne 19000) { throw "big.n8 is not 19,000 bytes" }
- $hasLow = $decls | Where-Object { $_ -ge 0x41 -and $_ -le 0x5A }
- $hasHigh = $decls | Where-Object { $_ -ge 0xC1 -and $_ -le 0xDA }
- if (-not $hasLow -or -not $hasHigh) { throw "decls.n8 lacks one PETSCII letter range" }
-
- $files = @(@{ Name = "source-test"; Path = $link.Program; Type = "prg" })
- foreach ($name in $fixtures.Keys) {
- $path = Join-Path $out ($name -replace '\.n8$', '.pet')
- [IO.File]::WriteAllBytes($path, $fixtures[$name])
- $files += @{ Name = $name; Path = $path; Type = "seq" }
- }
- $disk = Join-Path $out "source-test.d81"
- New-Nova128Disk -Path $disk -Files $files
-
- # ------------------------------------------------------------ expectations
- function Ok([string]$name) {
- $b = $fixtures[$name]; $f = Get-Fletcher $b
- return [ordered]@{ name = $name; code = 0; lines = (Get-Lines $b).Count; len = $b.Length;
- s1 = $f[0]; s2 = $f[1] }
- }
- $expected = @(
- (Ok "decls.n8"),
- (Ok "nofinal.n8"),
- (Ok "edge.n8"),
- [ordered]@{ name = "longln.n8"; code = 3; line = 3; col = 81 },
- [ordered]@{ name = "manyln.n8"; code = 4; line = 600; col = 1 },
- [ordered]@{ name = "big.n8"; code = 2; line = 500; col = 38 },
- [ordered]@{ name = "missing.n8"; code = 1; dos = 62 },
- (Ok "decls.n8")
- )
- $expected | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $out "expected.json")
-
- Write-Host ("built {0}" -f $link.Program)
- Write-Host ("disk {0} ({1} fixtures)" -f $disk, $fixtures.Count)
|