Regexp aggiornate, introduzione label / funzione
This commit is contained in:
parent
07b9de5f2a
commit
536773bc9e
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
*.gipu
|
||||
*.out
|
||||
*.elf
|
||||
.vscode/
|
||||
|
@ -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
|
||||
@ -328,6 +330,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)
|
||||
|
Loading…
Reference in New Issue
Block a user