ParseletRegistry
Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:42
Dual-keyed ParseletRegistry, accepts both string token types and integer token type IDs for fast dispatch in the Parser hot path.
Providers call registerPrefix(“NUMBER”, …) with string token types. Internally, we populate both string-keyed and integer-keyed maps so Parser.parseExpression() can use token.typeId (integer) for lookup while diagnostics and error messages use token.type (string).
Performance: Integer Map.get() avoids string hashing, saving ~2-5ns per dispatch. With ~10-15 dispatches per expression, that’s ~20-75ns.
Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new ParseletRegistry(): ParseletRegistry;Returns
Section titled “Returns”ParseletRegistry
Accessors
Section titled “Accessors”infixCount
Section titled “infixCount”Get Signature
Section titled “Get Signature”get infixCount(): number;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:165
Number of registered infix parselets.
Returns
Section titled “Returns”number
prefixCount
Section titled “prefixCount”Get Signature
Section titled “Get Signature”get prefixCount(): number;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:162
Number of registered prefix parselets.
Returns
Section titled “Returns”number
Methods
Section titled “Methods”clear()
Section titled “clear()”clear(): void;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:194
Returns
Section titled “Returns”void
getAllInfix()
Section titled “getAllInfix()”getAllInfix(): { category?: string; leftBindingPower: number; rightBindingPower: number; tokenType: string;}[];Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:147
Iterate all registered infix parselets for diagnostic display.
The field an InfixParselet actually declares is bindingPower. This
used to read leftBindingPower and rightBindingPower, which no
parselet in this codebase declares, so both reads were undefined, both
fell to the ?? 0 default, and the public getParseletRegistry()
reported a binding power of 0 for every one of the ~60 infix operators.
A host building a precedence table from it was told * and + bind
equally, and that neither binds at all.
The left/right split: bindingPower is the LEFT power, and the right is
one higher. That is the standard encoding for a left-associative
operator, and it is what the parser itself does, see
PrecedenceParser.parseExpression()’s bp + 1 for the right operand.
Every operator is reported that way, ^ included. Associativity is not
something a parselet declares, it is a property of how each one calls
parseExpression, so this API cannot report it without a new field on
the interface. See ParseletBindingPowers for why scraping a
plausible-looking one off the parselet is worse than not reporting it.
Returns
Section titled “Returns”{
category?: string;
leftBindingPower: number;
rightBindingPower: number;
tokenType: string;
}[]
getAllPrefix()
Section titled “getAllPrefix()”getAllPrefix(): { bindingPower: number; category?: string; tokenType: string;}[];Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:114
Iterate all registered prefix parselets for diagnostic display.
PrefixParselet declares no binding power, and this used to read a field
of that name and report 0 for every one of them. 0 is not a neutral
wrong answer: it is the value that means “not an operator, stop the
expression”, so a host drawing a table from this was told none of them
bind at all. A prefix parselet in this parser has no per-parselet power
to report, they all bind at the prefix level and each chooses for itself
at what power to parse its own operand, so that level is what is
reported. A parselet that does carry its own bindingPower still wins.
Returns
Section titled “Returns”{
bindingPower: number;
category?: string;
tokenType: string;
}[]
getInfix()
Section titled “getInfix()”getInfix(tokenType): | InfixParselet | undefined;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:181
Get infix parselet by string token type OR integer typeId. Fast path for integer IDs (Parser hot path), fallback for strings.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tokenType | string | number |
Returns
Section titled “Returns”| InfixParselet
| undefined
getPrefix()
Section titled “getPrefix()”getPrefix(tokenType): | PrefixParselet | undefined;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:172
Get prefix parselet by string token type OR integer typeId. Fast path for integer IDs (Parser hot path), fallback for strings (diagnostics, error messages, backwards compatibility).
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tokenType | string | number |
Returns
Section titled “Returns”| PrefixParselet
| undefined
hasInfix()
Section titled “hasInfix()”hasInfix(tokenType): boolean;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:190
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tokenType | string |
Returns
Section titled “Returns”boolean
hasPrefix()
Section titled “hasPrefix()”hasPrefix(tokenType): boolean;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:186
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tokenType | string |
Returns
Section titled “Returns”boolean
registerInfix()
Section titled “registerInfix()”registerInfix(tokenType, parselet): void;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:88
Register an infix parselet for tokenType. See registerPrefix for the collision-warning behavior this mirrors.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tokenType | string |
parselet | InfixParselet |
Returns
Section titled “Returns”void
registerPrefix()
Section titled “registerPrefix()”registerPrefix(tokenType, parselet): void;Defined in: packages/engine/src/parser/registry/ParseletRegistry.ts:73
Register a prefix parselet for tokenType.
If another parselet is already registered for this token type, it is
silently overwritten by default (Map.set() semantics), the old
parselet is simply unreachable from then on, with no error. This is
a real footgun for third-party packages: two packages independently
choosing the same custom token type will collide with zero signal
about which one “won”. Mirrors ResolverRegistry.register()‘s and
ExpressionEngine.registerPackage()‘s existing “warn and replace”
pattern for the same class of problem at the resolver-namespace and
package-name levels.
Note: this warns about registry-level collisions only. It does NOT
detect the separate case where tokenType is one of PrecedenceParser’s
Tier-1 fast-path token types (NUMBER, STRING, IDENT, LPAREN, MINUS,
PLUS, and the Tier-1 infix operators), those are deliberately kept
registered here for introspection/diagnostics even though Tier-1
always intercepts them before this registry is consulted (see
PrecedenceParser.parsePrefix()‘s docs), so warning there would
misfire on that intentional, already-documented pattern.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tokenType | string |
parselet | PrefixParselet |
Returns
Section titled “Returns”void