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) values, err := walk.Compound(state.value) if err != nil { panic("Tried to convert invalid atoms to values") } for _, value := range values { state.out <- walk.WalkItem { Value: value, Path: path, } } } 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 := <- state.in state.value = walk.Atomise([]walk.WalkValue{nextItem.Value}) state.path = walk.Atomise(nextItem.Path.ToWalkValues()) } type AppendNextCommand struct {} func (cmd AppendNextCommand) exec(state *ProgramState) { nextItem := <- state.in state.value = append(state.value, walk.Atomise([]walk.WalkValue{nextItem.Value})...) state.path = walk.Atomise(nextItem.Path.ToWalkValues()) } 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.SubexState, 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.SubexState 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.SubexState 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 = append(state.path, state.value...) }