diff options
Diffstat (limited to 'pkg/lang/vm/vm.go')
| -rw-r--r-- | pkg/lang/vm/vm.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/pkg/lang/vm/vm.go b/pkg/lang/vm/vm.go new file mode 100644 index 0000000..434eae3 --- /dev/null +++ b/pkg/lang/vm/vm.go @@ -0,0 +1,108 @@ +package vm + +import ( + "fmt" + "jinx/pkg/lang/vm/code" +) + +type VM struct { + code *code.Code + pc int + stack CallStack +} + +func New(code *code.Code) *VM { + return &VM{ + code: code, + pc: 0, + } +} + +func (vm *VM) Run() { + for vm.pc < vm.code.Len() { + op, advance := vm.code.GetOp(vm.pc) + vm.pc += advance + vm.step(op) + } +} + +type stepDecision int + +const ( + stepDecisionContinue stepDecision = iota + stepDecisionHalt +) + +func (vm *VM) step(op code.Op) stepDecision { + switch op { + case code.OpNop: + // do nothing + case code.OpHalt: + return stepDecisionHalt + + case code.OpPushInt: + x, advance := vm.code.GetInt(vm.pc) + vm.pc += advance + + vm.execPushInt(x) + case code.OpPushFloat: + x, advance := vm.code.GetFloat(vm.pc) + vm.pc += advance + + vm.execPushFloat(x) + case code.OpPushString: + str, advance := vm.code.GetString(vm.pc) + vm.pc += advance + + vm.execPushString(str) + case code.OpPushNull: + vm.execPushNull() + case code.OpPushTrue: + vm.execPushBool(true) + case code.OpPushFalse: + vm.execPushBool(false) + case code.OpPushArray: + vm.execPushArray() + case code.OpPushFunction: + panic("not implemented") + case code.OpPushObject: + panic("not implemented") + + case code.OpGetGlobal: + panic("not implemented") + case code.OpGetLocal: + offset, advance := vm.code.GetInt(vm.pc) + vm.pc += advance + + vm.execGetLocal(int(offset)) + case code.OpGetMember: + panic("not implemented") + case code.OpGetArg: + vm.execGetArg() + case code.OpGetEnv: + panic("not implemented") + + case code.OpAdd: + vm.execAdd() + case code.OpSub: + vm.execSub() + case code.OpIndex: + vm.execIndex() + case code.OpCall: + panic("not implemented") + + case code.OpJmp: + pc, _ := vm.code.GetUint(vm.pc) + vm.pc = int(pc) + case code.OpJez: + panic("not implemented") + + case code.OpRet: + panic("not implemented") + + default: + panic(fmt.Errorf("unimplemented op: %v", op)) + } + + return stepDecisionContinue +} |
