11package sitter
22
3- import "io"
3+ import (
4+ "fmt"
5+ )
46
57type IterMode int
68
@@ -9,71 +11,60 @@ const (
911 BFSMode
1012)
1113
12- // Iterator for a tree of nodes
13- type Iterator struct {
14- named bool
15- mode IterMode
16-
17- nodesToVisit []* Node
18- }
19-
20- // NewIterator takes a node and mode (DFS/BFS) and returns iterator over children of the node
21- func NewIterator (n * Node , mode IterMode ) * Iterator {
22- return & Iterator {
23- named : false ,
24- mode : mode ,
25- nodesToVisit : []* Node {n },
26- }
27- }
28-
29- // NewNamedIterator takes a node and mode (DFS/BFS) and returns iterator over named children of the node
30- func NewNamedIterator (n * Node , mode IterMode ) * Iterator {
31- return & Iterator {
32- named : true ,
33- mode : mode ,
34- nodesToVisit : []* Node {n },
14+ // TreeIterator takes a node and mode (DFS/BFS) and returns iterator over children of the node.
15+ // named determines whether to iterate over only named children
16+ func TreeIterator (n * Node , mode IterMode , named bool ) func (func (* Node ) bool ) {
17+ return func (yield func (* Node ) bool ) {
18+ nodesToVisit := []* Node {n }
19+ var current * Node
20+ for len (nodesToVisit ) > 0 {
21+ switch mode {
22+ case DFSMode :
23+ current , nodesToVisit = nodesToVisit [len (nodesToVisit )- 1 ], nodesToVisit [:len (nodesToVisit )- 1 ]
24+ case BFSMode :
25+ current , nodesToVisit = nodesToVisit [0 ], nodesToVisit [1 :]
26+ default :
27+ panic (fmt .Errorf ("unsupported iteration mode: %v" , mode ))
28+ }
29+ if ! yield (current ) {
30+ return
31+ }
32+ if named {
33+ for i := 0 ; i < int (current .NamedChildCount ()); i ++ {
34+ nodesToVisit = append (nodesToVisit , current .NamedChild (i ))
35+ }
36+ } else {
37+ for i := 0 ; i < int (current .ChildCount ()); i ++ {
38+ nodesToVisit = append (nodesToVisit , current .Child (i ))
39+ }
40+ }
41+ }
3542 }
3643}
3744
38- func (iter * Iterator ) Next () (* Node , error ) {
39- if len (iter .nodesToVisit ) == 0 {
40- return nil , io .EOF
41- }
42-
43- var n * Node
44- n , iter .nodesToVisit = iter .nodesToVisit [0 ], iter .nodesToVisit [1 :]
45-
46- var children []* Node
47- if iter .named {
48- for i := 0 ; i < int (n .NamedChildCount ()); i ++ {
49- children = append (children , n .NamedChild (i ))
45+ func QueryIterator (root * Node , query * Query ) func (func (map [string ]* Node ) bool ) {
46+ return func (yield func (map [string ]* Node ) bool ) {
47+ cursor := NewQueryCursor ()
48+ cursor .Exec (query , root )
49+ captures := make (map [uint32 ]string )
50+ for i := uint32 (0 ); i < query .CaptureCount (); i ++ {
51+ captures [i ] = query .CaptureNameForId (i )
5052 }
51- } else {
52- for i := 0 ; i < int (n .ChildCount ()); i ++ {
53- children = append (children , n .Child (i ))
54- }
55- }
5653
57- switch iter .mode {
58- case DFSMode :
59- iter .nodesToVisit = append (children , iter .nodesToVisit ... )
60- case BFSMode :
61- iter .nodesToVisit = append (iter .nodesToVisit , children ... )
62- default :
63- panic ("not implemented" )
64- }
65- return n , nil
66- }
54+ for {
55+ match , found := cursor .NextMatch ()
56+ if ! found {
57+ return
58+ }
59+ results := make (map [string ]* Node )
6760
68- func (iter * Iterator ) ForEach (fn func (* Node ) error ) error {
69- for {
70- n , err := iter .Next ()
71- if err != nil {
72- return err
73- }
74- err = fn (n )
75- if err != nil {
76- return err
61+ for _ , capture := range match .Captures {
62+ results [captures [capture.Index ]] = capture .Node
63+ }
64+
65+ if ! yield (results ) {
66+ return
67+ }
7768 }
7869 }
7970}
0 commit comments