diff options
| author | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-18 17:07:25 +0100 | 
|---|---|---|
| committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-18 17:07:25 +0100 | 
| commit | 7b48ab9f51a14a540b36722e34b844d21622fcc7 (patch) | |
| tree | b6acda783d4c7139a419b773272a34ff9024d2c8 /walk | |
| parent | e84cf4ec822c32b4de5098353db2dab700b92bfa (diff) | |
| download | stred-go-7b48ab9f51a14a540b36722e34b844d21622fcc7.tar | |
Creates functions for compounding atoms back into values in the walk module and uses them in subex/main
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 | 
