def round_impl_binary(context, builder, sig, args): fltty = sig.args[0] # Allow calling the intrinsic from the Python implementation below. # This avoids the conversion to an int in Python 3's unary round(). _round = types.ExternalFunction(_round_intrinsic(fltty), typing.signature(fltty, fltty)) def round_ndigits(x, ndigits): if math.isinf(x) or math.isnan(x): return x if ndigits >= 0: if ndigits > 22: # pow1 and pow2 are each safe from overflow, but # pow1*pow2 ~= pow(10.0, ndigits) might overflow. pow1 = 10.0**(ndigits - 22) pow2 = 1e22 else: pow1 = 10.0**ndigits pow2 = 1.0 y = (x * pow1) * pow2 if math.isinf(y): return x return (_round(y) / pow2) / pow1 else: pow1 = 10.0**(-ndigits) y = x / pow1 return _round(y) * pow1 res = context.compile_internal(builder, round_ndigits, sig, args) return impl_ret_untracked(context, builder, sig.return_type, res)
def hypot_float_impl(context, builder, sig, args): xty, yty = sig.args assert xty == yty == sig.return_type x, y = args # Windows has alternate names for hypot/hypotf, see # https://msdn.microsoft.com/fr-fr/library/a9yb3dbt%28v=vs.80%29.aspx fname = { types.float32: "_hypotf" if sys.platform == 'win32' else "hypotf", types.float64: "_hypot" if sys.platform == 'win32' else "hypot", }[xty] plat_hypot = types.ExternalFunction(fname, sig) if sys.platform == 'win32' and config.MACHINE_BITS == 32: inf = xty(float('inf')) def hypot_impl(x, y): if math.isinf(x) or math.isinf(y): return inf return plat_hypot(x, y) else: def hypot_impl(x, y): return plat_hypot(x, y) res = context.compile_internal(builder, hypot_impl, sig, args) return impl_ret_untracked(context, builder, sig.return_type, res)
def char_getitem_overload(_str, ind): if _str == std_str_type and isinstance(ind, types.Integer): sig = char_type( std_str_type, # string types.intp, # index ) get_char_from_string = types.ExternalFunction("get_char_from_string", sig) def impl(_str, ind): return get_char_from_string(_str, ind) return impl
@box(CharType) def box_char(typ, val, c): """ """ fnty = lir.FunctionType(lir.IntType(8).as_pointer(), [lir.IntType(8)]) fn = c.builder.module.get_or_insert_function(fnty, name="get_char_ptr") c_str = c.builder.call(fn, [val]) pystr = c.pyapi.string_from_string_and_size( c_str, c.context.get_constant(types.intp, 1)) # TODO: delete ptr return pystr del_str = types.ExternalFunction("del_str", types.void(std_str_type)) _hash_str = types.ExternalFunction("_hash_str", types.int64(std_str_type)) get_c_str = types.ExternalFunction("get_c_str", types.voidptr(std_str_type)) @overload_method(StringType, 'c_str') def str_c_str(str_typ): return lambda s: get_c_str(s) @overload_method(StringType, 'join') def str_join(str_typ, iterable_typ): # TODO: more efficient implementation (e.g. C++ string buffer) def str_join_impl(sep_str, str_container): res = "" counter = 0