|
|
@@ -0,0 +1,84 @@
|
|
|
+# Pascal-S validator pilot
|
|
|
+
|
|
|
+`pascals.atg` describes Wirth Pascal-S (1976) as implemented by
|
|
|
+`PascalS0` (Turbo-Pascal batch interpreter). It was authored from the
|
|
|
+P2 pilot skeleton and corrected against some 90 oracle probes —
|
|
|
+every construct below was checked against the running interpreter
|
|
|
+(no fpc involved anywhere).
|
|
|
+
|
|
|
+## Oracle notes
|
|
|
+
|
|
|
+`psc` was built with `fpc -Mtp` from `Pascals/` plus a `/tmp`-only
|
|
|
+`TrmInOut` stub (the shipped unit needs DOS `REGISTERS`/`MsDos`;
|
|
|
+only console setup, irrelevant to parse verdicts). Behaviors the
|
|
|
+harness respects, all verified:
|
|
|
+
|
|
|
+- Verdicts come from the `.lst` listing: `******* ^ NNN` markers
|
|
|
+ (full error table printed in `PascalS0.pas:errormsg`); absence =
|
|
|
+ accept. Feeding is via `psc src.lst` args with stdin `</dev/null`
|
|
|
+ (renders blocking on `read` harmless); 15s timeout (valid programs
|
|
|
+ finish instantly).
|
|
|
+- Lowercase is accepted (Turbo scanner), so the validator uses
|
|
|
+ `IGNORE CASE` — unlike the P2 pilot.
|
|
|
+- Mandatory program heading with file list:
|
|
|
+ `program t (input, output);` (bare `program t;` is error 9).
|
|
|
+ `input`/`output` exist for `eof`/`eoln` only.
|
|
|
+
|
|
|
+Key probed Pascal-S facts: `and`/`or`/`not`/`div`/`mod` words;
|
|
|
+`if`/`while`/`repeat`/`for to/downto`/`case` (no `ELSE`, no
|
|
|
+`OTHERWISE`); `(* *)` comments that do not nest, plus `{}`;
|
|
|
+`const`/`type`/`var`/nested routines with `var` params; integer,
|
|
|
+real, char, boolean (no string/enum/subrange/pointer/set/file
|
|
|
+types); multi-dim arrays with const bounds; records without
|
|
|
+variants; `read`/`readln`/`write`/`writeln` (bare `writeln;` is
|
|
|
+legal!); write-widths; `odd`/`abs`/`ord`/`chr`; `eof`/`eoln` with
|
|
|
+mandatory file arg; unary signs only at expression start
|
|
|
+(`a + +b` is error 58, but `-a` is fine); `NOT` anywhere;
|
|
|
+single-statement branches; empty statements; char/enum-less case
|
|
|
+labels (`pnumber`/`ident`/`pstring`).
|
|
|
+
|
|
|
+Absent (all probed): labels/`goto`, `forward`, `packed`, sets,
|
|
|
+pointers (`^` is error 24), files, `with`, procedural params,
|
|
|
+`break`/`exit`/`halt`/`return`, `nil`, `_` in identifiers (error
|
|
|
+24), `//` comments, `OTHERWISE`, `max`, const expressions
|
|
|
+(`3 + 4` is error 6), multi-char const strings (error 50),
|
|
|
+`1.`/`.5` reals, `$`/`#` literals, `IN`, chained assignment,
|
|
|
+function-calls-as-statements (error 45).
|
|
|
+
|
|
|
+## Grammar notes
|
|
|
+
|
|
|
+Single-statement branches (avoids `;`-capture), `begin..end` as
|
|
|
+statements, trailing-`;`-tolerant sections/fields/case-items,
|
|
|
+order-free declaration sections, no label section at all,
|
|
|
+`EofCall` with mandatory `(file)` (which is what rejects bare
|
|
|
+`eof`), strict EOF check (patched into `Parse` by `build.sh`,
|
|
|
+which also fails on degenerate `IF/WHILE FALSE` generation).
|
|
|
+
|
|
|
+Lenient acceptances (documented, never false positives):
|
|
|
+multi-char const strings (a `pchar` token breaks V1.53
|
|
|
+determinism — probe H2 shows the oracle's error 50); bare
|
|
|
+builtin calls (`odd;` parses although only `eof`/`eoln` strictness
|
|
|
+was probed); `TYPE`-level constructs the oracle would mark
|
|
|
+semantically are out of scope for a syntax validator.
|
|
|
+
|
|
|
+## Build
|
|
|
+
|
|
|
+```sh
|
|
|
+./build.sh # -> build/PascalS (build/ is git-ignored)
|
|
|
+```
|
|
|
+
|
|
|
+Needs `CR` (Coco/R), `gm2 -fiso`, the `parser.frm`/`scanner.frm`
|
|
|
+frames and `FileIO.def/.mod` — all resolved from the environment with
|
|
|
+sensible defaults (`CRFRAMES`, `M2LIB`, `CR`, `GM2`).
|
|
|
+
|
|
|
+## Differential results (PascalS vs `psc`)
|
|
|
+
|
|
|
+Accept battery (22 cases: all statements, arrays, records,
|
|
|
+`ord`/`chr`, reals, strings, `odd`, write-widths, `eof(input)`):
|
|
|
+**0 false positives**. Broken mutants (12: truncation, bad
|
|
|
+factors, unterminated comment, `@`, missing `TO`, `ELSE`,
|
|
|
+`goto`, `_`, `1..3`, set constructor): **0 missed**, positions
|
|
|
+close. Example corpus (`Pascals/eg0`–`eg7`): agree on all 8
|
|
|
+(`eg0`/`eg1` are intentionally broken and both sides reject them).
|
|
|
+`tests/deep.pas` (nested routines with `var` params, records,
|
|
|
+all statements, reals): clean on both sides.
|