blob: 6746e64f19bd5a18e403acb9e104fe2858c20b2d (
plain)
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
|
package vm
import (
"fmt"
"jinx/pkg/lang/vm/code"
)
type VM struct {
code *code.Code
pc int
stack CallStack
}
func New(code *code.Code) *VM {
return &VM{
code: code,
pc: 0,
stack: NewCallStack(),
}
}
func (vm *VM) GetResult() string {
return fmt.Sprintf("%v", vm.stack.Top().Pop().Data())
}
func (vm *VM) Run() {
for vm.pc < vm.code.Len() {
op, advance := vm.code.GetOp(vm.pc)
vm.pc += advance
if vm.step(op) == stepDecisionHalt {
return
}
}
}
type stepDecision int
const (
stepDecisionContinue stepDecision = iota
stepDecisionHalt
)
func (vm *VM) step(op code.Op) stepDecision {
switch op {
case code.OpNop:
// do nothing
case code.OpHalt:
return stepDecisionHalt
case code.OpPushInt:
x, advance := vm.code.GetInt(vm.pc)
vm.pc += advance
vm.execPushInt(x)
case code.OpPushFloat:
x, advance := vm.code.GetFloat(vm.pc)
vm.pc += advance
vm.execPushFloat(x)
case code.OpPushString:
str, advance := vm.code.GetString(vm.pc)
vm.pc += advance
vm.execPushString(str)
case code.OpPushNull:
vm.execPushNull()
case code.OpPushTrue:
vm.execPushBool(true)
case code.OpPushFalse:
vm.execPushBool(false)
case code.OpPushArray:
vm.execPushArray()
case code.OpPushFunction:
panic("not implemented")
case code.OpPushObject:
panic("not implemented")
case code.OpGetGlobal:
panic("not implemented")
case code.OpGetLocal:
offset, advance := vm.code.GetInt(vm.pc)
vm.pc += advance
vm.execGetLocal(int(offset))
case code.OpGetMember:
panic("not implemented")
case code.OpGetArg:
vm.execGetArg()
case code.OpGetEnv:
panic("not implemented")
case code.OpAdd:
vm.execAdd()
case code.OpSub:
vm.execSub()
case code.OpIndex:
vm.execIndex()
case code.OpCall:
panic("not implemented")
case code.OpJmp:
pc, _ := vm.code.GetUint(vm.pc)
vm.pc = int(pc)
case code.OpJez:
panic("not implemented")
case code.OpRet:
panic("not implemented")
default:
panic(fmt.Errorf("unimplemented op: %v", op))
}
return stepDecisionContinue
}
|