Skip to content

Instantly share code, notes, and snippets.

@sencagri
Created May 1, 2018 13:23
Show Gist options
  • Save sencagri/bc5454668144594889d5910e3e13c7b3 to your computer and use it in GitHub Desktop.
Save sencagri/bc5454668144594889d5910e3e13c7b3 to your computer and use it in GitHub Desktop.
assembler
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