# (c) Stephan Diehl, University of Trier, Germany, 2025 from . import tram class Assembler: @staticmethod def read_tram_code(filename): code = [] lines = [] labelmap = {} linemap = {} try: with open(filename, 'r', encoding='utf-8') as f: line_number = 0 for raw_line in f: line = raw_line.strip() if line.startswith("//") or line.startswith("#") or not line: continue if ":" in line: labels_part = line[:line.index(':')] labels = [label.strip() for label in labels_part.split(',')] linemap[line_number] = labels for label in labels: labelmap[label] = tram.Label(line_number,label) line = line[line.index(':') + 1:].strip() lines.append(line) line_number += 1 except IOError as e: print(f"Fehler beim Lesen der Datei: {e}") for i, line in enumerate(lines): labels = [labelmap.get(label,None) for label in linemap.get(i,[])] instr = Assembler.convert_to_instruction(line, labelmap, labels) code.append(instr) return code @staticmethod def convert_to_instruction(line, labelmap={}, labels=None): parts = line.split() instr =parts[0].upper() arg1 = Assembler.arg_to_number(parts, 1, labelmap) arg2 = Assembler.arg_to_number(parts, 2, labelmap) arg3 = Assembler.arg_to_number(parts, 3, labelmap) if instr == "CONST": code=tram.const(arg1,assigned_label=labels) elif instr == "LOAD": code=tram.load(arg1, arg2,assigned_label=labels) elif instr == "STORE": code=tram.store(arg1,arg2,assigned_label=labels) elif instr == "ADD": code=tram.add(assigned_label=labels) elif instr == "SUB": code=tram.sub(assigned_label=labels) elif instr == "MUL": code=tram.mul(assigned_label=labels) elif instr == "DIV": code=tram.div(assigned_label=labels) elif instr == "LT": code=tram.lt(assigned_label=labels) elif instr == "GT": code=tram.gt(assigned_label=labels) elif instr == "EQ": code=tram.eq(assigned_label=labels) elif instr == "NEQ": code=tram.neq(assigned_label=labels) elif instr == "IFZERO": code=tram.ifzero(arg1,assigned_label=labels) elif instr == "GOTO": code=tram.goto(arg1,assigned_label=labels) elif instr == "HALT": code=tram.halt(assigned_label=labels) elif instr == "NOP": code=tram.nop(assigned_label=labels) elif instr == "INVOKE": code=tram.invoke(arg1,arg2,arg3,assigned_label=labels) elif instr == "RETURN": code=tram.ireturn(assigned_label=labels) elif instr == "POP": code=tram.pop(assigned_label=labels) else: print(f"Keine gültige Instruktion: {line}") code = None return code @staticmethod def arg_to_number(parts, index, labelmap): if index >= len(parts): return 0 arg = parts[index] try: return int(arg) except ValueError: return labelmap.get(arg, 0)