package main type PrintValueCommand struct {} func (cmd PrintValueCommand) exec(state *ProgramState) { for _, item := range state.space { state.out <- item } } type ToggleTerminalCommand struct {} func (cmd ToggleTerminalCommand) exec(state *ProgramState) { toggled := map[TerminalValue]TerminalValue { ArrayBegin: MapBegin, ArrayEnd: MapEnd, MapBegin: ArrayBegin, MapEnd: ArrayEnd, } for i := range state.space { terminal, isTerminal := state.space[i].value.(TerminalValue) if !isTerminal { continue } state.space[i].value = toggled[terminal] } } type FilteredCommand struct { filter Filter command Command } func (cmd FilteredCommand) exec(state *ProgramState) { for _, item := range state.space { if cmd.filter.exec(item) { cmd.command.exec(state) return } } } type SequenceCommand struct { commands []Command } func (cmd SequenceCommand) exec(state *ProgramState) { for _, command := range cmd.commands { command.exec(state) } } type AppendCommand struct { values []WalkValue } func (cmd AppendCommand) exec(state *ProgramState) { for _, value := range cmd.values { state.space = append(state.space, WalkItem { path: nil, value: value, }) } } type PrependCommand struct { values []WalkValue } func (cmd PrependCommand) exec(state *ProgramState) { var newItems []WalkItem for _, value := range cmd.values { newItems = append(newItems, WalkItem { path: nil, value: value, }) } state.space = append(newItems, state.space...) } type PrintLiteralsCommand struct { items []WalkItem } func (cmd PrintLiteralsCommand) exec(state *ProgramState) { for _, item := range cmd.items { state.out <- item } } type DeleteAllCommand struct {} func (cmd DeleteAllCommand) exec(state *ProgramState) { state.space = nil } type Command interface { exec(*ProgramState) }