package main import ( "main/walk" "main/subex" ) type Command interface { exec(*ProgramState) } type PrintValueCommand struct {} func (cmd PrintValueCommand) exec(state *ProgramState) { pathValues, err := walk.Compound(state.path) if err != nil { panic("Tried to convert invalid atoms to values") } path := walk.PathFromWalkValues(pathValues) state.out.Print(path, state.value) } type SequenceCommand struct { commands []Command } func (cmd SequenceCommand) exec(state *ProgramState) { for _, command := range cmd.commands { command.exec(state) } } type NextCommand struct {} func (cmd NextCommand) exec(state *ProgramState) { nextItem, err := state.in.Read() if err != nil { panic("Missing next value") } state.value = nextItem.Value state.path = nextItem.Path } type AppendNextCommand struct {} func (cmd AppendNextCommand) exec(state *ProgramState) { nextItem, err := state.in.Read() if err != nil { panic("Missing next value") } state.value = append(state.value, nextItem.Value...) state.path = nextItem.Path } type DeleteValueCommand struct {} func (cmd DeleteValueCommand) exec(state *ProgramState) { state.value = nil } type DeletePathCommand struct {} func (cmd DeletePathCommand) exec(state *ProgramState) { state.path = nil } func runSubex(state subex.Transducer, in []walk.Atom) (out []walk.Atom, error bool) { atomsOut, error := subex.RunTransducer(state, in) if error { return nil, true } return atomsOut, false } type SubstituteValueCommand struct { subex subex.Transducer next Command } func (cmd SubstituteValueCommand) exec(state *ProgramState) { newValue, err := runSubex(cmd.subex, state.value) if err { return } state.value = newValue cmd.next.exec(state) } type SubstitutePathCommand struct { subex subex.Transducer next Command } func (cmd SubstitutePathCommand) exec(state *ProgramState) { newPath, err := runSubex(cmd.subex, state.path) if err { return } state.path = newPath cmd.next.exec(state) } type NoopCommand struct {} func (cmd NoopCommand) exec(state *ProgramState) {} type SwapXRegCommand struct {} func (cmd SwapXRegCommand) exec(state *ProgramState) { v := state.value state.value = state.xreg state.xreg = v } type AppendXRegCommand struct {} func (cmd AppendXRegCommand) exec(state *ProgramState) { state.xreg = append(state.xreg, state.value...) } type SwapPathCommand struct {} func (cmd SwapPathCommand) exec(state *ProgramState) { v := state.value state.value = state.path state.path = v } type AppendPathCommand struct {} func (cmd AppendPathCommand) exec(state *ProgramState) { state.path = walk.ConcatData(state.path, state.value) }