Demo changes
This commit is contained in:
19
vm/vm.go
19
vm/vm.go
@@ -119,7 +119,11 @@ func (vm *VM) Run() error {
|
||||
}
|
||||
|
||||
case code.OpPop:
|
||||
vm.pop()
|
||||
// This makes things like this work:
|
||||
// >> let x = 1; if (x == 1) { x = 2 }
|
||||
if vm.sp > 0 {
|
||||
vm.pop()
|
||||
}
|
||||
|
||||
case code.OpTrue:
|
||||
err := vm.push(True)
|
||||
@@ -563,6 +567,19 @@ func (vm *VM) callClosure(cl *object.Closure, numArgs int) error {
|
||||
return fmt.Errorf("wrong number of arguments: want=%d, got=%d", cl.Fn.NumParameters, numArgs)
|
||||
}
|
||||
|
||||
// Optimize tail calls and avoid a new frame
|
||||
if cl.Fn == vm.currentFrame().cl.Fn {
|
||||
nextOP := vm.currentFrame().NextOp()
|
||||
if nextOP == code.OpReturn {
|
||||
for p := 0; p < numArgs; p++ {
|
||||
vm.stack[vm.currentFrame().basePointer+p] = vm.stack[vm.sp-numArgs+p]
|
||||
}
|
||||
vm.sp -= numArgs + 1
|
||||
vm.currentFrame().ip = -1 // reset IP to the beginning of the frame
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
frame := NewFrame(cl, vm.sp-numArgs)
|
||||
vm.pushFrame(frame)
|
||||
vm.sp = frame.basePointer + cl.Fn.NumLocals
|
||||
|
||||
Reference in New Issue
Block a user