├── README.md ├── LICENSE ├── gen-opcodes.go ├── pygo.go ├── cmd └── tiny-interp │ └── main.go └── opcodes_gen.go /README.md: -------------------------------------------------------------------------------- 1 | pygo 2 | ==== 3 | 4 | `pygo` is WIP project to implement a `python` interpreter in the `Go` programming language. 5 | `pygo` is a learning vehicule for interpreter technologies. 6 | 7 | Most of this work has been derived from the 8 | [AOSA Book](http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html) 9 | chapter "A Python Interpreter Written in Python" and its accompanying source 10 | code in the [github.com/nedbat/byterun](https://github.com/nedbat/byterun) repository. 11 | 12 | `pygo` interprets `python2` bytecode. 13 | It does not (yet?) directly compile `python` code to bytecode and then 14 | interprets it. 15 | `pygo` assumes the code has been already compiled to bytecode by some mechanism. 16 | 17 | ## tiny-interp 18 | 19 | As in the AOSA book, we'll start with a tiny interpreter, `tiny-interp`. 20 | The code is under `cmd/tiny-interp`. 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright ©2016 The pygo Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | * Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | * Neither the name of the pygo project nor the names of its authors and 11 | contributors may be used to endorse or promote products derived from this 12 | software without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /gen-opcodes.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The pygo Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "bytes" 11 | "encoding/json" 12 | "fmt" 13 | "log" 14 | "os" 15 | "os/exec" 16 | ) 17 | 18 | func main() { 19 | cmd := exec.Command( 20 | "python3", "-c", 21 | "import json, dis, sys; json.dump(dis.opname, fp=sys.stdout)", 22 | ) 23 | buf := new(bytes.Buffer) 24 | cmd.Stdout = buf 25 | cmd.Stderr = os.Stderr 26 | err := cmd.Run() 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | 31 | var opnames []string 32 | err = json.NewDecoder(buf).Decode(&opnames) 33 | if err != nil { 34 | log.Fatalf("error decoding opnames: %v\n", err) 35 | } 36 | 37 | o, err := os.Create("opcodes_gen.go") 38 | if err != nil { 39 | log.Fatal(err) 40 | } 41 | defer o.Close() 42 | 43 | _, err = o.WriteString(header) 44 | if err != nil { 45 | log.Fatal(err) 46 | } 47 | 48 | fmt.Fprint(o, "// Python-3 Opcodes\nconst (\n") 49 | for i, v := range opnames { 50 | if v[0] == '<' { 51 | v = fmt.Sprintf("%03d", i) 52 | } 53 | fmt.Fprintf(o, "\tOp_%s Opcode = %d\n", v, i) 54 | } 55 | fmt.Fprint(o, ")\n\n") 56 | 57 | fmt.Fprint(o, "func (op Opcode) String() string {\n\tswitch op {\n") 58 | for i, v := range opnames { 59 | fmt.Fprintf(o, "\t\tcase %d: return %q\n", i, v) 60 | } 61 | fmt.Fprint(o, "\tdefault:panic(fmt.Errorf(\"invalid opcode value %%d\",byte(op)))\n}\nreturn \"\"}\n\n") 62 | 63 | err = o.Close() 64 | if err != nil { 65 | log.Fatal(err) 66 | } 67 | 68 | } 69 | 70 | const header = `// Copyright 2016 The pygo Authors. All rights reserved. 71 | // Use of this source code is governed by a BSD-style 72 | // license that can be found in the LICENSE file. 73 | 74 | package pygo 75 | 76 | ` 77 | -------------------------------------------------------------------------------- /pygo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The pygo Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:generate go run gen-opcodes.go 6 | //go:generate goimports -w opcodes_gen.go 7 | 8 | // pygo exposes an API to interpret Python bytecode. 9 | package pygo 10 | 11 | import ( 12 | "fmt" 13 | ) 14 | 15 | // Opcode is a single bytecode operation for the Python interpreter. 16 | // Operands (if any) for the opcode follow in the bytecode stream. 17 | type Opcode byte 18 | 19 | const ( 20 | OpLoadValue Opcode = iota 21 | OpLoadName 22 | OpStoreName 23 | OpAdd 24 | OpPrint 25 | ) 26 | 27 | // Instruction is a single instruction in a bytecode stream. 28 | type Instruction interface{} 29 | 30 | // Code is a complete bytecompiled program together with data. 31 | type Code struct { 32 | Prog []Instruction // Prog is the set of instructions to execute. 33 | Numbers []int // Numbers is the data being manipulated by the program. 34 | Names []string // Names is the list of variables' names. 35 | } 36 | 37 | // Interpreter interprets instructions for the pygo interpreter. 38 | type Interpreter struct { 39 | stack stack 40 | env map[string]int 41 | } 42 | 43 | // New creates a new Python interpreter. 44 | func New() *Interpreter { 45 | return &Interpreter{ 46 | stack: stack{}, 47 | env: make(map[string]int), 48 | } 49 | } 50 | 51 | // Run interprets code compiled to bytecode by some means. 52 | func (interp *Interpreter) Run(code Code) { 53 | prog := code.Prog 54 | for pc := 0; pc < len(prog); pc++ { 55 | op := prog[pc].(Opcode) 56 | switch op { 57 | case OpLoadValue: 58 | pc++ 59 | val := code.Numbers[prog[pc].(int)] 60 | interp.stack.push(val) 61 | case OpAdd: 62 | lhs := interp.stack.pop() 63 | rhs := interp.stack.pop() 64 | sum := lhs + rhs 65 | interp.stack.push(sum) 66 | case OpPrint: 67 | val := interp.stack.pop() 68 | fmt.Println(val) 69 | case OpLoadName: 70 | pc++ 71 | name := code.Names[prog[pc].(int)] 72 | val := interp.env[name] 73 | interp.stack.push(val) 74 | case OpStoreName: 75 | pc++ 76 | name := code.Names[prog[pc].(int)] 77 | val := interp.stack.pop() 78 | interp.env[name] = val 79 | } 80 | } 81 | } 82 | 83 | type stack struct { 84 | stk []int 85 | } 86 | 87 | func (s *stack) push(v int) { 88 | s.stk = append(s.stk, v) 89 | } 90 | 91 | func (s *stack) pop() int { 92 | i := len(s.stk) - 1 93 | v := s.stk[i] 94 | s.stk = s.stk[:i] 95 | return v 96 | } 97 | -------------------------------------------------------------------------------- /cmd/tiny-interp/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The pygo Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import "fmt" 8 | 9 | func main() { 10 | // code: the set of instructions to execute '7+5' 11 | code := Code{ 12 | Prog: []Instruction{ 13 | OpLoadValue, 0, 14 | OpStoreName, 0, 15 | OpLoadValue, 1, 16 | OpStoreName, 1, 17 | OpLoadName, 0, 18 | OpLoadName, 1, 19 | OpAdd, 20 | OpPrint, 21 | }, 22 | Numbers: []int{1, 2}, 23 | Names: []string{"a", "b"}, 24 | } 25 | 26 | interp := New() 27 | interp.Run(code) 28 | } 29 | 30 | // Opcode is a single bytecode operation for the tiny interpreter. 31 | // Operands (if any) for the opcode follow in the bytecode stream. 32 | type Opcode int 33 | 34 | const ( 35 | OpLoadValue Opcode = iota 36 | OpLoadName 37 | OpStoreName 38 | OpAdd 39 | OpPrint 40 | ) 41 | 42 | // Instruction is a single instruction in a bytecode stream. 43 | type Instruction interface{} 44 | 45 | // Code is a complete bytecompiled program together with data. 46 | type Code struct { 47 | Prog []Instruction // Prog is the set of instructions to execute. 48 | Numbers []int // Numbers is the data being manipulated by the program. 49 | Names []string // Names is the list of variables' names. 50 | } 51 | 52 | // Interpreter interprets instructions for the tiny-interp interpreter. 53 | type Interpreter struct { 54 | stack stack 55 | env map[string]int 56 | } 57 | 58 | func New() *Interpreter { 59 | return &Interpreter{ 60 | stack: stack{}, 61 | env: make(map[string]int), 62 | } 63 | } 64 | 65 | func (interp *Interpreter) Run(code Code) { 66 | prog := code.Prog 67 | for pc := 0; pc < len(prog); pc++ { 68 | op := prog[pc].(Opcode) 69 | switch op { 70 | case OpLoadValue: 71 | pc++ 72 | val := code.Numbers[prog[pc].(int)] 73 | interp.stack.push(val) 74 | case OpAdd: 75 | lhs := interp.stack.pop() 76 | rhs := interp.stack.pop() 77 | sum := lhs + rhs 78 | interp.stack.push(sum) 79 | case OpPrint: 80 | val := interp.stack.pop() 81 | fmt.Println(val) 82 | case OpLoadName: 83 | pc++ 84 | name := code.Names[prog[pc].(int)] 85 | val := interp.env[name] 86 | interp.stack.push(val) 87 | case OpStoreName: 88 | pc++ 89 | name := code.Names[prog[pc].(int)] 90 | val := interp.stack.pop() 91 | interp.env[name] = val 92 | } 93 | } 94 | } 95 | 96 | type stack struct { 97 | stk []int 98 | } 99 | 100 | func (s *stack) push(v int) { 101 | s.stk = append(s.stk, v) 102 | } 103 | 104 | func (s *stack) pop() int { 105 | i := len(s.stk) - 1 106 | v := s.stk[i] 107 | s.stk = s.stk[:i] 108 | return v 109 | } 110 | -------------------------------------------------------------------------------- /opcodes_gen.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The pygo Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package pygo 6 | 7 | import "fmt" 8 | 9 | // Python-3 Opcodes 10 | const ( 11 | Op_000 Opcode = 0 12 | Op_POP_TOP Opcode = 1 13 | Op_ROT_TWO Opcode = 2 14 | Op_ROT_THREE Opcode = 3 15 | Op_DUP_TOP Opcode = 4 16 | Op_DUP_TOP_TWO Opcode = 5 17 | Op_006 Opcode = 6 18 | Op_007 Opcode = 7 19 | Op_008 Opcode = 8 20 | Op_NOP Opcode = 9 21 | Op_UNARY_POSITIVE Opcode = 10 22 | Op_UNARY_NEGATIVE Opcode = 11 23 | Op_UNARY_NOT Opcode = 12 24 | Op_013 Opcode = 13 25 | Op_014 Opcode = 14 26 | Op_UNARY_INVERT Opcode = 15 27 | Op_BINARY_MATRIX_MULTIPLY Opcode = 16 28 | Op_INPLACE_MATRIX_MULTIPLY Opcode = 17 29 | Op_018 Opcode = 18 30 | Op_BINARY_POWER Opcode = 19 31 | Op_BINARY_MULTIPLY Opcode = 20 32 | Op_021 Opcode = 21 33 | Op_BINARY_MODULO Opcode = 22 34 | Op_BINARY_ADD Opcode = 23 35 | Op_BINARY_SUBTRACT Opcode = 24 36 | Op_BINARY_SUBSCR Opcode = 25 37 | Op_BINARY_FLOOR_DIVIDE Opcode = 26 38 | Op_BINARY_TRUE_DIVIDE Opcode = 27 39 | Op_INPLACE_FLOOR_DIVIDE Opcode = 28 40 | Op_INPLACE_TRUE_DIVIDE Opcode = 29 41 | Op_030 Opcode = 30 42 | Op_031 Opcode = 31 43 | Op_032 Opcode = 32 44 | Op_033 Opcode = 33 45 | Op_034 Opcode = 34 46 | Op_035 Opcode = 35 47 | Op_036 Opcode = 36 48 | Op_037 Opcode = 37 49 | Op_038 Opcode = 38 50 | Op_039 Opcode = 39 51 | Op_040 Opcode = 40 52 | Op_041 Opcode = 41 53 | Op_042 Opcode = 42 54 | Op_043 Opcode = 43 55 | Op_044 Opcode = 44 56 | Op_045 Opcode = 45 57 | Op_046 Opcode = 46 58 | Op_047 Opcode = 47 59 | Op_048 Opcode = 48 60 | Op_049 Opcode = 49 61 | Op_GET_AITER Opcode = 50 62 | Op_GET_ANEXT Opcode = 51 63 | Op_BEFORE_ASYNC_WITH Opcode = 52 64 | Op_053 Opcode = 53 65 | Op_054 Opcode = 54 66 | Op_INPLACE_ADD Opcode = 55 67 | Op_INPLACE_SUBTRACT Opcode = 56 68 | Op_INPLACE_MULTIPLY Opcode = 57 69 | Op_058 Opcode = 58 70 | Op_INPLACE_MODULO Opcode = 59 71 | Op_STORE_SUBSCR Opcode = 60 72 | Op_DELETE_SUBSCR Opcode = 61 73 | Op_BINARY_LSHIFT Opcode = 62 74 | Op_BINARY_RSHIFT Opcode = 63 75 | Op_BINARY_AND Opcode = 64 76 | Op_BINARY_XOR Opcode = 65 77 | Op_BINARY_OR Opcode = 66 78 | Op_INPLACE_POWER Opcode = 67 79 | Op_GET_ITER Opcode = 68 80 | Op_GET_YIELD_FROM_ITER Opcode = 69 81 | Op_PRINT_EXPR Opcode = 70 82 | Op_LOAD_BUILD_CLASS Opcode = 71 83 | Op_YIELD_FROM Opcode = 72 84 | Op_GET_AWAITABLE Opcode = 73 85 | Op_074 Opcode = 74 86 | Op_INPLACE_LSHIFT Opcode = 75 87 | Op_INPLACE_RSHIFT Opcode = 76 88 | Op_INPLACE_AND Opcode = 77 89 | Op_INPLACE_XOR Opcode = 78 90 | Op_INPLACE_OR Opcode = 79 91 | Op_BREAK_LOOP Opcode = 80 92 | Op_WITH_CLEANUP_START Opcode = 81 93 | Op_WITH_CLEANUP_FINISH Opcode = 82 94 | Op_RETURN_VALUE Opcode = 83 95 | Op_IMPORT_STAR Opcode = 84 96 | Op_085 Opcode = 85 97 | Op_YIELD_VALUE Opcode = 86 98 | Op_POP_BLOCK Opcode = 87 99 | Op_END_FINALLY Opcode = 88 100 | Op_POP_EXCEPT Opcode = 89 101 | Op_STORE_NAME Opcode = 90 102 | Op_DELETE_NAME Opcode = 91 103 | Op_UNPACK_SEQUENCE Opcode = 92 104 | Op_FOR_ITER Opcode = 93 105 | Op_UNPACK_EX Opcode = 94 106 | Op_STORE_ATTR Opcode = 95 107 | Op_DELETE_ATTR Opcode = 96 108 | Op_STORE_GLOBAL Opcode = 97 109 | Op_DELETE_GLOBAL Opcode = 98 110 | Op_099 Opcode = 99 111 | Op_LOAD_CONST Opcode = 100 112 | Op_LOAD_NAME Opcode = 101 113 | Op_BUILD_TUPLE Opcode = 102 114 | Op_BUILD_LIST Opcode = 103 115 | Op_BUILD_SET Opcode = 104 116 | Op_BUILD_MAP Opcode = 105 117 | Op_LOAD_ATTR Opcode = 106 118 | Op_COMPARE_OP Opcode = 107 119 | Op_IMPORT_NAME Opcode = 108 120 | Op_IMPORT_FROM Opcode = 109 121 | Op_JUMP_FORWARD Opcode = 110 122 | Op_JUMP_IF_FALSE_OR_POP Opcode = 111 123 | Op_JUMP_IF_TRUE_OR_POP Opcode = 112 124 | Op_JUMP_ABSOLUTE Opcode = 113 125 | Op_POP_JUMP_IF_FALSE Opcode = 114 126 | Op_POP_JUMP_IF_TRUE Opcode = 115 127 | Op_LOAD_GLOBAL Opcode = 116 128 | Op_117 Opcode = 117 129 | Op_118 Opcode = 118 130 | Op_CONTINUE_LOOP Opcode = 119 131 | Op_SETUP_LOOP Opcode = 120 132 | Op_SETUP_EXCEPT Opcode = 121 133 | Op_SETUP_FINALLY Opcode = 122 134 | Op_123 Opcode = 123 135 | Op_LOAD_FAST Opcode = 124 136 | Op_STORE_FAST Opcode = 125 137 | Op_DELETE_FAST Opcode = 126 138 | Op_127 Opcode = 127 139 | Op_128 Opcode = 128 140 | Op_129 Opcode = 129 141 | Op_RAISE_VARARGS Opcode = 130 142 | Op_CALL_FUNCTION Opcode = 131 143 | Op_MAKE_FUNCTION Opcode = 132 144 | Op_BUILD_SLICE Opcode = 133 145 | Op_MAKE_CLOSURE Opcode = 134 146 | Op_LOAD_CLOSURE Opcode = 135 147 | Op_LOAD_DEREF Opcode = 136 148 | Op_STORE_DEREF Opcode = 137 149 | Op_DELETE_DEREF Opcode = 138 150 | Op_139 Opcode = 139 151 | Op_CALL_FUNCTION_VAR Opcode = 140 152 | Op_CALL_FUNCTION_KW Opcode = 141 153 | Op_CALL_FUNCTION_VAR_KW Opcode = 142 154 | Op_SETUP_WITH Opcode = 143 155 | Op_EXTENDED_ARG Opcode = 144 156 | Op_LIST_APPEND Opcode = 145 157 | Op_SET_ADD Opcode = 146 158 | Op_MAP_ADD Opcode = 147 159 | Op_LOAD_CLASSDEREF Opcode = 148 160 | Op_BUILD_LIST_UNPACK Opcode = 149 161 | Op_BUILD_MAP_UNPACK Opcode = 150 162 | Op_BUILD_MAP_UNPACK_WITH_CALL Opcode = 151 163 | Op_BUILD_TUPLE_UNPACK Opcode = 152 164 | Op_BUILD_SET_UNPACK Opcode = 153 165 | Op_SETUP_ASYNC_WITH Opcode = 154 166 | Op_155 Opcode = 155 167 | Op_156 Opcode = 156 168 | Op_157 Opcode = 157 169 | Op_158 Opcode = 158 170 | Op_159 Opcode = 159 171 | Op_160 Opcode = 160 172 | Op_161 Opcode = 161 173 | Op_162 Opcode = 162 174 | Op_163 Opcode = 163 175 | Op_164 Opcode = 164 176 | Op_165 Opcode = 165 177 | Op_166 Opcode = 166 178 | Op_167 Opcode = 167 179 | Op_168 Opcode = 168 180 | Op_169 Opcode = 169 181 | Op_170 Opcode = 170 182 | Op_171 Opcode = 171 183 | Op_172 Opcode = 172 184 | Op_173 Opcode = 173 185 | Op_174 Opcode = 174 186 | Op_175 Opcode = 175 187 | Op_176 Opcode = 176 188 | Op_177 Opcode = 177 189 | Op_178 Opcode = 178 190 | Op_179 Opcode = 179 191 | Op_180 Opcode = 180 192 | Op_181 Opcode = 181 193 | Op_182 Opcode = 182 194 | Op_183 Opcode = 183 195 | Op_184 Opcode = 184 196 | Op_185 Opcode = 185 197 | Op_186 Opcode = 186 198 | Op_187 Opcode = 187 199 | Op_188 Opcode = 188 200 | Op_189 Opcode = 189 201 | Op_190 Opcode = 190 202 | Op_191 Opcode = 191 203 | Op_192 Opcode = 192 204 | Op_193 Opcode = 193 205 | Op_194 Opcode = 194 206 | Op_195 Opcode = 195 207 | Op_196 Opcode = 196 208 | Op_197 Opcode = 197 209 | Op_198 Opcode = 198 210 | Op_199 Opcode = 199 211 | Op_200 Opcode = 200 212 | Op_201 Opcode = 201 213 | Op_202 Opcode = 202 214 | Op_203 Opcode = 203 215 | Op_204 Opcode = 204 216 | Op_205 Opcode = 205 217 | Op_206 Opcode = 206 218 | Op_207 Opcode = 207 219 | Op_208 Opcode = 208 220 | Op_209 Opcode = 209 221 | Op_210 Opcode = 210 222 | Op_211 Opcode = 211 223 | Op_212 Opcode = 212 224 | Op_213 Opcode = 213 225 | Op_214 Opcode = 214 226 | Op_215 Opcode = 215 227 | Op_216 Opcode = 216 228 | Op_217 Opcode = 217 229 | Op_218 Opcode = 218 230 | Op_219 Opcode = 219 231 | Op_220 Opcode = 220 232 | Op_221 Opcode = 221 233 | Op_222 Opcode = 222 234 | Op_223 Opcode = 223 235 | Op_224 Opcode = 224 236 | Op_225 Opcode = 225 237 | Op_226 Opcode = 226 238 | Op_227 Opcode = 227 239 | Op_228 Opcode = 228 240 | Op_229 Opcode = 229 241 | Op_230 Opcode = 230 242 | Op_231 Opcode = 231 243 | Op_232 Opcode = 232 244 | Op_233 Opcode = 233 245 | Op_234 Opcode = 234 246 | Op_235 Opcode = 235 247 | Op_236 Opcode = 236 248 | Op_237 Opcode = 237 249 | Op_238 Opcode = 238 250 | Op_239 Opcode = 239 251 | Op_240 Opcode = 240 252 | Op_241 Opcode = 241 253 | Op_242 Opcode = 242 254 | Op_243 Opcode = 243 255 | Op_244 Opcode = 244 256 | Op_245 Opcode = 245 257 | Op_246 Opcode = 246 258 | Op_247 Opcode = 247 259 | Op_248 Opcode = 248 260 | Op_249 Opcode = 249 261 | Op_250 Opcode = 250 262 | Op_251 Opcode = 251 263 | Op_252 Opcode = 252 264 | Op_253 Opcode = 253 265 | Op_254 Opcode = 254 266 | Op_255 Opcode = 255 267 | ) 268 | 269 | func (op Opcode) String() string { 270 | switch op { 271 | case 0: 272 | return "<0>" 273 | case 1: 274 | return "POP_TOP" 275 | case 2: 276 | return "ROT_TWO" 277 | case 3: 278 | return "ROT_THREE" 279 | case 4: 280 | return "DUP_TOP" 281 | case 5: 282 | return "DUP_TOP_TWO" 283 | case 6: 284 | return "<6>" 285 | case 7: 286 | return "<7>" 287 | case 8: 288 | return "<8>" 289 | case 9: 290 | return "NOP" 291 | case 10: 292 | return "UNARY_POSITIVE" 293 | case 11: 294 | return "UNARY_NEGATIVE" 295 | case 12: 296 | return "UNARY_NOT" 297 | case 13: 298 | return "<13>" 299 | case 14: 300 | return "<14>" 301 | case 15: 302 | return "UNARY_INVERT" 303 | case 16: 304 | return "BINARY_MATRIX_MULTIPLY" 305 | case 17: 306 | return "INPLACE_MATRIX_MULTIPLY" 307 | case 18: 308 | return "<18>" 309 | case 19: 310 | return "BINARY_POWER" 311 | case 20: 312 | return "BINARY_MULTIPLY" 313 | case 21: 314 | return "<21>" 315 | case 22: 316 | return "BINARY_MODULO" 317 | case 23: 318 | return "BINARY_ADD" 319 | case 24: 320 | return "BINARY_SUBTRACT" 321 | case 25: 322 | return "BINARY_SUBSCR" 323 | case 26: 324 | return "BINARY_FLOOR_DIVIDE" 325 | case 27: 326 | return "BINARY_TRUE_DIVIDE" 327 | case 28: 328 | return "INPLACE_FLOOR_DIVIDE" 329 | case 29: 330 | return "INPLACE_TRUE_DIVIDE" 331 | case 30: 332 | return "<30>" 333 | case 31: 334 | return "<31>" 335 | case 32: 336 | return "<32>" 337 | case 33: 338 | return "<33>" 339 | case 34: 340 | return "<34>" 341 | case 35: 342 | return "<35>" 343 | case 36: 344 | return "<36>" 345 | case 37: 346 | return "<37>" 347 | case 38: 348 | return "<38>" 349 | case 39: 350 | return "<39>" 351 | case 40: 352 | return "<40>" 353 | case 41: 354 | return "<41>" 355 | case 42: 356 | return "<42>" 357 | case 43: 358 | return "<43>" 359 | case 44: 360 | return "<44>" 361 | case 45: 362 | return "<45>" 363 | case 46: 364 | return "<46>" 365 | case 47: 366 | return "<47>" 367 | case 48: 368 | return "<48>" 369 | case 49: 370 | return "<49>" 371 | case 50: 372 | return "GET_AITER" 373 | case 51: 374 | return "GET_ANEXT" 375 | case 52: 376 | return "BEFORE_ASYNC_WITH" 377 | case 53: 378 | return "<53>" 379 | case 54: 380 | return "<54>" 381 | case 55: 382 | return "INPLACE_ADD" 383 | case 56: 384 | return "INPLACE_SUBTRACT" 385 | case 57: 386 | return "INPLACE_MULTIPLY" 387 | case 58: 388 | return "<58>" 389 | case 59: 390 | return "INPLACE_MODULO" 391 | case 60: 392 | return "STORE_SUBSCR" 393 | case 61: 394 | return "DELETE_SUBSCR" 395 | case 62: 396 | return "BINARY_LSHIFT" 397 | case 63: 398 | return "BINARY_RSHIFT" 399 | case 64: 400 | return "BINARY_AND" 401 | case 65: 402 | return "BINARY_XOR" 403 | case 66: 404 | return "BINARY_OR" 405 | case 67: 406 | return "INPLACE_POWER" 407 | case 68: 408 | return "GET_ITER" 409 | case 69: 410 | return "GET_YIELD_FROM_ITER" 411 | case 70: 412 | return "PRINT_EXPR" 413 | case 71: 414 | return "LOAD_BUILD_CLASS" 415 | case 72: 416 | return "YIELD_FROM" 417 | case 73: 418 | return "GET_AWAITABLE" 419 | case 74: 420 | return "<74>" 421 | case 75: 422 | return "INPLACE_LSHIFT" 423 | case 76: 424 | return "INPLACE_RSHIFT" 425 | case 77: 426 | return "INPLACE_AND" 427 | case 78: 428 | return "INPLACE_XOR" 429 | case 79: 430 | return "INPLACE_OR" 431 | case 80: 432 | return "BREAK_LOOP" 433 | case 81: 434 | return "WITH_CLEANUP_START" 435 | case 82: 436 | return "WITH_CLEANUP_FINISH" 437 | case 83: 438 | return "RETURN_VALUE" 439 | case 84: 440 | return "IMPORT_STAR" 441 | case 85: 442 | return "<85>" 443 | case 86: 444 | return "YIELD_VALUE" 445 | case 87: 446 | return "POP_BLOCK" 447 | case 88: 448 | return "END_FINALLY" 449 | case 89: 450 | return "POP_EXCEPT" 451 | case 90: 452 | return "STORE_NAME" 453 | case 91: 454 | return "DELETE_NAME" 455 | case 92: 456 | return "UNPACK_SEQUENCE" 457 | case 93: 458 | return "FOR_ITER" 459 | case 94: 460 | return "UNPACK_EX" 461 | case 95: 462 | return "STORE_ATTR" 463 | case 96: 464 | return "DELETE_ATTR" 465 | case 97: 466 | return "STORE_GLOBAL" 467 | case 98: 468 | return "DELETE_GLOBAL" 469 | case 99: 470 | return "<99>" 471 | case 100: 472 | return "LOAD_CONST" 473 | case 101: 474 | return "LOAD_NAME" 475 | case 102: 476 | return "BUILD_TUPLE" 477 | case 103: 478 | return "BUILD_LIST" 479 | case 104: 480 | return "BUILD_SET" 481 | case 105: 482 | return "BUILD_MAP" 483 | case 106: 484 | return "LOAD_ATTR" 485 | case 107: 486 | return "COMPARE_OP" 487 | case 108: 488 | return "IMPORT_NAME" 489 | case 109: 490 | return "IMPORT_FROM" 491 | case 110: 492 | return "JUMP_FORWARD" 493 | case 111: 494 | return "JUMP_IF_FALSE_OR_POP" 495 | case 112: 496 | return "JUMP_IF_TRUE_OR_POP" 497 | case 113: 498 | return "JUMP_ABSOLUTE" 499 | case 114: 500 | return "POP_JUMP_IF_FALSE" 501 | case 115: 502 | return "POP_JUMP_IF_TRUE" 503 | case 116: 504 | return "LOAD_GLOBAL" 505 | case 117: 506 | return "<117>" 507 | case 118: 508 | return "<118>" 509 | case 119: 510 | return "CONTINUE_LOOP" 511 | case 120: 512 | return "SETUP_LOOP" 513 | case 121: 514 | return "SETUP_EXCEPT" 515 | case 122: 516 | return "SETUP_FINALLY" 517 | case 123: 518 | return "<123>" 519 | case 124: 520 | return "LOAD_FAST" 521 | case 125: 522 | return "STORE_FAST" 523 | case 126: 524 | return "DELETE_FAST" 525 | case 127: 526 | return "<127>" 527 | case 128: 528 | return "<128>" 529 | case 129: 530 | return "<129>" 531 | case 130: 532 | return "RAISE_VARARGS" 533 | case 131: 534 | return "CALL_FUNCTION" 535 | case 132: 536 | return "MAKE_FUNCTION" 537 | case 133: 538 | return "BUILD_SLICE" 539 | case 134: 540 | return "MAKE_CLOSURE" 541 | case 135: 542 | return "LOAD_CLOSURE" 543 | case 136: 544 | return "LOAD_DEREF" 545 | case 137: 546 | return "STORE_DEREF" 547 | case 138: 548 | return "DELETE_DEREF" 549 | case 139: 550 | return "<139>" 551 | case 140: 552 | return "CALL_FUNCTION_VAR" 553 | case 141: 554 | return "CALL_FUNCTION_KW" 555 | case 142: 556 | return "CALL_FUNCTION_VAR_KW" 557 | case 143: 558 | return "SETUP_WITH" 559 | case 144: 560 | return "EXTENDED_ARG" 561 | case 145: 562 | return "LIST_APPEND" 563 | case 146: 564 | return "SET_ADD" 565 | case 147: 566 | return "MAP_ADD" 567 | case 148: 568 | return "LOAD_CLASSDEREF" 569 | case 149: 570 | return "BUILD_LIST_UNPACK" 571 | case 150: 572 | return "BUILD_MAP_UNPACK" 573 | case 151: 574 | return "BUILD_MAP_UNPACK_WITH_CALL" 575 | case 152: 576 | return "BUILD_TUPLE_UNPACK" 577 | case 153: 578 | return "BUILD_SET_UNPACK" 579 | case 154: 580 | return "SETUP_ASYNC_WITH" 581 | case 155: 582 | return "<155>" 583 | case 156: 584 | return "<156>" 585 | case 157: 586 | return "<157>" 587 | case 158: 588 | return "<158>" 589 | case 159: 590 | return "<159>" 591 | case 160: 592 | return "<160>" 593 | case 161: 594 | return "<161>" 595 | case 162: 596 | return "<162>" 597 | case 163: 598 | return "<163>" 599 | case 164: 600 | return "<164>" 601 | case 165: 602 | return "<165>" 603 | case 166: 604 | return "<166>" 605 | case 167: 606 | return "<167>" 607 | case 168: 608 | return "<168>" 609 | case 169: 610 | return "<169>" 611 | case 170: 612 | return "<170>" 613 | case 171: 614 | return "<171>" 615 | case 172: 616 | return "<172>" 617 | case 173: 618 | return "<173>" 619 | case 174: 620 | return "<174>" 621 | case 175: 622 | return "<175>" 623 | case 176: 624 | return "<176>" 625 | case 177: 626 | return "<177>" 627 | case 178: 628 | return "<178>" 629 | case 179: 630 | return "<179>" 631 | case 180: 632 | return "<180>" 633 | case 181: 634 | return "<181>" 635 | case 182: 636 | return "<182>" 637 | case 183: 638 | return "<183>" 639 | case 184: 640 | return "<184>" 641 | case 185: 642 | return "<185>" 643 | case 186: 644 | return "<186>" 645 | case 187: 646 | return "<187>" 647 | case 188: 648 | return "<188>" 649 | case 189: 650 | return "<189>" 651 | case 190: 652 | return "<190>" 653 | case 191: 654 | return "<191>" 655 | case 192: 656 | return "<192>" 657 | case 193: 658 | return "<193>" 659 | case 194: 660 | return "<194>" 661 | case 195: 662 | return "<195>" 663 | case 196: 664 | return "<196>" 665 | case 197: 666 | return "<197>" 667 | case 198: 668 | return "<198>" 669 | case 199: 670 | return "<199>" 671 | case 200: 672 | return "<200>" 673 | case 201: 674 | return "<201>" 675 | case 202: 676 | return "<202>" 677 | case 203: 678 | return "<203>" 679 | case 204: 680 | return "<204>" 681 | case 205: 682 | return "<205>" 683 | case 206: 684 | return "<206>" 685 | case 207: 686 | return "<207>" 687 | case 208: 688 | return "<208>" 689 | case 209: 690 | return "<209>" 691 | case 210: 692 | return "<210>" 693 | case 211: 694 | return "<211>" 695 | case 212: 696 | return "<212>" 697 | case 213: 698 | return "<213>" 699 | case 214: 700 | return "<214>" 701 | case 215: 702 | return "<215>" 703 | case 216: 704 | return "<216>" 705 | case 217: 706 | return "<217>" 707 | case 218: 708 | return "<218>" 709 | case 219: 710 | return "<219>" 711 | case 220: 712 | return "<220>" 713 | case 221: 714 | return "<221>" 715 | case 222: 716 | return "<222>" 717 | case 223: 718 | return "<223>" 719 | case 224: 720 | return "<224>" 721 | case 225: 722 | return "<225>" 723 | case 226: 724 | return "<226>" 725 | case 227: 726 | return "<227>" 727 | case 228: 728 | return "<228>" 729 | case 229: 730 | return "<229>" 731 | case 230: 732 | return "<230>" 733 | case 231: 734 | return "<231>" 735 | case 232: 736 | return "<232>" 737 | case 233: 738 | return "<233>" 739 | case 234: 740 | return "<234>" 741 | case 235: 742 | return "<235>" 743 | case 236: 744 | return "<236>" 745 | case 237: 746 | return "<237>" 747 | case 238: 748 | return "<238>" 749 | case 239: 750 | return "<239>" 751 | case 240: 752 | return "<240>" 753 | case 241: 754 | return "<241>" 755 | case 242: 756 | return "<242>" 757 | case 243: 758 | return "<243>" 759 | case 244: 760 | return "<244>" 761 | case 245: 762 | return "<245>" 763 | case 246: 764 | return "<246>" 765 | case 247: 766 | return "<247>" 767 | case 248: 768 | return "<248>" 769 | case 249: 770 | return "<249>" 771 | case 250: 772 | return "<250>" 773 | case 251: 774 | return "<251>" 775 | case 252: 776 | return "<252>" 777 | case 253: 778 | return "<253>" 779 | case 254: 780 | return "<254>" 781 | case 255: 782 | return "<255>" 783 | default: 784 | panic(fmt.Errorf("invalid opcode value %%d", byte(op))) 785 | } 786 | return "" 787 | } 788 | --------------------------------------------------------------------------------