Everything is a closure
Some checks failed
Build / build (push) Failing after 1m56s
Test / build (push) Failing after 2m33s

This commit is contained in:
Chuck Smith
2024-03-13 17:08:17 -04:00
parent e373e9f68a
commit 78b560e457
7 changed files with 132 additions and 81 deletions

View File

@@ -6,15 +6,18 @@ import (
)
type Frame struct {
fn *object.CompiledFunction
cl *object.Closure
ip int
basePointer int
}
func NewFrame(fn *object.CompiledFunction, basePointer int) *Frame {
return &Frame{fn: fn, ip: -1, basePointer: basePointer}
func NewFrame(cl *object.Closure, basePointer int) *Frame {
return &Frame{
cl: cl,
ip: -1,
basePointer: basePointer}
}
func (f *Frame) Instructions() code.Instructions {
return f.fn.Instructions
return f.cl.Fn.Instructions
}

View File

@@ -29,7 +29,8 @@ type VM struct {
func New(bytecode *compiler.Bytecode) *VM {
mainFn := &object.CompiledFunction{Instructions: bytecode.Instructions}
mainFrame := NewFrame(mainFn, 0)
mainClosure := &object.Closure{Fn: mainFn}
mainFrame := NewFrame(mainClosure, 0)
frames := make([]*Frame, MaxFrames)
frames[0] = mainFrame
@@ -260,6 +261,17 @@ func (vm *VM) Run() error {
if err != nil {
return err
}
case code.OpClosure:
constIndex := code.ReadUint16(ins[ip+1:])
_ = code.ReadUint8(ins[ip+3:])
vm.currentFrame().ip += 3
err := vm.pushClosure(int(constIndex))
if err != nil {
return err
}
}
}
@@ -479,8 +491,8 @@ func (vm *VM) executeMinusOperator() error {
func (vm *VM) executeCall(numArgs int) error {
callee := vm.stack[vm.sp-1-numArgs]
switch callee := callee.(type) {
case *object.CompiledFunction:
return vm.callFunction(callee, numArgs)
case *object.Closure:
return vm.callClosure(callee, numArgs)
case *object.Builtin:
return vm.callBuiltin(callee, numArgs)
default:
@@ -488,14 +500,14 @@ func (vm *VM) executeCall(numArgs int) error {
}
}
func (vm *VM) callFunction(fn *object.CompiledFunction, numArgs int) error {
if numArgs != fn.NumParameters {
return fmt.Errorf("wrong number of arguments: want=%d, got=%d", fn.NumParameters, numArgs)
func (vm *VM) callClosure(cl *object.Closure, numArgs int) error {
if numArgs != cl.Fn.NumParameters {
return fmt.Errorf("wrong number of arguments: want=%d, got=%d", cl.Fn.NumParameters, numArgs)
}
frame := NewFrame(fn, vm.sp-numArgs)
frame := NewFrame(cl, vm.sp-numArgs)
vm.pushFrame(frame)
vm.sp = frame.basePointer + fn.NumLocals
vm.sp = frame.basePointer + cl.Fn.NumLocals
return nil
}
@@ -521,6 +533,17 @@ func (vm *VM) callBuiltin(builtin *object.Builtin, numArgs int) error {
return nil
}
func (vm *VM) pushClosure(constIndex 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}
return vm.push(closure)
}
func nativeBoolToBooleanObject(input bool) *object.Boolean {
if input {
return True