def buildComparisonNode(provider, node, source_ref): assert len(node.comparators) == len(node.ops) # Comparisons are re-formulated as described in the developer manual. When # having multiple comparators, things require assignment expressions and # references of them to work properly. Then they can become normal "and" # code. # The operands are split out in two parts strangely. left = buildNode(provider, node.left, source_ref) rights = [ buildNode(provider, comparator, source_ref) for comparator in node.comparators ] comparators = [getKind(comparator) for comparator in node.ops] # Normal, and simple case, we only have one comparison, which is what our # node handles only. Then we can handle it if len(rights) == 1: return makeComparisonNode( left=left, right=rights[0], # TODO: The terminology of Nuitka might be messed up here. comparator=comparators[0], source_ref=source_ref) return buildComplexComparisonNode(provider, left, rights, comparators, source_ref)
def makeValueComparisonReturn(left, right, comparator): yield StatementAssignmentVariable( variable = tmp_variable, source = makeComparisonNode( left = left, right = right, comparator = comparator, source_ref = source_ref ), source_ref = source_ref, ) yield StatementConditional( condition = ExpressionOperationNOT( operand = ExpressionTempVariableRef( variable = tmp_variable, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_variable, source_ref = source_ref ), source_ref = source_ref ) ), no_branch = None, source_ref = source_ref )
def buildComparisonNode(provider, node, source_ref): assert len(node.comparators) == len(node.ops) # Comparisons are re-formulated as described in the developer manual. When # having multiple comparators, things require assignment expressions and # references of them to work properly. Then they can become normal "and" # code. # The operands are split out in two parts strangely. left = buildNode(provider, node.left, source_ref) rights = [ buildNode(provider, comparator, source_ref) for comparator in node.comparators ] comparators = [ getKind(comparator) for comparator in node.ops ] # Normal, and simple case, we only have one comparison, which is what our # node handles only. Then we can handle it if len(rights) == 1: return makeComparisonNode( left = left, right = rights[0], # TODO: The terminology of Nuitka might be messed up here. comparator = comparators[0], source_ref = source_ref ) return buildComplexComparisonNode(provider, left, rights, comparators, source_ref)
def makeValueComparisonReturn(left, right, comparator): yield StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable, source_ref = source_ref ), source = makeComparisonNode( left = left, right = right, comparator = comparator, source_ref = source_ref ), source_ref = source_ref, ) yield StatementConditional( condition = ExpressionOperationNOT( operand = ExpressionTempVariableRef( variable = tmp_variable, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_variable, source_ref = source_ref ), source_ref = source_ref ) ), no_branch = None, source_ref = source_ref )
def buildComparisonNode(provider, node, source_ref): from nuitka.nodes.NodeMakingHelpers import makeComparisonNode assert len(node.comparators) == len(node.ops) # Comparisons are re-formulated as described in the developer manual. When # having multiple compators, things require assignment expressions and # references of them to work properly. Then they can become normal "and" # code. # The operands are split out left = buildNode(provider, node.left, source_ref) rights = [ buildNode(provider, comparator, source_ref) for comparator in node.comparators ] # Only the first comparison has as left operands as the real thing, the # others must reference the previous comparison right one temp variable ref. result = [] # For PyLint to like it, this will hold the previous one, normally. keeper_variable = None for comparator, right in zip(node.ops, rights): if result: # Now we know it's not the only one, so we change the "left" to be a # reference to the previously saved right side. left = ExpressionTempKeeperRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref) keeper_variable = None if right is not rights[-1]: # Now we know it's not the last one, so we ought to preseve the # "right" so it can be referenced by the next part that will # come. We do it by assining it to a temp variable to be shared with # the next part. keeper_variable = provider.allocateTempKeeperVariable() right = ExpressionAssignmentTempKeeper( variable=keeper_variable.makeReference(provider), source=right, source_ref=source_ref) comparator = getKind(comparator) result.append( makeComparisonNode(left=left, right=right, comparator=comparator, source_ref=source_ref)) assert keeper_variable is None return buildAndNode(provider=provider, values=result, source_ref=source_ref)
def buildComparisonNode(provider, node, source_ref): from nuitka.nodes.NodeMakingHelpers import makeComparisonNode assert len(node.comparators) == len(node.ops) # Comparisons are re-formulated as described in the developer manual. When having # multiple compators, things require assignment expressions and references of them to # work properly. Then they can become normal "and" code. # The operands are split out left = buildNode(provider, node.left, source_ref) rights = [buildNode(provider, comparator, source_ref) for comparator in node.comparators] # Only the first comparison has as left operands as the real thing, the others must # reference the previous comparison right one temp variable ref. result = [] # For PyLint to like it, this will hold the previous one, normally. keeper_variable = None for comparator, right in zip(node.ops, rights): if result: # Now we know it's not the only one, so we change the "left" to be a reference # to the previously saved right side. left = ExpressionTempKeeperRef(variable=keeper_variable.makeReference(provider), source_ref=source_ref) keeper_variable = None if right is not rights[-1]: # Now we know it's not the last one, so we ought to preseve the "right" so it # can be referenced by the next part that will come. We do it by assining it # to a temp variable to be shared with the next part. keeper_variable = provider.getTempKeeperVariable() right = ExpressionAssignmentTempKeeper( variable=keeper_variable.makeReference(provider), source=right, source_ref=source_ref ) comparator = getKind(comparator) result.append(makeComparisonNode(left=left, right=right, comparator=comparator, source_ref=source_ref)) assert keeper_variable is None return buildAndNode(provider=provider, values=result, source_ref=source_ref)
def buildComparisonNode(provider, node, source_ref): from nuitka.nodes.NodeMakingHelpers import makeComparisonNode assert len(node.comparators) == len(node.ops) # Comparisons are re-formulated as described in the developer manual. When # having multiple compators, things require assignment expressions and # references of them to work properly. Then they can become normal "and" # code. # The operands are split out left = buildNode(provider, node.left, source_ref) rights = [buildNode(provider, comparator, source_ref) for comparator in node.comparators] # Only the first comparison has as left operands as the real thing, the # others must reference the previous comparison right one temp variable ref. values = [] # For PyLint to like it, this will hold the previous one, normally. keeper_variable = None temp_scope = None final = [] for comparator, right in zip(node.ops, rights): if values: # Now we know it's not the only one, so we change the "left" to be a # reference to the previously saved right side. left = ExpressionTempVariableRef(variable=keeper_variable.makeReference(provider), source_ref=source_ref) keeper_variable = None if right is not rights[-1]: # Now we know it's not the last one, so we ought to preseve the # "right" so it can be referenced by the next part that will # come. We do it by assining it to a temp variable to be shared with # the next part. if temp_scope is None: temp_scope = provider.allocateTempScope(name="comparison") keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="value_%d" % (rights.index(right) + 2) ) tried = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref ), source=right, source_ref=source_ref, ) # TODO: The delete must be placed later. final.append( StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref ), tolerant=True, source_ref=source_ref, ) ) right = makeTryFinallyExpression( tried=tried, final=None, expression=ExpressionTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref ), source_ref=source_ref, ) comparator = getKind(comparator) values.append(makeComparisonNode(left=left, right=right, comparator=comparator, source_ref=source_ref)) assert keeper_variable is None result = buildAndNode(provider=provider, values=values, source_ref=source_ref) if final: return makeTryFinallyExpression(tried=None, expression=result, final=final, source_ref=source_ref) else: return result
def buildComplexComparisonNode(provider, left, rights, comparators, source_ref): # This is a bit complex, due to the many details, pylint: disable=too-many-locals outline_body = ExpressionOutlineBody(provider=provider, name="comparison_chain", source_ref=source_ref) variables = [ outline_body.allocateTempVariable(temp_scope=None, name="operand_%d" % count) for count in range(2, len(rights) + 2) ] tmp_variable = outline_body.allocateTempVariable(temp_scope=None, name="comparison_result") def makeTempAssignment(count, value): return StatementAssignmentVariable( variable=variables[count], source=value, source_ref=source_ref, ) def makeReleaseStatement(count): return StatementReleaseVariable(variable=variables[count], source_ref=source_ref) def makeValueComparisonReturn(left, right, comparator): yield StatementAssignmentVariable( variable=tmp_variable, source=makeComparisonNode(left=left, right=right, comparator=comparator, source_ref=source_ref), source_ref=source_ref, ) yield StatementConditional( condition=ExpressionOperationNOT(operand=ExpressionTempVariableRef( variable=tmp_variable, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementReturn(expression=ExpressionTempVariableRef( variable=tmp_variable, source_ref=source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref) statements = [] final = [] for count, value in enumerate(rights): if value is not rights[-1]: statements.append(makeTempAssignment(count, value)) final.append(makeReleaseStatement(count)) right = ExpressionTempVariableRef(variable=variables[count], source_ref=source_ref) else: right = value if count != 0: left = ExpressionTempVariableRef(variable=variables[count - 1], source_ref=source_ref) comparator = comparators[count] if value is not rights[-1]: statements.extend( makeValueComparisonReturn(left, right, comparator)) else: statements.append( StatementReturn(expression=makeComparisonNode( left=left, right=right, comparator=comparator, source_ref=source_ref), source_ref=source_ref)) final.append( StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref)) outline_body.setBody( makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement(provider=outline_body, tried=statements, final=final, source_ref=source_ref))) return outline_body
def buildComparisonNode(provider, node, source_ref): from nuitka.nodes.NodeMakingHelpers import makeComparisonNode assert len(node.comparators) == len(node.ops) # Comparisons are re-formulated as described in the developer manual. When # having multiple compators, things require assignment expressions and # references of them to work properly. Then they can become normal "and" # code. # The operands are split out left = buildNode(provider, node.left, source_ref) rights = [ buildNode(provider, comparator, source_ref) for comparator in node.comparators ] # Only the first comparison has as left operands as the real thing, the # others must reference the previous comparison right one temp variable ref. values = [] # For PyLint to like it, this will hold the previous one, normally. keeper_variable = None temp_scope = None final = [] for comparator, right in zip(node.ops, rights): if values: # Now we know it's not the only one, so we change the "left" to be a # reference to the previously saved right side. left = ExpressionTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref) keeper_variable = None if right is not rights[-1]: # Now we know it's not the last one, so we ought to preseve the # "right" so it can be referenced by the next part that will # come. We do it by assining it to a temp variable to be shared with # the next part. if temp_scope is None: temp_scope = provider.allocateTempScope(name="comparison") keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="value_%d" % (rights.index(right) + 2), ) tried = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref), source=right, source_ref=source_ref, ) # TODO: The delete must be placed later. final.append( StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref, )) right = makeTryFinallyExpression( tried=tried, final=None, expression=ExpressionTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref), source_ref=source_ref) comparator = getKind(comparator) values.append( makeComparisonNode(left=left, right=right, comparator=comparator, source_ref=source_ref)) assert keeper_variable is None result = buildAndNode(provider=provider, values=values, source_ref=source_ref) if final: return makeTryFinallyExpression(tried=None, expression=result, final=final, source_ref=source_ref) else: return result
def buildComplexComparisonNode(provider, left, rights, comparators, source_ref): # This is a bit complex, due to the many details, pylint: disable=R0914 outline_body = ExpressionOutlineBody( provider = provider, name = "comparison_chain", source_ref = source_ref ) variables = [ outline_body.allocateTempVariable( temp_scope = None, name = "operand_%d" % count ) for count in range(2, len(rights)+2) ] tmp_variable = outline_body.allocateTempVariable( temp_scope = None, name = "comparison_result" ) def makeTempAssignment(count, value): return StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = variables[count], source_ref = source_ref ), source = value, source_ref = source_ref, ) def makeReleaseStatement(count): return StatementReleaseVariable( variable = variables[count], source_ref = source_ref ) def makeValueComparisonReturn(left, right, comparator): yield StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable, source_ref = source_ref ), source = makeComparisonNode( left = left, right = right, comparator = comparator, source_ref = source_ref ), source_ref = source_ref, ) yield StatementConditional( condition = ExpressionOperationNOT( operand = ExpressionTempVariableRef( variable = tmp_variable, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_variable, source_ref = source_ref ), source_ref = source_ref ) ), no_branch = None, source_ref = source_ref ) statements = [] final = [] for count, value in enumerate(rights): if value is not rights[-1]: statements.append( makeTempAssignment(count, value) ) final.append( makeReleaseStatement(count) ) right = ExpressionTempVariableRef( variable = variables[count], source_ref = source_ref ) else: right = value if count != 0: left = ExpressionTempVariableRef( variable = variables[count-1], source_ref = source_ref ) comparator = comparators[count] if value is not rights[-1]: statements.extend( makeValueComparisonReturn( left, right, comparator ) ) else: statements.append( StatementReturn( expression = makeComparisonNode( left = left, right = right, comparator = comparator, source_ref = source_ref ), source_ref = source_ref ) ) final.append( StatementReleaseVariable( variable = tmp_variable, source_ref = source_ref ) ) outline_body.setBody( makeStatementsSequenceFromStatement( statement = makeTryFinallyStatement( provider = outline_body, tried = statements, final = final, source_ref = source_ref ) ) ) return outline_body