Everything is a closure
This commit is contained in:
11
vm/frame.go
11
vm/frame.go
@@ -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
|
||||
}
|
||||
|
||||
39
vm/vm.go
39
vm/vm.go
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user