command.go (4776B)
1 package main 2 3 import ( 4 "main/subex" 5 "main/walk" 6 "fmt" 7 ) 8 9 type Command interface { 10 exec(*ProgramState) 11 String() string 12 } 13 14 type PrintValueCommand struct {} 15 func (cmd PrintValueCommand) exec(state *ProgramState) { 16 err := state.out.Write(walk.WalkItem { 17 Path: state.path, 18 Value: state.value, 19 }) 20 if err != nil { 21 panic("Error while outputting") 22 } 23 state.pc++ 24 } 25 func (cmd PrintValueCommand) String() string { 26 return "p" 27 } 28 29 type NextCommand struct {} 30 func (cmd NextCommand) exec(state *ProgramState) { 31 nextItem, err := state.in.Read() 32 if err != nil { 33 panic("Missing next value") 34 } 35 state.value = nextItem.Value 36 state.path = nextItem.Path 37 state.pc++ 38 } 39 func (cmd NextCommand) String() string { 40 return "n" 41 } 42 43 type AppendNextCommand struct {} 44 func (cmd AppendNextCommand) exec(state *ProgramState) { 45 nextItem, err := state.in.Read() 46 if err != nil { 47 panic("Missing next value") 48 } 49 state.value = append(state.value, nextItem.Value...) 50 state.path = nextItem.Path 51 state.pc++ 52 } 53 func (cmd AppendNextCommand) String() string { 54 return "N" 55 } 56 57 type DeleteValueCommand struct {} 58 func (cmd DeleteValueCommand) exec(state *ProgramState) { 59 state.value = nil 60 state.pc++ 61 } 62 func (cmd DeleteValueCommand) String() string { 63 return "d" 64 } 65 66 type DeletePathCommand struct {} 67 func (cmd DeletePathCommand) exec(state *ProgramState) { 68 state.path = nil 69 state.pc++ 70 } 71 func (cmd DeletePathCommand) String() string { 72 return "D" 73 } 74 75 func runSubex(state subex.Transducer, in walk.ValueList) (walk.ValueList, bool) { 76 out, error := subex.RunTransducer(state, in) 77 if error { 78 return nil, true 79 } 80 return out, false 81 } 82 83 type SubstituteValueCommand struct { 84 subex subex.Transducer 85 } 86 func (cmd SubstituteValueCommand) exec(state *ProgramState) { 87 newValue, err := runSubex(cmd.subex, state.value) 88 if err { 89 state.pc++ 90 } else { 91 state.pc += 2 92 state.value = newValue 93 } 94 } 95 func (cmd SubstituteValueCommand) String() string { 96 return "s/.../" 97 } 98 99 type SubstitutePathCommand struct { 100 subex subex.Transducer 101 } 102 func (cmd SubstitutePathCommand) exec(state *ProgramState) { 103 newPath, err := runSubex(cmd.subex, state.path) 104 if err { 105 state.pc++ 106 } else { 107 state.pc += 2 108 state.path = newPath 109 } 110 } 111 func (cmd SubstitutePathCommand) String() string { 112 return "S/.../" 113 } 114 115 type NoopCommand struct {} 116 func (cmd NoopCommand) exec(state *ProgramState) { 117 state.pc++ 118 } 119 func (cmd NoopCommand) String() string { 120 return "o" 121 } 122 123 type SwapXRegCommand struct {} 124 func (cmd SwapXRegCommand) exec(state *ProgramState) { 125 v := state.value 126 state.value = state.xreg 127 state.xreg = v 128 state.pc++ 129 } 130 func (cmd SwapXRegCommand) String() string { 131 return "x" 132 } 133 134 type AppendXRegCommand struct {} 135 func (cmd AppendXRegCommand) exec(state *ProgramState) { 136 state.xreg = append(state.xreg, state.value...) 137 state.pc++ 138 } 139 func (cmd AppendXRegCommand) String() string { 140 return "X" 141 } 142 143 type SwapYRegCommand struct {} 144 func (cmd SwapYRegCommand) exec(state *ProgramState) { 145 v := state.value 146 state.value = state.yreg 147 state.yreg = v 148 state.pc++ 149 } 150 func (cmd SwapYRegCommand) String() string { 151 return "y" 152 } 153 154 type AppendYRegCommand struct {} 155 func (cmd AppendYRegCommand) exec(state *ProgramState) { 156 state.yreg = append(state.yreg, state.value...) 157 state.pc++ 158 } 159 func (cmd AppendYRegCommand) String() string { 160 return "Y" 161 } 162 163 type SwapZRegCommand struct {} 164 func (cmd SwapZRegCommand) exec(state *ProgramState) { 165 v := state.value 166 state.value = state.zreg 167 state.zreg = v 168 state.pc++ 169 } 170 func (cmd SwapZRegCommand) String() string { 171 return "z" 172 } 173 174 type AppendZRegCommand struct {} 175 func (cmd AppendZRegCommand) exec(state *ProgramState) { 176 state.zreg = append(state.zreg, state.value...) 177 state.pc++ 178 } 179 func (cmd AppendZRegCommand) String() string { 180 return "Z" 181 } 182 183 type SwapPathCommand struct {} 184 func (cmd SwapPathCommand) exec(state *ProgramState) { 185 v := state.value 186 state.value = state.path 187 state.path = v 188 state.pc++ 189 } 190 func (cmd SwapPathCommand) String() string { 191 return "k" 192 } 193 194 type AppendPathCommand struct {} 195 func (cmd AppendPathCommand) exec(state *ProgramState) { 196 state.path = append(state.path, state.value...) 197 state.pc++ 198 } 199 func (cmd AppendPathCommand) String() string { 200 return "K" 201 } 202 203 type JumpCommand struct { 204 destination int 205 } 206 func (cmd JumpCommand) exec(state *ProgramState) { 207 state.pc = cmd.destination 208 } 209 func (cmd JumpCommand) String() string { 210 return fmt.Sprintf("b%v", cmd.destination) 211 } 212 213 // Placeholder as the branch destination may not have been parsed when the branch command is 214 // Should never appear in a program to actually be run 215 type BranchPlaceholderCommand struct { 216 label rune 217 } 218 func (cmd BranchPlaceholderCommand) exec(state *ProgramState) { 219 panic("Tried to execute a BranchPlaceholderCommand!!!") 220 } 221 func (cmd BranchPlaceholderCommand) String() string { 222 return fmt.Sprintf("b%c", cmd.label) 223 }