-
-
Save sencagri/bc5454668144594889d5910e3e13c7b3 to your computer and use it in GitHub Desktop.
assembler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
from instructionSet import instructionSet | |
# program counter | |
pc = 100 | |
# jump list | |
colonList = list() | |
# var list | |
varList = list() | |
# param list | |
param = list() | |
# result list | |
output = list() | |
# delimiter characters used for splitting line | |
delimiter = ", | " | |
def incrementPC(): | |
global pc | |
pc = pc + 4 | |
def to_twoscomplement(bits, value): | |
if value < 0: | |
value = ( 1<<bits ) + value | |
formatstring = '{:0%ib}' % bits | |
return formatstring.format(value) | |
def getInputFile(isAsm2Bin): | |
if isAsm2Bin: | |
program = "sample_program.txt" | |
else: | |
program = "sample_program2.txt" | |
file = open(program, "r") | |
lines = file.readlines() | |
file.close() | |
if len(lines) == 0: | |
print("No input data!") | |
exit() | |
return lines | |
def decodeParameters(stringPart): | |
for par in stringPart[1:]: | |
# register value | |
if str.startswith(par, "R") or str.startswith(par, "#"): | |
paramDigit = par[1:]; | |
param.append("{0:05b}".format(int(paramDigit))) | |
if str.startswith(par, "["): | |
pb = str.find(par, "[") + len("[") | |
par = par[pb:] | |
if str.startswith(par, "R"): | |
pb = str.find(par, "R") + 1 | |
par = par[pb:] | |
param.append("{0:05b}".format(int(par))) | |
if str.endswith(par, "]"): | |
pe = str.find(par, "]") | |
par = par[:pe] | |
findVar = [item for item in varList if item[0] == par] | |
if len(findVar) > 0: | |
findVar = findVar[0] | |
pcOfVar = findVar[1] | |
param.append(to_twoscomplement(12,pcOfVar)) | |
test =1 | |
def extractVars_asm2bin(inData): | |
global pc | |
prevLine = inData[0] | |
globalname = "" | |
globalFound = False | |
colonFound = False | |
for line in inData: | |
line = str(line) | |
if len(line.strip()) == 0: | |
continue | |
if line[0] == ";": | |
continue | |
if str.find(line,globalname): | |
globalFound = True | |
if str.find(line, ".global") > -1: | |
posg = str.index(line, ".global") + len(".global") | |
globalname = line[posg:] | |
if str.find(line, ".word") > -1: | |
pos = str.index(prevLine, ":") | |
varName = prevLine[:pos] | |
varList.append([varName, pc]) | |
pos =str.find(line, ".word") + len(".word") | |
values = line[pos:] | |
values = str.replace(values, "\n", "") | |
values = re.split(", | ", values) | |
values = list(filter(None, values)) | |
values = list(values) | |
lenVal = len(values) -1 | |
pc += lenVal*4 | |
if str.find(line, ":") > -1: | |
colonFound = True | |
if globalFound and colonFound == False and str.find(line, globalname) == -1: | |
incrementPC() | |
colonFound = False | |
prevLine = line | |
pc = 100 | |
def dec_asm2bin(inData): | |
for line in inData: | |
processLine_asm2bin(line) | |
def putParams(insBinary): | |
def processLine_asm2bin(line): | |
endPos = len(line) | |
if endPos > 0: | |
# check if comment added | |
commentIndex = str.find(line, ";") | |
if commentIndex > -1: | |
endPos = commentIndex | |
# copy only to the semicolon pos | |
stringPart = line[:endPos] | |
# check if it is variable or not | |
if str.find(line, ".word") > -1: | |
pos = str.find(line, ".word") + len(".word") | |
vars = line[pos:] | |
vars = re.split(delimiter, vars) | |
for var in vars: | |
varName.append(var, "{0:10b}".format(var)) | |
incrementPC() | |
if len(stringPart) > 0: | |
# check if line is jump point, if so add colonName to list then exit | |
colonIndex = str.find(stringPart, ":") | |
if colonIndex > 0: | |
colonName = stringPart[:colonIndex] | |
colonList.append([colonName, pc]) | |
return | |
# split by delimiter character | |
stringPart = re.split(delimiter, stringPart) | |
stringPart = list(filter(None, stringPart)) | |
# search first string in instruction list | |
candidateInst = stringPart[0] | |
candidateRes = [item for item in instructionSet if item[0] == candidateInst] | |
# we found the instruction | |
if len(candidateRes) > 0: | |
insBinary = candidateRes[0][1]; | |
paramSize = 0; | |
insSet = list(set(insBinary)) | |
for x in insSet: | |
if not str.isdigit(x): | |
paramSize+=1 | |
if paramSize == 3: | |
decodeParameters(stringPart) | |
insBinary = putParams(insBinary) | |
insBinary = str.replace(insBinary, "mmmmm", param[0]) | |
insBinary = str.replace(insBinary, "nnnnn", param[1]) | |
insBinary = str.replace(insBinary, "ddddd", param[2]) | |
if paramSize == 2: | |
decodeParameters(stringPart) | |
if paramSize == 1: | |
decodeParameters() | |
param.clear() | |
incrementPC() | |
output.append(insBinary) | |
def main(): | |
isAsm2Bin = True | |
inData = getInputFile(isAsm2Bin) | |
# clean empty lines | |
inData = list(filter(None, inData)) | |
if isAsm2Bin: | |
extractVars_asm2bin(inData) | |
dec_asm2bin(inData) | |
else: | |
dec_bin2asm(inData) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment