stred

Stred: Streaming Tree Editor. Like sed but for JSON
git clone http://shtanton.xyz/git/repo/stred
Log | Files | Refs

commit 7b63b7c9d03b23f496ec9bfb8e91be3693b19a8f
parent 9ba3b1d97e8fd2a2e3c4bb08fe350c8dd5f9733e
Author: Charlie Stanton <charlie@shtanton.xyz>
Date:   Sun, 26 Feb 2023 09:37:30 +0000

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

Diffstat:
Msubex/main.go | 4++--
Msubex/subexstate.go | 10+++++-----
Mwalk/walk.go | 4++++
3 files changed, 11 insertions(+), 7 deletions(-)

diff --git 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 @@ -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 @@ -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...) +}