1.1 --- a/fixnames.py Sat Aug 12 01:46:35 2006 +0200
1.2 +++ b/fixnames.py Sat Aug 12 18:47:05 2006 +0200
1.3 @@ -21,6 +21,22 @@
1.4 License along with this library; see the file LICENCE.txt
1.5 If not, write to the Free Software Foundation, Inc.,
1.6 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1.7 +
1.8 +--------
1.9 +
1.10 +To use this module, first instantiate a Fixer object:
1.11 +
1.12 +fixer = Fixer()
1.13 +
1.14 +Then, apply the fixer to an existing Simplifier object:
1.15 +
1.16 +simplifier = ...
1.17 +fixer.process(simplifier)
1.18 +
1.19 +If an existing simplifier has been used to process a module containing built-in
1.20 +classes and functions, apply the fixer as follows:
1.21 +
1.22 +fixer.process(simplifier, builtins_simplifier)
1.23 """
1.24
1.25 from simplified import *
1.26 @@ -46,9 +62,12 @@
1.27
1.28 self.visitor = self
1.29
1.30 - def process(self, visitor):
1.31 + def process(self, visitor, builtins_visitor=None):
1.32
1.33 - "Process the resources of the given 'visitor'."
1.34 + """
1.35 + Process the resources of the given 'visitor' optionally using a
1.36 + 'builtins_visitor' to reference built-in objects.
1.37 + """
1.38
1.39 self.subprograms = []
1.40 self.current_subprograms = []
1.41 @@ -58,7 +77,12 @@
1.42 # defined at that level.
1.43
1.44 self.global_namespace = None
1.45 - visitor.result = self.process_node(visitor.result)
1.46 + self.module = visitor.result
1.47 + if builtins_visitor is not None:
1.48 + self.builtins_module = builtins_visitor.result
1.49 + else:
1.50 + self.builtins_module = None
1.51 + self.process_node(visitor.result)
1.52
1.53 # Then, process all functions and methods, providing a global namespace.
1.54
1.55 @@ -174,7 +198,7 @@
1.56
1.57 "Transform the 'loadname' node to a specific, scope-sensitive node."
1.58
1.59 - scope = self.namespace.find_for_load(loadname.name)
1.60 + scope = self.namespace.find(loadname.name)
1.61
1.62 # For structure namespaces, load an attribute.
1.63
1.64 @@ -188,25 +212,25 @@
1.65 # Where a distinct global namespace exists, examine it.
1.66
1.67 if self.global_namespace is not None:
1.68 - scope = self.global_namespace.find_for_load(loadname.name)
1.69 + scope = self.global_namespace.find(loadname.name)
1.70
1.71 # Where the name is outside the global namespace, it must be a
1.72 # built-in.
1.73
1.74 if scope == "global":
1.75 - result = self.dispatch(LoadBuiltin(name=loadname.name))
1.76 + result = self.dispatch(LoadAttr(expr=LoadRef(ref=self.builtins_module), name=loadname.name))
1.77
1.78 # Otherwise, it is within the global namespace and must be a
1.79 # global.
1.80
1.81 else:
1.82 - result = self.dispatch(LoadGlobal(name=loadname.name))
1.83 + result = self.dispatch(LoadAttr(expr=LoadRef(ref=self.module), name=loadname.name))
1.84
1.85 # Where no global namespace exists, we are at the module level and
1.86 # must be accessing a built-in.
1.87
1.88 else:
1.89 - result = self.dispatch(LoadBuiltin(name=loadname.name))
1.90 + result = self.dispatch(LoadAttr(expr=LoadRef(ref=self.builtins_module), name=loadname.name))
1.91
1.92 # For local accesses...
1.93
1.94 @@ -221,7 +245,7 @@
1.95 # module level).
1.96
1.97 else:
1.98 - result = self.dispatch(LoadGlobal(name=loadname.name))
1.99 + result = self.dispatch(LoadAttr(expr=LoadRef(ref=self.module), name=loadname.name))
1.100
1.101 return result
1.102
1.103 @@ -229,7 +253,7 @@
1.104
1.105 "Transform the 'storename' node to a specific, scope-sensitive node."
1.106
1.107 - scope = self.namespace.find_for_store(storename.name)
1.108 + scope = self.namespace.find(storename.name)
1.109
1.110 # For structure namespaces, store an attribute.
1.111
1.112 @@ -240,7 +264,7 @@
1.113 # assignment and store the name globally.
1.114
1.115 elif scope == "global":
1.116 - return self.dispatch(StoreGlobal(name=storename.name, expr=storename.expr))
1.117 + return self.dispatch(StoreAttr(lvalue=LoadRef(ref=self.module), name=storename.name, expr=storename.expr))
1.118
1.119 # For local namespace accesses...
1.120
1.121 @@ -256,7 +280,7 @@
1.122 # considered global.
1.123
1.124 else:
1.125 - return self.dispatch(StoreGlobal(name=storename.name, expr=storename.expr))
1.126 + return self.dispatch(StoreAttr(lvalue=LoadRef(ref=self.module), name=storename.name, expr=storename.expr))
1.127
1.128 def visitInvoke(self, invoke):
1.129
1.130 @@ -273,6 +297,9 @@
1.131 else:
1.132 return self.default(invoke)
1.133
1.134 +class ScopeMismatch(Exception):
1.135 + pass
1.136 +
1.137 class NameOrganiser:
1.138
1.139 """
1.140 @@ -281,52 +308,46 @@
1.141 """
1.142
1.143 def __init__(self, structure=None):
1.144 +
1.145 + "Initialise the namespace with an optional 'structure'."
1.146 +
1.147 self.structure = structure
1.148 if structure is not None:
1.149 self.local = "structure"
1.150 else:
1.151 self.local = "local"
1.152 +
1.153 + # Names may be self.local or "global".
1.154 +
1.155 self.names = {}
1.156 - self.not_local = []
1.157
1.158 def make_global(self, name):
1.159 - if name not in self.not_local:
1.160 - self.not_local.append(name)
1.161 + if not self.names.has_key(name):
1.162 + self.names[name] = "global"
1.163 + elif self.names[name] == self.local:
1.164 + raise ScopeMismatch, "Name '%s' already considered as %s." % (name, self.local)
1.165
1.166 - def find_for_store(self, name):
1.167 - if name not in self.not_local:
1.168 - return self.local
1.169 - else:
1.170 - return "global"
1.171 -
1.172 - def find_for_load(self, name):
1.173 - if name not in self.not_local and self.names.has_key(name):
1.174 - return self.local
1.175 - else:
1.176 - return "global"
1.177 + def find(self, name):
1.178 + return self.names.get(name, "global")
1.179
1.180 def store(self, name):
1.181 - if name not in self.not_local:
1.182 - self.names[name] = None
1.183 + if self.names.get(name) != "global":
1.184 + self.names[name] = self.local
1.185 else:
1.186 - raise KeyError, name
1.187 + raise ScopeMismatch, "Name '%s' already considered as global." % name
1.188
1.189 - def load(self, name):
1.190 - if name in self.not_local or not self.names.has_key(name):
1.191 - raise KeyError, name
1.192 + def merge(self, name, scope):
1.193 + if self.names.get(name) in (None, scope):
1.194 + self.names[name] = scope
1.195 else:
1.196 - return self.names[name]
1.197 -
1.198 - def merge(self, name):
1.199 - if not self.names.has_key(name):
1.200 - self.names[name] = None
1.201 + raise ScopeMismatch, "Name '%s' already considered as %s." % (name, self.names[name])
1.202
1.203 def merge_namespace(self, namespace):
1.204 - self.merge_names(namespace.names.keys())
1.205 + self.merge_items(namespace.names.items())
1.206
1.207 - def merge_names(self, names):
1.208 - for name in names:
1.209 - self.merge(name)
1.210 + def merge_items(self, items):
1.211 + for name, scope in items:
1.212 + self.merge(name, scope)
1.213
1.214 def __repr__(self):
1.215 return repr(self.names)
3.1 --- a/simplify.py Sat Aug 12 01:46:35 2006 +0200
3.2 +++ b/simplify.py Sat Aug 12 18:47:05 2006 +0200
3.3 @@ -21,6 +21,17 @@
3.4 License along with this library; see the file LICENCE.txt
3.5 If not, write to the Free Software Foundation, Inc.,
3.6 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
3.7 +
3.8 +--------
3.9 +
3.10 +To use this module, first instantiate a Simplifier object:
3.11 +
3.12 +simplifier = Simplifier()
3.13 +
3.14 +Then, apply the simplifier to an AST tree:
3.15 +
3.16 +module = compiler.parseFile(...)
3.17 +simplifier.process(module)
3.18 """
3.19
3.20 from simplified import *
3.21 @@ -45,6 +56,13 @@
3.22 """
3.23
3.24 def __init__(self, builtins=0):
3.25 +
3.26 + """
3.27 + Initialise the simplifier with the optional 'builtins' parameter
3.28 + indicating whether the module contains the built-in classes and
3.29 + functions.
3.30 + """
3.31 +
3.32 Visitor.__init__(self)
3.33 self.result = None # The resulting tree.
3.34 self.subprograms = [] # Subprograms outside the tree.
3.35 @@ -77,6 +95,12 @@
3.36 # Relatively trivial transformations.
3.37
3.38 def visitModule(self, module):
3.39 +
3.40 + """
3.41 + Process the given 'module', producing a Module object which contains the
3.42 + resulting program nodes.
3.43 + """
3.44 +
3.45 self.result = Module(module)
3.46 module_code = self.dispatch(module.node)
3.47
3.48 @@ -709,10 +733,25 @@
3.49 return result
3.50
3.51 def _visitFunction(self, function, subprogram):
3.52 - if function.flags & 4 != 0: has_star = 1
3.53 - else: has_star = 0
3.54 - if function.flags & 8 != 0: has_dstar = 1
3.55 - else: has_dstar = 0
3.56 +
3.57 + """
3.58 + A common function generator which transforms the given 'function' node
3.59 + and initialises the given 'subprogram' appropriately.
3.60 + """
3.61 +
3.62 + # Discover star and dstar parameters.
3.63 +
3.64 + if function.flags & 4 != 0:
3.65 + has_star = 1
3.66 + else:
3.67 + has_star = 0
3.68 + if function.flags & 8 != 0:
3.69 + has_dstar = 1
3.70 + else:
3.71 + has_dstar = 0
3.72 +
3.73 + # Discover the number of defaults and positional parameters.
3.74 +
3.75 ndefaults = len(function.defaults)
3.76 npositional = len(function.argnames) - has_star - has_dstar
3.77