<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/subex/subexstate.go
diff options
context:
space:
mode:
Diffstat (limited to 'subex/subexstate.go')
-rw-r--r--subex/subexstate.go43
1 files changed, 31 insertions, 12 deletions
diff --git a/subex/subexstate.go b/subex/subexstate.go
index 62e9d1a..855d44a 100644
--- a/subex/subexstate.go
+++ b/subex/subexstate.go
@@ -2,6 +2,8 @@ package subex
import (
"main/walk"
+ "strconv"
+ "errors"
)
// A state of execution for the transducer
@@ -236,41 +238,54 @@ func (state SubexRangeState) accepting(store Store) [][]walk.Atom {
return nil
}
-func sumValues(values []walk.Atom) walk.ValueNumber {
+func sumValues(atoms []walk.Atom) (walk.ValueNumber, error) {
var sum float64 = 0
+ values, err := walk.MemoryCompound(atoms)
+ if err != nil {
+ return 0, err
+ }
for _, value := range values {
switch v := value.(type) {
+ case walk.ValueNull:
case walk.ValueBool:
if (bool(v)) {
sum += 1
}
case walk.ValueNumber:
sum += float64(v)
- case rune:
- if '0' <= v && v <= '9' {
- sum += float64(v - '0')
+ case walk.ValueString:
+ num, err := strconv.ParseFloat(string(v), 64)
+ if err == nil {
+ sum += num
+ } else {
+ return 0, errors.New("Tried to sum non-castable string")
}
default:
+ return 0, errors.New("Tried to sum non-number")
}
}
- return walk.ValueNumber(sum)
+ return walk.ValueNumber(sum), nil
}
// Run the inputState machine and sum any values output, output the sum
-// Cast non numbers into numbers, ignore anything uncastable
+// Cast non numbers into numbers, branch dies if it is not castable
type SubexSumState struct {
inputState SubexState
next SubexState
- sum walk.ValueNumber
+ acc []walk.Atom
}
func (state SubexSumState) child() SubexState {
return state.inputState
}
func (state SubexSumState) nextAcc(output []walk.Atom) interface{} {
- return sumValues(append(output, state.sum))
+ return walk.ConcatData(state.acc, output)
}
func (state SubexSumState) feedNext(acc interface{}, store Store, char walk.Atom) []SubexBranch {
- total := acc.(walk.ValueNumber)
+ childOutput := acc.([]walk.Atom)
+ total, err := sumValues(childOutput)
+ if err != nil {
+ return nil
+ }
output := []walk.Atom{total}
nextStates := state.next.eat(store.clone(), char)
for i := range nextStates {
@@ -279,7 +294,11 @@ func (state SubexSumState) feedNext(acc interface{}, store Store, char walk.Atom
return nextStates
}
func (state SubexSumState) acceptNext(acc interface{}, store Store) [][]walk.Atom {
- total := acc.(walk.ValueNumber)
+ childOutput := acc.([]walk.Atom)
+ total, err := sumValues(childOutput)
+ if err != nil {
+ return nil
+ }
output := []walk.Atom{total}
outputs := state.next.accepting(store.clone())
for i := range outputs {
@@ -288,11 +307,11 @@ func (state SubexSumState) acceptNext(acc interface{}, store Store) [][]walk.Ato
return outputs
}
func (state SubexSumState) nextParent(child SubexState, acc interface{}) SubexState {
- sum := acc.(walk.ValueNumber)
+ childOutput := acc.([]walk.Atom)
return &SubexSumState {
inputState: child,
next: state.next,
- sum: sum,
+ acc: childOutput,
}
}
func (state SubexSumState) eat(store Store, char walk.Atom) (nextStates []SubexBranch) {