<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/walk
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2023-04-19 09:48:04 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2023-04-19 09:48:04 +0100
commitc6905e06ba73f47495ba86cebe1cb42f141f308d (patch)
tree20e81487ab79691437109a6ed54fc1ad174ded66 /walk
parent7b48ab9f51a14a540b36722e34b844d21622fcc7 (diff)
downloadstred-go-c6905e06ba73f47495ba86cebe1cb42f141f308d.tar
Adds casting strings to numbers in the sum operator
Diffstat (limited to 'walk')
-rw-r--r--walk/walk.go91
1 files changed, 73 insertions, 18 deletions
diff --git a/walk/walk.go b/walk/walk.go
index 4da8040..36e9805 100644
--- a/walk/walk.go
+++ b/walk/walk.go
@@ -390,41 +390,92 @@ func Atomise(in <-chan WalkValue) <-chan Atom {
return out
}
-func Compound(in <-chan Atom) <-chan WalkValue {
- out := make(chan WalkValue)
- go func(out chan<- WalkValue, in <-chan Atom) {
- for {
+func MemoryAtomise(in []WalkValue) (out []Atom) {
+ inChan := make(chan WalkValue)
+ go func(in []WalkValue, out chan<- WalkValue) {
+ for _, value := range in {
+ out<-value
+ }
+ close(out)
+ }(in, inChan)
+ outChan := Atomise(inChan)
+ for atom := range outChan {
+ out = append(out, atom)
+ }
+ return out
+}
+
+type CompoundError int
+
+const (
+ CompoundRuneOutsideString CompoundError = iota
+ CompoundEndStringOutsideString
+ CompoundUnknownAtom
+ CompoundMissingEnd
+ CompoundInvalidStringAtom
+)
+
+func (err CompoundError) Error() string {
+ switch err {
+ case CompoundRuneOutsideString:
+ return "Compound Error: Rune Outside String"
+ case CompoundEndStringOutsideString:
+ return "Compound Error: End String Outside String"
+ case CompoundUnknownAtom:
+ return "Compound Error: Unknown Atom"
+ case CompoundMissingEnd:
+ return "Compound Error: Missing End"
+ case CompoundInvalidStringAtom:
+ return "Compound Error: Invalid String Atom"
+ default:
+ panic("Invalid CompoundError")
+ }
+}
+
+type CompoundResult struct {
+ value WalkValue
+ error error
+}
+
+func Compound(in <-chan Atom) <-chan CompoundResult {
+ out := make(chan CompoundResult)
+ go func(out chan<- CompoundResult, in <-chan Atom) {
+ outer: for {
atom, hasAtom := <-in
if !hasAtom {
break
}
switch v := atom.(type) {
case TerminalValue:
- out<-v
+ out<-CompoundResult{v, nil}
continue
case ValueNull:
- out<-v
+ out<-CompoundResult{v, nil}
continue
case ValueBool:
- out<-v
+ out<-CompoundResult{v, nil}
continue
case ValueNumber:
- out<-v
+ out<-CompoundResult{v, nil}
continue
case rune:
- panic("Error! Rune output by subex but not in a string")
+ out<-CompoundResult{nil, CompoundRuneOutsideString}
+ break outer
case EndString:
- panic("Error! subex output an EndString before BeginString")
+ out<-CompoundResult{nil, CompoundEndStringOutsideString}
+ break outer
case StartString:
default:
- panic("Unknown atom type")
+ out<-CompoundResult{nil, CompoundUnknownAtom}
+ break outer
}
// Handle string start
var builder strings.Builder
loop: for {
atom, hasAtom := <-in
if !hasAtom {
- panic("Missing EndString")
+ out<-CompoundResult{nil, CompoundMissingEnd}
+ break outer
}
switch v := atom.(type) {
case EndString:
@@ -432,17 +483,18 @@ func Compound(in <-chan Atom) <-chan WalkValue {
case rune:
builder.WriteRune(v)
default:
- panic("Invalid atom in string")
+ out<-CompoundResult{nil, CompoundInvalidStringAtom}
+ break outer
}
}
- out<-ValueString(builder.String())
+ out<-CompoundResult{ValueString(builder.String()), nil}
}
close(out)
}(out, in)
return out
}
-func MemoryCompound(in []Atom) (out []WalkValue) {
+func MemoryCompound(in []Atom) (out []WalkValue, err error) {
inChan := make(chan Atom)
go func(in []Atom, out chan<- Atom) {
for _, atom := range in {
@@ -451,8 +503,11 @@ func MemoryCompound(in []Atom) (out []WalkValue) {
close(out)
}(in, inChan)
outChan := Compound(inChan)
- for value := range outChan {
- out = append(out, value)
+ for result := range outChan {
+ if result.error != nil {
+ return out, result.error
+ }
+ out = append(out, result.value)
}
- return out
+ return out, nil
} \ No newline at end of file