closures and they can recurse!!!
Some checks failed
Build / build (push) Failing after 1m35s
Test / build (push) Has been cancelled

This commit is contained in:
Chuck Smith
2024-03-14 20:08:40 -04:00
parent 78b560e457
commit cc78fee3c8
10 changed files with 640 additions and 39 deletions

View File

@@ -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)
}