Regexp aggiornate, introduzione label / funzione

This commit is contained in:
Giulio De Pasquale 2017-05-19 19:57:00 +02:00
parent 07b9de5f2a
commit 536773bc9e
2 changed files with 44 additions and 39 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*.gipu
*.out
*.elf
.vscode/

View File

@ -170,7 +170,7 @@ class VMAssembler:
imm_op_re = re.compile(".*[iI]$")
reg_op_re = re.compile(".*[rR]$")
arg = instruction.args[0]
section = next((x for x in sections if x.name == arg.name), None)
section = next((x for x in functions if x.name == arg.name), None)
# TODO this is due the VMComponent structure
instruction.args[0].name = section.offset
instruction.args[0].value = section.offset
@ -293,7 +293,8 @@ class VMInstruction:
continue
else:
# section
sec_comp = next((x for x in sections if x.name == el), None)
print(el)
sec_comp = next((x for x in functions if x.name == el), None)
if sec_comp:
self.args.append(VMComponent(
sec_comp.name, sec_comp.offset))
@ -305,7 +306,7 @@ class VMInstruction:
return "{} {}".format(self.opcode.name, ", ".join([x.name for x in self.args]))
class VMSection:
class VMFunction:
"""
Represents a code section or "label" such as "main:"
"""
@ -316,6 +317,7 @@ class VMSection:
self.offset = 0
self.line_start = line_start
self.line_end = 0
self.labels = []
def set_size(self, size):
self.size = size
@ -329,6 +331,7 @@ class VMSection:
def set_line_end(self, end):
self.line_end = end
def __repr__(self):
return "{} | ls: {}, le: {}, s: {}, o: {}".format(self.name, hex(self.line_start), hex(self.line_end), hex(self.size), hex(self.offset))
@ -376,59 +379,60 @@ op_names = [["MOVI", "imm2reg"],
reg_names = ["R0", "R1", "R2", "R3", "S0", "S1", "S2", "S3", "IP", "BP", "SP"]
ops = [VMComponent(le[0], i, le[1]) for i, le in enumerate(op_names)]
regs = [VMComponent(s.casefold(), i) for i, s in enumerate(reg_names)]
sections = []
section_re = re.compile("[a-zA-Z]*\:$")
immediate_re = re.compile("^[0-9].*")
register_re = re.compile("(^[rRsS]{1}[0-9]{1}$)|([iIbBsS]{1}[pP]{1}$)")
functions = []
instruction_re = re.compile("([\w]{4})(?:\ +(?:([\w]+)\ *(?:,[\ ]*([\w]+))*))?") # 1: opcode 2+: args
function_re = re.compile("(?:def\ )([a-zA-Z]*)\:")
immediate_re = re.compile("(?:0x)?[0-9]*[0-9]$")
register_re = re.compile("(^[rRsS]{1}[0-4]{1}$)|([iIrRsS]{1}[pP]{1}$)")
labeldef_re = re.compile("([a-zA-Z]*)\:")
labelcall_re = re.compile("(?:[jJ]{1}[pPmM]{1}[pPaAbBeEnN]{1}[iIrR]{1}\ *)([\w]*)")
def parse_sections(lines):
def parse_functions(lines):
current_size = 0
current_section = None
cur_func = None
# first parsing to get sections' names
# first parsing to get functions' names
for i, line in enumerate(lines):
if section_re.match(line):
if current_section:
tmp = next(x for x in sections if x.name == current_section)
match = function_re.match(line)
if match:
if cur_func:
tmp = next(x for x in functions if x.name == cur_func)
tmp.set_line_end(i-1)
current_section = line.casefold()[:-1]
sections.append(VMSection(current_section, i + 1))
cur_func = match.group(2)
functions.append(VMFunction(cur_func, i + 1))
continue
#components = [x for x in re.split('\W', line) if x]
#instruction = VMInstruction(components[0], components[1:])
#current_size += instruction.size
tmp = next(x for x in sections if x.name == current_section)
tmp = next(x for x in functions if x.name == cur_func)
tmp.set_line_end(i)
# calculating sizes and offsets
for line in lines:
if section_re.match(line):
if current_section:
tmp = next(x for x in sections if x.name == current_section)
match = function_re.match(line)
if match:
if cur_func:
tmp = next(x for x in functions if x.name == cur_func)
tmp.set_size(current_size)
current_section = line.casefold()[:-1]
cur_func = match.group(2)
current_size = 0
continue
components = [x for x in re.split('\W', line) if x]
instruction = VMInstruction(components[0], components[1:])
current_size += instruction.size
tmp = next(x for x in sections if x.name == current_section)
components = [x for x in instruction_re.match(line).groups() if x is not None]
current_size += VMInstruction(components[0], components[1:]).size
tmp = next(x for x in functions if x.name == cur_func)
tmp.set_size(current_size)
# if not, main as to be the first entry
for i in range(len(sections)):
if sections[i].name == "main" and i is not 0:
sections[0], sections[i] = sections[i], sections[0]
for i in range(len(functions)):
if functions[i].name == "main" and i is not 0:
functions[0], functions[i] = functions[i], functions[0]
break
calc_section_offsets()
def calc_section_offsets():
calc_fun_offsets()
def calc_fun_offsets():
current_offset = 0
for i in range(1, len(sections)):
prev_size = sections[i - 1].size
for i in range(1, len(functions)):
prev_size = functions[i - 1].size
current_offset += prev_size
sections[i].set_offset(current_offset)
functions[i].set_offset(current_offset)
def main():
@ -443,13 +447,13 @@ def main():
filedata = [x.strip() for x in filedata if x.strip()]
# let's parse the whole file for labels
parse_sections(filedata)
parse_functions(filedata)
if "main" not in [x.name for x in sections]:
if "main" not in [x.name for x in functions]:
sys.stderr.write("No main specified!")
return
for s in sections:
for s in functions:
section_code = filedata[s.line_start:s.line_end+1]
for line in section_code:
vma.process_code_line(line)