1.1 --- a/annotate.py Wed Jul 19 00:21:49 2006 +0200
1.2 +++ b/annotate.py Thu Jul 20 00:25:43 2006 +0200
1.3 @@ -25,12 +25,11 @@
1.4 import compiler
1.5
1.6 class Namespace:
1.7 - def __init__(self, local_is_structure=0, parent=None):
1.8 + def __init__(self, local_is_structure=0):
1.9 if local_is_structure:
1.10 self.local = "structure"
1.11 else:
1.12 self.local = "local"
1.13 - self.parent = parent
1.14 self.names = {}
1.15 self.not_local = []
1.16
1.17 @@ -38,21 +37,27 @@
1.18 if name not in self.not_local:
1.19 self.not_local.append(name)
1.20
1.21 - def find(self, name):
1.22 + def find_for_store(self, name):
1.23 if name not in self.not_local:
1.24 return self.local
1.25 else:
1.26 return "global"
1.27
1.28 + def find_for_load(self, name):
1.29 + if name not in self.not_local and self.names.has_key(name):
1.30 + return self.local
1.31 + else:
1.32 + return "global"
1.33 +
1.34 def store(self, name, types):
1.35 if name not in self.not_local:
1.36 self.names[name] = types
1.37 else:
1.38 - self.parent.store(name, types)
1.39 + raise KeyError, name
1.40
1.41 def load(self, name):
1.42 if name in self.not_local or not self.names.has_key(name):
1.43 - return self.parent.load(name)
1.44 + raise KeyError, name
1.45 else:
1.46 return self.names[name]
1.47
1.48 @@ -85,7 +90,7 @@
1.49 self.types = None
1.50 self.temp = {}
1.51
1.52 - def process(self, node):
1.53 + def process(self, node, global_namespace=None):
1.54 if hasattr(node, "structure"):
1.55 self.structure = node.structure
1.56 has_structure = 1
1.57 @@ -94,8 +99,11 @@
1.58 has_structure = 0
1.59
1.60 self.namespace = Namespace(self.structure is not None)
1.61 + self.global_namespace = global_namespace or self.namespace # NOTE: Improve this.
1.62 +
1.63 if has_structure:
1.64 node.structure.namespace = self.namespace
1.65 + node.namespace = self.namespace
1.66
1.67 self.visitor = self
1.68 result = self.dispatch(node)
1.69 @@ -103,10 +111,26 @@
1.70 return result
1.71
1.72 def default(self, node):
1.73 - for attr in ("args", "params"):
1.74 + for attr in ("args",):
1.75 value = getattr(node, attr, None)
1.76 if value is not None:
1.77 setattr(node, attr, self.dispatches(value))
1.78 +
1.79 + # NOTE: This will eventually use both defaults and supplied arguments.
1.80 +
1.81 + for attr in ("params",):
1.82 + value = getattr(node, attr, None)
1.83 + if value is not None:
1.84 + params = []
1.85 + for name, default in value:
1.86 + if default is not None:
1.87 + n = self.dispatch(default)
1.88 + self.namespace.store(name, self.types)
1.89 + else:
1.90 + n = None
1.91 + self.namespace.store(name, [])
1.92 + params.append((name, n))
1.93 + setattr(node, attr, params)
1.94 for attr in ("expr", "lvalue", "test", "handler", "star", "dstar"):
1.95 value = getattr(node, attr, None)
1.96 if value is not None:
1.97 @@ -122,7 +146,7 @@
1.98
1.99 def visitGlobal(self, global_):
1.100 for name in global_.names:
1.101 - self.make_global(name)
1.102 + self.namespace.make_global(name)
1.103 return global_
1.104
1.105 def visitLoadRef(self, loadref):
1.106 @@ -130,25 +154,47 @@
1.107 return loadref
1.108
1.109 def visitLoadName(self, loadname):
1.110 - if self.namespace.find(loadname.name) == "structure":
1.111 + scope = self.namespace.find_for_load(loadname.name)
1.112 + print "LoadName", scope
1.113 + if scope == "structure":
1.114 return self.dispatch(LoadAttr(expr=LoadRef(ref=self.structure), name=loadname.name))
1.115 + elif scope == "global":
1.116 + return self.dispatch(LoadGlobal(name=loadname.name))
1.117 else:
1.118 - self.types = self.namespace.load(loadname, loadname.name)
1.119 + self.types = self.namespace.load(loadname.name)
1.120 return loadname
1.121
1.122 def visitStoreName(self, storename):
1.123 - if self.namespace.find(storename.name) == "structure":
1.124 + scope = self.namespace.find_for_store(storename.name)
1.125 + print "StoreName", scope
1.126 + if scope == "structure":
1.127 return self.dispatch(StoreAttr(lvalue=LoadRef(ref=self.structure), name=storename.name, expr=storename.expr))
1.128 + elif scope == "global":
1.129 + return self.dispatch(StoreGlobal(name=storename.name, expr=storename.expr))
1.130 else:
1.131 - self.namespace.store(storename, storename.name, self.types)
1.132 + storename.expr = self.dispatch(storename.expr)
1.133 + self.namespace.store(storename.name, self.types)
1.134 return storename
1.135
1.136 + def visitLoadGlobal(self, loadglobal):
1.137 + self.types = self.global_namespace.load(loadglobal.name)
1.138 + return loadglobal
1.139 +
1.140 + def visitStoreGlobal(self, storeglobal):
1.141 + storeglobal.expr = self.dispatch(storeglobal.expr)
1.142 +
1.143 + # NOTE: This may always be a merge operation.
1.144 +
1.145 + self.global_namespace.store(storeglobal.name, self.types)
1.146 + return storeglobal
1.147 +
1.148 def visitLoadTemp(self, loadtemp):
1.149 index = getattr(loadtemp, "index", None)
1.150 self.types = self.temp[index]
1.151 return loadtemp
1.152
1.153 def visitStoreTemp(self, storetemp):
1.154 + storetemp.expr = self.dispatch(storetemp.expr)
1.155 index = getattr(storetemp, "index", None)
1.156 self.temp[index] = self.types
1.157 return storetemp
1.158 @@ -159,7 +205,7 @@
1.159 return releasetemp
1.160
1.161 def visitLoadAttr(self, loadattr):
1.162 - self.dispatch(loadattr.expr)
1.163 + loadattr.expr = self.dispatch(loadattr.expr)
1.164 types = []
1.165 for ref in self.types:
1.166 types += ref.namespace.load(loadattr.name)
1.167 @@ -167,9 +213,9 @@
1.168 return loadattr
1.169
1.170 def visitStoreAttr(self, storeattr):
1.171 - self.dispatch(storeattr.expr)
1.172 + storeattr.expr = self.dispatch(storeattr.expr)
1.173 expr = self.types
1.174 - self.dispatch(storeattr.lvalue)
1.175 + storeattr.lvalue = self.dispatch(storeattr.lvalue)
1.176 for ref in self.types:
1.177 ref.namespace.store(storeattr.name, expr)
1.178 return storeattr