diff --git a/.gitignore b/.gitignore index b23b836..cec544a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.gipu *.out +*.elf .vscode/ diff --git a/assembler/assembler.py b/assembler/assembler.py index 76c8968..543301f 100644 --- a/assembler/assembler.py +++ b/assembler/assembler.py @@ -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)