-
Notifications
You must be signed in to change notification settings - Fork 0
/
decompile.go
123 lines (118 loc) · 2.94 KB
/
decompile.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main
import "fmt"
func decompile(constants []any, ops []byte) {
fmt.Println("Constants:")
for i, constantValue := range constants {
fmt.Printf(" %d: %v\n", i, constantValue)
}
fmt.Println("\nOps:")
i := 0
for i < len(ops) {
op := ops[i]
fmt.Printf(" %d: (%d) ", i, op)
i++
switch op {
case OpPop:
fmt.Print("[1] Pop")
case OpBinary:
fmt.Print("[2] Binary")
binop := ops[i]
i++
switch binop {
case OpBinaryPlus:
fmt.Print(" Plus")
case OpBinarySubtract:
fmt.Print(" Subtract")
case OpBinaryMultiply:
fmt.Print(" Multiply")
case OpBinaryDivide:
fmt.Print(" Divide")
case OpBinaryEqual:
fmt.Print(" Equal")
case OpBinaryGreaterThan:
fmt.Print(" GreaterThan")
case OpBinaryLessThan:
fmt.Print(" LessThan")
case OpBinaryConcat:
fmt.Print(" Concat")
}
case OpNot:
fmt.Print("[1] Not")
case OpCallVariadicFunction:
argCount := int(ops[i])
i++
fmt.Printf("[2] PrintLn of %d arguments", argCount)
case OpJumpIfFalse:
num1 := int(ops[i])
i++
num2 := int(ops[i])
i++
jumpAmount := num1*256 + num2
fmt.Printf("[3] JumpIfFalse +%d -> %d", jumpAmount, i+jumpAmount)
case OpJumpForward:
num1 := int(ops[i])
i++
num2 := int(ops[i])
i++
jumpAmount := num1*256 + num2
fmt.Printf("[3] JumpForward +%d -> %d", jumpAmount, i+jumpAmount)
case OpJumpBack:
num1 := int(ops[i])
i++
num2 := int(ops[i])
i++
jumpAmount := num1*256 + num2
fmt.Printf("[3] JumpBack -%d -> %d", jumpAmount, i-jumpAmount)
case OpInlineNumber:
num := ops[i]
i++
fmt.Printf("[2] InlineNumber %d", num)
case OpLoadConstant:
index := ops[i]
i++
constantValue := constants[index]
fmt.Printf("[2] LoadConstant %d '%v'", index, constantValue)
case OpReadVariable:
index := ops[i]
constantValue := constants[index]
i++
fmt.Printf("[2] ReadVariable %d '%v'", index, constantValue)
case OpSetVariable:
index := ops[i]
constantValue := constants[index]
i++
fmt.Printf("[2] SetVariable %d '%v'", index, constantValue)
case OpInstantiate:
index := ops[i]
constantValue := constants[index]
i++
fmt.Printf("[2] Instantiate %d '%v'", index, constantValue)
case OpCallBuiltin:
index := ops[i]
i++
constantValue := constants[index]
fmt.Printf("[2] Builtin call %d '%v'", index, constantValue)
case OpCallFunction:
index := ops[i]
i++
constantValue := constants[index]
fmt.Printf("[2] Function call %d '%v'", index, constantValue)
case OpFieldAccess:
index := ops[i]
constantValue := constants[index]
i++
fmt.Printf("[2] Field access %d '%v'", index, constantValue)
case OpSetField:
index := ops[i]
constantValue := constants[index]
i++
fmt.Printf("[2] Set field %d '%v'", index, constantValue)
case OpDuplicate:
fmt.Print("[1] Duplicate")
case InvalidOp:
fmt.Print("[1] !! Invalid op !!")
}
fmt.Println()
}
fmt.Printf(" Exit position: %d\n", i)
}