1# Copyright 2021, Kay Hayen, mailto:kay.hayen@gmail.com 2# 3# Part of "Nuitka", an optimizing Python compiler that is compatible and 4# integrates with CPython, but also works on its own. 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18""" Node the calls to the 'sum' built-in. 19 20This is a rather challenging case for optimization, as it has C code behind 21it that could be in-lined sometimes for more static analysis. 22 23""" 24 25from nuitka.specs import BuiltinParameterSpecs 26 27from .ExpressionBases import ( 28 ExpressionChildHavingBase, 29 ExpressionChildrenHavingBase, 30) 31 32 33class ExpressionBuiltinSumMixin(object): 34 # Mixins are required to slots 35 __slots__ = () 36 37 builtin_spec = BuiltinParameterSpecs.builtin_sum_spec 38 39 def computeBuiltinSpec(self, trace_collection, given_values): 40 assert self.builtin_spec is not None, self 41 42 if not self.builtin_spec.isCompileTimeComputable(given_values): 43 trace_collection.onExceptionRaiseExit(BaseException) 44 45 # TODO: Raise exception known step 0. 46 47 return self, None, None 48 49 return trace_collection.getCompileTimeComputationResult( 50 node=self, 51 computation=lambda: self.builtin_spec.simulateCall(given_values), 52 description="Built-in call to '%s' computed." 53 % (self.builtin_spec.getName()), 54 ) 55 56 57class ExpressionBuiltinSum1(ExpressionBuiltinSumMixin, ExpressionChildHavingBase): 58 kind = "EXPRESSION_BUILTIN_SUM1" 59 60 named_child = "sequence" 61 62 def __init__(self, sequence, source_ref): 63 assert sequence is not None 64 65 ExpressionChildHavingBase.__init__(self, value=sequence, source_ref=source_ref) 66 67 def computeExpression(self, trace_collection): 68 sequence = self.subnode_sequence 69 70 # TODO: Protect against large xrange constants 71 return self.computeBuiltinSpec( 72 trace_collection=trace_collection, given_values=(sequence,) 73 ) 74 75 76class ExpressionBuiltinSum2(ExpressionBuiltinSumMixin, ExpressionChildrenHavingBase): 77 kind = "EXPRESSION_BUILTIN_SUM2" 78 79 named_children = ("sequence", "start") 80 81 def __init__(self, sequence, start, source_ref): 82 assert sequence is not None 83 assert start is not None 84 85 ExpressionChildrenHavingBase.__init__( 86 self, values={"sequence": sequence, "start": start}, source_ref=source_ref 87 ) 88 89 def computeExpression(self, trace_collection): 90 sequence = self.subnode_sequence 91 start = self.subnode_start 92 93 # TODO: Protect against large xrange constants 94 return self.computeBuiltinSpec( 95 trace_collection=trace_collection, given_values=(sequence, start) 96 ) 97