← board

🗼 Lighthouse — compile the FPC compiler (pp.pas) with PXX

The goal

PXX compiles the Free Pascal Compiler's own source (compiler/pp.pas and its unit graph) and the produced fpc' works. The point is conformance: the FPC compiler source is the largest, most edge-case-dense real Object Pascal corpus available, so compiling it correctly proves dialect conformance at industrial scale — not on toy tests. The motive is better software built on 50 years of borrowed Pascal language design; this is how we prove we inherited it correctly.

The operational motive (user, 2026-07-18) is bug harvest: real code — libraries, applications — beats any fuzzer, and every corpus pulled in so far surfaced new compiler bugs. FPC's source is the densest such corpus, and uniquely it composes into a second-order oracle: any subtle pxx miscompile in fpc' amplifies into visible output divergence when fpc' compiles the downstream corpus. The trophy is a gimmick; the bug list is the point.

RTL-coupling note (verified 2026-07-18): the earlier probe's claim that FPC's compiler needs FPC's exact ansistring/System internals was checked against real 3.2.2 source and is wrong — coupling is semantic only (refcounted strings via documented API, one missing Initialize() intrinsic). Details in experiment-compile-fpc-as-stress-probe.md (Path B, corrected). The shadow-RTL model that carried Synapse is expected to carry here too.

Acceptance = the differential oracle (not "it runs")

The bar is not "pp.pas compiles." It is:

  1. PXX compiles FPC source → fpc'.
  2. fpc' compiles a real corpus, and its output matches upstream FPC's output byte-for-byte.

A match is a brutal, end-to-end correctness signal. "Compiles and runs" is a weaker waypoint; the differential match is the proof.

Evidence — what the FPC compiler source ACTUALLY uses

Empirical grep over /home/rene/src/fpc-source/compiler (FPC 3.2.2, 861 .pas/.pp/.inc files), 2026-06-18. Distinguishes features the compiler implements from features its own source uses — they are very different.

Feature Real usage in compiler source A gate to compile pp.pas?
Generics (generic T = …) 0 declarations (112 file hits = comments + the compiler's own handling of generics) ❌ no
Interfaces (= interface) 2 files ❌ negligible
Operator overload 4 files ❌ negligible
Variants (as a type) ~0 (hits = comments / case-variant records) ❌ no
inline asm bodies 4 files minor (codegen emits via nodes, not asm{})
{$mode objfpc} uniform / consistent ✅ dialect breadth
bestreal / extended 35 files the one real language gate
classes / objects / virtual pervasive ✅ already have

Conclusion: the FPC compiler source is linguistically conservative — same discipline PXX used to bootstrap itself. The big ecosystem features (generics, interfaces, operators, variants) are NOT needed to compile the compiler. They gate the ecosystem corpus (Lazarus / packages), a separate and larger climb.

Principle — implements-vs-uses

A compiler implements a huge feature set; its source uses a small subset. Choose corpus rungs by what each uses. The compiler-source rung needs far less than the ecosystem rung — do not price it as if it needed the whole dialect.

Two mountains (keep them separate)

  1. Language conformance — compile the Pascal. Turns out conservative (table above): full classes (have), {$mode objfpc} breadth, extended-precision constant folding (35 files), heavy conditional compilation, likely nested-procedure frame capture. Achievable.
  2. Build-system / toolchain compat — acting as a drop-in fpc: same CLI flags, the undocumented version-locked .ppu precompiled-unit binary format, ppas, fpcmake. Brutal (the .ppu format especially) — and AVOIDABLE.

Avoid mountain 2: whole-program compile

For the conformance proof, point PXX at compiler/pp.pas and compile whole-program from source — PXX follows uses and compiles every unit in one shot. No .ppu, no make, no fpc-CLI emulation. The makefile/aliasing complexity is only needed for a drop-in fpc replacement — a different, much later, maybe-never goal. Do NOT let it block the proof.

The one real language gate — extended precision

FPC uses bestreal (= extended 80-bit on x86; = double off-x86) for constant folding so folded constants carry max target precision.

Honesty note: do the proof on x86-64 first, where extended is real. Off-x86 a PXX-built FPC inherits the same reduced precision FPC itself has there (FPC drops extendeddouble off-x86) — conformance-preserving, not a PXX defect; document as inherited.

The corpus ladder (the climb that resolves this lighthouse)

Each rung exposes the next missing feature → a concrete ticket → fix → corpus grows. Metric = kLOC of real FPC compiling+matching, not a binary done.

Lazarus helloworld (DONE) → Synapse (in progress) → mid-size FPC libs
  → FPC RTL units → compiler/pp.pas (whole-program)  ← the differential summit

Pre-filed tickets (the known walls, in order — backlog, 2026-07-18)

The 2026-07-18 gap analysis converted the known walls into concrete backlog tickets; unknown walls behind them get filed as the probe hits them:

  1. [[feature-pascal-asmmode-directive-tolerance]] — {$asmMode default} rejected; first token of cutils.pas and of every compiler unit. Trivial.
  2. [[feature-mimic-fpc-compiler-define-profile]] — {$i fpcdefs.inc} needs the build-time CPU define profile (-dx86_64, …); Synapse per-library defines pattern applied to FPC's compiler.
  3. [[feature-pascal-initialize-finalize-intrinsics]] — Initialize() / Finalize() standard procs (cclasses.pas raw-Move refcount idiom). The only verified RTL-semantics gap after the coupling-claim correction.
  4. (existing, for the differential bar only) 80-bit extended constant folding — see "The one real language gate" above and feature-extended-type-support (rainy-day). Not needed for "compiles and runs".

Beyond these: shadow-RTL surface accretion (SysUtils/CStreams breadth) filed per-gap as hit, Synapse-style.

Known unknown

A prior manual attempt halted on a first blocker (not recorded). When the climb resumes, re-run pp.pas whole-program through PXX and capture the first error as the first concrete sub-ticket. Nobody has probed past wall #1; the pre-filed list above covers the walls visible from the doorway, not the whole corridor.

Log