prevent dependency loops in script at 0x18d0a9, 0x18d023 and 0x943ca

This commit is contained in:
Bryan Bishop
2012-04-27 14:58:57 -05:00
parent 9e92ebd40b
commit a58aeae5cc

View File

@@ -714,9 +714,10 @@ class TextScript:
self.size = self.byte_count = self.last_address - original_address self.size = self.byte_count = self.last_address - original_address
return commands return commands
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
if recompute: #if recompute:
raise NotImplementedError, bryan_message # raise NotImplementedError, bryan_message
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
def to_asm(self, label=None): def to_asm(self, label=None):
@@ -918,7 +919,7 @@ class EncodedText:
self.parse() self.parse()
script_parse_table[self.address : self.last_address] = self script_parse_table[self.address : self.last_address] = self
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
return [] return []
def parse(self): def parse(self):
@@ -1186,7 +1187,7 @@ class SingleByteParam():
def parse(self): self.byte = ord(rom[self.address]) def parse(self): self.byte = ord(rom[self.address])
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
return [] return []
def to_asm(self): def to_asm(self):
@@ -1236,7 +1237,7 @@ class MultiByteParam():
else: else:
self.parsed_address = calculate_pointer_from_bytes_at(self.address, bank=None) self.parsed_address = calculate_pointer_from_bytes_at(self.address, bank=None)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
return [] return []
#you won't actually use this to_asm because it's too generic #you won't actually use this to_asm because it's too generic
@@ -1277,18 +1278,22 @@ class PointerLabelParam(MultiByteParam):
self.parsed_address = calculate_pointer_from_bytes_at(self.address, bank=self.bank) self.parsed_address = calculate_pointer_from_bytes_at(self.address, bank=self.bank)
MultiByteParam.parse(self) MultiByteParam.parse(self)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
dependencies = [] dependencies = []
if self.parsed_address == self.address: if self.parsed_address == self.address:
return dependencies return dependencies
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
thing = script_parse_table[self.parsed_address] thing = script_parse_table[self.parsed_address]
if thing and thing.address == self.parsed_address and not (thing is self): if thing and thing.address == self.parsed_address and not (thing is self):
if self.debug: if self.debug:
print "parsed address is: " + hex(self.parsed_address) + " with label: " + thing.label.name + " of type: " + str(thing.__class__) print "parsed address is: " + hex(self.parsed_address) + " with label: " + thing.label.name + " of type: " + str(thing.__class__)
dependencies.append(thing) dependencies.append(thing)
dependencies.extend(thing.get_dependencies(recompute=recompute)) if not thing in global_dependencies:
global_dependencies.add(thing)
more = thing.get_dependencies(recompute=recompute, global_dependencies=global_dependencies)
dependencies.extend(more)
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -1483,7 +1488,8 @@ class RawTextPointerLabelParam(PointerLabelParam):
self.calculated_address = address self.calculated_address = address
self.text = TextScript(address, map_group=self.map_group, map_id=self.map_id, debug=self.debug) self.text = TextScript(address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
global_dependencies.add(self.text)
return [self.text] return [self.text]
class TextPointerLabelParam(PointerLabelParam): class TextPointerLabelParam(PointerLabelParam):
@@ -1543,13 +1549,14 @@ class Command:
#start parsing this command's parameter bytes #start parsing this command's parameter bytes
self.parse() self.parse()
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
dependencies = [] dependencies = []
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
for (key, param) in self.params.items(): for (key, param) in self.params.items():
if hasattr(param, "get_dependencies") and param != self: if hasattr(param, "get_dependencies") and param != self:
deps = param.get_dependencies(recompute=recompute) deps = param.get_dependencies(recompute=recompute, global_dependencies=global_dependencies)
if deps != None and not self in deps: if deps != None and not self in deps:
dependencies.extend(deps) dependencies.extend(deps)
self.dependencies = dependencies self.dependencies = dependencies
@@ -2067,12 +2074,13 @@ class Script:
self.commands = commands self.commands = commands
return commands return commands
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
dependencies = [] dependencies = []
for command in self.commands: for command in self.commands:
deps = command.get_dependencies(recompute=recompute) deps = command.get_dependencies(recompute=recompute, global_dependencies=global_dependencies)
dependencies.extend(deps) dependencies.extend(deps)
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -2151,7 +2159,7 @@ class Warp(Command):
script_parse_table[kwargs["address"] : kwargs["address"] + self.size] = self script_parse_table[kwargs["address"] : kwargs["address"] + self.size] = self
Command.__init__(self, *args, **kwargs) Command.__init__(self, *args, **kwargs)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
return [] return []
all_warps = [] all_warps = []
@@ -2203,13 +2211,15 @@ class XYTrigger(Command):
self.dependencies = None self.dependencies = None
Command.__init__(self, *args, **kwargs) Command.__init__(self, *args, **kwargs)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
dependencies = [] dependencies = []
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
thing = script_parse_table[self.params[4].parsed_address] thing = script_parse_table[self.params[4].parsed_address]
if thing and thing != self.params[4]: if thing and thing != self.params[4]:
dependencies.append(thing) dependencies.append(thing)
global_dependencies.add(thing)
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -2298,10 +2308,12 @@ class ItemFragmentParam(PointerLabelParam):
itemfrag = ItemFragment(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug) itemfrag = ItemFragment(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
self.itemfrag = itemfrag self.itemfrag = itemfrag
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
self.dependencies = [self.itemfrag].extend(self.itemfrag.get_dependencies(recompute=recompute)) self.dependencies = [self.itemfrag].extend(self.itemfrag.get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
global_dependencies.add(self.itemfrag)
return self.dependencies return self.dependencies
class TrainerFragment(Command): class TrainerFragment(Command):
@@ -2350,19 +2362,20 @@ class TrainerFragment(Command):
self.dependencies = None self.dependencies = None
Command.__init__(self, *args, **kwargs) Command.__init__(self, *args, **kwargs)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
deps = [] deps = []
if not is_valid_address(self.address): return deps if not is_valid_address(self.address): return deps
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
deps.append(self.params[3]) #deps.append(self.params[3])
deps.extend(self.params[3].get_dependencies(recompute=recompute)) deps.extend(self.params[3].get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
deps.append(self.params[4]) #deps.append(self.params[4])
deps.extend(self.params[4].get_dependencies(recompute=recompute)) deps.extend(self.params[4].get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
deps.append(self.params[5]) #deps.append(self.params[5])
deps.extend(self.params[5].get_dependencies(recompute=recompute)) deps.extend(self.params[5].get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
deps.append(self.params[6]) #deps.append(self.params[6])
deps.extend(self.params[6].get_dependencies(recompute=recompute)) deps.extend(self.params[6].get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
self.dependencies = dep self.dependencies = dep
return deps return deps
@@ -2389,19 +2402,21 @@ class TrainerFragmentParam(PointerLabelParam):
address = calculate_pointer_from_bytes_at(self.address, bank=self.bank) address = calculate_pointer_from_bytes_at(self.address, bank=self.bank)
self.calculated_address = address self.calculated_address = address
if address == 0x26ef: if address == 0x26ef:
self.dependencies = [] self.trainerfrag = None
else: else:
trainerfrag = TrainerFragment(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug) trainerfrag = TrainerFragment(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
self.dependencies = [trainerfrag] self.trainerfrag = trainerfrag
PointerLabelParam.parse(self) PointerLabelParam.parse(self)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
deps = [] deps = []
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
deps.extend(self.dependencies) if self.trainerfrag:
if len(self.dependencies) > 0: global_dependencies.add(self.trainerfrag)
deps.extend(self.dependencies[0].get_dependencies(recompute=recompute)) deps.append(self.trainerfrag)
deps.extend(self.trainerfrag.get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
self.dependencies = deps self.dependencies = deps
return deps return deps
@@ -2659,12 +2674,13 @@ class SignpostRemoteBase:
self.dependencies = None self.dependencies = None
self.parse() self.parse()
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
dependencies = [] dependencies = []
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
for p in self.params: for p in self.params:
deps = p.get_dependencies(recompute=recompute) deps = p.get_dependencies(recompute=recompute, global_dependencies=global_dependencies)
dependencies.extend(deps) dependencies.extend(deps)
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -2903,12 +2919,13 @@ class Signpost(Command):
else: else:
raise Exception, "unknown signpost type byte="+hex(func) + " signpost@"+hex(self.address) raise Exception, "unknown signpost type byte="+hex(func) + " signpost@"+hex(self.address)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
dependencies = [] dependencies = []
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
for p in self.params: for p in self.params:
dependencies.extend(p.get_dependencies(recompute=recompute)) dependencies.extend(p.get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -3025,11 +3042,13 @@ class MapHeader:
self.time_of_day = DecimalParam(address=address+7) self.time_of_day = DecimalParam(address=address+7)
self.fishing_group = DecimalParam(address=address+8) self.fishing_group = DecimalParam(address=address+8)
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
dependencies = [self.second_map_header] dependencies = [self.second_map_header]
dependencies.append(self.second_map_header.get_dependencies(recompute=recompute)) global_dependencies.add(self.second_map_header)
dependencies.append(self.second_map_header.get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -3161,12 +3180,14 @@ class SecondMapHeader:
return True return True
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
dependencies = [self.script_header, self.event_header, self.blockdata] dependencies = [self.script_header, self.event_header, self.blockdata]
dependencies.append(self.script_header.get_dependencies(recompute=recompute)) global_dependencies.update(dependencies)
dependencies.append(self.event_header.get_dependencies(recompute=recompute)) dependencies.append(self.script_header.get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
dependencies.append(self.event_header.get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -3339,8 +3360,9 @@ class MapEventHeader:
self.last_address = after_signposts+1 self.last_address = after_signposts+1
return True return True
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
bases = [] bases = []
bases += self.people_events bases += self.people_events
@@ -3350,7 +3372,7 @@ class MapEventHeader:
dependencies = [] dependencies = []
for p in bases: for p in bases:
dependencies.extend(p.get_dependencies(recompute=recompute)) dependencies.extend(p.get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -3545,16 +3567,18 @@ class MapScriptHeader:
print "done parsing a MapScriptHeader map_group="+str(map_group)+" map_id="+str(map_id) print "done parsing a MapScriptHeader map_group="+str(map_group)+" map_id="+str(map_id)
return True return True
def get_dependencies(self, recompute=False): def get_dependencies(self, recompute=False, global_dependencies=set()):
if self.dependencies != None and not recompute: if self.dependencies != None and not recompute:
global_dependencies.update(self.dependencies)
return self.dependencies return self.dependencies
dependencies = [] dependencies = []
for p in list(self.triggers): for p in list(self.triggers):
#dependencies.append(p[0]) #dependencies.append(p[0])
dependencies.extend(p[0].get_dependencies(recompute=recompute)) dependencies.extend(p[0].get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
for callback in self.callbacks: for callback in self.callbacks:
dependencies.append(callback["callback"]) dependencies.append(callback["callback"])
dependencies.extend(callback["callback"].get_dependencies(recompute=recompute)) global_dependencies.add(callback["callback"])
dependencies.extend(callback["callback"].get_dependencies(recompute=recompute, global_dependencies=global_dependencies))
self.dependencies = dependencies self.dependencies = dependencies
return dependencies return dependencies
@@ -4381,7 +4405,7 @@ def flatten(x):
"flattens a list of sublists into just one list" "flattens a list of sublists into just one list"
return list(flattener(x)) return list(flattener(x))
def get_dependencies_for(some_object, recompute=False): def get_dependencies_for(some_object, recompute=False, global_dependencies=set()):
""" """
calculates which labels need to be satisfied for an object calculates which labels need to be satisfied for an object
to be inserted into the asm and compile successfully. to be inserted into the asm and compile successfully.
@@ -4394,9 +4418,10 @@ def get_dependencies_for(some_object, recompute=False):
if isinstance(some_object, int): if isinstance(some_object, int):
some_object = script_parse_table[some_object] some_object = script_parse_table[some_object]
if some_object.dependencies != None and not recompute: if some_object.dependencies != None and not recompute:
return list(flatten(some_object.dependencies)) global_dependencies.update(some_object.dependencies)
deps = some_object.get_dependencies(recompute=recompute) else:
return list(flatten(deps)) some_object.get_dependencies(recompute=recompute, global_dependencies=global_dependencies)
return global_dependencies
except RuntimeError, e: except RuntimeError, e:
#1552, 1291, 2075, 1552, 1291... #1552, 1291, 2075, 1552, 1291...
print "some_object is: " + str(some_object) print "some_object is: " + str(some_object)