fixed FlattenInListTransform by providing a temp block expression that injects the...
authorStefan Behnel <scoder@users.berlios.de>
Sun, 7 Dec 2008 20:14:13 +0000 (21:14 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Sun, 7 Dec 2008 20:14:13 +0000 (21:14 +0100)
Cython/Compiler/Main.py
Cython/Compiler/Optimize.py
Cython/Compiler/UtilNodes.py

index 330e7554b475b15483d1a5510a18e9c31e063846..14cc6a63fc3ee72305af852cabf15f1b90c978c3 100644 (file)
@@ -114,7 +114,7 @@ class Context:
             _specific_post_parse,
             InterpretCompilerDirectives(self, self.pragma_overrides),
             _align_function_definitions,
-#            FlattenInListTransform(),
+            FlattenInListTransform(),
             WithTransform(self),
             DecoratorTransform(self),
             AnalyseDeclarationsTransform(self),
index d59b5765d62c7ad9fecc1cf1eaabe66fa1d0be16..a6c819b9d6b82de521152cabae1dc293a174ab0d 100644 (file)
@@ -321,11 +321,7 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations):
         if len(args) == 0:
             return ExprNodes.BoolNode(pos = node.pos, value = node.operator == 'not_in')
 
-        if True or node.operand1.is_simple():
-            lhs = node.operand1
-        else:
-            # FIXME: allocate temp for evaluated node.operand1
-            return node
+        lhs = UtilNodes.ResultRefNode(node.operand1)
 
         conds = []
         for arg in args:
@@ -339,8 +335,6 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations):
                                 pos = node.pos, 
                                 operand = cond,
                                 type = PyrexTypes.c_bint_type))
-            if type(lhs) is not ExprNodes.CloneNode:
-                lhs = ExprNodes.CloneNode(lhs)
         def concat(left, right):
             return ExprNodes.BoolBinopNode(
                                 pos = node.pos, 
@@ -348,8 +342,9 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations):
                                 operand1 = left,
                                 operand2 = right)
 
-        return reduce(concat, conds)
-        
+        condition = reduce(concat, conds)
+        return UtilNodes.TempBlockExprNode(lhs, condition)
+
     def visit_Node(self, node):
         self.visitchildren(node)
         return node
index 3563d49069b348062fad9b44fd900728bc1303eb..780b8c89f889e7e8cf0352ae603823e319821702 100644 (file)
@@ -105,3 +105,72 @@ class TempsBlockNode(Node):
     def annotate(self, code):
         self.body.annotate(code)
 
+
+class ResultRefNode(AtomicExprNode):
+    # A reference to the result of an expression.  The result_code
+    # must be set externally (usually a temp name).
+
+    subexprs = []
+
+    def __init__(self, expression):
+        self.pos = expression.pos
+        self.expression = expression
+
+    def analyse_types(self, env):
+        self.type = self.expression.type
+
+    def result(self):
+        return self.result_code
+
+    def generate_evaluation_code(self, code):
+        pass
+
+    def generate_result_code(self, code):
+        pass
+        
+    def generate_disposal_code(self, code):
+        pass
+                
+    def allocate_temps(self, env):
+        pass
+        
+    def release_temp(self, env):
+        pass
+
+    def free_temps(self, code):
+        pass
+
+
+class TempBlockExprNode(ExprNodes.NewTempExprNode):
+    # A wrapper around a subexpression that moves an expression into a
+    # temp variable and provides it to the subexpression.
+
+    subexprs = ['temp_expression', 'subexpression']
+
+    def __init__(self, lazy_temp, subexpression):
+        self.pos = subexpression.pos
+        self.lazy_temp = lazy_temp
+        self.temp_expression = lazy_temp.expression
+        self.subexpression = subexpression
+
+    def result(self):
+        return self.subexpression.result()
+
+    def analyse_types(self, env):
+        self.temp_expression.analyse_types(env)
+        self.subexpression.analyse_types(env)
+        self.type = self.subexpression.type
+
+    def generate_evaluation_code(self, code):
+        self.temp_expression.generate_evaluation_code(code)
+        if self.temp_expression.is_temp:
+            temp = self.temp_expression.result()
+        else:
+            self.temp_expression.make_owned_reference(code)
+            temp = code.funcstate.allocate_temp(
+                self.temp_expression.type, manage_ref=True)
+            code.putln("%s = %s;" % (temp, self.temp_expression.result()))
+        self.lazy_temp.result_code = temp
+        self.subexpression.generate_evaluation_code(code)
+        if not self.temp_expression.is_temp:
+            code.funcstate.release_temp(temp)