Implemented instruction splitting as a generator
This commit is contained in:
parent
f31ea5e825
commit
56ce523642
5 changed files with 93 additions and 81 deletions
61
src/token/Instructions.go
Normal file
61
src/token/Instructions.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
package token
|
||||
|
||||
// Instructions yields on each AST node.
|
||||
func (list List) Instructions(yield func(List) bool) {
|
||||
start := 0
|
||||
groupLevel := 0
|
||||
blockLevel := 0
|
||||
|
||||
for i, t := range list {
|
||||
switch t.Kind {
|
||||
case NewLine:
|
||||
if start == i {
|
||||
start = i + 1
|
||||
continue
|
||||
}
|
||||
|
||||
if groupLevel > 0 || blockLevel > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if !yield(list[start:i]) {
|
||||
return
|
||||
}
|
||||
|
||||
start = i + 1
|
||||
|
||||
case GroupStart:
|
||||
groupLevel++
|
||||
|
||||
case GroupEnd:
|
||||
groupLevel--
|
||||
|
||||
case BlockStart:
|
||||
blockLevel++
|
||||
|
||||
case BlockEnd:
|
||||
blockLevel--
|
||||
|
||||
if groupLevel > 0 || blockLevel > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if !yield(list[start : i+1]) {
|
||||
return
|
||||
}
|
||||
|
||||
start = i + 1
|
||||
|
||||
case EOF:
|
||||
if start < i {
|
||||
yield(list[start:i])
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if start < len(list) {
|
||||
yield(list[start:])
|
||||
}
|
||||
}
|
20
src/token/Instructions_test.go
Normal file
20
src/token/Instructions_test.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package token_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.urbach.dev/cli/q/src/token"
|
||||
"git.urbach.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestInstructions(t *testing.T) {
|
||||
src := []byte("a := 1\nb := 2\n")
|
||||
tokens := token.Tokenize(src)
|
||||
nodes := []string{}
|
||||
|
||||
for param := range tokens.Instructions {
|
||||
nodes = append(nodes, param.Text(src))
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, nodes, []string{"a:=1", "b:=2"})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue