# 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).