# HG changeset patch # User paulb@localhost.localdomain # Date 1172447955 -3600 # Node ID 319e35c72bb18e0904490e58a9bbe2c694659f94 # Parent 397411420aedeca2702b9d72ba7a51275f68f78d Fixed the setting of types in the Namespace set_types method, always taking a copy of anything passed in. Fixed various places where subprograms were produced or copied, ensuring that they get registered with their module owners. Added returns, return_locals and raises to Subprogram nodes so that recursive calls initially provide empty results and that return types eventually build up on such nodes. Moved global/module namespace adjustment to process_node in order to ensure correct namespaces for re-run invocations. Removed the "identical instance" behaviour from ProlificMultipleInstanceClass since star argument lists produced by list methods ended up using the owning list instance, polluting the contents of such lists. diff -r 397411420aed -r 319e35c72bb1 annotate.py --- a/annotate.py Mon Feb 26 00:53:19 2007 +0100 +++ b/annotate.py Mon Feb 26 00:59:15 2007 +0100 @@ -179,9 +179,11 @@ else: self.builtins_namespace = self.global_namespace - return self.process_node(module, self.global_namespace) + # NOTE: Not declaring module namespace usage, even though it is used. - def process_node(self, node, locals): + return self.process_node(module, self.global_namespace, 0) + + def process_node(self, node, locals, using_module_namespace): """ Process a subprogram or module 'node', indicating the initial 'locals'. @@ -223,34 +225,64 @@ # Dispatch to the code itself. node.namespace = self.namespace + self.set_module_namespace(using_module_namespace) + result = self.dispatch(node) + self.extract_results(result) while self.rerun_subprograms.has_key(node): all_rerun_locals = self.rerun_subprograms[node] del self.rerun_subprograms[node] for rerun_locals in all_rerun_locals: print "Re-running", node, "with", rerun_locals - node.namespace = self.namespace = rerun_locals - result = self.dispatch(node) - result.namespace = self.namespace - if not hasattr(result, "raises"): - result.raises = [] - combine(result.raises, self.namespace.raises) + self.namespace = rerun_locals + node.namespace = rerun_locals + self.set_module_namespace(using_module_namespace) - # Obtain the return values. - - self.last_returns = self.namespace.returns - self.last_raises = self.namespace.raises - self.returned_locals = self.namespace.return_locals + result = self.dispatch(node) + self.extract_results(result) # Restore the previous subprogram and namespace. self.namespace = self.current_namespaces.pop() self.current_subprograms.pop() + self.reset_module_namespace(using_module_namespace) return result + def set_module_namespace(self, using_module_namespace): + + """ + In order to keep global accesses working, the module namespace must be + adjusted. + """ + + if using_module_namespace: + self.module.namespace = self.namespace + + def reset_module_namespace(self, using_module_namespace): + + """ + In order to keep global accesses working, the module namespace must be + reset. + """ + + if using_module_namespace: + self.module.namespace = self.namespace + + def extract_results(self, result): + + "Extract results from the namespace." + + result.namespace = self.namespace + if hasattr(result, "raises"): + combine(result.raises, self.namespace.raises) + if hasattr(result, "returns"): + combine(result.returns, self.namespace.returns) + if hasattr(result, "return_locals"): + combine(result.return_locals, self.namespace.return_locals) + def annotate(self, node, types=None): """ @@ -258,7 +290,10 @@ 'types' or the namespace's current type information. """ - self.system.annotate(node, types or self.namespace.types) + if types is None: + self.system.annotate(node, self.namespace.types) + else: + self.system.annotate(node, types) def annotate_parameters(self, node, items): @@ -655,7 +690,7 @@ raised. """ - self.namespace.set_types(self.namespace.raises[:]) + self.namespace.set_types(self.namespace.raises) self.annotate(loadexc) return loadexc @@ -1004,19 +1039,14 @@ namespace.store(target.name, [Attribute(None, target)]) # Process the subprogram. - # In order to keep global accesses working, the module namespace must be - # adjusted. - if using_module_namespace: - self.module.namespace = namespace - - self.process_node(target, namespace) + self.process_node(target, namespace, using_module_namespace) # NOTE: Improve and verify this. # If the invocation returns a value, acquire the return types. if getattr(target, "returns_value", 0): - self.namespace.set_types(self.last_returns) + self.namespace.set_types(target.returns) self.annotate(invoke) # If it is a normal block, merge the locals. @@ -1029,7 +1059,7 @@ # Merge the locals snapshots. - for locals in self.returned_locals: + for locals in target.return_locals: # For blocks returning values (such as operations), do not merge # snapshots or results. @@ -1048,14 +1078,8 @@ if not hasattr(invoke, "raises"): invoke.raises = [] - combine(invoke.raises, self.last_raises) - combine(self.namespace.raises, self.last_raises) - - # In order to keep global accesses working, the module namespace must be - # adjusted. - - if using_module_namespace: - self.module.namespace = self.namespace + combine(invoke.raises, target.raises) + combine(self.namespace.raises, target.raises) def process_args(self, invocation): @@ -1253,19 +1277,22 @@ ) ] + new_subprogram = Subprogram( + instance=instance, + name=None, + returns_value=1, + params=[], + star=None, + dstar=None, + code=code + ) + subprogram.module.simplifier.subnames[new_subprogram.full_name()] = new_subprogram + invocation.stars[subprogram.full_name()] = InvokeRef( invocation.original, instance=instance, produces_result=1, - ref=Subprogram( - instance=instance, - name=None, - returns_value=1, - params=[], - star=None, - dstar=None, - code=code - ) + ref=new_subprogram ) return invocation.stars[subprogram.full_name()] @@ -1368,19 +1395,22 @@ ) ] + new_subprogram = Subprogram( + instance=instance, + name=None, + returns_value=1, + params=[], + star=None, + dstar=None, + code=code + ) + subprogram.module.simplifier.subnames[new_subprogram.full_name()] = new_subprogram + invocation.dstars[subprogram.full_name()] = InvokeRef( invocation.original, instance=instance, produces_result=1, - ref=Subprogram( - instance=instance, - name=None, - returns_value=1, - params=[], - star=None, - dstar=None, - code=code - ) + ref=new_subprogram ) return invocation.dstars[subprogram.full_name()] @@ -1414,7 +1444,7 @@ "Set the current collection of 'types'." - self.types = types + self.types = types[:] def add(self, name, types): @@ -1429,7 +1459,7 @@ "Store in (or associate with) the given 'name' the specified 'types'." - self.names[name] = types + self.names[name] = types[:] __setitem__ = store @@ -1476,10 +1506,10 @@ """ self.merge_items(namespace.names.items()) + combine(self.raises, namespace.raises) if everything: combine(self.returns, namespace.returns) combine(self.return_locals, namespace.return_locals) - combine(self.raises, namespace.raises) for name, values in namespace.temp.items(): if values: if not self.temp.has_key(name) or not self.temp[name]: @@ -1518,7 +1548,7 @@ self.names = {} def __repr__(self): - return repr(self.names) + return repr(self.names) + " (temp) " + repr(self.temp) class Importer: @@ -1756,6 +1786,14 @@ return results +def prompt(vars): + try: + while 1: + s = raw_input("> ") + print eval(s) + except EOFError: + pass + # Convenience functions. def load(name, builtins=None, module_name=None, importer=None, no_annotate=0): diff -r 397411420aed -r 319e35c72bb1 simplified.py --- a/simplified.py Mon Feb 26 00:53:19 2007 +0100 +++ b/simplified.py Mon Feb 26 00:59:15 2007 +0100 @@ -516,6 +516,9 @@ def __init__(self, *args, **kw): Node.__init__(self, *args, **kw) WithName.__init__(self) + self.returns = [] + self.return_locals = [] + self.raises = [] class Module(Comparable): @@ -601,8 +604,10 @@ key = (subprogram, instance) if not self.attributes_for_instances.has_key(key): - self.attributes_for_instances[key] = Attribute(attribute.context, subprogram.copy(instance, subprogram.full_name())) - print "New subprogram", self.attributes_for_instances[key].type, "for", key + new_subprogram = subprogram.copy(instance, subprogram.full_name()) + subprogram.module.simplifier.subnames[new_subprogram.full_name()] = new_subprogram + self.attributes_for_instances[key] = Attribute(attribute.context, new_subprogram) + print "New subprogram", new_subprogram, "for", key return self.attributes_for_instances[key] @@ -642,8 +647,8 @@ def has_instance(self, node): requesting_instance = getattr(node, "instance", None) - return requesting_instance is not None and requesting_instance.get_class() is self or \ - self.instance_relations.has_key(requesting_instance) or self.instances.has_key(self._get_key(node)) + #return requesting_instance is not None and requesting_instance.get_class() is self or \ + return self.instance_relations.has_key(requesting_instance) or self.instances.has_key(self._get_key(node)) def add_instance(self, node, instance): requesting_instance = getattr(node, "instance", None) @@ -655,8 +660,8 @@ def get_instance(self, node): requesting_instance = getattr(node, "instance", None) - if requesting_instance is not None and requesting_instance.get_class() is self: - return requesting_instance + #if requesting_instance is not None and requesting_instance.get_class() is self: + # return requesting_instance return self.instance_relations.get(requesting_instance) or self.instances[self._get_key(node)] class Instance(Structure): @@ -692,7 +697,10 @@ # NOTE: initialise built-in types, initialise built-in constants. #def full_name(self): - # return self.typename + "-c" + # try: + # return Instance.full_name(self) + # except KeyError: + # return self.typename + "-c" class Attribute: