import sys OPS = { "load": 0, "store": 1, "add": 2, "sub": 3, "and": 4, "lsr": 5, "bra": 6, "bne": 7, "halt": 8, "cmp": 9, "bge": 10, "beq": 11, } def compile(lines): addr = 0 labels = {} compiled = [] for line in lines: if not line: # empty line, ignore continue if line.startswith(";"): # comment continue if line.endswith(":"): # label labels[line.split(":")[0]] = addr continue match line.split(" "): case [inst, gr, m, *adr]: if int(m) == 1: assert adr == [] compiled.append("{:02x}: {:01x}{:01x}{:02x}".format( addr, OPS[inst], int(gr) * 4 + int(m), int(adr[0], 16) if int(m) != 1 else 0, )) case [inst, label]: assert inst in ("bra", "bne", "bge", "beq") compiled.append("{:02x}: {:01x}000".format( addr, OPS[inst], )) addr += 1 compiled.append("{:02x}: <{}>".format( addr, label )) case ["halt"]: compiled.append("{:02x}: {:01x}000".format(addr, OPS["halt"])) case [oper]: compiled.append("{:02x}: {:04x}".format(addr, int(oper, 16))) case _: compiled.append(" !!!", line) continue addr += 1 linked = [] for line_nr, line in enumerate(compiled): for label, label_nr in labels.items(): line = line.replace(f"<{label}>", f"{label_nr - line_nr:04x}") linked.append(line) return linked, labels def write(prog, labels): prog_pad = 0x100 - len(prog) prog = "\n".join(prog + [f"{len(prog)+n:02x}: 0000" for n in range(prog_pad)]) print("PM:") print(prog) if __name__ == "__main__": write(*compile([line.strip() for line in sys.stdin]))