Refactor VM and next instruction and argument reading
This commit is contained in:
@@ -14,18 +14,30 @@ type Frame struct {
|
|||||||
func NewFrame(cl *object.Closure, basePointer int) *Frame {
|
func NewFrame(cl *object.Closure, basePointer int) *Frame {
|
||||||
return &Frame{
|
return &Frame{
|
||||||
cl: cl,
|
cl: cl,
|
||||||
ip: -1,
|
|
||||||
basePointer: basePointer,
|
basePointer: basePointer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextOp ...
|
func (f *Frame) ReadNextOp() code.Opcode {
|
||||||
func (f *Frame) NextOp() code.Opcode {
|
op := code.Opcode(f.cl.Fn.Instructions[f.ip])
|
||||||
return code.Opcode(f.Instructions()[f.ip+1])
|
f.ip++
|
||||||
|
return op
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Frame) Reset() {
|
func (f *Frame) PeekNextOp() code.Opcode {
|
||||||
f.ip = -1
|
return code.Opcode(f.cl.Fn.Instructions[f.ip])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frame) ReadUint8() uint8 {
|
||||||
|
n := code.ReadUint8(f.cl.Fn.Instructions[f.ip:])
|
||||||
|
f.ip++
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frame) ReadUint16() uint16 {
|
||||||
|
n := code.ReadUint16(f.cl.Fn.Instructions[f.ip:])
|
||||||
|
f.ip += 2
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Frame) Instructions() code.Instructions {
|
func (f *Frame) Instructions() code.Instructions {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import (
|
|||||||
"monkey/internal/utils"
|
"monkey/internal/utils"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
)
|
)
|
||||||
@@ -39,13 +38,6 @@ func isTruthy(obj object.Object) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func nativeBoolToBooleanObject(input bool) *object.Boolean {
|
|
||||||
if input {
|
|
||||||
return True
|
|
||||||
}
|
|
||||||
return False
|
|
||||||
}
|
|
||||||
|
|
||||||
// executeModule compiles the named module and returns a *object.Module object
|
// executeModule compiles the named module and returns a *object.Module object
|
||||||
func executeModule(name string, state *VMState) (object.Object, error) {
|
func executeModule(name string, state *VMState) (object.Object, error) {
|
||||||
filename := utils.FindModule(name)
|
filename := utils.FindModule(name)
|
||||||
@@ -217,11 +209,92 @@ func (vm *VM) pop() object.Object {
|
|||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeLoadBuiltin() error {
|
||||||
|
builtinIndex := vm.frame.ReadUint8()
|
||||||
|
builtin := builtins.BuiltinsIndex[builtinIndex]
|
||||||
|
return vm.push(builtin)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeConstant() error {
|
||||||
|
constIndex := vm.frame.ReadUint16()
|
||||||
|
return vm.push(vm.state.Constants[constIndex])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeAssignGlobal() error {
|
||||||
|
globalIndex := vm.frame.ReadUint16()
|
||||||
|
vm.state.Globals[globalIndex] = vm.pop()
|
||||||
|
return vm.push(Null)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeAssignLocal() error {
|
||||||
|
localIndex := vm.frame.ReadUint8()
|
||||||
|
vm.stack[vm.frame.basePointer+int(localIndex)] = vm.pop()
|
||||||
|
return vm.push(Null)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeSetGlobal() error {
|
||||||
|
globalIndex := vm.frame.ReadUint16()
|
||||||
|
|
||||||
|
ref := vm.pop()
|
||||||
|
if immutable, ok := ref.(object.Immutable); ok {
|
||||||
|
vm.state.Globals[globalIndex] = immutable.Clone()
|
||||||
|
} else {
|
||||||
|
vm.state.Globals[globalIndex] = ref
|
||||||
|
}
|
||||||
|
|
||||||
|
return vm.push(Null)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeGetGlobal() error {
|
||||||
|
globalIndex := vm.frame.ReadUint16()
|
||||||
|
return vm.push(vm.state.Globals[globalIndex])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeSetLocal() error {
|
||||||
|
localIndex := vm.frame.ReadUint8()
|
||||||
|
|
||||||
|
ref := vm.pop()
|
||||||
|
if immutable, ok := ref.(object.Immutable); ok {
|
||||||
|
vm.stack[vm.frame.basePointer+int(localIndex)] = immutable.Clone()
|
||||||
|
} else {
|
||||||
|
vm.stack[vm.frame.basePointer+int(localIndex)] = ref
|
||||||
|
}
|
||||||
|
|
||||||
|
return vm.push(Null)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeGetLocal() error {
|
||||||
|
localIndex := vm.frame.ReadUint8()
|
||||||
|
return vm.push(vm.stack[vm.frame.basePointer+int(localIndex)])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeGetFree() error {
|
||||||
|
freeIndex := vm.frame.ReadUint8()
|
||||||
|
return vm.push(vm.frame.cl.Free[freeIndex])
|
||||||
|
}
|
||||||
|
|
||||||
func (vm *VM) executeLoadModule() error {
|
func (vm *VM) executeLoadModule() error {
|
||||||
name := vm.pop()
|
name := vm.pop()
|
||||||
return vm.loadModule(name)
|
return vm.loadModule(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeCurrentClosure() error {
|
||||||
|
currentClosure := vm.frame.cl
|
||||||
|
return vm.push(currentClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeTrue() error {
|
||||||
|
return vm.push(True)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeFalse() error {
|
||||||
|
return vm.push(False)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeNull() error {
|
||||||
|
return vm.push(Null)
|
||||||
|
}
|
||||||
|
|
||||||
func (vm *VM) buildHash(startIndex, endIndex int) (object.Object, error) {
|
func (vm *VM) buildHash(startIndex, endIndex int) (object.Object, error) {
|
||||||
hashedPairs := make(map[object.HashKey]object.HashPair)
|
hashedPairs := make(map[object.HashKey]object.HashPair)
|
||||||
|
|
||||||
@@ -242,8 +315,9 @@ func (vm *VM) buildHash(startIndex, endIndex int) (object.Object, error) {
|
|||||||
return &object.Hash{Pairs: hashedPairs}, nil
|
return &object.Hash{Pairs: hashedPairs}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) executeMakeHash(startIndex, endIndex int) error {
|
func (vm *VM) executeMakeHash() error {
|
||||||
hash, err := vm.buildHash(startIndex, endIndex)
|
startIndex := vm.sp - int(vm.frame.ReadUint16())
|
||||||
|
hash, err := vm.buildHash(startIndex, vm.sp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -261,8 +335,9 @@ func (vm *VM) buildArray(startIndex, endIndex int) (object.Object, error) {
|
|||||||
return &object.Array{Elements: elements}, nil
|
return &object.Array{Elements: elements}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) executeMakeArray(startIndex, endIndex int) error {
|
func (vm *VM) executeMakeArray() error {
|
||||||
hash, err := vm.buildArray(startIndex, endIndex)
|
startIndex := vm.sp - int(vm.frame.ReadUint16())
|
||||||
|
hash, err := vm.buildArray(startIndex, vm.sp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -270,6 +345,12 @@ func (vm *VM) executeMakeArray(startIndex, endIndex int) error {
|
|||||||
return vm.push(hash)
|
return vm.push(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeClosure() error {
|
||||||
|
constIndex := vm.frame.ReadUint16()
|
||||||
|
numFree := vm.frame.ReadUint8()
|
||||||
|
return vm.pushClosure(int(constIndex), int(numFree))
|
||||||
|
}
|
||||||
|
|
||||||
func (vm *VM) executeAdd() error {
|
func (vm *VM) executeAdd() error {
|
||||||
right := vm.pop()
|
right := vm.pop()
|
||||||
left := vm.pop()
|
left := vm.pop()
|
||||||
@@ -577,7 +658,9 @@ func (vm *VM) executeGetItem() error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vm *VM) executeCall(args int) error {
|
func (vm *VM) executeCall() error {
|
||||||
|
args := int(vm.frame.ReadUint8())
|
||||||
|
|
||||||
callee := vm.stack[vm.sp-1-args]
|
callee := vm.stack[vm.sp-1-args]
|
||||||
switch callee := callee.(type) {
|
switch callee := callee.(type) {
|
||||||
case *object.Closure:
|
case *object.Closure:
|
||||||
@@ -601,6 +684,25 @@ func (vm *VM) executeReturn() error {
|
|||||||
return vm.push(returnValue)
|
return vm.push(returnValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeJumpIfFalse() error {
|
||||||
|
pos := int(vm.frame.ReadUint16())
|
||||||
|
if !isTruthy(vm.pop()) {
|
||||||
|
vm.frame.ip = pos
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executeJump() error {
|
||||||
|
pos := int(vm.frame.ReadUint16())
|
||||||
|
vm.frame.ip = pos
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VM) executePop() error {
|
||||||
|
vm.pop()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (vm *VM) callClosure(cl *object.Closure, numArgs int) error {
|
func (vm *VM) callClosure(cl *object.Closure, numArgs int) error {
|
||||||
if numArgs != cl.Fn.NumParameters {
|
if numArgs != cl.Fn.NumParameters {
|
||||||
return fmt.Errorf("wrong number of arguments: want=%d, got=%d", cl.Fn.NumParameters, numArgs)
|
return fmt.Errorf("wrong number of arguments: want=%d, got=%d", cl.Fn.NumParameters, numArgs)
|
||||||
@@ -608,13 +710,13 @@ func (vm *VM) callClosure(cl *object.Closure, numArgs int) error {
|
|||||||
|
|
||||||
// Optimize tail calls and avoid a new frame
|
// Optimize tail calls and avoid a new frame
|
||||||
if cl.Fn == vm.frame.cl.Fn {
|
if cl.Fn == vm.frame.cl.Fn {
|
||||||
nextOP := vm.frame.NextOp()
|
nextOP := vm.frame.PeekNextOp()
|
||||||
if nextOP == code.OpReturn {
|
if nextOP == code.OpReturn {
|
||||||
for p := 0; p < numArgs; p++ {
|
for p := 0; p < numArgs; p++ {
|
||||||
vm.stack[vm.frame.basePointer+p] = vm.stack[vm.sp-numArgs+p]
|
vm.stack[vm.frame.basePointer+p] = vm.stack[vm.sp-numArgs+p]
|
||||||
}
|
}
|
||||||
vm.sp -= numArgs + 1
|
vm.sp -= numArgs + 1
|
||||||
vm.frame.ip = -1 // reset IP to the beginning of the frame
|
vm.frame.ip = 0 // reset IP to the beginning of the frame
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -688,9 +790,6 @@ func (vm *VM) LastPoppedStackElem() object.Object {
|
|||||||
|
|
||||||
func (vm *VM) Run() (err error) {
|
func (vm *VM) Run() (err error) {
|
||||||
var n int
|
var n int
|
||||||
var ip int
|
|
||||||
var ins code.Instructions
|
|
||||||
var op code.Opcode
|
|
||||||
|
|
||||||
if vm.Debug {
|
if vm.Debug {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@@ -700,98 +799,59 @@ func (vm *VM) Run() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for err == nil {
|
for err == nil {
|
||||||
vm.frame.ip++
|
op := vm.frame.ReadNextOp()
|
||||||
|
|
||||||
ip = vm.frame.ip
|
|
||||||
ins = vm.frame.Instructions()
|
|
||||||
op = code.Opcode(ins[ip])
|
|
||||||
|
|
||||||
if vm.Debug {
|
if vm.Debug {
|
||||||
n++
|
n++
|
||||||
log.Printf(
|
log.Printf(
|
||||||
"%-25s %-20s\n",
|
"%-25s %-20s\n",
|
||||||
fmt.Sprintf(
|
fmt.Sprintf("%04d %s", vm.frame.ip, op),
|
||||||
"%04d %s", ip,
|
|
||||||
strings.Split(ins[ip:].String(), "\n")[0][4:],
|
|
||||||
),
|
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"[ip=%02d fp=%02d, sp=%02d]",
|
"[ip=%02d fp=%02d, sp=%02d]",
|
||||||
ip, vm.fp-1, vm.sp,
|
vm.frame.ip, vm.fp-1, vm.sp,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch op {
|
switch op {
|
||||||
case code.OpConstant:
|
case code.OpConstant:
|
||||||
constIndex := code.ReadUint16(ins[ip+1:])
|
err = vm.executeConstant()
|
||||||
vm.frame.ip += 2
|
|
||||||
err = vm.push(vm.state.Constants[constIndex])
|
|
||||||
|
|
||||||
case code.OpPop:
|
case code.OpPop:
|
||||||
vm.pop()
|
err = vm.executePop()
|
||||||
|
|
||||||
case code.OpTrue:
|
case code.OpTrue:
|
||||||
err = vm.push(True)
|
err = vm.executeTrue()
|
||||||
|
|
||||||
case code.OpFalse:
|
case code.OpFalse:
|
||||||
err = vm.push(False)
|
err = vm.executeFalse()
|
||||||
|
|
||||||
case code.OpJump:
|
case code.OpJump:
|
||||||
pos := int(code.ReadUint16(ins[ip+1:]))
|
err = vm.executeJump()
|
||||||
vm.frame.ip = pos - 1
|
|
||||||
|
|
||||||
case code.OpJumpNotTruthy:
|
case code.OpJumpNotTruthy:
|
||||||
pos := int(code.ReadUint16(ins[ip+1:]))
|
err = vm.executeJumpIfFalse()
|
||||||
vm.frame.ip += 2
|
|
||||||
if !isTruthy(vm.pop()) {
|
|
||||||
vm.frame.ip = pos - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
case code.OpNull:
|
case code.OpNull:
|
||||||
err = vm.push(Null)
|
err = vm.executeNull()
|
||||||
|
|
||||||
case code.OpSetGlobal:
|
case code.OpSetGlobal:
|
||||||
globalIndex := code.ReadUint16(ins[ip+1:])
|
err = vm.executeSetGlobal()
|
||||||
vm.frame.ip += 2
|
|
||||||
|
|
||||||
ref := vm.pop()
|
|
||||||
if immutable, ok := ref.(object.Immutable); ok {
|
|
||||||
vm.state.Globals[globalIndex] = immutable.Clone()
|
|
||||||
} else {
|
|
||||||
vm.state.Globals[globalIndex] = ref
|
|
||||||
}
|
|
||||||
|
|
||||||
err = vm.push(Null)
|
|
||||||
|
|
||||||
case code.OpAssignGlobal:
|
case code.OpAssignGlobal:
|
||||||
globalIndex := code.ReadUint16(ins[ip+1:])
|
err = vm.executeAssignGlobal()
|
||||||
vm.frame.ip += 2
|
|
||||||
vm.state.Globals[globalIndex] = vm.pop()
|
|
||||||
|
|
||||||
err = vm.push(Null)
|
|
||||||
|
|
||||||
case code.OpAssignLocal:
|
case code.OpAssignLocal:
|
||||||
localIndex := code.ReadUint8(ins[ip+1:])
|
err = vm.executeAssignLocal()
|
||||||
vm.frame.ip += 1
|
|
||||||
|
|
||||||
vm.stack[vm.frame.basePointer+int(localIndex)] = vm.pop()
|
|
||||||
|
|
||||||
err = vm.push(Null)
|
|
||||||
|
|
||||||
case code.OpGetGlobal:
|
case code.OpGetGlobal:
|
||||||
globalIndex := code.ReadUint16(ins[ip+1:])
|
err = vm.executeGetGlobal()
|
||||||
vm.frame.ip += 2
|
|
||||||
err = vm.push(vm.state.Globals[globalIndex])
|
|
||||||
|
|
||||||
case code.OpArray:
|
case code.OpArray:
|
||||||
numElements := int(code.ReadUint16(ins[ip+1:]))
|
err = vm.executeMakeArray()
|
||||||
vm.frame.ip += 2
|
|
||||||
err = vm.executeMakeArray(vm.sp-numElements, vm.sp)
|
|
||||||
|
|
||||||
case code.OpHash:
|
case code.OpHash:
|
||||||
numElements := int(code.ReadUint16(ins[ip+1:]))
|
err = vm.executeMakeHash()
|
||||||
vm.frame.ip += 2
|
|
||||||
err = vm.executeMakeHash(vm.sp-numElements, vm.sp)
|
|
||||||
|
|
||||||
case code.OpSetItem:
|
case code.OpSetItem:
|
||||||
err = vm.executeSetItem()
|
err = vm.executeSetItem()
|
||||||
@@ -800,86 +860,77 @@ func (vm *VM) Run() (err error) {
|
|||||||
err = vm.executeGetItem()
|
err = vm.executeGetItem()
|
||||||
|
|
||||||
case code.OpCall:
|
case code.OpCall:
|
||||||
args := int(code.ReadUint8(ins[ip+1:]))
|
err = vm.executeCall()
|
||||||
vm.frame.ip++
|
|
||||||
err = vm.executeCall(args)
|
|
||||||
|
|
||||||
case code.OpReturn:
|
case code.OpReturn:
|
||||||
err = vm.executeReturn()
|
err = vm.executeReturn()
|
||||||
|
|
||||||
case code.OpSetLocal:
|
case code.OpSetLocal:
|
||||||
localIndex := code.ReadUint8(ins[ip+1:])
|
err = vm.executeSetLocal()
|
||||||
vm.frame.ip += 1
|
|
||||||
|
|
||||||
ref := vm.pop()
|
|
||||||
if immutable, ok := ref.(object.Immutable); ok {
|
|
||||||
vm.stack[vm.frame.basePointer+int(localIndex)] = immutable.Clone()
|
|
||||||
} else {
|
|
||||||
vm.stack[vm.frame.basePointer+int(localIndex)] = ref
|
|
||||||
}
|
|
||||||
|
|
||||||
err = vm.push(Null)
|
|
||||||
|
|
||||||
case code.OpGetLocal:
|
case code.OpGetLocal:
|
||||||
localIndex := code.ReadUint8(ins[ip+1:])
|
err = vm.executeGetLocal()
|
||||||
vm.frame.ip += 1
|
|
||||||
err = vm.push(vm.stack[vm.frame.basePointer+int(localIndex)])
|
|
||||||
|
|
||||||
case code.OpGetBuiltin:
|
case code.OpGetBuiltin:
|
||||||
builtinIndex := code.ReadUint8(ins[ip+1:])
|
err = vm.executeLoadBuiltin()
|
||||||
vm.frame.ip++
|
|
||||||
builtin := builtins.BuiltinsIndex[builtinIndex]
|
|
||||||
err = vm.push(builtin)
|
|
||||||
|
|
||||||
case code.OpClosure:
|
case code.OpClosure:
|
||||||
constIndex := code.ReadUint16(ins[ip+1:])
|
err = vm.executeClosure()
|
||||||
numFree := code.ReadUint8(ins[ip+3:])
|
|
||||||
vm.frame.ip += 3
|
|
||||||
err = vm.pushClosure(int(constIndex), int(numFree))
|
|
||||||
|
|
||||||
case code.OpGetFree:
|
case code.OpGetFree:
|
||||||
freeIndex := code.ReadUint8(ins[ip+1:])
|
err = vm.executeGetFree()
|
||||||
vm.frame.ip += 1
|
|
||||||
err = vm.push(vm.frame.cl.Free[freeIndex])
|
|
||||||
|
|
||||||
case code.OpCurrentClosure:
|
case code.OpCurrentClosure:
|
||||||
currentClosure := vm.frame.cl
|
err = vm.executeCurrentClosure()
|
||||||
err = vm.push(currentClosure)
|
|
||||||
|
|
||||||
case code.OpLoadModule:
|
case code.OpLoadModule:
|
||||||
err = vm.executeLoadModule()
|
err = vm.executeLoadModule()
|
||||||
|
|
||||||
case code.OpAdd:
|
case code.OpAdd:
|
||||||
err = vm.executeAdd()
|
err = vm.executeAdd()
|
||||||
|
|
||||||
case code.OpSub:
|
case code.OpSub:
|
||||||
err = vm.executeSub()
|
err = vm.executeSub()
|
||||||
|
|
||||||
case code.OpMul:
|
case code.OpMul:
|
||||||
err = vm.executeMul()
|
err = vm.executeMul()
|
||||||
|
|
||||||
case code.OpDiv:
|
case code.OpDiv:
|
||||||
err = vm.executeDiv()
|
err = vm.executeDiv()
|
||||||
|
|
||||||
case code.OpMod:
|
case code.OpMod:
|
||||||
err = vm.executeMod()
|
err = vm.executeMod()
|
||||||
|
|
||||||
case code.OpOr:
|
case code.OpOr:
|
||||||
err = vm.executeOr()
|
err = vm.executeOr()
|
||||||
|
|
||||||
case code.OpAnd:
|
case code.OpAnd:
|
||||||
err = vm.executeAnd()
|
err = vm.executeAnd()
|
||||||
|
|
||||||
case code.OpBitwiseOR:
|
case code.OpBitwiseOR:
|
||||||
err = vm.executeBitwiseOr()
|
err = vm.executeBitwiseOr()
|
||||||
|
|
||||||
case code.OpBitwiseXOR:
|
case code.OpBitwiseXOR:
|
||||||
err = vm.executeBitwiseXor()
|
err = vm.executeBitwiseXor()
|
||||||
|
|
||||||
case code.OpBitwiseAND:
|
case code.OpBitwiseAND:
|
||||||
err = vm.executeBitwiseAnd()
|
err = vm.executeBitwiseAnd()
|
||||||
|
|
||||||
case code.OpLeftShift:
|
case code.OpLeftShift:
|
||||||
err = vm.executeLeftShift()
|
err = vm.executeLeftShift()
|
||||||
|
|
||||||
case code.OpRightShift:
|
case code.OpRightShift:
|
||||||
err = vm.executeRightShift()
|
err = vm.executeRightShift()
|
||||||
|
|
||||||
case code.OpEqual:
|
case code.OpEqual:
|
||||||
err = vm.executeEqual()
|
err = vm.executeEqual()
|
||||||
|
|
||||||
case code.OpNotEqual:
|
case code.OpNotEqual:
|
||||||
err = vm.executeNotEqual()
|
err = vm.executeNotEqual()
|
||||||
|
|
||||||
case code.OpGreaterThan:
|
case code.OpGreaterThan:
|
||||||
err = vm.executeGreaterThan()
|
err = vm.executeGreaterThan()
|
||||||
|
|
||||||
case code.OpGreaterThanEqual:
|
case code.OpGreaterThanEqual:
|
||||||
err = vm.executeGreaterThanOrEqual()
|
err = vm.executeGreaterThanOrEqual()
|
||||||
|
|
||||||
@@ -902,7 +953,7 @@ func (vm *VM) Run() (err error) {
|
|||||||
if vm.Debug {
|
if vm.Debug {
|
||||||
log.Printf(
|
log.Printf(
|
||||||
"%-25s [ip=%02d fp=%02d, sp=%02d]",
|
"%-25s [ip=%02d fp=%02d, sp=%02d]",
|
||||||
"", ip, vm.fp-1, vm.sp,
|
"", vm.frame.ip, vm.fp-1, vm.sp,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user