1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-11-29 18:49:22 +00:00

Track the gotos that we have encountered in a routine.

This commit is contained in:
Chris Pressey 2018-03-27 17:27:09 +01:00
parent f86041721d
commit bb0e7aa992

View File

@ -101,7 +101,7 @@ class Context(object):
self._touched = set() self._touched = set()
self._range = dict() self._range = dict()
self._writeable = set() self._writeable = set()
self._has_encountered_goto = False self._gotos_encountered = set()
for ref in inputs: for ref in inputs:
if ref.is_constant(): if ref.is_constant():
@ -273,11 +273,11 @@ class Context(object):
for ref in refs: for ref in refs:
self._writeable.add(ref) self._writeable.add(ref)
def set_encountered_goto(self): def encounter_gotos(self, gotos):
self._has_encountered_goto = True self._gotos_encountered |= gotos
def has_encountered_goto(self): def encountered_gotos(self):
return self._has_encountered_goto return self._gotos_encountered
class Analyzer(object): class Analyzer(object):
@ -346,7 +346,7 @@ class Analyzer(object):
if ref in type_.outputs: if ref in type_.outputs:
raise UnmeaningfulOutputError(routine, ref.name) raise UnmeaningfulOutputError(routine, ref.name)
if not context.has_encountered_goto(): if not context.encountered_gotos():
for ref in type_.outputs: for ref in type_.outputs:
context.assert_meaningful(ref, exception_class=UnmeaningfulOutputError) context.assert_meaningful(ref, exception_class=UnmeaningfulOutputError)
for ref in context.each_touched(): for ref in context.each_touched():
@ -379,7 +379,7 @@ class Analyzer(object):
dest = instr.dest dest = instr.dest
src = instr.src src = instr.src
if context.has_encountered_goto(): if context.encountered_gotos():
raise IllegalJumpError(instr, instr) raise IllegalJumpError(instr, instr)
if opcode == 'ld': if opcode == 'ld':
@ -595,7 +595,7 @@ class Analyzer(object):
self.assert_affected_within('outputs', type_, current_type) self.assert_affected_within('outputs', type_, current_type)
self.assert_affected_within('trashes', type_, current_type) self.assert_affected_within('trashes', type_, current_type)
context.set_encountered_goto() context.encounter_gotos(set([instr.location]))
elif opcode == 'trash': elif opcode == 'trash':
context.set_touched(instr.dest) context.set_touched(instr.dest)
context.set_unmeaningful(instr.dest) context.set_unmeaningful(instr.dest)
@ -636,8 +636,7 @@ class Analyzer(object):
context._touched = set(context1._touched) | set(context2._touched) context._touched = set(context1._touched) | set(context2._touched)
context.set_meaningful(*list(outgoing_meaningful)) context.set_meaningful(*list(outgoing_meaningful))
context._writeable = set(context1._writeable) | set(context2._writeable) context._writeable = set(context1._writeable) | set(context2._writeable)
if context1.has_encountered_goto() or context2.has_encountered_goto(): context.encounter_gotos(context1.encountered_gotos() | context2.encountered_gotos())
context.set_encountered_goto()
for ref in outgoing_trashes: for ref in outgoing_trashes:
context.set_touched(ref) context.set_touched(ref)