Expand description
The expl3 call-site model: argspec arity for expl3 function names, and the statement segmentation built on it.
Two halves, both semantics layered on the syntax tree (like
define’s definition scan): expl3_slots derives
per-slot arity from the letters after the final : in \cs_new:Npn,
\tl_if_empty:nTF, …, and segment_expl_statements applies it to an
in-region element stream to produce the statement model the formatter’s
expl3 layout consumes. Neither builds Ir or touches layout policy — a
wrong answer here can only produce ugly formatting downstream, never a
wrong tree or a lost byte.
Like xparse, the argspec is a spec mini-language that is
parsed, never executed (AGENTS.md decision #1): each letter names the
shape an argument takes at the call site, a bounded, purely lexical
fact — squarely decision #2’s “the semantic layer assigns arity”. No
signature database is involved: the name string alone carries the spec, so
there is nothing to curate and nothing to drift. Only meaningful inside an
expl3 region, where :/_ are catcode-11 and the whole name lexes as one
CONTROL_WORD — callers of the segmentation guarantee the stream is
in-region (out-of-region, colon names lex split and everything degrades to
the fallback).
The letter-by-letter model (interface3’s argument specifiers):
N,V→Expl3Slot::SingleToken: one token, typically a control sequence (Vdiffers fromNonly in expansion, not call-site shape).n,c,v,o,x,e,f→Expl3Slot::Group: one braced{…}group (again, the letters differ only in how the material is processed, which we never model).T,F→Expl3Slot::Branch: a braced conditional branch. Sanctioned only as a trailing run — in a standard argspecT/Fare always last, so a mid-specT/Fis treated as unknown.p→Expl3Slot::ParameterText: TeX parameter text (#1#2…), which has no fixed token count but a static end: TeX’s own rule that the parameter text runs to the first explicit{. The consumer scans by that shape.w(arbitrary delimiters) andD(kernel primitive) have no lexically derivable call-site shape → the whole name is unrecognized (None), as is any unknown letter (including one added to expl3 after this list was written — new letters degrade to unrecognized, never to a wrong arity).
Structs§
- Statement
Map - The statement-boundary map for one element stream:
boundary_after(i)says a statement ends in the gap after elementi. Boundaries sit on whole top-level siblings — a boundary never splits a CST node, so anything the greedy parser over-attached to a consumed sibling rides along in its statement.
Enums§
- Expl3
Slot - The call-site shape of one expl3 argument slot, derived from an argspec letter.
Functions§
- conditional_
branches - The number of trailing
T/Fbranch arguments of an expl3 conditional, read from the command name’s argspec (the substring after the final:).\tl_if_empty:nTF→Some(2),\bool_if:nT/:nF→Some(1);Nonefor any name without a:-argspec ending inT/F— a non-conditional expl3 function (\seq_new:N), or a LaTeX2e command with no colon (\@ifpackageloaded). In an expl3 argspecT/Fdenote only the true/false branch slots, so a trailingT/Frun is exactly the branch count. - expl3_
slots - The argument slots of an expl3 function name, read from its argspec suffix
(the substring after the final
:), orNonewhen the name has no derivable call-site arity. - segment_
expl_ statements - Segment an in-region element stream into statements. See the module docs
for the model; the caller guarantees the stream is inside an expl3 region
(so
:/_were letters and names carry their argspec suffix).