def generateSetLiteralCreationCode(to_name, expression, emit, context): if not needsSetLiteralReverseInsertion(): return generateSetCreationCode(to_name, expression, emit, context) emit( "%s = PySet_New( NULL );" % ( to_name, ) ) context.addCleanupTempName(to_name) elements = expression.getElements() element_names = [] for count, element in enumerate(elements): element_name = context.allocateTempName( "set_element_%d" % (count+1) ) element_names.append(element_name) generateExpressionCode( to_name = element_name, expression = element, emit = emit, context = context ) for count, element in enumerate(elements): element_name = element_names[len(elements)-count-1] if element.isKnownToBeHashable(): emit( "PySet_Add( %s, %s );" % ( to_name, element_name ) ) else: res_name = context.getIntResName() emit( "%s = PySet_Add( %s, %s );" % ( res_name, to_name, element_name ) ) getErrorExitBoolCode( condition = "%s != 0" % res_name, emit = emit, context = context ) if context.needsCleanup(element_name): emit("Py_DECREF( %s );" % element_name) context.removeCleanupTempName(element_name)
def getSimulator(self): if needsSetLiteralReverseInsertion(): @functools.wraps(set) def mySet(value): return set(reversed(tuple(value))) return mySet else: return set
def makeSequenceCreationOrConstant(sequence_kind, elements, source_ref): # Sequence creation. Tries to avoid creations with only constant # elements. Would be caught by optimization, but would be useless churn. For # mutable constants we cannot do it though. # Due to the many sequence types, there is a lot of cases here # pylint: disable=too-many-branches for element in elements: if not element.isExpressionConstantRef(): constant = False break else: constant = True sequence_kind = sequence_kind.lower() # Note: This would happen in optimization instead, but lets just do it # immediately to save some time. if constant: if sequence_kind == "tuple": const_type = tuple elif sequence_kind == "list": const_type = list elif sequence_kind == "set": const_type = set if needsSetLiteralReverseInsertion(): elements = tuple(reversed(elements)) else: assert False, sequence_kind result = makeConstantRefNode( constant=const_type(element.getConstant() for element in elements), source_ref=source_ref, user_provided=True, ) else: if sequence_kind == "tuple": result = ExpressionMakeTuple(elements=elements, source_ref=source_ref) elif sequence_kind == "list": result = ExpressionMakeList(elements=elements, source_ref=source_ref) elif sequence_kind == "set": result = ExpressionMakeSetLiteral(elements=elements, source_ref=source_ref) else: assert False, sequence_kind if elements: result.setCompatibleSourceReference( source_ref=elements[-1].getCompatibleSourceReference()) return result
def makeSequenceCreationOrConstant(sequence_kind, elements, source_ref): # Sequence creation. Tries to avoid creations with only constant # elements. Would be caught by optimization, but would be useless churn. For # mutable constants we cannot do it though. # Due to the many sequence types, there is a lot of cases here # pylint: disable=too-many-branches for element in elements: if not element.isExpressionConstantRef(): constant = False break else: constant = True sequence_kind = sequence_kind.lower() # Note: This would happen in optimization instead, but lets just do it # immediately to save some time. if constant: if sequence_kind == "tuple": const_type = tuple elif sequence_kind == "list": const_type = list elif sequence_kind == "set": const_type = set if needsSetLiteralReverseInsertion(): elements = tuple(reversed(elements)) else: assert False, sequence_kind result = makeConstantRefNode( constant=const_type(element.getConstant() for element in elements), source_ref=source_ref, user_provided=True, ) else: if sequence_kind == "tuple": result = ExpressionMakeTuple(elements=elements, source_ref=source_ref) elif sequence_kind == "list": result = ExpressionMakeList(elements=elements, source_ref=source_ref) elif sequence_kind == "set": result = ExpressionMakeSetLiteral(elements=elements, source_ref=source_ref) else: assert False, sequence_kind if elements: result.setCompatibleSourceReference( source_ref=elements[-1].getCompatibleSourceReference() ) return result
def generateSetLiteralCreationCode(to_name, expression, emit, context): if not needsSetLiteralReverseInsertion(): return generateSetCreationCode(to_name, expression, emit, context) with withObjectCodeTemporaryAssignment( to_name, "set_result", expression, emit, context ) as result_name: emit("%s = PySet_New( NULL );" % (result_name,)) context.addCleanupTempName(result_name) elements = expression.getElements() element_names = [] for count, element in enumerate(elements): element_name = context.allocateTempName("set_element_%d" % (count + 1)) element_names.append(element_name) generateExpressionCode( to_name=element_name, expression=element, emit=emit, context=context ) for count, element in enumerate(elements): element_name = element_names[len(elements) - count - 1] if element.isKnownToBeHashable(): emit("PySet_Add( %s, %s );" % (result_name, element_name)) else: res_name = context.getIntResName() emit( "%s = PySet_Add( %s, %s );" % (res_name, result_name, element_name) ) getErrorExitBoolCode( condition="%s != 0" % res_name, emit=emit, context=context ) if context.needsCleanup(element_name): emit("Py_DECREF( %s );" % element_name) context.removeCleanupTempName(element_name)
def computeExpressionIter1(self, iter_node, trace_collection): result = ExpressionMakeTuple(elements=self.subnode_elements, source_ref=self.source_ref) self.parent.replaceChild(self, result) del self.parent return ( iter_node, "new_expression", """\ Iteration over set lowered to iteration over tuple.""", ) needs_set_literal_reverse = needsSetLiteralReverseInsertion() def makeExpressionMakeSetLiteral(elements, source_ref): if elements: if needs_set_literal_reverse: return ExpressionMakeSetLiteral(elements, source_ref) else: return ExpressionMakeSet(elements, source_ref) else: # TODO: Get rid of user provided for empty set refs, makes no sense. return ExpressionConstantSetEmptyRef(user_provided=False, source_ref=source_ref) @functools.wraps(set)