diff options
| author | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-19 09:48:04 +0100 | 
|---|---|---|
| committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-19 09:48:04 +0100 | 
| commit | c6905e06ba73f47495ba86cebe1cb42f141f308d (patch) | |
| tree | 20e81487ab79691437109a6ed54fc1ad174ded66 /walk | |
| parent | 7b48ab9f51a14a540b36722e34b844d21622fcc7 (diff) | |
| download | stred-go-c6905e06ba73f47495ba86cebe1cb42f141f308d.tar | |
Adds casting strings to numbers in the sum operator
Diffstat (limited to 'walk')
| -rw-r--r-- | walk/walk.go | 91 | 
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 | 
