|
|
@@ -0,0 +1,90 @@
|
|
|
+# P2 Pascal validator pilot
|
|
|
+
|
|
|
+`p2_pascal.atg` describes Wirth/Ammann Pascal-P2 (1972-73) as
|
|
|
+implemented by `pcom`. It was authored from the P4 pilot skeleton and
|
|
|
+corrected against some 60 oracle probes — every construct below was
|
|
|
+checked against the real compiler, whose parser (`pcomp.pas`) is the
|
|
|
+ground truth for the language. (The `Grammars/P2/p2_pascal.atg` file in
|
|
|
+the reference collection is a mislabeled Oberon grammar, unrelated.)
|
|
|
+
|
|
|
+## Oracle notes
|
|
|
+
|
|
|
+`pcom` was built with `fpc -Miso` from the ISO-7185-modified sources
|
|
|
+(`Pascal-P2-master/source/`), needing a one-character fix in a
|
|
|
+`/tmp` copy (duplicate `'1'` in an identifier-scan set that fpc
|
|
|
+rejects). Behaviors the harness must respect, all verified:
|
|
|
+
|
|
|
+- **Uppercase only** (CDC charset): lowercase never assigns the
|
|
|
+ scanner symbol and the compiler ping-pongs forever. Test sources
|
|
|
+ are uppercase; the validator is case-sensitive and rejects
|
|
|
+ lowercase cleanly (oracle-consistent, never a false positive).
|
|
|
+- **Trailing newline required**: files without one spin at EOF
|
|
|
+ (`EOF ENCOUNTERED` flood). The harness appends `\n`.
|
|
|
+- **Spin on sync-loss**: illegal characters (`_ & { @ #` → error
|
|
|
+ 399) and some shapes never recover — the compiler loops instead of
|
|
|
+ listing. Harness rule: timeout (10s; valid programs finish
|
|
|
+ instantly) counts as oracle-reject. Every accept-case was verified
|
|
|
+ to terminate.
|
|
|
+- Verdicts: `**** ^NNN` markers in the listing (`NNN` is Wirth's
|
|
|
+ error number); absence = accept. Semantic markers (undeclared
|
|
|
+ identifiers etc.) also count as reject, so the battery uses only
|
|
|
+ well-formed programs.
|
|
|
+- `PROGRAM T; BEGIN END.` (no `VAR`) and `PROGRAM HELLO(OUTPUT)`
|
|
|
+ both terminate cleanly — used as harness sanity checks.
|
|
|
+
|
|
|
+Key probed P2 facts (vs P4): `AND`/`OR`/`NOT` words but **no `&`**;
|
|
|
+`DIV`/`MOD`/`IN`; `CASE` with **no `ELSE`**; `(* *)` comments that
|
|
|
+do **not nest**, no `{}`; numeric-only labels and `GOTO`; reals
|
|
|
+strictly `digits.digits[E...]` (no `1.`, no `.5`); consts are
|
|
|
+`[sign] literal` (no expressions); enums without `= N`; set
|
|
|
+elements without `..` ranges; untagged variants rejected
|
|
|
+(`CASE tag: type` required); `TEXT`/`FILE` types absent
|
|
|
+(`FILE OF` → 399 unimplemented); `PACK`/`UNPACK`/`PRED`/`SUCC`
|
|
|
+parse but unconditionally mark 399 (stubs — kept out of the
|
|
|
+battery); `NEW` exists but `DISPOSE` does not (`RELEASE` does);
|
|
|
+no `ROUND`/`HALT`/`EXIT`/`RETURN`; no procedural types (the
|
|
|
+compiler crashes on them); no `EXTERN`; `FORWARD` exists;
|
|
|
+`WRITELN`/`READLN`/`READ`/`EOF`/etc. require parentheses
|
|
|
+(`WRITELN;` is error 9) while user routines allow bare calls;
|
|
|
+`EOLN`/`READ` take file args; `PACKED`, multi-dim arrays,
|
|
|
+subrange/const bounds, `CHAR` indices, pointer forwards,
|
|
|
+`OTHERWISE`-less everything.
|
|
|
+
|
|
|
+## Grammar notes
|
|
|
+
|
|
|
+Single-statement `if`/`while`/`for` branches (standard Pascal, avoids
|
|
|
+`;`-capture across case items), `begin..end` compounds as statements,
|
|
|
+trailing-`;`-tolerant sections/fields/case-items, order-free
|
|
|
+repeatable declaration sections (as in pcom's `BLOCK`), mandatory
|
|
|
+`(`...`)` on the 13+16 predeclared routines (`StdProc`/`StdFunc`,
|
|
|
+which is what rejects bare `WRITELN;`), write-width params,
|
|
|
+`PROGRAM name[(files)]` headings, strict EOF check (patched into
|
|
|
+`Parse` by `build.sh`, which also fails on degenerate `IF/WHILE
|
|
|
+FALSE` generation).
|
|
|
+
|
|
|
+Lenient acceptances (documented misses, never false positives):
|
|
|
+`DISPOSE`/`ROUND`/user-`TEXT` parse as ordinary identifier calls/
|
|
|
+types although pcom marks them; lowercase is rejected while fpc
|
|
|
+would accept (P2 direction wins — pcom is the oracle here).
|
|
|
+
|
|
|
+## Build
|
|
|
+
|
|
|
+```sh
|
|
|
+./build.sh # -> build/P2 (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 (P2 vs `pcom`)
|
|
|
+
|
|
|
+Accept battery (23 cases: all statements, `NEW`/deref/`NIL`,
|
|
|
+`ORD`/`CHR`, reals, strings, sets, `ODD`/`TRUNC`, trig, `EOF(INPUT)`)
|
|
|
++ `tests/deep.pas` (labels/goto, nested routines with `var` params,
|
|
|
+records, enums, subranges, pointers, all statements): **0 false
|
|
|
+positives**. Broken mutants (13, incl. spin-cases `&`, `{}`, `@`,
|
|
|
+unterminated comment, `ELSE`, ident labels, `1.5.2`, bare
|
|
|
+`WRITELN`): **0 missed**, positions close. Real P2 corpus
|
|
|
+(`Pascal-P2-master/sample_programs`, `p2/Examples`): 5/5 agree
|
|
|
+(`qsort` needed the trailing-newline normalization).
|