[pypy-svn] r5153 - in pypy/trunk/src: Pyrex/Compiler pypy/translator pypy/translator/test
arigo at codespeak.net
arigo at codespeak.net
Thu Jun 17 19:44:51 CEST 2004
Author: arigo
Date: Thu Jun 17 19:44:50 2004
New Revision: 5153
Modified:
pypy/trunk/src/Pyrex/Compiler/ExprNodes.py
pypy/trunk/src/Pyrex/Compiler/Lexicon.pickle
pypy/trunk/src/Pyrex/Compiler/Lexicon.py
pypy/trunk/src/Pyrex/Compiler/Parsing.py
pypy/trunk/src/pypy/translator/genpyrex.py
pypy/trunk/src/pypy/translator/test/test_pyrextrans.py
Log:
Implemented in-place operators in Pyrex, but only the 'name += expr' syntax.
For the more involved syntaxes like 'expr1[expr2] = expr3' we would have to
precompute expr1 and expr2 and store them in temporary variables. Not sure
how to do this. But 'v12 += v34' is probably all we need for PyPy.
Fixed genpyrex.py to use this extension. Remember that in-place operators are
actually binary operators returning a result: an in-place operator
SpaceOperation() still has two args and a new result variable, and corresponds
to the C API call 'result = PyNumber_InPlaceXxx(arg1, arg2)'. To emulate
this, genpyrex.py now generates code like 'result = arg1; result += arg2'.
Modified: pypy/trunk/src/Pyrex/Compiler/ExprNodes.py
==============================================================================
--- pypy/trunk/src/Pyrex/Compiler/ExprNodes.py (original)
+++ pypy/trunk/src/Pyrex/Compiler/ExprNodes.py Thu Jun 17 19:44:50 2004
@@ -2268,7 +2268,7 @@
def generate_result_code(self, code):
if self.operand1.type.is_pyobject:
function = self.py_operation_function()
- if function == "PyNumber_Power":
+ if self.operator == "**":
extra_args = ", Py_None"
else:
extra_args = ""
@@ -2296,6 +2296,7 @@
class NumBinopNode(BinopNode):
# Binary operation taking numeric arguments.
+ inplace = 0
def analyse_c_operation(self, env):
type1 = self.operand1.type
@@ -2320,7 +2321,10 @@
self.operand2.result)
def py_operation_function(self):
- return self.py_functions[self.operator]
+ function = self.py_functions[self.operator]
+ if self.inplace:
+ function = function.replace("PyNumber_", "PyNumber_InPlace")
+ return function
py_functions = {
"|": "PyNumber_Or",
Modified: pypy/trunk/src/Pyrex/Compiler/Lexicon.pickle
==============================================================================
Binary files. No diff available.
Modified: pypy/trunk/src/Pyrex/Compiler/Lexicon.py
==============================================================================
--- pypy/trunk/src/Pyrex/Compiler/Lexicon.py (original)
+++ pypy/trunk/src/Pyrex/Compiler/Lexicon.py Thu Jun 17 19:44:50 2004
@@ -66,7 +66,9 @@
bra = Any("([{")
ket = Any(")]}")
punct = Any(":,;+-*/|&<>=.%`~^?")
- diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**")
+ diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**",
+ "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=",
+ "<<=", ">>=", "**=")
spaces = Rep1(Any(" \t\f"))
comment = Str("#") + Rep(AnyBut("\n"))
escaped_newline = Str("\\\n")
Modified: pypy/trunk/src/Pyrex/Compiler/Parsing.py
==============================================================================
--- pypy/trunk/src/Pyrex/Compiler/Parsing.py (original)
+++ pypy/trunk/src/Pyrex/Compiler/Parsing.py Thu Jun 17 19:44:50 2004
@@ -637,6 +637,23 @@
def p_expression_or_assignment(s):
expr_list = [p_expr(s)]
+ if s.sy in augassign_ops:
+ n1 = expr_list[0]
+ op = s.sy[:-1]
+ pos = s.position()
+ s.next()
+ n2 = p_expr(s)
+ # Parse a limited form of augmented assignment:
+ # 'name += expr' --> 'name = name + y'
+ # with a specially marked binop node.
+ # Augmented assignment to more complex expressions isn't supported yet.
+ if isinstance(n1, ExprNodes.NameNode):
+ n1copy = ExprNodes.NameNode(n1.pos, name = n1.name)
+ else:
+ s.error("not implemented: augmented assignment to an expression more complex than a variable name")
+ binop = ExprNodes.binop_node(pos, op, n1, n2)
+ binop.inplace = 1
+ return Nodes.SingleAssignmentNode(pos, lhs = n1copy, rhs = binop)
while s.sy == '=':
s.next()
expr_list.append(p_expr(s))
@@ -663,6 +680,11 @@
#return Nodes.StatListNode(nodes[0].pos, stats = nodes)
return Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes)
+augassign_ops = (
+ '+=', '-=', '*=', '/=', '%=', '&=', '|=', '^=',
+ '<<=', '>>=', '**='
+)
+
def flatten_parallel_assignments(input, output):
# The input is a list of expression nodes, representing
# the LHSs and RHS of one (possibly cascaded) assignment
Modified: pypy/trunk/src/pypy/translator/genpyrex.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genpyrex.py (original)
+++ pypy/trunk/src/pypy/translator/genpyrex.py Thu Jun 17 19:44:50 2004
@@ -26,12 +26,11 @@
return "%s = %s %s" % (self.resultname, operator) + args
elif len(args) == 2:
#Inplace operators
- inp=['+=','-=','*=','/=','%=','^=','//=','div=','**=','<<=','>>=','!=','&=']
+ inp=['+=','-=','*=','/=','%=','&=','|=','^=','//=',
+ '<<=','>>=','**=']
if operator in inp:
- temp_str="temp_xx12=%s %s %s\n"%(args[0], operator[:-1], args[1])
- temp_str+="%s=temp_xx12\n"%args[0]
- temp_str+="%s=temp_xx12"%self.resultname
- return temp_str
+ return "%s = %s; %s %s %s" % (self.resultname, args[0],
+ self.resultname, operator, args[1])
else:
return "%s = %s %s %s" % (self.resultname, args[0], operator, args[1])
elif len(args) == 3 and operator == "**": #special case, have to handle it manually
Modified: pypy/trunk/src/pypy/translator/test/test_pyrextrans.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_pyrextrans.py (original)
+++ pypy/trunk/src/pypy/translator/test/test_pyrextrans.py Thu Jun 17 19:44:50 2004
@@ -41,6 +41,10 @@
poor_man_range = self.build_cfunc(snippet.poor_man_range)
self.assertEquals(poor_man_range(10), range(10))
+ def poor_man_rev_range(self):
+ poor_man_rev_range = self.build_cfunc(snippet.poor_man_rev_range)
+ self.assertEquals(poor_man_rev_range(10), range(9,-1,-1))
+
def test_simple_id(self):
#we just want to see, if renaming of parameter works correctly
#if the first branch is the end branch
More information about the Pypy-commit
mailing list