Commit 6633bf5a authored by Stefan Behnel's avatar Stefan Behnel

fixed FlattenInListTransform by providing a temp block expression that injects...

fixed FlattenInListTransform by providing a temp block expression that injects the temp result into a subexpression
parent ce2617e2
......@@ -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),
......
......@@ -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
......
......@@ -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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment