diff options
| author | Mel <einebeere@gmail.com> | 2022-05-17 23:07:33 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-05-17 23:07:33 +0200 |
| commit | ec5ee8647bcbf6ab073711c6892710776925c54d (patch) | |
| tree | 1228a72291123e0f520616b9d21f1e013e49351d /pkg/lang/vm/vm.go | |
| parent | b09a14147d397904722ee7c25e4defc56135b96f (diff) | |
| download | jinx-ec5ee8647bcbf6ab073711c6892710776925c54d.tar.zst jinx-ec5ee8647bcbf6ab073711c6892710776925c54d.zip | |
Lang VM Prototype
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 +} |
