diff options
| author | Mel <einebeere@gmail.com> | 2022-05-18 19:37:47 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-05-18 19:37:47 +0200 |
| commit | e4d68d39ce7f990895686139cd5cba20d2b2ef89 (patch) | |
| tree | 8862118abb2181f3bb244daaec5ced0497bc07fd /pkg/lang/vm/vm.go | |
| parent | 089fa82b8f83695cb17b8f41d0376c03303e7663 (diff) | |
| download | jinx-e4d68d39ce7f990895686139cd5cba20d2b2ef89.tar.zst jinx-e4d68d39ce7f990895686139cd5cba20d2b2ef89.zip | |
Handle errors gracefully in VM
Diffstat (limited to 'pkg/lang/vm/vm.go')
| -rw-r--r-- | pkg/lang/vm/vm.go | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/pkg/lang/vm/vm.go b/pkg/lang/vm/vm.go index 6746e64..c538841 100644 --- a/pkg/lang/vm/vm.go +++ b/pkg/lang/vm/vm.go @@ -19,19 +19,28 @@ func New(code *code.Code) *VM { } } -func (vm *VM) GetResult() string { - return fmt.Sprintf("%v", vm.stack.Top().Pop().Data()) +func (vm *VM) GetResult() (string, error) { + res, err := vm.stack.Top().Pop() + if err != nil { + return "", err + } + + return fmt.Sprintf("%v", res.Data()), nil } -func (vm *VM) Run() { +func (vm *VM) Run() error { for vm.pc < vm.code.Len() { op, advance := vm.code.GetOp(vm.pc) vm.pc += advance - if vm.step(op) == stepDecisionHalt { - return + if decision, err := vm.step(op); err != nil { + return err + } else if decision == stepDecisionHalt { + return nil } } + + return nil } type stepDecision int @@ -41,12 +50,13 @@ const ( stepDecisionHalt ) -func (vm *VM) step(op code.Op) stepDecision { +func (vm *VM) step(op code.Op) (stepDecision, error) { + var err error switch op { case code.OpNop: // do nothing case code.OpHalt: - return stepDecisionHalt + return stepDecisionHalt, nil case code.OpPushInt: x, advance := vm.code.GetInt(vm.pc) @@ -82,7 +92,7 @@ func (vm *VM) step(op code.Op) stepDecision { offset, advance := vm.code.GetInt(vm.pc) vm.pc += advance - vm.execGetLocal(int(offset)) + err = vm.execGetLocal(int(offset)) case code.OpGetMember: panic("not implemented") case code.OpGetArg: @@ -91,11 +101,11 @@ func (vm *VM) step(op code.Op) stepDecision { panic("not implemented") case code.OpAdd: - vm.execAdd() + err = vm.execAdd() case code.OpSub: - vm.execSub() + err = vm.execSub() case code.OpIndex: - vm.execIndex() + err = vm.execIndex() case code.OpCall: panic("not implemented") @@ -109,8 +119,8 @@ func (vm *VM) step(op code.Op) stepDecision { panic("not implemented") default: - panic(fmt.Errorf("unimplemented op: %v", op)) + err = ErrInvalidOp{Op: uint8(op)} } - return stepDecisionContinue + return stepDecisionContinue, err } |
