1.1 --- a/annotate.py Tue Oct 24 23:05:02 2006 +0200
1.2 +++ b/annotate.py Tue Oct 24 23:10:22 2006 +0200
1.3 @@ -233,51 +233,34 @@
1.4 except AnnotationMessage, exc:
1.5 raise AnnotationError(exc, node)
1.6
1.7 - def visitLoadRef(self, loadref):
1.8 - self.namespace.set_types([Attribute(None, loadref.ref)])
1.9 - self.annotate(loadref)
1.10 - return loadref
1.11 + # Program structure/control-flow.
1.12 +
1.13 + def visitConditional(self, conditional):
1.14
1.15 - def visitLoadName(self, loadname):
1.16 - self.namespace.set_types(self.namespace.load(loadname.name))
1.17 - result = loadname
1.18 - self.annotate(result)
1.19 - return result
1.20 + # Conditionals keep local namespace changes isolated.
1.21 + # With Return nodes inside the body/else sections, the changes are
1.22 + # communicated to the caller.
1.23
1.24 - def visitStoreName(self, storename):
1.25 - storename.expr = self.dispatch(storename.expr)
1.26 - self.namespace.store(storename.name, self.namespace.types)
1.27 - return storename
1.28 + conditional.test = self.dispatch(conditional.test)
1.29 + saved_namespace = self.namespace
1.30
1.31 - def visitLoadTemp(self, loadtemp):
1.32 - index = getattr(loadtemp, "index", None)
1.33 - try:
1.34 - if getattr(loadtemp, "release", 0):
1.35 - self.namespace.set_types(self.namespace.temp[index].pop())
1.36 - else:
1.37 - self.namespace.set_types(self.namespace.temp[index][-1])
1.38 - except KeyError:
1.39 - raise AnnotationMessage, "Temporary store index '%s' not defined." % index
1.40 - self.annotate(loadtemp)
1.41 - return loadtemp
1.42 + self.namespace = Namespace()
1.43 + self.namespace.merge_namespace(saved_namespace)
1.44 + conditional.body = self.dispatches(conditional.body)
1.45 + body_namespace = self.namespace
1.46
1.47 - def visitStoreTemp(self, storetemp):
1.48 - storetemp.expr = self.dispatch(storetemp.expr)
1.49 - index = getattr(storetemp, "index", None)
1.50 - if not self.namespace.temp.has_key(index):
1.51 - self.namespace.temp[index] = []
1.52 - self.namespace.temp[index].append(self.namespace.types)
1.53 - return storetemp
1.54 + self.namespace = Namespace()
1.55 + self.namespace.merge_namespace(saved_namespace)
1.56 + conditional.else_ = self.dispatches(conditional.else_)
1.57 + else_namespace = self.namespace
1.58
1.59 - def visitReleaseTemp(self, releasetemp):
1.60 - index = getattr(releasetemp, "index", None)
1.61 - try:
1.62 - self.namespace.temp[index].pop()
1.63 - except KeyError:
1.64 - raise AnnotationMessage, "Temporary store index '%s' not defined." % index
1.65 - except IndexError:
1.66 - pass #raise AnnotationMessage, "Temporary store index '%s' is empty." % index
1.67 - return releasetemp
1.68 + self.namespace = Namespace()
1.69 + self.namespace.merge_namespace(body_namespace)
1.70 + self.namespace.merge_namespace(else_namespace)
1.71 +
1.72 + return conditional
1.73 +
1.74 + # Namespace operations.
1.75
1.76 def visitLoadAttr(self, loadattr):
1.77 loadattr.expr = self.dispatch(loadattr.expr)
1.78 @@ -307,6 +290,47 @@
1.79 self.annotate(loadattr)
1.80 return loadattr
1.81
1.82 + def visitLoadName(self, loadname):
1.83 + self.namespace.set_types(self.namespace.load(loadname.name))
1.84 + result = loadname
1.85 + self.annotate(result)
1.86 + return result
1.87 +
1.88 + def visitLoadRef(self, loadref):
1.89 + self.namespace.set_types([Attribute(None, loadref.ref)])
1.90 + self.annotate(loadref)
1.91 + return loadref
1.92 +
1.93 + def visitLoadTemp(self, loadtemp):
1.94 + index = getattr(loadtemp, "index", None)
1.95 + try:
1.96 + if getattr(loadtemp, "release", 0):
1.97 + self.namespace.set_types(self.namespace.temp[index].pop())
1.98 + else:
1.99 + self.namespace.set_types(self.namespace.temp[index][-1])
1.100 + except KeyError:
1.101 + raise AnnotationMessage, "Temporary store index '%s' not defined." % index
1.102 + self.annotate(loadtemp)
1.103 + return loadtemp
1.104 +
1.105 + def visitReleaseTemp(self, releasetemp):
1.106 + index = getattr(releasetemp, "index", None)
1.107 + try:
1.108 + self.namespace.temp[index].pop()
1.109 + except KeyError:
1.110 + raise AnnotationMessage, "Temporary store index '%s' not defined." % index
1.111 + except IndexError:
1.112 + pass #raise AnnotationMessage, "Temporary store index '%s' is empty." % index
1.113 + return releasetemp
1.114 +
1.115 + def visitReturn(self, return_):
1.116 + if hasattr(return_, "expr"):
1.117 + return_.expr = self.dispatch(return_.expr)
1.118 + combine(self.namespace.returns, self.namespace.types)
1.119 + self.annotate(return_)
1.120 + self.namespace.snapshot()
1.121 + return return_
1.122 +
1.123 def visitStoreAttr(self, storeattr):
1.124 storeattr.expr = self.dispatch(storeattr.expr)
1.125 expr = self.namespace.types
1.126 @@ -321,38 +345,20 @@
1.127 storeattr.writes = writes
1.128 return storeattr
1.129
1.130 - def visitConditional(self, conditional):
1.131 -
1.132 - # Conditionals keep local namespace changes isolated.
1.133 - # With Return nodes inside the body/else sections, the changes are
1.134 - # communicated to the caller.
1.135 -
1.136 - conditional.test = self.dispatch(conditional.test)
1.137 - saved_namespace = self.namespace
1.138 -
1.139 - self.namespace = Namespace()
1.140 - self.namespace.merge_namespace(saved_namespace)
1.141 - conditional.body = self.dispatches(conditional.body)
1.142 - body_namespace = self.namespace
1.143 + def visitStoreName(self, storename):
1.144 + storename.expr = self.dispatch(storename.expr)
1.145 + self.namespace.store(storename.name, self.namespace.types)
1.146 + return storename
1.147
1.148 - self.namespace = Namespace()
1.149 - self.namespace.merge_namespace(saved_namespace)
1.150 - conditional.else_ = self.dispatches(conditional.else_)
1.151 - else_namespace = self.namespace
1.152 -
1.153 - self.namespace = Namespace()
1.154 - self.namespace.merge_namespace(body_namespace)
1.155 - self.namespace.merge_namespace(else_namespace)
1.156 + def visitStoreTemp(self, storetemp):
1.157 + storetemp.expr = self.dispatch(storetemp.expr)
1.158 + index = getattr(storetemp, "index", None)
1.159 + if not self.namespace.temp.has_key(index):
1.160 + self.namespace.temp[index] = []
1.161 + self.namespace.temp[index].append(self.namespace.types)
1.162 + return storetemp
1.163
1.164 - return conditional
1.165 -
1.166 - def visitReturn(self, return_):
1.167 - if hasattr(return_, "expr"):
1.168 - return_.expr = self.dispatch(return_.expr)
1.169 - combine(self.namespace.returns, self.namespace.types)
1.170 - self.annotate(return_)
1.171 - self.namespace.snapshot()
1.172 - return return_
1.173 + # Invocations are a chapter of their own.
1.174
1.175 def visitInvoke(self, invoke):
1.176