From b80b72cfe2e02ce7b9467e161703a47e433f992d Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Wed, 19 Apr 2023 16:00:04 +0100 Subject: Replaces the workspace with 3 distinct registers: path, value and xreg workspace contained a list of WalkItems, pairs of paths and values. The new system can still hold a list of values but only one path, which is in itself a list of values. The X register is miscellaneous. All 3 hold a list of values (which are JSON tokens) --- main/command.go | 49 +++++++++++++++++++++++++------------------------ main/main.go | 13 +++++++++---- walk/walk.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 28 deletions(-) diff --git a/main/command.go b/main/command.go index 8053b86..511bda8 100644 --- a/main/command.go +++ b/main/command.go @@ -7,8 +7,12 @@ import ( type PrintValueCommand struct {} func (cmd PrintValueCommand) exec(state *ProgramState) { - for _, item := range state.space { - state.out <- item + path := walk.PathFromWalkValues(state.path) + for _, value := range state.value { + state.out <- walk.WalkItem { + Value: value, + Path: path, + } } } @@ -21,12 +25,12 @@ func (cmd ToggleTerminalCommand) exec(state *ProgramState) { walk.MapEnd: walk.ArrayEnd, } - for i := range state.space { - terminal, isTerminal := state.space[i].Value.(walk.TerminalValue) + for i := range state.value { + terminal, isTerminal := state.value[i].(walk.TerminalValue) if !isTerminal { continue } - state.space[i].Value = toggled[terminal] + state.value[i] = toggled[terminal] } } @@ -35,8 +39,12 @@ type FilteredCommand struct { command Command } func (cmd FilteredCommand) exec(state *ProgramState) { - for _, item := range state.space { - if cmd.filter.exec(item) { + path := walk.PathFromWalkValues(state.path) + for _, value := range state.value { + if cmd.filter.exec(walk.WalkItem { + Value: value, + Path: path, + }) { cmd.command.exec(state) return } @@ -56,38 +64,30 @@ type AppendLiteralCommand struct { values []walk.WalkValue } func (cmd AppendLiteralCommand) exec(state *ProgramState) { - for _, value := range cmd.values { - state.space = append(state.space, walk.WalkItem { - Path: nil, - Value: value, - }) - } + state.value = append(state.value, cmd.values...) } type PrependLiteralCommand struct { values []walk.WalkValue } func (cmd PrependLiteralCommand) exec(state *ProgramState) { - var newItems []walk.WalkItem - for _, value := range cmd.values { - newItems = append(newItems, walk.WalkItem { - Path: nil, - Value: value, - }) - } - state.space = append(newItems, state.space...) + var newItems []walk.WalkValue + newItems = append(newItems, cmd.values...) + state.value = append(newItems, state.value...) } type NextCommand struct {} func (cmd NextCommand) exec(state *ProgramState) { nextItem := <- state.in - state.space = []walk.WalkItem{nextItem} + state.value = []walk.WalkValue{nextItem.Value} + state.path = nextItem.Path.ToWalkValues() } type AppendNextCommand struct {} func (cmd AppendNextCommand) exec(state *ProgramState) { nextItem := <- state.in - state.space = append(state.space, nextItem) + state.value = append(state.value, nextItem.Value) + state.path = nextItem.Path.ToWalkValues() } type PrintLiteralsCommand struct { @@ -101,7 +101,8 @@ func (cmd PrintLiteralsCommand) exec(state *ProgramState) { type DeleteAllCommand struct {} func (cmd DeleteAllCommand) exec(state *ProgramState) { - state.space = nil + state.path = nil + state.value = nil } type SubstituteCommand struct { diff --git a/main/main.go b/main/main.go index 902c5b9..923ffa6 100644 --- a/main/main.go +++ b/main/main.go @@ -9,7 +9,7 @@ import ( type Program []Command type ProgramState struct { - space []walk.WalkItem + path, value, xreg []walk.WalkValue in chan walk.WalkItem out chan walk.WalkItem program []Command @@ -50,13 +50,18 @@ func main() { go func () { for walkItem := range dataStream { - state.space = []walk.WalkItem{walkItem} + state.value = []walk.WalkValue{walkItem.Value} + state.path = walkItem.Path.ToWalkValues() for _, cmd := range state.program { cmd.exec(&state) } if !quiet { - for _, item := range state.space { - state.out <- item + path := walk.PathFromWalkValues(state.path) + for _, value := range state.value { + state.out <- walk.WalkItem { + Value: value, + Path: path, + } } } } diff --git a/walk/walk.go b/walk/walk.go index 64f16ac..cc17245 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -5,10 +5,41 @@ import ( "encoding/json" "fmt" "strings" + "math" ) +// int or string type PathSegment interface {} type Path []PathSegment +func (path Path) ToWalkValues() []WalkValue { + var values []WalkValue + for _, segment := range path { + switch s := segment.(type) { + case int: + values = append(values, ValueNumber(s)) + case string: + values = append(values, ValueString(s)) + default: + panic("Invalid PathSegment") + } + } + return values +} + +func PathFromWalkValues(values []WalkValue) Path { + var segments []PathSegment + for _, value := range values { + switch v := value.(type) { + case ValueNumber: + segments = append(segments, int(math.Round(float64(v)))) + case ValueString: + segments = append(segments, string(v)) + default: + panic("Invalid value in path") + } + } + return segments +} type TerminalValue int const ( -- cgit v1.2.3