diff --git a/src/mudlib/zmachine/zcpu.py b/src/mudlib/zmachine/zcpu.py index e19f5ad..36e3fd1 100644 --- a/src/mudlib/zmachine/zcpu.py +++ b/src/mudlib/zmachine/zcpu.py @@ -43,7 +43,7 @@ class ZCpuRestart(ZCpuError): class ZCpu: def __init__( - self, zmem, zopdecoder, zstack, zobjects, zstring, zstreammanager, zui + self, zmem, zopdecoder, zstack, zobjects, zstring, zstreammanager, zui, zlexer ): self._memory = zmem self._opdecoder = zopdecoder @@ -52,6 +52,7 @@ class ZCpu: self._string = zstring self._streammanager = zstreammanager self._ui = zui + self._lexer = zlexer def _get_handler(self, opcode_class, opcode_number): try: @@ -556,8 +557,10 @@ class ZCpu: pass def op_verify(self, *args): - """TODO: Write docstring here.""" - raise ZCpuNotImplemented + """Verify story file checksum. Branch if checksum matches.""" + expected_checksum = self._memory.read_word(0x1C) + actual_checksum = self._memory.generate_checksum() + self._branch(expected_checksum == actual_checksum) def op_piracy(self, *args): """TODO: Write docstring here.""" @@ -619,9 +622,22 @@ class ZCpu: self._memory[text_buffer_addr + 1 + len(text)] = 0 # Tokenize if parse buffer provided - # Note: ZLexer not yet wired up - tokenization will be added when needed if parse_buffer_addr != 0: - pass # TODO: add tokenization when ZLexer is integrated + max_words = self._memory[parse_buffer_addr] + tokens = self._lexer.parse_input(text) + num_words = min(len(tokens), max_words) + self._memory[parse_buffer_addr + 1] = num_words + offset = 0 + for i in range(num_words): + word_str, dict_addr = tokens[i] + # Find word position in text + pos = text.find(word_str, offset) + word_len = len(word_str) + base = parse_buffer_addr + 2 + (i * 4) + self._memory.write_word(base, dict_addr) + self._memory[base + 2] = word_len + self._memory[base + 3] = pos + 1 # 1-indexed from start of text buffer + offset = pos + word_len def op_sread_v4(self, *args): """TODO: Write docstring here.""" diff --git a/src/mudlib/zmachine/zmachine.py b/src/mudlib/zmachine/zmachine.py index c3826c2..4228207 100644 --- a/src/mudlib/zmachine/zmachine.py +++ b/src/mudlib/zmachine/zmachine.py @@ -7,6 +7,7 @@ from . import zlogging from .zcpu import ZCpu +from .zlexer import ZLexer from .zmemory import ZMemory from .zobjectparser import ZObjectParser from .zopdecoder import ZOpDecoder @@ -33,6 +34,7 @@ class ZMachine: self._opdecoder.program_counter = self._mem.read_word(0x06) self._ui = ui self._stream_manager = ZStreamManager(self._mem, self._ui) + self._lexer = ZLexer(self._mem) self._cpu = ZCpu( self._mem, self._opdecoder, @@ -41,6 +43,7 @@ class ZMachine: self._stringfactory, self._stream_manager, self._ui, + self._lexer, ) # --------- Public APIs ----------- diff --git a/tests/test_zmachine_opcodes.py b/tests/test_zmachine_opcodes.py index 18aa369..015e84a 100644 --- a/tests/test_zmachine_opcodes.py +++ b/tests/test_zmachine_opcodes.py @@ -107,6 +107,7 @@ class ZMachineOpcodeTests(TestCase): Mock(), # string Mock(), # stream manager self.ui, + Mock(), # lexer ) def test_op_nop(self): @@ -356,6 +357,7 @@ class ZMachineObjectOpcodeTests(TestCase): self.string, Mock(), # stream manager self.ui, + Mock(), # lexer ) def test_op_get_sibling_with_sibling(self): @@ -536,6 +538,7 @@ class ZMachineComplexOpcodeTests(TestCase): Mock(), # string Mock(), # stream manager self.ui, + Mock(), # lexer ) def test_op_sread_v3_basic_input(self):