diff --git a/riscemu/assembler.py b/riscemu/assembler.py index 44a7113..1633377 100644 --- a/riscemu/assembler.py +++ b/riscemu/assembler.py @@ -69,6 +69,7 @@ class ParseContext: def _finalize_section(self): if self.section is None: return + if self.section.type == MemorySectionType.Data: section = BinaryDataMemorySection( self.section.data, self.section.name, self.context, self.program.name, self.section.base @@ -79,12 +80,12 @@ class ParseContext: self.section.data, self.section.name, self.context, self.program.name, self.section.base ) self.program.add_section(section) + self.section = None def new_section(self, name: str, type: MemorySectionType, alignment: int = 4): - base = 0 - if self.section is not None: - base = align_addr(self.section.current_address(), alignment) + base = align_addr(self.current_address(), alignment) + self._finalize_section() self.section = CurrentSection(name, type, base) @@ -95,6 +96,11 @@ class ParseContext: if is_relative: self.program.relative_labels.add(name) + def current_address(self): + if self.section: + return self.section.current_address() + return self.program.base if self.program.base is not None else 0 + def __repr__(self): return "{}(\n\tsetion={},\n\tprogram={}\n)".format( self.__class__.__name__, self.section, self.program @@ -123,7 +129,7 @@ class AssemblerDirectives: ASSERT_LEN(args, 1) ASSERT_IN_SECTION_TYPE(context, MemorySectionType.Data) align_to = parse_numeric_argument(args[0]) - current_mod = context.section.current_address() % align_to + current_mod = context.current_address() % align_to if current_mod == 0: return context.section.data += bytearray(align_to - current_mod) diff --git a/riscemu/parser.py b/riscemu/parser.py index 551ddd2..83f960e 100644 --- a/riscemu/parser.py +++ b/riscemu/parser.py @@ -19,7 +19,7 @@ def parse_instruction(token: Token, args: Tuple[str], context: ParseContext): context.new_section('.text', MemorySectionType.Instructions) if context.section.type != MemorySectionType.Instructions: raise ParseException("{} {} encountered in invalid context: {}".format(token, args, context)) - ins = SimpleInstruction(token.value, args, context.context, context.section.current_address()) + ins = SimpleInstruction(token.value, args, context.context, context.current_address()) context.section.data.append(ins) @@ -27,11 +27,11 @@ def parse_label(token: Token, args: Tuple[str], context: ParseContext): name = token.value[:-1] if re.match(r'^\d+$', name): # relative label: - context.context.numbered_labels[name].append(context.section.current_address()) + context.context.numbered_labels[name].append(context.current_address()) else: if name in context.context.labels: print(FMT_PARSE + 'Warn: Symbol {} defined twice!'.format(name)) - context.add_label(name, context.section.current_address(), is_relative=True) + context.add_label(name, context.current_address(), is_relative=True) PARSERS: Dict[TokenType, Callable[[Token, Tuple[str], ParseContext], None]] = {