First implementation of the compiler
This commit is contained in:
76
Project-02-03/vistram/assembler.py
Normal file
76
Project-02-03/vistram/assembler.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# (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)
|
||||
Reference in New Issue
Block a user