1.1 --- a/micropython/ast.py Mon May 19 00:22:00 2008 +0200
1.2 +++ b/micropython/ast.py Sat Jun 07 21:55:24 2008 +0200
1.3 @@ -105,8 +105,8 @@
1.4 self.code = []
1.5 self.temp_position = self.unit.stack_local_usage
1.6
1.7 - if unit.node is not None:
1.8 - self.dispatch(unit.node)
1.9 + if unit.astnode is not None:
1.10 + self.dispatch(unit.astnode)
1.11
1.12 self.calculate_stack_usage()
1.13 return self.code
1.14 @@ -511,14 +511,15 @@
1.15
1.16 for pos in range(nargs_min, nargs_max):
1.17 if pos not in employed_positions:
1.18 - self.new_op(LoadConst(target))
1.19 - self.new_op(LoadAttr(target.default_attrs[pos - nargs_min]))
1.20 + #self.new_op(LoadConst(target))
1.21 + #self.new_op(LoadAttr(target.default_attrs[pos - nargs_min]))
1.22 + self.new_op(LoadAddress(target.default_attrs[pos - nargs_min]))
1.23
1.24 - # If the position corresponds to the current frame element,
1.25 - # skip generating the instruction.
1.26 + # If the position corresponds to the current frame element,
1.27 + # skip generating the instruction.
1.28
1.29 - if frame_pos != pos:
1.30 - self.new_op(StoreFrame(pos))
1.31 + if frame_pos != pos:
1.32 + self.new_op(StoreFrame(pos))
1.33
1.34 frame_pos += 1
1.35
2.1 --- a/micropython/common.py Mon May 19 00:22:00 2008 +0200
2.2 +++ b/micropython/common.py Sat Jun 07 21:55:24 2008 +0200
2.3 @@ -50,11 +50,11 @@
2.4
2.5 def __init__(self, unit_name, node, message):
2.6 self.unit_name = unit_name
2.7 - self.node = node
2.8 + self.astnode = node
2.9 self.message = message
2.10
2.11 def __repr__(self):
2.12 - return "Error in %r at line %d: %s" % (self.unit_name, self.node.lineno, self.message)
2.13 + return "Error in %r at line %d: %s" % (self.unit_name, self.astnode.lineno, self.message)
2.14
2.15 def __str__(self):
2.16 return repr(self)
3.1 --- a/micropython/data.py Mon May 19 00:22:00 2008 +0200
3.2 +++ b/micropython/data.py Sat Jun 07 21:55:24 2008 +0200
3.3 @@ -146,7 +146,7 @@
3.4 if not self.namespace.has_key(name):
3.5 self.globals.add(name)
3.6 else:
3.7 - raise InspectError(self.full_name(), self.node, "Name %r is both global and local in %r" % (name, self.full_name()))
3.8 + raise InspectError(self.full_name(), self.astnode, "Name %r is both global and local in %r" % (name, self.full_name()))
3.9
3.10 def get_assignments(self, name):
3.11 if self.assignments.has_key(name):
3.12 @@ -319,7 +319,7 @@
3.13 NamespaceDict.__init__(self, global_namespace)
3.14 self.name = name
3.15 self.parent = parent
3.16 - self.node = node
3.17 + self.astnode = node
3.18
3.19 # Superclasses, descendants and attributes.
3.20
3.21 @@ -641,7 +641,7 @@
3.22 self.defaults = defaults
3.23 self.has_star = has_star
3.24 self.has_dstar = has_dstar
3.25 - self.node = node
3.26 + self.astnode = node
3.27
3.28 # Initialise the positional names.
3.29
3.30 @@ -709,7 +709,7 @@
3.31 if name not in self.argnames and not self.has_key(name):
3.32 self.globals.add(name)
3.33 else:
3.34 - raise InspectError(self.full_name(), self.node, "Name %r is global and local in %r" % (name, self.full_name()))
3.35 + raise InspectError(self.full_name(), self.astnode, "Name %r is global and local in %r" % (name, self.full_name()))
3.36
3.37 def parameters(self):
3.38
3.39 @@ -789,7 +789,7 @@
3.40 "Make a function from a method."
3.41
3.42 function = Function(self.name, self.parent, self.argnames[1:], self.defaults,
3.43 - self.has_star, self.has_dstar, self.global_namespace, self.node)
3.44 + self.has_star, self.has_dstar, self.global_namespace, self.astnode)
3.45 function.default_attrs = self.default_attrs
3.46 return function
3.47
3.48 @@ -831,7 +831,7 @@
3.49
3.50 # Original location details.
3.51
3.52 - self.node = None
3.53 + self.astnode = None
3.54
3.55 # Complete lists of classes and functions.
3.56
4.1 --- a/micropython/inspect.py Mon May 19 00:22:00 2008 +0200
4.2 +++ b/micropython/inspect.py Sat Jun 07 21:55:24 2008 +0200
4.3 @@ -17,6 +17,58 @@
4.4
4.5 You should have received a copy of the GNU General Public License along with
4.6 this program. If not, see <http://www.gnu.org/licenses/>.
4.7 +
4.8 +--------
4.9 +
4.10 +The results of inspecting a module are as follows:
4.11 +
4.12 +Constants
4.13 +---------
4.14 +
4.15 +All constants identified within the code shall be registered.
4.16 +
4.17 +Classes
4.18 +-------
4.19 +
4.20 +All global classes shall be registered; local classes (within functions) or
4.21 +nested classes (within classes) are not currently registered.
4.22 +
4.23 +Base classes must be detected and constant.
4.24 +
4.25 +All classes without bases are made to inherit from __builtins__.object in order
4.26 +to support some standard methods.
4.27 +
4.28 +Functions
4.29 +---------
4.30 +
4.31 +All functions and lambda definitions shall be registered.
4.32 +
4.33 +Namespaces
4.34 +----------
4.35 +
4.36 +Modules define their own "global" namespace, within which classes, functions
4.37 +and lambda definitions establish a hierarchy of namespaces.
4.38 +
4.39 +Only local, global and built-in namespaces are recognised; closures are not
4.40 +supported.
4.41 +
4.42 +Assignments
4.43 +-----------
4.44 +
4.45 +Name assignment and attribute assignment involving modules and classes cause
4.46 +names to be associated with values within namespaces.
4.47 +
4.48 +Any assignments within loops are considered to cause the targets of such
4.49 +assignments to provide non-constant values.
4.50 +
4.51 +Assignments to names are only really considered to cause the targets of such
4.52 +assignments to provide constant values if the targets reside in the module
4.53 +namespace or in class namespaces, subject to the above conditions.
4.54 +
4.55 +Assignments to names within functions are not generally considered to cause the
4.56 +targets of such assignments to provide constant values since functions can be
4.57 +invoked many times with different inputs. However, there may be benefits in
4.58 +considering a local to be constant within a single invocation.
4.59 """
4.60
4.61 from micropython.common import *
4.62 @@ -44,6 +96,8 @@
4.63 Module.__init__(self, name)
4.64 self.visitor = self
4.65
4.66 + # Import machinery links.
4.67 +
4.68 self.importer = importer
4.69 self.builtins = self.importer.modules.get("__builtins__")
4.70 self.loaded = 0
4.71 @@ -59,6 +113,7 @@
4.72 # Namespace state.
4.73
4.74 self.in_init = 0 # Find instance attributes in __init__ methods.
4.75 + self.in_method = 0 # Find instance attributes in all methods.
4.76 self.in_loop = 0 # Note loop "membership", affecting assignments.
4.77 self.namespaces = []
4.78 self.module = None
4.79 @@ -74,7 +129,7 @@
4.80
4.81 "Process the given 'module'."
4.82
4.83 - self.node = self.module = module
4.84 + self.astnode = self.module = module
4.85 processed = self.dispatch(module)
4.86 if self.has_key("__all__"):
4.87 all = self["__all__"]
4.88 @@ -113,13 +168,32 @@
4.89 self.all_objects.add(obj)
4.90
4.91 def store_lambda(self, obj):
4.92 +
4.93 + "Store a lambda function 'obj'."
4.94 +
4.95 self.all_objects.add(obj)
4.96
4.97 + def store_class_attr(self, name):
4.98 +
4.99 + "Record class attribute 'name' in the current class."
4.100 +
4.101 + if self.in_method and self.namespaces[-2].has_key(name):
4.102 +
4.103 + if isinstance(self.expr, Attr):
4.104 + assigned_value = self.expr.value
4.105 + else:
4.106 + assigned_value = self.expr
4.107 +
4.108 + self.namespaces[-2].set(name, assigned_value, 0)
4.109 + return 1
4.110 +
4.111 + return 0
4.112 +
4.113 def store_instance_attr(self, name):
4.114
4.115 "Record instance attribute 'name' in the current class."
4.116
4.117 - if self.in_init:
4.118 + if self.in_method:
4.119
4.120 # Current namespace is the function.
4.121 # Previous namespace is the class.
4.122 @@ -150,6 +224,15 @@
4.123 self.dispatch(n)
4.124 return Instance()
4.125
4.126 + def _visitConst(self, node):
4.127 + return self._make_constant(node.value)
4.128 +
4.129 + def _make_constant(self, value):
4.130 + if not self.constant_values.has_key(value):
4.131 + const = Const(value)
4.132 + self.constant_values[value] = const
4.133 + return self.constant_values[value]
4.134 +
4.135 def _visitFunction(self, node, name):
4.136
4.137 """
4.138 @@ -189,11 +272,14 @@
4.139 # Current namespace is the function.
4.140 # Previous namespace is the class.
4.141
4.142 - if name == "__init__" and isinstance(self.namespaces[-2], Class):
4.143 - self.in_init = 1
4.144 + if len(self.namespaces) > 1 and isinstance(self.namespaces[-2], Class):
4.145 + if name == "__init__":
4.146 + self.in_init = 1
4.147 + self.in_method = 1
4.148
4.149 self.dispatch(node.code)
4.150 self.in_init = 0
4.151 + self.in_method = 0
4.152 self.namespaces.pop()
4.153
4.154 if name is not None:
4.155 @@ -218,7 +304,8 @@
4.156 def visitAssAttr(self, node):
4.157 expr = self.dispatch(node.expr)
4.158 if isinstance(expr, Attr) and expr.name == "self":
4.159 - self.store_instance_attr(node.attrname)
4.160 + if not self.store_class_attr(node.attrname):
4.161 + self.store_instance_attr(node.attrname)
4.162 return None
4.163
4.164 def visitAssList(self, node):
4.165 @@ -250,6 +337,12 @@
4.166 visitCallFunc = OP
4.167
4.168 def visitClass(self, node):
4.169 +
4.170 + """
4.171 + Register the class at the given 'node' subject to the restrictions
4.172 + mentioned in the module docstring.
4.173 + """
4.174 +
4.175 if self.namespaces:
4.176 print "Class %r in %r is not global: ignored." % (node.name, self.namespaces[-1].full_name())
4.177 return None
4.178 @@ -297,9 +390,7 @@
4.179 visitCompare = OP
4.180
4.181 def visitConst(self, node):
4.182 - const = Const(node.value)
4.183 - self.constant_values[node.value] = const
4.184 - return const
4.185 + return self._visitConst(node)
4.186
4.187 visitContinue = NOP
4.188
4.189 @@ -411,8 +502,7 @@
4.190
4.191 def visitKeyword(self, node):
4.192 self.dispatch(node.expr)
4.193 - const = Const(node.name)
4.194 - self.constant_values[node.name] = const
4.195 + self._visitConst(node)
4.196 self.keyword_names.add(node.name)
4.197 return None
4.198
4.199 @@ -439,9 +529,7 @@
4.200 def visitName(self, node):
4.201 name = node.name
4.202 if name == "None":
4.203 - const = Const(None)
4.204 - self.constant_values[None] = const
4.205 - return const
4.206 + return self._make_constant(None)
4.207 elif self.namespaces and self.namespaces[-1].has_key(name):
4.208 return self.namespaces[-1][name]
4.209 elif self.has_key(name):
5.1 --- a/micropython/rsvp.py Mon May 19 00:22:00 2008 +0200
5.2 +++ b/micropython/rsvp.py Sat Jun 07 21:55:24 2008 +0200
5.3 @@ -31,6 +31,12 @@
5.4 new_code.append(item)
5.5 return new_code
5.6
5.7 +def name(attr):
5.8 + if isinstance(attr, Attr):
5.9 + return attr.name
5.10 + else:
5.11 + return attr
5.12 +
5.13 class Instruction:
5.14
5.15 "A generic instruction."
5.16 @@ -63,7 +69,11 @@
5.17 "An instruction accessing an object's attribute."
5.18
5.19 def __repr__(self):
5.20 - return "%s(%r)" % (self.__class__.__name__, self.get_operand())
5.21 + position = self.get_operand()
5.22 + if position is not None:
5.23 + return "%s(%r) # %s" % (self.__class__.__name__, position, name(self.attr))
5.24 + else:
5.25 + return "%s(%r)" % (self.__class__.__name__, name(self.attr))
5.26
5.27 def get_operand(self):
5.28 return self.attr.position
5.29 @@ -77,9 +87,11 @@
5.30 def __repr__(self):
5.31 location, position, result = self.get_operands()
5.32 if location is not None:
5.33 - return "%s(%r, %r -> %r)" % (self.__class__.__name__, location, position, result)
5.34 + return "%s(%r) # %r, %r (%s)" % (self.__class__.__name__, result, location, position, name(self.attr))
5.35 + elif result is not None:
5.36 + return "%s(%r) # %s" % (self.__class__.__name__, result, name(self.attr))
5.37 else:
5.38 - return "%s(%r)" % (self.__class__.__name__, result)
5.39 + return "%s(...) # %s" % (self.__class__.__name__, name(self.attr))
5.40
5.41 def get_operands(self):
5.42 if isinstance(self.attr, Attr):
6.1 --- a/tests/attributes.py Mon May 19 00:22:00 2008 +0200
6.2 +++ b/tests/attributes.py Sat Jun 07 21:55:24 2008 +0200
6.3 @@ -5,6 +5,11 @@
6.4
6.5 def __init__(self, value):
6.6 self.instattr = value
6.7 + self.clsattr
6.8 +
6.9 + def update(self, value):
6.10 + self.attr = value
6.11 + self.clsattr = value
6.12
6.13 C
6.14 C.clsattr
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/tests/range.py Sat Jun 07 21:55:24 2008 +0200
7.3 @@ -0,0 +1,7 @@
7.4 +#!/usr/bin/env python
7.5 +
7.6 +a = 1
7.7 +b = 2
7.8 +range(a, b)
7.9 +
7.10 +# vim: tabstop=4 expandtab shiftwidth=4