diff options
Diffstat (limited to 'pkg/lang/vm/exec.go')
| -rw-r--r-- | pkg/lang/vm/exec.go | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go index 4f37ad3..655f7f1 100644 --- a/pkg/lang/vm/exec.go +++ b/pkg/lang/vm/exec.go @@ -29,6 +29,10 @@ func (vm *VM) execPushArray() { vm.stack.Push(value.NewArray([]value.Value{})) } +func (vm *VM) execPushFunction(pc int) { + vm.stack.Push(value.NewFunction(pc)) +} + func (vm *VM) execGetLocal(offset int) error { local, err := vm.stack.Local(int(offset)) if err != nil { @@ -262,6 +266,30 @@ func (vm *VM) execLte() error { return nil } +func (vm *VM) execCall() error { + f, err := vm.stack.Pop() + if err != nil { + return err + } + + if f.Type().Kind != value.FunctionType { + return ErrInvalidOperandType{ + Op: code.OpCall, + X: f.Type(), + } + } + + fn := f.Data().(value.FunctionData) + + if err = vm.stack.PushCall(fn.Pc(), vm.pc); err != nil { + return err + } + + vm.pc = fn.Pc() + + return nil +} + func (vm *VM) execJumpIf(pc int, cond bool) error { b, err := vm.stack.Pop() if err != nil { @@ -291,6 +319,22 @@ func (vm *VM) execJumpIf(pc int, cond bool) error { return nil } +func (vm *VM) execRet() error { + returned, err := vm.stack.Pop() + if err != nil { + return err + } + + pc, err := vm.stack.PopCall() + if err != nil { + return err + } + + vm.stack.Push(returned) + vm.pc = pc + return nil +} + func (vm *VM) execTempArrLen() error { a, err := vm.stack.Pop() if err != nil { |
