Implemented token splitting as a generator

This commit is contained in:
2025-03-20 00:26:42 +01:00
parent 9a8bf8ff64
commit c2e489f987
4 changed files with 39 additions and 60 deletions

View File

@ -8,11 +8,10 @@ import (
func NewList(tokens token.List) []*Expression { func NewList(tokens token.List) []*Expression {
var list []*Expression var list []*Expression
tokens.Split(func(parameter token.List) error { for param := range tokens.Split {
expression := Parse(parameter) expression := Parse(param)
list = append(list, expression) list = append(list, expression)
return nil }
})
return list return list
} }

View File

@ -96,30 +96,24 @@ func scanFunctionSignature(file *fs.File, tokens token.List, i int, delimiter to
outputTokens := tokens[typeStart:typeEnd] outputTokens := tokens[typeStart:typeEnd]
err := outputTokens.Split(func(tokens token.List) error { for param := range outputTokens.Split {
function.Output = append(function.Output, core.NewParameter(tokens)) function.Output = append(function.Output, core.NewParameter(param))
return nil
})
if err != nil {
return nil, i, err
} }
} }
parameters := tokens[paramsStart:paramsEnd] parameters := tokens[paramsStart:paramsEnd]
err := parameters.Split(func(tokens token.List) error { for param := range parameters.Split {
if len(tokens) == 0 { if len(param) == 0 {
return errors.New(errors.MissingParameter, file, parameters[0].Position) return nil, i, errors.New(errors.MissingParameter, file, parameters[0].Position)
} }
if len(tokens) == 1 { if len(param) == 1 {
return errors.New(errors.MissingType, file, tokens[0].End()) return nil, i, errors.New(errors.MissingType, file, param[0].End())
} }
function.Input = append(function.Input, core.NewParameter(tokens)) function.Input = append(function.Input, core.NewParameter(param))
return nil }
})
return function, i, err return function, i, nil
} }

View File

@ -30,9 +30,9 @@ func (list List) LastIndexKind(kind Kind) int {
} }
// Split calls the callback function on each set of tokens in a comma separated list. // Split calls the callback function on each set of tokens in a comma separated list.
func (list List) Split(call func(List) error) error { func (list List) Split(yield func(List) bool) {
if len(list) == 0 { if len(list) == 0 {
return nil return
} }
start := 0 start := 0
@ -52,18 +52,16 @@ func (list List) Split(call func(List) error) error {
} }
parameter := list[start:i] parameter := list[start:i]
err := call(parameter)
if err != nil { if !yield(parameter) {
return err return
} }
start = i + 1 start = i + 1
} }
} }
parameter := list[start:] yield(list[start:])
return call(parameter)
} }
// Text returns the concatenated token text. // Text returns the concatenated token text.

View File

@ -1,7 +1,6 @@
package token_test package token_test
import ( import (
"errors"
"testing" "testing"
"git.urbach.dev/cli/q/src/token" "git.urbach.dev/cli/q/src/token"
@ -23,35 +22,28 @@ func TestSplit(t *testing.T) {
tokens := token.Tokenize(src) tokens := token.Tokenize(src)
parameters := []string{} parameters := []string{}
err := tokens.Split(func(parameter token.List) error { for param := range tokens.Split {
parameters = append(parameters, parameter.Text(src)) parameters = append(parameters, param.Text(src))
return nil }
})
assert.Nil(t, err)
assert.DeepEqual(t, parameters, []string{"1+2", "3*4", "5*6", "7+8"}) assert.DeepEqual(t, parameters, []string{"1+2", "3*4", "5*6", "7+8"})
} }
func TestSplitBreak(t *testing.T) {
src := []byte("1,2")
tokens := token.Tokenize(src)
for range tokens.Split {
break
}
}
func TestSplitEmpty(t *testing.T) { func TestSplitEmpty(t *testing.T) {
tokens := token.List{} tokens := token.List{}
err := tokens.Split(func(parameter token.List) error { for range tokens.Split {
return errors.New("error") t.Fail()
}) }
assert.Nil(t, err)
}
func TestSplitError(t *testing.T) {
src := []byte("1,2,3")
tokens := token.Tokenize(src)
err := tokens.Split(func(parameter token.List) error {
return errors.New("error")
})
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "error")
} }
func TestSplitGroups(t *testing.T) { func TestSplitGroups(t *testing.T) {
@ -59,12 +51,10 @@ func TestSplitGroups(t *testing.T) {
tokens := token.Tokenize(src) tokens := token.Tokenize(src)
parameters := []string{} parameters := []string{}
err := tokens.Split(func(parameter token.List) error { for param := range tokens.Split {
parameters = append(parameters, parameter.Text(src)) parameters = append(parameters, param.Text(src))
return nil }
})
assert.Nil(t, err)
assert.DeepEqual(t, parameters, []string{"f(1,2)", "g(3,4)"}) assert.DeepEqual(t, parameters, []string{"f(1,2)", "g(3,4)"})
} }
@ -73,11 +63,9 @@ func TestSplitSingle(t *testing.T) {
tokens := token.Tokenize(src) tokens := token.Tokenize(src)
parameters := []string{} parameters := []string{}
err := tokens.Split(func(parameter token.List) error { for param := range tokens.Split {
parameters = append(parameters, parameter.Text(src)) parameters = append(parameters, param.Text(src))
return nil }
})
assert.Nil(t, err)
assert.DeepEqual(t, parameters, []string{"123"}) assert.DeepEqual(t, parameters, []string{"123"})
} }