File: rfloat.py

package info (click to toggle)
pypy 5.6.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 97,040 kB
  • ctags: 185,069
  • sloc: python: 1,147,862; ansic: 49,642; cpp: 5,245; asm: 5,169; makefile: 529; sh: 481; xml: 232; lisp: 45
file content (171 lines) | stat: -rw-r--r-- 4,993 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
from rpython.annotator import model as annmodel
from rpython.rlib.objectmodel import _hash_float
from rpython.rlib.rarithmetic import base_int
from rpython.rlib import jit
from rpython.rtyper.annlowlevel import llstr
from rpython.rtyper.error import TyperError
from rpython.rtyper.lltypesystem.lltype import (Signed, Bool, Float)
from rpython.rtyper.rmodel import Repr
from rpython.tool.pairtype import pairtype

class FloatRepr(Repr):
    lowleveltype = Float

    def convert_const(self, value):
        if not isinstance(value, (int, base_int, float)):  # can be bool too
            raise TyperError("not a float: %r" % (value,))
        return float(value)

    def get_ll_eq_function(self):
        return None
    get_ll_gt_function = get_ll_eq_function
    get_ll_lt_function = get_ll_eq_function
    get_ll_ge_function = get_ll_eq_function
    get_ll_le_function = get_ll_eq_function

    def get_ll_hash_function(self):
        return _hash_float

    def rtype_bool(_, hop):
        vlist = hop.inputargs(Float)
        return hop.genop('float_is_true', vlist, resulttype=Bool)

    def rtype_neg(_, hop):
        vlist = hop.inputargs(Float)
        return hop.genop('float_neg', vlist, resulttype=Float)

    def rtype_pos(_, hop):
        vlist = hop.inputargs(Float)
        return vlist[0]

    def rtype_abs(_, hop):
        vlist = hop.inputargs(Float)
        return hop.genop('float_abs', vlist, resulttype=Float)

    def rtype_int(_, hop):
        vlist = hop.inputargs(Float)
        # int(x) never raises in RPython, you need to use
        # rarithmetic.ovfcheck_float_to_int() if you want this
        hop.exception_cannot_occur()
        return hop.genop('cast_float_to_int', vlist, resulttype=Signed)

    def rtype_float(_, hop):
        vlist = hop.inputargs(Float)
        hop.exception_cannot_occur()
        return vlist[0]

    @jit.elidable
    def ll_str(self, f):
        from rpython.rlib.rfloat import formatd
        return llstr(formatd(f, 'f', 6))

float_repr = FloatRepr()

class __extend__(annmodel.SomeFloat):
    def rtyper_makerepr(self, rtyper):
        return float_repr

    def rtyper_makekey(self):
        return self.__class__,


class __extend__(pairtype(FloatRepr, FloatRepr)):

    #Arithmetic

    def rtype_add(_, hop):
        return _rtype_template(hop, 'add')

    rtype_inplace_add = rtype_add

    def rtype_sub(_, hop):
        return _rtype_template(hop, 'sub')

    rtype_inplace_sub = rtype_sub

    def rtype_mul(_, hop):
        return _rtype_template(hop, 'mul')

    rtype_inplace_mul = rtype_mul

    def rtype_truediv(_, hop):
        return _rtype_template(hop, 'truediv')

    rtype_inplace_truediv = rtype_truediv

    # turn 'div' on floats into 'truediv'
    rtype_div         = rtype_truediv
    rtype_inplace_div = rtype_inplace_truediv

    # 'floordiv' on floats not supported in RPython

    #comparisons: eq is_ ne lt le gt ge

    def rtype_eq(_, hop):
        return _rtype_compare_template(hop, 'eq')

    rtype_is_ = rtype_eq

    def rtype_ne(_, hop):
        return _rtype_compare_template(hop, 'ne')

    def rtype_lt(_, hop):
        return _rtype_compare_template(hop, 'lt')

    def rtype_le(_, hop):
        return _rtype_compare_template(hop, 'le')

    def rtype_gt(_, hop):
        return _rtype_compare_template(hop, 'gt')

    def rtype_ge(_, hop):
        return _rtype_compare_template(hop, 'ge')

#Helpers FloatRepr,FloatRepr

def _rtype_template(hop, func):
    vlist = hop.inputargs(Float, Float)
    return hop.genop('float_'+func, vlist, resulttype=Float)

def _rtype_compare_template(hop, func):
    vlist = hop.inputargs(Float, Float)
    return hop.genop('float_'+func, vlist, resulttype=Bool)


# ______________________________________________________________________
# Support for r_singlefloat and r_longfloat from rpython.rlib.rarithmetic

from rpython.rtyper.lltypesystem import lltype
from rpython.rtyper.rmodel import Repr

class __extend__(annmodel.SomeSingleFloat):
    def rtyper_makerepr(self, rtyper):
        return SingleFloatRepr()
    def rtyper_makekey(self):
        return self.__class__,

class SingleFloatRepr(Repr):
    lowleveltype = lltype.SingleFloat

    def rtype_float(self, hop):
        v, = hop.inputargs(lltype.SingleFloat)
        hop.exception_cannot_occur()
        # we use cast_primitive to go between Float and SingleFloat.
        return hop.genop('cast_primitive', [v],
                         resulttype = lltype.Float)

class __extend__(annmodel.SomeLongFloat):
    def rtyper_makerepr(self, rtyper):
        return LongFloatRepr()
    def rtyper_makekey(self):
        return self.__class__,

class LongFloatRepr(Repr):
    lowleveltype = lltype.LongFloat

    def rtype_float(self, hop):
        v, = hop.inputargs(lltype.LongFloat)
        hop.exception_cannot_occur()
        # we use cast_primitive to go between Float and LongFloat.
        return hop.genop('cast_primitive', [v],
                         resulttype = lltype.Float)