functions with bindings
This commit is contained in:
45
vm/vm.go
45
vm/vm.go
@@ -15,19 +15,6 @@ var Null = &object.Null{}
|
||||
var True = &object.Boolean{Value: true}
|
||||
var False = &object.Boolean{Value: false}
|
||||
|
||||
type Frame struct {
|
||||
fn *object.CompiledFunction
|
||||
ip int
|
||||
}
|
||||
|
||||
func NewFrame(fn *object.CompiledFunction) *Frame {
|
||||
return &Frame{fn: fn, ip: -1}
|
||||
}
|
||||
|
||||
func (f *Frame) Instructions() code.Instructions {
|
||||
return f.fn.Instructions
|
||||
}
|
||||
|
||||
type VM struct {
|
||||
constants []object.Object
|
||||
|
||||
@@ -42,7 +29,7 @@ type VM struct {
|
||||
|
||||
func New(bytecode *compiler.Bytecode) *VM {
|
||||
mainFn := &object.CompiledFunction{Instructions: bytecode.Instructions}
|
||||
mainFrame := NewFrame(mainFn)
|
||||
mainFrame := NewFrame(mainFn, 0)
|
||||
|
||||
frames := make([]*Frame, MaxFrames)
|
||||
frames[0] = mainFrame
|
||||
@@ -220,13 +207,15 @@ func (vm *VM) Run() error {
|
||||
if !ok {
|
||||
return fmt.Errorf("calling non-function")
|
||||
}
|
||||
frame := NewFrame(fn)
|
||||
frame := NewFrame(fn, vm.sp)
|
||||
vm.pushFrame(frame)
|
||||
vm.sp = frame.basePointer + fn.NumLocals
|
||||
|
||||
case code.OpReturnValue:
|
||||
returnValue := vm.pop()
|
||||
vm.popFrame()
|
||||
vm.pop()
|
||||
|
||||
frame := vm.popFrame()
|
||||
vm.sp = frame.basePointer - 1
|
||||
|
||||
err := vm.push(returnValue)
|
||||
if err != nil {
|
||||
@@ -234,14 +223,32 @@ func (vm *VM) Run() error {
|
||||
}
|
||||
|
||||
case code.OpReturn:
|
||||
vm.popFrame()
|
||||
vm.pop()
|
||||
frame := vm.popFrame()
|
||||
vm.sp = frame.basePointer - 1
|
||||
|
||||
err := vm.push(Null)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case code.OpSetLocal:
|
||||
localIndex := code.ReadUint8(ins[ip+1:])
|
||||
vm.currentFrame().ip += 1
|
||||
|
||||
frame := vm.currentFrame()
|
||||
|
||||
vm.stack[frame.basePointer+int(localIndex)] = vm.pop()
|
||||
|
||||
case code.OpGetLocal:
|
||||
localIndex := code.ReadUint8(ins[ip+1:])
|
||||
vm.currentFrame().ip += 1
|
||||
|
||||
frame := vm.currentFrame()
|
||||
|
||||
err := vm.push(vm.stack[frame.basePointer+int(localIndex)])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user