package main import ( "main/walk" "main/subex" ) type PrintValueCommand struct {} func (cmd PrintValueCommand) exec(state *ProgramState) { path := walk.PathFromWalkValues(state.path) for _, value := range state.value { 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.WalkValue{nextItem.Value} state.path = nextItem.Path.ToWalkValues() } type AppendNextCommand struct {} func (cmd AppendNextCommand) exec(state *ProgramState) { nextItem := <- state.in state.value = append(state.value, nextItem.Value) state.path = nextItem.Path.ToWalkValues() } type DeleteAllCommand struct {} func (cmd DeleteAllCommand) exec(state *ProgramState) { state.path = nil state.value = nil } type SubstituteCommand struct { subex subex.SubexState next Command } func (cmd SubstituteCommand) exec(state *ProgramState) { valueStream := make(chan walk.WalkValue) go func(in []walk.WalkValue, out chan<- walk.WalkValue) { for _, value := range in { out <- value } close(out) }(state.value, valueStream) atomStream := walk.Atomise(valueStream) atomsOut, error := subex.RunTransducer(cmd.subex, atomStream) if error { return } valuesOut, err := walk.MemoryCompound(atomsOut) if err != nil { return } state.value = valuesOut cmd.next.exec(state) } type Command interface { exec(*ProgramState) } 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...) }