diff options
author | Charlie Stanton <charlie@shtanton.xyz> | 2023-02-26 09:37:30 +0000 |
---|---|---|
committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-02-26 09:37:30 +0000 |
commit | 7b63b7c9d03b23f496ec9bfb8e91be3693b19a8f (patch) | |
tree | 824aa1c659e532537f812be36d0e0384eae1b2fd | |
parent | 9ba3b1d97e8fd2a2e3c4bb08fe350c8dd5f9733e (diff) | |
download | stred-go-7b63b7c9d03b23f496ec9bfb8e91be3693b19a8f.tar |
Replace append with walk.ConcatData in many places to fix bug to do with semantics of append
When doing append, be very careful as it does make changes in place to the underlying array of the slice which may affect other slices
-rw-r--r-- | subex/main.go | 4 | ||||
-rw-r--r-- | subex/subexstate.go | 10 | ||||
-rw-r--r-- | walk/walk.go | 4 |
3 files changed, 11 insertions, 7 deletions
diff --git a/subex/main.go b/subex/main.go index e53a3c6..138de9a 100644 --- a/subex/main.go +++ b/subex/main.go @@ -66,7 +66,7 @@ type SubexBranch struct { func (pair SubexBranch) eat(char walk.Datum) []SubexBranch { states := pair.state.eat(pair.store, char) for i := range states { - states[i].output = append(pair.output, states[i].output...) + states[i].output = walk.ConcatData(pair.output, states[i].output) } return states } @@ -110,7 +110,7 @@ func RunTransducer(transducer SubexState, input <-chan walk.Datum) (output []wal for _, state := range states { outputEnds := state.accepting() for _, outputEnd := range outputEnds { - return append(state.output, outputEnd...), false + return walk.ConcatData(state.output, outputEnd), false } } return nil, true diff --git a/subex/subexstate.go b/subex/subexstate.go index 9e0d61a..415714f 100644 --- a/subex/subexstate.go +++ b/subex/subexstate.go @@ -35,7 +35,7 @@ type SubexStoreState struct { func (state SubexStoreState) eat(store Store, char walk.Datum) (nextStates []SubexBranch) { acceptedOutputs := state.match.accepting(store) for _, acceptedOutput := range acceptedOutputs { - nextStore := store.withValue(state.slot, append(state.toStore, acceptedOutput...)) + nextStore := store.withValue(state.slot, walk.ConcatData(state.toStore, acceptedOutput)) nextStates = append(nextStates, state.next.eat(nextStore.clone(), char)...) } nextMatchStates := state.match.eat(store.clone(), char) @@ -45,7 +45,7 @@ func (state SubexStoreState) eat(store Store, char walk.Datum) (nextStates []Sub match: matchState.state, slot: state.slot, next: state.next, - toStore: append(state.toStore, matchState.output...), + toStore: walk.ConcatData(state.toStore, matchState.output), }, output: nil, store: store.clone(), @@ -56,7 +56,7 @@ func (state SubexStoreState) eat(store Store, char walk.Datum) (nextStates []Sub func (state SubexStoreState) accepting(store Store) (outputs [][]walk.Datum) { acceptedOutputs := state.match.accepting(store) for _, acceptedOutput := range acceptedOutputs { - nextStore := store.withValue(state.slot, append(state.toStore, acceptedOutput...)) + nextStore := store.withValue(state.slot, walk.ConcatData(state.toStore, acceptedOutput)) outputs = append(outputs, state.next.accepting(nextStore)...) } return outputs @@ -79,7 +79,7 @@ func (state SubexOutputState) eat(store Store, char walk.Datum) []SubexBranch { content := state.build(store) nextStates := state.next.eat(store, char) for i := range nextStates { - nextStates[i].output = append(content, nextStates[i].output...) + nextStates[i].output = walk.ConcatData(content, nextStates[i].output) } return nextStates } @@ -87,7 +87,7 @@ func (state SubexOutputState) accepting(store Store) [][]walk.Datum { content := state.build(store) outputs := state.next.accepting(store) for i := range outputs { - outputs[i] = append(content, outputs[i]...) + outputs[i] = walk.ConcatData(content, outputs[i]) } return outputs } diff --git a/walk/walk.go b/walk/walk.go index 30bfb29..a9b40b7 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -373,3 +373,7 @@ func JsonOut(in chan WalkItem) { } fmt.Print("\n") } + +func ConcatData(first []Datum, second []Datum) []Datum { + return append(append([]Datum(nil), first...), second...) +} |