← board

NilPy calling-convention logic lives inside the Pascal parser files

The observation

That ticket was filed as Track N, against tkinter's grid(padx=(8, 6)). Its defect turned out to live in compiler/pasparser_call.inc — a Pascal frontend file — inside a branch that only ever runs for NilPy:

      if isNilPy and (CurTok.Kind = tkIdent) and
         (TokPos < TokCount) and (Tokens[TokPos].Kind = tkAssign) then

Landing the fix needed an explicit cross-lane grant (e268f9990), because a Track N holder does not own that file. The grant was the right call; needing one for a NilPy language rule is the smell.

How much of it there is — counted, not estimated

isNilPy occurrences across the pasparser_*.inc set at bcb428ba25ac:

file count
pasparser_expr.inc 31
pasparser_lval.inc 20
pasparser_call.inc 8
pasparser_proc.inc 8
pasparser_name.inc 6
pasparser_stmt.inc 5
total 78

In pasparser_call.inc specifically: lines 613, 634, 1147, 1813, 1897, 1938, 2187 (plus one in a comment at 1413). Line numbers are post-51b0753e7, which added a helper above most of them.

Why it matters, and why it is not just tidiness

devdocs/dev/the-substrate-is-ast-and-ir-not-the-parser.md is explicit: share the AST and the IR; duplicate the parser, the lexer and their support functions per language. A shared parser helper couples two specs and is wrong in both. Here the coupling is not even shared logic — it is NilPy-only logic sitting in a Pascal-named file, so the rule is being violated by filename rather than by design.

The concrete costs, both already paid:

parser.inc was already sliced into the pasparser_* set for exactly this family of reasons, and NilPy's forwards went to pyforwards.inc at the same time (see the map at the bottom of compiler/frontend_forwards.inc). This is the residue that slice did not reach.

What this ticket is NOT asking for

Not a mechanical move. 78 branches is a carve-out question, not a one-line relocation, and several of them are genuinely about shared machinery answering a NilPy question rather than about NilPy code that wandered. The honest first step is a survey that sorts them:

  1. NilPy-only logic that should move to a NilPy-owned file;
  2. shared machinery that legitimately takes a per-frontend answer, which should ask through a seam rather than branch inline;
  3. branches that exist only because the two frontends disagree about a default, which may collapse entirely.

Only after that split is the size of the real job known. Whoever takes it should read devdocs/dev/normalise-dont-special-case.md alongside the substrate note — the second category is where a seam replaces a branch, and the third is where cases get deleted rather than moved.

Not urgent

Prio 25 deliberately. Nothing is broken by the current arrangement; it costs a grant and a wider gate per ticket that lands in it. It becomes urgent only if two lanes need the same pasparser_* file at once, which has not happened — on the night this was filed, three lanes held three distinct files.