#!/usr/bin/env python3 import sys from typing import Iterable, Tuple from parser import parser from parsetypes import * def check_num_args(instruction: Instruction) -> Tuple[int, int]: return (0, 20) def check_supports_jump(instruction: Instruction) -> bool: return True def check_instructions( instructions: Iterable[Instruction], ) -> Iterable[ErrorInstruction]: for i in instructions: if isinstance(i, ErrorInstruction): yield i continue (min, max) = check_num_args(i) if not (min <= i.num_args <= max): yield ErrorInstruction.from_instruction( i, f"Expected between {min} and {max} args, got {i.num_args}." ) if not check_supports_jump(i) and i.jumptarget: yield ErrorInstruction.from_instruction( i, f"OPcode got jump, but it's not supported here." ) labels: dict[str,int] = {} def assemble(program: Iterable[Instruction|JumpTarget]) -> None: pc = 0 for ins in program: if isinstance(ins, JumpTarget): pass with open(sys.argv[1], "rb") as f: data = f.read() data2 = data.decode("ascii") result: list[Instruction | JumpTarget] result = parser.parse(data2, tracking=True) errors = check_instructions(ins for ins in result if isinstance(ins, Instruction)) if errors: for e in errors: print(f"On line {e.lineno}: {e.opcode} : {e.error_message}") sys.exit(1) assemble(result) pass