''' 1. Kreieren der Symboltabelle 2. Einlesen der Datei a. Entfernen der Kommentare -- erledigt b. Suchen der (Label) und Ablegen dieser in die Symboltabelle -- erledigt c. Entfernen der (Label) aus dem ASM-File d. HACK-Code erzeugen ''' import sys, os from pathlib import Path import re from icecream import ic symboltable = {} asm = [] def appendTable(table, id, item): print("appendTable ",id, " ", item ) table["@"+ str(item)] = id symboltable = table def createSymboltable(): return { key: (value) for key, value in { **{'@SP': 0, '@LCL': 1, '@ARG': 2, '@THIS': 3, '@THAT': 4, '@SCREEN': 0x4000, '@KBD': 0x6000,}, **{f'@R{i}': i for i in range(16)} }.items()} def load_asm_file(filename): fp = open(filename, 'r') comment = r"^/" eol = r"^\n" tmp = [] t = fp.readlines() for l in t: if re.match(comment, l): pass elif re.match(eol, l): pass else: tmp.append(re.sub('\s', '', l).split('//')[0]) # Wenn noch ein Kommentar hinter der Anweisung steht dann Abtrenen fp.close() #ic("tmp = ", tmp) return tmp def label_to_symboltable(data): #ic(len(data)) i = 0 tmp = {} for l in data: if (l.startswith('(') and l.endswith(')')): l = l[:-1] l = l.lstrip('(') tmp['@'+str(l)] = i #ic(l) else: i=i+1 if len(tmp) != 0: symboltable.update(tmp) #ic(symboltable) #ic (data) # c. Löschen der (Label) aus der Liste count = 0 for i in tmp: #ic(tmp[i]) # Zeilennummern data.pop(tmp[i]-count) #ic(len(data)) searchSymbols(data) def searchSymbols(asm): ''' wenn Zeile mit @ beginnt schauen ob Variable in Symboltable sonst ist Variable @x ein int, dann ohne @ in die Symboltable übernehmen ''' #ic(asm) i = 16 for line in asm: if line.startswith('@'): #ic (i, " ",line[1:]) if line[1:].isdigit(): if line not in symboltable: addtoSymboltable(line, int(line[1:])) elif line not in symboltable: #ic("Symbol nicht in Table") addtoSymboltable(line, i) i = i+1 def ciinstruction(): c = "111" # dest = comp; jump def addtoSymboltable(key,value): ic(key, value) symboltable[key]=value def createAsmFile(): datename = os.path.splitext(os.path.basename(filename))[0]+".hack" ic(datename) f = open(datename,"w") for line in asm: if line in symboltable: f.write('{0:016b}'.format(symboltable[line]) + "\n") else: #M=D f.write('1111111111111111\n') f.close() if __name__ == "__main__": filename = sys.argv[1] #filename = "Pong.asm" symboltable = createSymboltable() asm = load_asm_file(filename) label_to_symboltable(asm) searchSymbols(asm) createAsmFile() #print("Symtable = ",symboltable)