1- import {
2- assertIsNode ,
3- GetNodeFromKind ,
4- InstructionNode ,
5- Node ,
6- NodeKind ,
7- ProgramNode ,
8- REGISTERED_NODE_KINDS ,
9- } from '@codama/nodes' ;
1+ import { GetNodeFromKind , Node , NodeKind } from '@codama/nodes' ;
102
11- import { findLastNodeFromPath , NodePath } from './NodePath' ;
3+ import { assertIsNodePath , NodePath } from './NodePath' ;
4+
5+ type MutableNodePath = Node [ ] ;
126
137export class NodeStack {
148 /**
@@ -21,78 +15,56 @@ export class NodeStack {
2115 *
2216 * There must at least be one stack in the heap at all times.
2317 */
24- private readonly heap : [ ...Node [ ] [ ] , Node [ ] ] ;
18+ private readonly heap : [ ...MutableNodePath [ ] , MutableNodePath ] ;
2519
26- constructor ( ...heap : readonly [ ...( readonly ( readonly Node [ ] ) [ ] ) , readonly Node [ ] ] | readonly [ ] ) {
27- this . heap = heap . length === 0 ? [ [ ] ] : ( [ ...heap . map ( nodes => [ ...nodes ] ) ] as [ ...Node [ ] [ ] , Node [ ] ] ) ;
20+ constructor ( ...heap : readonly [ ...( readonly NodePath [ ] ) , NodePath ] | readonly [ ] ) {
21+ this . heap =
22+ heap . length === 0 ? [ [ ] ] : ( [ ...heap . map ( nodes => [ ...nodes ] ) ] as [ ...MutableNodePath [ ] , MutableNodePath ] ) ;
2823 }
2924
30- public get stack ( ) : Node [ ] {
25+ private get currentPath ( ) : MutableNodePath {
3126 return this . heap [ this . heap . length - 1 ] ;
3227 }
3328
3429 public push ( node : Node ) : void {
35- this . stack . push ( node ) ;
30+ this . currentPath . push ( node ) ;
3631 }
3732
3833 public pop ( ) : Node | undefined {
39- return this . stack . pop ( ) ;
34+ return this . currentPath . pop ( ) ;
4035 }
4136
4237 public peek ( ) : Node | undefined {
43- return this . isEmpty ( ) ? undefined : this . stack [ this . stack . length - 1 ] ;
38+ return this . isEmpty ( ) ? undefined : this . currentPath [ this . currentPath . length - 1 ] ;
4439 }
4540
46- public pushStack ( newStack : readonly Node [ ] = [ ] ) : void {
47- this . heap . push ( [ ...newStack ] ) ;
41+ public pushPath ( newPath : NodePath = [ ] ) : void {
42+ this . heap . push ( [ ...newPath ] ) ;
4843 }
4944
50- public popStack ( ) : readonly Node [ ] {
51- const oldStack = this . heap . pop ( ) as Node [ ] ;
45+ public popPath ( ) : NodePath {
5246 if ( this . heap . length === 0 ) {
5347 // TODO: Coded error
5448 throw new Error ( 'The heap of stacks can never be empty.' ) ;
5549 }
56- return [ ...oldStack ] as readonly Node [ ] ;
57- }
58-
59- public find < TKind extends NodeKind > ( kind : TKind | TKind [ ] ) : GetNodeFromKind < TKind > | undefined {
60- return findLastNodeFromPath ( [ ...this . stack ] as unknown as NodePath < GetNodeFromKind < TKind > > , kind ) ;
61- }
62-
63- public getProgram ( ) : ProgramNode | undefined {
64- return this . find ( 'programNode' ) ;
65- }
66-
67- public getInstruction ( ) : InstructionNode | undefined {
68- return this . find ( 'instructionNode' ) ;
50+ return [ ...this . heap . pop ( ) ! ] ;
6951 }
7052
71- public all ( ) : readonly Node [ ] {
72- return [ ... this . stack ] ;
73- }
74-
75- public getPath < TKind extends NodeKind > ( kind ?: TKind | TKind [ ] ) : NodePath < GetNodeFromKind < TKind > > {
76- const node = this . peek ( ) ;
77- assertIsNode ( node , kind ?? REGISTERED_NODE_KINDS ) ;
78- return [ ... this . stack ] as unknown as NodePath < GetNodeFromKind < TKind > > ;
53+ public getPath ( ) : NodePath ;
54+ public getPath < TKind extends NodeKind > ( kind : TKind | TKind [ ] ) : NodePath < GetNodeFromKind < TKind > > ;
55+ public getPath < TKind extends NodeKind > ( kind ?: TKind | TKind [ ] ) : NodePath {
56+ const path = [ ... this . currentPath ] ;
57+ if ( kind ) {
58+ assertIsNodePath ( path , kind ) ;
59+ }
60+ return path ;
7961 }
8062
8163 public isEmpty ( ) : boolean {
82- return this . stack . length === 0 ;
64+ return this . currentPath . length === 0 ;
8365 }
8466
8567 public clone ( ) : NodeStack {
8668 return new NodeStack ( ...this . heap ) ;
8769 }
88-
89- public toString ( ) : string {
90- return this . toStringArray ( ) . join ( ' > ' ) ;
91- }
92-
93- public toStringArray ( ) : string [ ] {
94- return this . stack . map ( ( node ) : string => {
95- return 'name' in node ? `[${ node . kind } ]${ node . name } ` : `[${ node . kind } ]` ;
96- } ) ;
97- }
9870}
0 commit comments