mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
more vm opcodes
This commit is contained in:
parent
bcc1a6b91f
commit
6696887f0e
@ -40,10 +40,23 @@ class Opcode(enum.IntEnum):
|
||||
CMP_GTE = 105
|
||||
CALL = 200
|
||||
RETURN = 201
|
||||
JUMP = 202
|
||||
JUMP_IF_TRUE = 203
|
||||
JUMP_IF_FALSE = 204
|
||||
SYSCALL = 205
|
||||
SYSCALL = 202
|
||||
JUMP = 203
|
||||
JUMP_IF_TRUE = 204
|
||||
JUMP_IF_FALSE = 205
|
||||
JUMP_IF_STATUS_ZERO = 206
|
||||
JUMP_IF_STATUS_NE = 207
|
||||
JUMP_IF_STATUS_EQ = 208
|
||||
JUMP_IF_STATUS_CC = 209
|
||||
JUMP_IF_STATUS_CS = 210
|
||||
JUMP_IF_STATUS_VC = 211
|
||||
JUMP_IF_STATUS_VS = 212
|
||||
JUMP_IF_STATUS_GE = 213
|
||||
JUMP_IF_STATUS_LE = 214
|
||||
JUMP_IF_STATUS_GT = 215
|
||||
JUMP_IF_STATUS_LT = 216
|
||||
JUMP_IF_STATUS_POS = 217
|
||||
JUMP_IF_STATUS_NEG = 218
|
||||
|
||||
|
||||
class Value:
|
||||
|
71
tinyvm/vm.py
71
tinyvm/vm.py
@ -52,7 +52,7 @@ Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||
# various arithmetic operations, logical operations, boolean test and comparison operations
|
||||
# jump label
|
||||
# jump_if_true label, jump_if_false label
|
||||
# @todo jump_if_status_XX label special system dependent status register conditional check such as carry bit or overflow bit)
|
||||
# jump_if_status_XX label special system dependent status register conditional check such as carry bit or overflow bit)
|
||||
# return (return values on stack)
|
||||
# syscall function (special system dependent implementation)
|
||||
# call function (arguments are on stack)
|
||||
@ -74,7 +74,7 @@ import tkinter
|
||||
import tkinter.font
|
||||
from typing import Dict, List, Tuple, Union, no_type_check
|
||||
from .program import Instruction, Variable, Block, Program, Opcode, Value
|
||||
from .core import Memory, DataType, TerminateExecution
|
||||
from .core import Memory, DataType, TerminateExecution, ExecutionError
|
||||
|
||||
|
||||
class CallFrameMarker:
|
||||
@ -167,15 +167,9 @@ class VM:
|
||||
charin_address = 0xd001
|
||||
|
||||
def __init__(self, program: Program, timerprogram: Program=None) -> None:
|
||||
opcode_names = [oc.name for oc in Opcode]
|
||||
timerprogram = timerprogram or Program([])
|
||||
for ocname in opcode_names:
|
||||
if not hasattr(self, "opcode_" + ocname):
|
||||
raise NotImplementedError("missing opcode method for " + ocname)
|
||||
for method in dir(self):
|
||||
if method.startswith("opcode_"):
|
||||
if not method[7:] in opcode_names:
|
||||
raise RuntimeError("opcode method for undefined opcode " + method)
|
||||
for opcode in Opcode:
|
||||
if opcode not in self.dispatch_table:
|
||||
raise NotImplementedError("missing opcode dispatch for " + opcode.name)
|
||||
for oc in Opcode:
|
||||
if oc not in self.dispatch_table:
|
||||
raise NotImplementedError("no dispatch entry in table for " + oc.name)
|
||||
@ -186,7 +180,7 @@ class VM:
|
||||
self.memory.mark_readonly(start, end)
|
||||
self.main_stack = Stack()
|
||||
self.timer_stack = Stack()
|
||||
self.main_program, self.timer_program, self.variables, self.labels = self.flatten_programs(program, timerprogram)
|
||||
self.main_program, self.timer_program, self.variables, self.labels = self.flatten_programs(program, timerprogram or Program([]))
|
||||
self.connect_instruction_pointers(self.main_program)
|
||||
self.connect_instruction_pointers(self.timer_program)
|
||||
self.program = self.main_program
|
||||
@ -516,23 +510,6 @@ class VM:
|
||||
self.pc = callframe.returninstruction
|
||||
return False
|
||||
|
||||
def opcode_JUMP(self, instruction: Instruction) -> bool:
|
||||
return True # jump simply points to the next instruction elsewhere
|
||||
|
||||
def opcode_JUMP_IF_TRUE(self, instruction: Instruction) -> bool:
|
||||
result = self.stack.pop()
|
||||
if result:
|
||||
self.pc = self.pc.alt_next # alternative next instruction
|
||||
return False
|
||||
return True
|
||||
|
||||
def opcode_JUMP_IF_FALSE(self, instruction: Instruction) -> bool:
|
||||
result = self.stack.pop()
|
||||
if result:
|
||||
return True
|
||||
self.pc = self.pc.alt_next # alternative next instruction
|
||||
return False
|
||||
|
||||
def opcode_SYSCALL(self, instruction: Instruction) -> bool:
|
||||
syscall = instruction.args[0]
|
||||
assert isinstance(syscall, str)
|
||||
@ -542,6 +519,27 @@ class VM:
|
||||
else:
|
||||
raise RuntimeError("no syscall method for " + syscall)
|
||||
|
||||
def opcode_JUMP(self, instruction: Instruction) -> bool:
|
||||
return True # jump simply points to the next instruction elsewhere
|
||||
|
||||
def opcode_JUMP_IF_TRUE(self, instruction: Instruction) -> bool:
|
||||
result = self.stack.pop()
|
||||
assert isinstance(result, Value)
|
||||
if result.value:
|
||||
self.pc = self.pc.alt_next # alternative next instruction
|
||||
return False
|
||||
return True
|
||||
|
||||
def opcode_JUMP_IF_FALSE(self, instruction: Instruction) -> bool:
|
||||
result = self.stack.pop()
|
||||
if result.value: # type: ignore
|
||||
return True
|
||||
self.pc = self.pc.alt_next # alternative next instruction
|
||||
return False
|
||||
|
||||
def opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG(self, instruction: Instruction) -> bool:
|
||||
raise ExecutionError("unsupported conditional jump", instruction) # @todo implement hardware specific status register flags
|
||||
|
||||
dispatch_table = {
|
||||
Opcode.TERMINATE: opcode_TERMINATE,
|
||||
Opcode.NOP: opcode_NOP,
|
||||
@ -570,10 +568,23 @@ class VM:
|
||||
Opcode.CMP_GTE: opcode_CMP_GTE,
|
||||
Opcode.CALL: opcode_CALL,
|
||||
Opcode.RETURN: opcode_RETURN,
|
||||
Opcode.SYSCALL: opcode_SYSCALL,
|
||||
Opcode.JUMP: opcode_JUMP,
|
||||
Opcode.JUMP_IF_TRUE: opcode_JUMP_IF_TRUE,
|
||||
Opcode.JUMP_IF_FALSE: opcode_JUMP_IF_FALSE,
|
||||
Opcode.SYSCALL: opcode_SYSCALL,
|
||||
Opcode.JUMP_IF_STATUS_ZERO: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_NE: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_EQ: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_CC: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_CS: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_VC: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_VS: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_GE: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_LE: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_GT: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_LT: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_POS: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
Opcode.JUMP_IF_STATUS_NEG: opcode_JUMP_IF_STATUS_UNSUPPORTED_FLAG,
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user