1.1 --- a/lib/operator.py Sun Sep 05 02:20:05 2010 +0200
1.2 +++ b/lib/operator.py Sun Sep 05 21:14:40 2010 +0200
1.3 @@ -220,4 +220,20 @@
1.4 def ne(a, b):
1.5 return binary_op(a, b, lambda a: a.__ne__, lambda b: b.__ne__)
1.6
1.7 +# Access and slicing functions.
1.8 +
1.9 +def getitem(a, b):
1.10 + return a.__getitem__(b)
1.11 +
1.12 +def setitem(a, b, c):
1.13 + a.__setitem__(b, c)
1.14 +
1.15 +# NOTE: Should be able to optimise temporary instance allocations for slices.
1.16 +
1.17 +def getslice(a, b, c):
1.18 + return a.__getitem__(slice(b, c))
1.19 +
1.20 +def setslice(a, b, c, d):
1.21 + a.__setitem__(slice(b, c), d)
1.22 +
1.23 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/micropython/ast.py Sun Sep 05 02:20:05 2010 +0200
2.2 +++ b/micropython/ast.py Sun Sep 05 21:14:40 2010 +0200
2.3 @@ -86,6 +86,7 @@
2.4 self.loop_blocks = []
2.5 self.exception_blocks = []
2.6 self.in_exception_handler = 0
2.7 + self.in_assignment = 0 # for slicing and subscript
2.8
2.9 self.reset()
2.10
2.11 @@ -415,36 +416,29 @@
2.12 self._visitName(node, self.name_load_instructions)
2.13
2.14 def visitSlice(self, node):
2.15 + args = [node.expr]
2.16 +
2.17 if node.lower is None:
2.18 + args.append(compiler.ast.Name("None"))
2.19 if node.upper is None:
2.20 - args = []
2.21 + args.append(compiler.ast.Name("None"))
2.22 else:
2.23 - args = [compiler.ast.Name("None"), node.upper]
2.24 + args.append(node.upper)
2.25 else:
2.26 - args = [node.lower]
2.27 + args.append(node.lower)
2.28 if node.upper is None:
2.29 args.append(compiler.ast.Name("None"))
2.30 else:
2.31 args.append(node.upper)
2.32
2.33 - # NOTE: Need to guarantee reliable access to the slice built-in.
2.34 -
2.35 - slice = compiler.ast.CallFunc(compiler.ast.Name("slice"), args)
2.36 -
2.37 - self.dispatch(node.expr)
2.38 - self._startCallFunc()
2.39 - self._generateAttr(node, "__getitem__", self.attribute_load_instructions)
2.40 - temp_target, target, temp_context = self._generateCallFunc([slice], node)
2.41 - self._doCallFunc(temp_target, target)
2.42 - self._endCallFunc(temp_target, temp_context)
2.43 + temp_fn = self._getOperatorFunction(node, self.in_assignment and "AssSlice" or "Slice")
2.44 + self._visitCall(node, temp_fn, args)
2.45 + self.discard_temp(temp_fn)
2.46
2.47 def visitSubscript(self, node):
2.48 - self.dispatch(node.expr)
2.49 - self._startCallFunc()
2.50 - self._generateAttr(node, "__getitem__", self.attribute_load_instructions)
2.51 - temp_target, target, temp_context = self._generateCallFunc(node.subs, node)
2.52 - self._doCallFunc(temp_target, target)
2.53 - self._endCallFunc(temp_target, temp_context)
2.54 + temp_fn = self._getOperatorFunction(node, self.in_assignment and "AssSubscript" or "Subscript")
2.55 + self._visitCall(node, temp_fn, [node.expr] + node.subs)
2.56 + self.discard_temp(temp_fn)
2.57
2.58 def visitTuple(self, node):
2.59 self._generateTuple(node)
2.60 @@ -464,9 +458,12 @@
2.61
2.62 self.record_value(self.has_immediate_usage(node.nodes))
2.63
2.64 + self.in_assignment = 1
2.65 +
2.66 for n in node.nodes:
2.67 self.dispatch(n)
2.68
2.69 + self.in_assignment = 0
2.70 self.discard_value()
2.71
2.72 def visitAssAttr(self, node):
2.73 @@ -527,7 +524,7 @@
2.74 # Find the augmented assignment function and attempt to use it.
2.75
2.76 temp_fn = self._getOperatorAugAssignFunction(node)
2.77 - self._visitBinaryCall(node, temp_fn, node.node, node.expr)
2.78 + self._visitCall(node, temp_fn, (node.node, node.expr))
2.79 self.discard_temp(temp_fn)
2.80
2.81 # Assign the result to the name.
3.1 --- a/micropython/common.py Sun Sep 05 02:20:05 2010 +0200
3.2 +++ b/micropython/common.py Sun Sep 05 21:14:40 2010 +0200
3.3 @@ -283,7 +283,14 @@
3.4 "<" : "lt",
3.5 "<=" : "le",
3.6 ">=" : "ge",
3.7 - ">" : "gt"
3.8 + ">" : "gt",
3.9 +
3.10 + # Access and slicing.
3.11 +
3.12 + "AssSlice" : "setslice",
3.13 + "Slice" : "getslice",
3.14 + "AssSubscript" : "setitem",
3.15 + "Subscript" : "getitem",
3.16 }
3.17
3.18 # vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/micropython/inspect.py Sun Sep 05 02:20:05 2010 +0200
4.2 +++ b/micropython/inspect.py Sun Sep 05 21:14:40 2010 +0200
4.3 @@ -105,6 +105,7 @@
4.4 # Current expression state.
4.5
4.6 self.expr = None
4.7 + self.in_assignment = 0 # For slice and subscript handling.
4.8
4.9 # Namespace state.
4.10
4.11 @@ -416,12 +417,12 @@
4.12 module = attr.get_value()
4.13 return module
4.14
4.15 - def _visitOperator(self, node):
4.16 + def _visitOperator(self, node, operator_name=None):
4.17
4.18 "Accounting method for the operator 'node'."
4.19
4.20 operator_module = self._ensureOperators()
4.21 - operator_fn = operator_functions[node.__class__.__name__]
4.22 + operator_fn = operator_functions[operator_name or node.__class__.__name__]
4.23 self.use_specific_attribute(operator_module.full_name(), operator_fn)
4.24 return self.OP(node)
4.25
4.26 @@ -552,8 +553,10 @@
4.27
4.28 def visitAssign(self, node):
4.29 self.expr = self.dispatch(node.expr)
4.30 + self.in_assignment = 1
4.31 for n in node.nodes:
4.32 self.dispatch(n)
4.33 + self.in_assignment = 0
4.34 return None
4.35
4.36 def visitAssAttr(self, node):
4.37 @@ -977,15 +980,7 @@
4.38 visitRightShift = _visitBinary
4.39
4.40 def visitSlice(self, node):
4.41 - expr = self.dispatch(node.expr)
4.42 - self._visitAttr(expr, "__getitem__", node)
4.43 -
4.44 - if node.lower is not None:
4.45 - self.dispatch(node.lower)
4.46 - if node.upper is not None:
4.47 - self.dispatch(node.upper)
4.48 -
4.49 - self.use_specific_attribute("__builtins__", "slice")
4.50 + self._visitOperator(node, self.in_assignment and "AssSlice" or "Slice")
4.51
4.52 visitSliceobj = OP
4.53
4.54 @@ -997,11 +992,7 @@
4.55 visitSub = _visitBinary
4.56
4.57 def visitSubscript(self, node):
4.58 - expr = self.dispatch(node.expr)
4.59 - self._visitAttr(expr, "__getitem__", node)
4.60 -
4.61 - for sub in node.subs:
4.62 - self.dispatch(sub)
4.63 + self._visitOperator(node, self.in_assignment and "AssSubscript" or "Subscript")
4.64
4.65 def visitTryExcept(self, node):
4.66 self.dispatch(node.body)
5.1 --- a/micropython/trans.py Sun Sep 05 02:20:05 2010 +0200
5.2 +++ b/micropython/trans.py Sun Sep 05 21:14:40 2010 +0200
5.3 @@ -1261,28 +1261,9 @@
5.4 """
5.5
5.6 temp_fn = self._getOperatorFunction(node)
5.7 - self._visitUnaryCall(node, temp_fn, node.expr)
5.8 + self._visitCall(node, temp_fn, (node.expr,))
5.9 self.discard_temp(temp_fn)
5.10
5.11 - def _visitUnaryCall(self, node, temp_fn, expr):
5.12 -
5.13 - """
5.14 - Invoke the appropriate operator module function for the operation
5.15 - represented by 'node', given a 'temp_fn' reference to a function, along
5.16 - with the 'expr' operand node.
5.17 - """
5.18 -
5.19 - # Evaluate and store the operand in temporary storage.
5.20 -
5.21 - self.dispatch(expr)
5.22 - temp = self.optimiser.optimise_temp_storage()
5.23 -
5.24 - self._generateInvocation(temp_fn, (temp,))
5.25 -
5.26 - # Compilation duties...
5.27 -
5.28 - self.discard_temp(temp)
5.29 -
5.30 def _visitBinaryBit(self, node):
5.31
5.32 """
5.33 @@ -1296,7 +1277,7 @@
5.34
5.35 for right in node.nodes:
5.36 if left is not None:
5.37 - self._visitBinaryCall(node, temp_fn, left, right)
5.38 + self._visitCall(node, temp_fn, (left, right))
5.39 left = right
5.40
5.41 self.discard_temp(temp_fn)
5.42 @@ -1309,33 +1290,31 @@
5.43 """
5.44
5.45 temp_fn = self._getOperatorFunction(node)
5.46 - self._visitBinaryCall(node, temp_fn, node.left, node.right)
5.47 + self._visitCall(node, temp_fn, (node.left, node.right))
5.48 self.discard_temp(temp_fn)
5.49
5.50 - def _visitBinaryCall(self, node, temp_fn, left, right):
5.51 + def _visitCall(self, node, temp_fn, args):
5.52
5.53 """
5.54 Invoke the appropriate operator module function for the operation
5.55 represented by 'node', given a 'temp_fn' reference to a function, along
5.56 - with the 'left' and 'right' operand nodes.
5.57 + with the 'args' (the operand nodes).
5.58 """
5.59
5.60 - # Evaluate and store the left operand in temporary storage.
5.61 + # Evaluate and store the operands in temporary storage.
5.62
5.63 - self.dispatch(left)
5.64 - temp1 = self.optimiser.optimise_temp_storage()
5.65 + temp_list = []
5.66
5.67 - # Evaluate and store the right operand in temporary storage.
5.68 + for arg in args:
5.69 + self.dispatch(arg)
5.70 + temp_list.append(self.optimiser.optimise_temp_storage())
5.71
5.72 - self.dispatch(right)
5.73 - temp2 = self.optimiser.optimise_temp_storage()
5.74 -
5.75 - self._generateInvocation(temp_fn, (temp1, temp2))
5.76 + self._generateInvocation(temp_fn, temp_list)
5.77
5.78 # Compilation duties...
5.79
5.80 - self.discard_temp(temp1)
5.81 - self.discard_temp(temp2)
5.82 + for temp in temp_list:
5.83 + self.discard_temp(temp)
5.84
5.85 def _generateInvocation(self, temp_fn, temp_list):
5.86
5.87 @@ -1354,11 +1333,11 @@
5.88 self._doCallFunc(temp_fn)
5.89 self._endCallFunc(temp_fn)
5.90
5.91 - def _getOperatorFunction(self, node):
5.92 + def _getOperatorFunction(self, node, operator_name=None):
5.93
5.94 "Return an operator function reference for the given 'node'."
5.95
5.96 - return self._generateOperatorFunction(node.__class__.__name__)
5.97 + return self._generateOperatorFunction(operator_name or node.__class__.__name__)
5.98
5.99 def _getOperatorAugAssignFunction(self, node):
5.100