closures and they can recurse!!!
This commit is contained in:
31
vm/vm.go
31
vm/vm.go
@@ -264,10 +264,27 @@ func (vm *VM) Run() error {
|
||||
|
||||
case code.OpClosure:
|
||||
constIndex := code.ReadUint16(ins[ip+1:])
|
||||
_ = code.ReadUint8(ins[ip+3:])
|
||||
numFree := code.ReadUint8(ins[ip+3:])
|
||||
vm.currentFrame().ip += 3
|
||||
|
||||
err := vm.pushClosure(int(constIndex))
|
||||
err := vm.pushClosure(int(constIndex), int(numFree))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case code.OpGetFree:
|
||||
freeIndex := code.ReadUint8(ins[ip+1:])
|
||||
vm.currentFrame().ip += 1
|
||||
|
||||
currentClosure := vm.currentFrame().cl
|
||||
err := vm.push(currentClosure.Free[freeIndex])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case code.OpCurrentClosure:
|
||||
currentClosure := vm.currentFrame().cl
|
||||
err := vm.push(currentClosure)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -533,14 +550,20 @@ func (vm *VM) callBuiltin(builtin *object.Builtin, numArgs int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vm *VM) pushClosure(constIndex int) error {
|
||||
func (vm *VM) pushClosure(constIndex, numFree int) error {
|
||||
constant := vm.constants[constIndex]
|
||||
function, ok := constant.(*object.CompiledFunction)
|
||||
if !ok {
|
||||
return fmt.Errorf("not a function %+v", constant)
|
||||
}
|
||||
|
||||
closure := &object.Closure{Fn: function}
|
||||
free := make([]object.Object, numFree)
|
||||
for i := 0; i < numFree; i++ {
|
||||
free[i] = vm.stack[vm.sp-numFree+i]
|
||||
}
|
||||
vm.sp = vm.sp - numFree
|
||||
|
||||
closure := &object.Closure{Fn: function, Free: free}
|
||||
return vm.push(closure)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user