Execute Computer/Zero: Difference between revisions
Python improve assembly parser
(Add Python) |
(Python improve assembly parser) |
||
Line 647:
=={{header|Python}}==
<lang python>"""Computer/zero Assembly emulator. Requires Python >= 3.7"""
import re
from typing import Dict
from typing import Iterable
Line 653 ⟶ 656:
from typing import Optional
from typing import Tuple
Line 676 ⟶ 678:
}
RE_INSTRUCTION = re.compile(
r"\s*"
r"(?:(?P<label>\w+):)?"
r"\s*"
rf"(?P<opcode>{'|'.join(OPCODES)})?"
r"\s*"
r"\s*"
r"(?:;(?P<comment>[\w\s]+))?"
)
class Instruction(NamedTuple):▼
opcode: Optional[str]▼
argument: Union[str, int, None]▼
class AssemblySyntaxError(Exception):
pass
▲class Instruction(NamedTuple):
label: Optional[str]
▲ opcode: Optional[str]
comment: Optional[str]
def parse(assembly: str) -> Tuple[
instructions:
labels: Dict[str, int] = {}
linenum: int = 0
for line in
if not
labels[label] = linenum
instruction = line.strip().split()▼
if instruction[0] in OPCODES:▼
# Opcode without argument▼
else:▼
▲ argument = None
▲ raise Exception(f"unknown instruction '{line}', {linenum}")
▲ instructions.append(Instruction(opcode, argument))
linenum += 1
Line 742 ⟶ 722:
def compile(instructions:
for instruction in instructions:
if
argument = 0
if instruction.opcode:
Line 785 ⟶ 765:
break
else:
raise Exception(f"error:
return accumulator
Line 928 ⟶ 908:
def main() -> None:
for sample in SAMPLES:
instructions, labels = parse(sample
bytecode = bytes(compile(instructions, labels))
print(
|