Parser: fixed error when labels where used outside of sections

float_support
Anton Lydike 3 years ago
parent 204d2c9a5b
commit ce5b01d463

@ -69,6 +69,7 @@ class ParseContext:
def _finalize_section(self): def _finalize_section(self):
if self.section is None: if self.section is None:
return return
if self.section.type == MemorySectionType.Data: if self.section.type == MemorySectionType.Data:
section = BinaryDataMemorySection( section = BinaryDataMemorySection(
self.section.data, self.section.name, self.context, self.program.name, self.section.base 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.section.data, self.section.name, self.context, self.program.name, self.section.base
) )
self.program.add_section(section) self.program.add_section(section)
self.section = None self.section = None
def new_section(self, name: str, type: MemorySectionType, alignment: int = 4): def new_section(self, name: str, type: MemorySectionType, alignment: int = 4):
base = 0 base = align_addr(self.current_address(), alignment)
if self.section is not None:
base = align_addr(self.section.current_address(), alignment)
self._finalize_section() self._finalize_section()
self.section = CurrentSection(name, type, base) self.section = CurrentSection(name, type, base)
@ -95,6 +96,11 @@ class ParseContext:
if is_relative: if is_relative:
self.program.relative_labels.add(name) 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): def __repr__(self):
return "{}(\n\tsetion={},\n\tprogram={}\n)".format( return "{}(\n\tsetion={},\n\tprogram={}\n)".format(
self.__class__.__name__, self.section, self.program self.__class__.__name__, self.section, self.program
@ -123,7 +129,7 @@ class AssemblerDirectives:
ASSERT_LEN(args, 1) ASSERT_LEN(args, 1)
ASSERT_IN_SECTION_TYPE(context, MemorySectionType.Data) ASSERT_IN_SECTION_TYPE(context, MemorySectionType.Data)
align_to = parse_numeric_argument(args[0]) 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: if current_mod == 0:
return return
context.section.data += bytearray(align_to - current_mod) context.section.data += bytearray(align_to - current_mod)

@ -19,7 +19,7 @@ def parse_instruction(token: Token, args: Tuple[str], context: ParseContext):
context.new_section('.text', MemorySectionType.Instructions) context.new_section('.text', MemorySectionType.Instructions)
if context.section.type != MemorySectionType.Instructions: if context.section.type != MemorySectionType.Instructions:
raise ParseException("{} {} encountered in invalid context: {}".format(token, args, context)) 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) context.section.data.append(ins)
@ -27,11 +27,11 @@ def parse_label(token: Token, args: Tuple[str], context: ParseContext):
name = token.value[:-1] name = token.value[:-1]
if re.match(r'^\d+$', name): if re.match(r'^\d+$', name):
# relative label: # relative label:
context.context.numbered_labels[name].append(context.section.current_address()) context.context.numbered_labels[name].append(context.current_address())
else: else:
if name in context.context.labels: if name in context.context.labels:
print(FMT_PARSE + 'Warn: Symbol {} defined twice!'.format(name)) 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]] = { PARSERS: Dict[TokenType, Callable[[Token, Tuple[str], ParseContext], None]] = {

Loading…
Cancel
Save