From c6905e06ba73f47495ba86cebe1cb42f141f308d Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Wed, 19 Apr 2023 09:48:04 +0100 Subject: Adds casting strings to numbers in the sum operator --- walk/walk.go | 91 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 18 deletions(-) (limited to 'walk') 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 -- cgit v1.2.3