Skip to content

Commit 0255384

Browse files
Integerize rx/tpl lex bookkeeping and force-inline Rust hot path.
Replace string-set Scan bookkeeping with lid/kid flag tables across portable targets; add #[inline(always)] on Rust emit/prev_is_value so -O full-parse keeps the lex wins instead of regressing via call/layout effects. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 4efbe84 commit 0255384

4 files changed

Lines changed: 279 additions & 229 deletions

File tree

src/emit-portable.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,32 @@ export function kidOf(plan: LexIdPlan, kind: string): number {
682682
return i >= 0 ? i : 0;
683683
}
684684

685+
/**
686+
* Bool table indexed by lid for O(1) set membership in emitted lexers.
687+
* Slot 0 stays false: lids[0]='' means "not any literal" (Ident/Number text → lid 0).
688+
*/
689+
export function lidFlagTable(plan: LexIdPlan, texts: readonly string[]): boolean[] {
690+
const t = Array.from({ length: plan.lids.length }, () => false);
691+
for (const x of texts) {
692+
const i = plan.lids.indexOf(x);
693+
if (i > 0) t[i] = true;
694+
}
695+
return t;
696+
}
697+
698+
/**
699+
* Bool table indexed by kid for O(1) kind-set membership.
700+
* Only sets slots for kinds actually present in the plan (missing → skip, never alias to 0).
701+
*/
702+
export function kidFlagTable(plan: LexIdPlan, kinds: readonly string[]): boolean[] {
703+
const t = Array.from({ length: plan.kids.length }, () => false);
704+
for (const x of kinds) {
705+
const i = plan.kids.indexOf(x);
706+
if (i >= 0) t[i] = true;
707+
}
708+
return t;
709+
}
710+
685711
// ── Arena id tables (rule_id / tt_id for slim Node + inlined leaves) ──
686712
//
687713
// Arena stores only rule nodes; leaf kids are negative i32 encodings that pack

0 commit comments

Comments
 (0)