← board

{$...} inside a brace comment survives {$NESTEDCOMMENTS OFF} in pxx

TRIED AND REVERTED 2026-08-19 — read before attempting it. The one-line fix is real, it is in the right place, and it breaks the self-build. Do not spend the session rediscovering that; see "Why the obvious fix cannot land" below. Left in backlog/; nothing of it is applied.

Measured, delphi mode (nested comments off) on both compilers

program dc;
{ outer {$DEFINE FOO} still outer }
begin writeln('compiled'); end.
construct FPC -Mdelphi pxx -Mdelphi
plain nested brace — { outer { inner } still outer } reject reject — agree
brace directive{ outer {$DEFINE FOO} still outer } reject accept

So the plain nesting rule is right; the divergence is specific to a {$ sequence. With nesting off, FPC treats the directive's closing brace as ending the enclosing comment and then parses the trailing prose as code. pxx keeps scanning, apparently special-casing {$ in the comment scanner regardless of NestedComments.

The same applies to a {$MODE ...} written inside a comment, which is how this was hit: prose about directives is a natural thing to write in a file header.

Severity: low, and in the safe direction

pxx is more permissive — it accepts sources FPC rejects, never the reverse. Nothing miscompiles and no value is wrong; a file that builds under pxx may fail under FPC, which is the direction this project already accepts by default (CLAUDE.md: pxx's dialect is deliberately lax, FPC-parity strictness lives behind per-feature strict flags). Hence prio 25 rather than a bug- ticket.

It matters mainly for corpus work: a real Delphi codebase whose comments contain directive text compiles here and would not under the reference compiler, so "it builds with pxx" is weaker evidence than it looks for that file.

Fix shape

In the brace-comment scanner, the {$ special case should apply only when NestedComments is on. Behind --strict-fpc if flipping it unconditionally turns out to break existing sources — check lib/** and the Pascal corpora first, since header comments discussing directives are common and this has been the lenient behaviour for the project's whole history.

Gate

The { outer {$DEFINE FOO} still outer } case above is rejected in delphi mode and still accepted with nested comments on, matching FPC in both; lib-test and the Pascal corpora still build.

2026-08-19 — the obvious fix cannot land, measured

The divergence is exactly where this ticket says it is. Two sites in compiler/lexer.inc (the active scanner in SkipSpace, and the inactive-conditional-branch scanner above it) nest the comment on an inner open-brace when

(NestedComments or ((SrcPos < Length(Source)) and (Source[SrcPos + 1] = '$')))

— the $ arm fires regardless of the switch, which is the whole bug. Both sites carry a comment saying it is deliberate, "lets prose mention conditional directives inside comments safely".

Dropping that arm gives exact FPC parity in delphi mode and changes nothing under NestedComments (which defaults to True here, the real FPC default — the "off (default) keeps the historic flat scan" note next to it is stale). It also stops the compiler compiling itself:

pascal26:8534: error: unexpected character

69 brace comments in compiler/** open by quoting a directive — the first one reached is ir.inc's range-check note, which opens { and then a {$R+} on the same line — plus 4 more in lib/**. Every one of them is a comment whose brace count only balances because of the $ arm. So the tolerance is not decorative; this codebase is written on top of it.

That makes this a dialect decision, not a lexer fix, and it belongs with the house rule in CLAUDE.md: "PXX's own dialect stays deliberately lax by default; FPC-parity strictness lives behind per-feature strict flags." The parity behaviour wants a --strict-comments-style flag that the conformance sweep turns on, leaving the default lax — and landing that means the flag AND leaving all 69 sites alone, which is a different and larger job than this ticket describes.

Method note

The first pass of this measurement claimed zero in-tree reliance and was wrong: the grep was grep -rn "{ [^}]*{\$" in double quotes, where \$ collapses to $ and the pattern anchors to end-of-line, so it matched nothing and looked like a clean bill of health. The self-build caught it one build later. Single quotes ('{ *{\$') give the real 69.

KNOWN-INCOMPAT 2026-09-02 — the lax direction, and the fix breaks the self-build

Two independent reasons, either sufficient, and the order matters.

First: it is the lax direction. pxx accepts a source FPC rejects. CLAUDE.md is explicit that us accepting what FPC rejects is not a defect — no correct program is refused, nothing computes a wrong value. A program relying on {$...} inside a brace comment terminating that comment is relying on a lexer accident to change which text is code.

Second, and only second: the obvious fix does not land. Recorded here 2026-08-19 — the one-line change is real, is in the right place, and breaks the self-build. That is evidence about COST, not about correctness. A fix being hard is never why something stops being a defect, which is why it is not the first reason.

What would reopen it: real source that is correct under FPC and wrong here because pxx keeps the comment open. Absent that, this is a difference in what the two lexers tolerate inside a comment, and ours tolerates more.