Files
2025-12-08 00:03:18 +01:00

77 lines
3.3 KiB
Python

# (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)