88 lines
2.2 KiB
TypeScript
88 lines
2.2 KiB
TypeScript
import type { ParseState } from "../types/index.js";
|
|
|
|
/**
|
|
* Create a new, empty parse state.
|
|
*
|
|
* @param maxDepth - Maximum recursive nesting depth (default 10).
|
|
*/
|
|
export function createParseState(maxDepth = 10): ParseState {
|
|
return {
|
|
counters: new Map(),
|
|
depth: 0,
|
|
maxDepth,
|
|
cache: new Map(),
|
|
custom: new Map(),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Deep-clone a parse state.
|
|
*
|
|
* Counter, cache, and custom maps are each cloned independently so
|
|
* mutations to the clone do not affect the original.
|
|
*/
|
|
export function cloneParseState(state: ParseState): ParseState {
|
|
return {
|
|
counters: new Map(state.counters),
|
|
depth: state.depth,
|
|
maxDepth: state.maxDepth,
|
|
cache: new Map(state.cache),
|
|
custom: new Map(state.custom),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Increment nesting depth in-place.
|
|
* Called by the engine before recursing into a nested template.
|
|
*/
|
|
export function incrementDepth(state: ParseState): void {
|
|
state.depth++;
|
|
}
|
|
|
|
/**
|
|
* Decrement nesting depth in-place.
|
|
* Called by the engine after returning from a nested template.
|
|
*/
|
|
export function decrementDepth(state: ParseState): void {
|
|
state.depth--;
|
|
}
|
|
|
|
/**
|
|
* Get the current value of a named counter and advance it.
|
|
*
|
|
* If the counter has never been set, it is initialised to `initialValue - 1`
|
|
* so that the first call returns exactly `initialValue`.
|
|
*
|
|
* @param state - The active parse state.
|
|
* @param name - Counter name.
|
|
* @param initialValue - Value returned on the first call (default 1).
|
|
*/
|
|
export function getCounter(
|
|
state: ParseState,
|
|
name: string,
|
|
initialValue = 1
|
|
): number {
|
|
const current = state.counters.get(name) ?? initialValue - 1;
|
|
const next = current + 1;
|
|
state.counters.set(name, next);
|
|
return next;
|
|
}
|
|
|
|
/**
|
|
* Reset a named counter to an explicit value.
|
|
*
|
|
* @param state - The active parse state.
|
|
* @param name - Counter name.
|
|
* @param value - New stored value (default 1, so the next read returns 2).
|
|
*/
|
|
export function resetCounter(state: ParseState, name: string, value = 1): void {
|
|
state.counters.set(name, value);
|
|
}
|
|
|
|
/**
|
|
* Clear **all** named counters, resetting the map to empty.
|
|
*/
|
|
export function clearCounters(state: ParseState): void {
|
|
state.counters.clear();
|
|
}
|