diff options
Diffstat (limited to 'walk')
-rw-r--r-- | walk/walk.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/walk/walk.go b/walk/walk.go index 33e5554..4da8040 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -4,6 +4,7 @@ import ( "io" "encoding/json" "fmt" + "strings" ) type PathSegment interface {} @@ -377,3 +378,81 @@ func JsonOut(in chan WalkItem) { func ConcatData(first []Atom, second []Atom) []Atom { return append(append([]Atom(nil), first...), second...) } + +func Atomise(in <-chan WalkValue) <-chan Atom { + out := make(chan Atom) + go func(out chan<- Atom, input <-chan WalkValue) { + for value := range input { + value.Pieces(out) + } + close(out) + }(out, in) + return out +} + +func Compound(in <-chan Atom) <-chan WalkValue { + out := make(chan WalkValue) + go func(out chan<- WalkValue, in <-chan Atom) { + for { + atom, hasAtom := <-in + if !hasAtom { + break + } + switch v := atom.(type) { + case TerminalValue: + out<-v + continue + case ValueNull: + out<-v + continue + case ValueBool: + out<-v + continue + case ValueNumber: + out<-v + continue + case rune: + panic("Error! Rune output by subex but not in a string") + case EndString: + panic("Error! subex output an EndString before BeginString") + case StartString: + default: + panic("Unknown atom type") + } + // Handle string start + var builder strings.Builder + loop: for { + atom, hasAtom := <-in + if !hasAtom { + panic("Missing EndString") + } + switch v := atom.(type) { + case EndString: + break loop + case rune: + builder.WriteRune(v) + default: + panic("Invalid atom in string") + } + } + out<-ValueString(builder.String()) + } + close(out) + }(out, in) + return out +} + +func MemoryCompound(in []Atom) (out []WalkValue) { + inChan := make(chan Atom) + go func(in []Atom, out chan<- Atom) { + for _, atom := range in { + out<-atom + } + close(out) + }(in, inChan) + outChan := Compound(inChan) + for value := range outChan { + out = append(out, value) + } + return out +}
\ No newline at end of file |