Expand description
Parser plans: the flat runtime representation of a parser AST.
After validation and type synthesis, a ParserAst is lowered into a
ParserPlan — a flat arena of PlanNodes that the runtime interpreter
(praxis-runtime::parser) walks against the input buffer. The compiled plan
is registered in a process-wide arena and identified by a
PlanId; MIR passes that id as an i64 immediate (no
pointer-as-immediate needed).
Design constraints:
- Flat and self-contained: nodes reference children by index (no
Box, no ownedStringon the hot path). Separators and template literals are interned into a parallel&'static [&'static str]slice so the runtime reads them without dereferencing Rust owned data. - Record schemas for named-capture templates are built at runtime (the
interpreter knows the field descriptors from the child plans’ result
types); the plan stores only field names as
&'static str.
Not #[repr(C)]. These are ordinary Rust enums and slices with the
default representation, and nothing here crosses an FFI boundary: the plan
is consumed by praxis-runtime, which is Rust and links against this crate,
and only the plan id is passed as a JIT immediate. If a plan ever does
need to be read by generated code, that is a real representation change
(explicit #[repr(C)], no enums with payloads, no &str fat pointers) and
not something to assume from this comment.
§Ownership
Each CompiledPlan owns a bumpalo arena holding everything the plan’s
&'static fields point into, so a plan is reclaimable at all; registration
is bounded and checked, so a long enough compile cannot wrap the index and
hand the runtime a different plan; and a PlanId is a NonZeroU32, so
“no plan” is not spelled 0 — it is not spellable at all.
Reclamation has the same ordering obligation as the JIT generation arena:
record schemas the runtime builds for named-capture templates borrow their
field names from plan storage, so plans may only be retired once the heap
is drained. praxis_runtime::retire_parser_plans is the gate; see
retire_all_plans.
Structs§
- Compiled
Plan - A lowered plan together with the arena that owns everything it points at.
- Parser
Plan - A compiled parser plan: the node arena plus auxiliary interned data.
- PlanId
- The identity of a registered parser plan.
- Source
Order - The order the parser wrote them in —
FieldOrderfor a plan lowered outside a compilation, where there is no other spelling to agree with. - TooMany
Plans - Registration refused: the process has compiled more parser plans than the arena admits.
Enums§
- Block
Item Node - One item of a
block(...)(§7.5), in plan form. - Plan
Node - One node in the flattened parser plan. Index-based: children refer to other
nodes by their position in the
ParserPlan::nodesslice. - Section
Item Node - One named argument of a heterogeneous
sections(...)other than its unbounded tail (§7.5), in plan form. - Template
Part Node - One part of a template, in plan form.
- Template
Shape - What a lowered template’s parts add up to (§7.3).
Constants§
- MAX_
PLANS - The registration bound. Chosen so an id always fits a
u32with room to spare, and so a runaway registration loop is caught long before the narrowing could matter.
Traits§
- Field
Order - Who decides the layout order of the anonymous record a named-capture parser builds (§5.6, ADR-152).
Functions§
- get_
plan - Look up a plan by id.
Noneif the id names no registered plan (the caller treats that as a parse fault). - lower_
to_ plan - Lower a validated
ParserAstinto a self-owningCompiledPlan. - plan_
count - How many plans are registered. For tests and diagnostics.
- register_
plan - Register a compiled plan, returning its id.
- retire_
all_ ⚠plans - Drop every registered plan, releasing its arena.