import re opToBinOP = { "ADD": "01", "MUL": "02", "SUB": "03", "DIV": "04", "COP": "05", "AFC": "06", "LOAD": "07", "STORE": "08", "INF": "09", "SUP": "0A", "EQ": "0B", "NOT": "0C", "AND": "0D", "OR": "0E", "JMP": "0F", "JMF": "10", "CAL": "11", "RET": "12", "PRI": "13", "NOP": "FF" } def output(s, num, oneline=False): fileOutput = open(f'asm{num}', 'w') if oneline: fileOutput.write(s) else : fileOutput.write("\n".join(s)) fileOutput.close() def convertToRegister(s): l = [] if not re.match(r"\d_LABEL", s[0]): optionalFlag = "" incr = 0 op = s[0] else: optionalFlag = s[0] + " " incr = 1 op = s[1] match op: case "ADD": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("ADD 0 0 1") l.append("STORE " + s[1 + incr] + " 0") case "MUL": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("MUL 0 0 1") l.append("STORE " + s[1 + incr] + " 0") case "SUB": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("SUB 0 0 1") l.append("STORE " + s[1 + incr] + " 0") case "DIV_INT": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("DIV 0 0 1") l.append("STORE " + s[1 + incr] + " 0") case "COP": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("STORE " + s[1 + incr] + " 0") case "AFC": l.append(optionalFlag + "AFC 0 " + s[2 + incr]) l.append("STORE " + s[1 + incr] + " 0") case "JMP": l.append(" ".join(s)) case "JMF": l.append(" ".join(s)) case "INF": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("INF 2 0 1") case "SUP": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("SUP 2 1 0") case "EQ": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("EQ 2 1 0") case "PRI": l.append(optionalFlag + "PRI " + s[2 + incr]) case "AND": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("AND 2 0 1") case "OR": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("LOAD 1 " + s[3 + incr]) l.append("OR 2 0 1") case "NOT": l.append(optionalFlag + "LOAD 0 " + s[2 + incr]) l.append("NOT 2 0") """ R2 will contain the information whether to jump or not""" return l totalLine = 0 # TODO Check the number of line is never reached labelCount = 0 # used to create a new label each time fileInput = open("asm", "r") ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines())) fileInput.close() ASMLinesLabel = ASMLines[:] # will contain at the end of the first loop the code with labels inserted ASMLinesRegister = [] # will contain at the end of the 2nd loop the registry-based code with labels ASMLinesFinal = [] # will contain the output, register-based, code for i, l in enumerate(ASMLines): items = l.split(" ") if items[0] in ["JMP", "JMF"]: lineToJumpTo = int(items[ 1 if items[0] == "JMP" else 2 ]) if re.match(r"\d_LABEL .*", ASMLinesLabel[lineToJumpTo]): ASMLinesLabel[i] = " ".join(ASMLines[i].split()[:-1] + [ASMLinesLabel[lineToJumpTo].split()[0]]) else: ASMLinesLabel[lineToJumpTo] = f"{labelCount}_LABEL " + ASMLines[lineToJumpTo] ASMLinesLabel[i] = " ".join(ASMLinesLabel[i].split()[:-1] + [f"{labelCount}_LABEL"]) labelCount += 1 print("labels : ", ASMLinesLabel) for i, l in enumerate(ASMLinesLabel): ASMLinesRegister.extend(convertToRegister(l.split())) print("regs : ", ASMLinesRegister) labels = {} for i, l in enumerate(ASMLinesRegister): if re.match(r"\d_LABEL .*", l): labels[l.split()[0]] = i ASMLinesRegister[i] = " ".join(ASMLinesRegister[i].split()[1:]) print(ASMLinesRegister) for i, l in enumerate(ASMLinesRegister): label = re.match(r"\d_LABEL", l.split()[-1]) if label: ASMLinesFinal.append(" ".join(l.split()[:-1] + [str(labels[label[0]])])) else: ASMLinesFinal.append(l) print(ASMLinesFinal) output(ASMLinesFinal, 2) lines = [] for i, l in enumerate(ASMLinesFinal): arr = l.split() while len(arr) < 4: arr.append(0) lines.append(f"(x\"{opToBinOP[arr[0]]}{int(arr[1]):02X}{int(arr[2]):02X}{int(arr[3]):02X}\")") ASMLinesConverted = "(" + ",".join(lines) + ",others => (x\"ff000000\")" print("converted to VHDL-friendly format : " + ASMLinesConverted) output(ASMLinesConverted, 3, True)