forked from davyxu/tabtoy
/
vm.go
71 lines (51 loc) · 1.02 KB
/
vm.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
package exprvm
type Machine struct {
DataStack *Stack
}
func (self *Machine) Run(chunk *Chunk) {
for pc := 0; pc < len(chunk.Commands); {
cmd := chunk.Commands[pc]
if cmd.Type == Opcode_Exit {
break
}
self.execute(cmd)
pc++
}
}
func (self *Machine) execute(cmd Command) (err error) {
switch cmd.Type {
case Opcode_Push:
self.DataStack.Push(cmd.Operand[0])
case Opcode_Add, Opcode_Sub, Opcode_Div, Opcode_Mul:
v1 := self.DataStack.Pop()
v2 := self.DataStack.Pop()
result := arithOp(cmd.Type, v2, v1)
self.DataStack.Push(result)
case Opcode_Minus:
v := self.DataStack.Pop()
self.DataStack.Push(-v.(int))
default:
panic("Unknown opcode")
}
return nil
}
func arithOp(op Opcode, a, b interface{}) interface{} {
an := a.(int)
bn := b.(int)
switch op {
case Opcode_Add:
return an + bn
case Opcode_Sub:
return an - bn
case Opcode_Mul:
return an * bn
case Opcode_Div:
return an / bn
}
return nil
}
func NewMachine() *Machine {
return &Machine{
DataStack: NewStack(),
}
}