File: interp_number.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (118 lines) | stat: -rw-r--r-- 4,408 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
from rpython.rlib.rarithmetic import widen
from pypy.module._hpy_universal.apiset import API

def make_unary(name, spacemeth):
    assert spacemeth.startswith('space.')
    spacemeth = spacemeth[len('space.'):]
    #
    @API.func("HPy HPy_unary(HPyContext *ctx, HPy h1)", func_name=name)
    def HPy_unary(space, handles, ctx, h1):
        w_obj1 = handles.deref(h1)
        meth = getattr(space, spacemeth)
        w_res = meth(w_obj1)
        return handles.new(w_res)
    #
    globals()[name] = HPy_unary

def make_binary(name, spacemeth):
    assert spacemeth.startswith('space.')
    spacemeth = spacemeth[len('space.'):]
    #
    @API.func("HPy HPy_binary(HPyContext *ctx, HPy h1, HPy h2)", func_name=name)
    def HPy_binary(space, handles, ctx, h1, h2):
        w_obj1 = handles.deref(h1)
        w_obj2 = handles.deref(h2)
        meth = getattr(space, spacemeth)
        w_res = meth(w_obj1, w_obj2)
        return handles.new(w_res)
    #
    globals()[name] = HPy_binary


make_unary('HPy_Negative', 'space.neg')
make_unary('HPy_Positive', 'space.pos')
make_unary('HPy_Absolute', 'space.abs')
make_unary('HPy_Invert', 'space.invert')
make_unary('HPy_Index', 'space.index')

make_binary('HPy_Add', 'space.add')
make_binary('HPy_Subtract', 'space.sub')
make_binary('HPy_Multiply', 'space.mul')
make_binary('HPy_FloorDivide', 'space.floordiv')
make_binary('HPy_TrueDivide', 'space.truediv')
make_binary('HPy_Remainder', 'space.mod')
make_binary('HPy_Divmod', 'space.divmod')
make_binary('HPy_Lshift', 'space.lshift')
make_binary('HPy_Rshift', 'space.rshift')
make_binary('HPy_And', 'space.and_')
make_binary('HPy_Xor', 'space.xor')
make_binary('HPy_Or', 'space.or_')
make_binary('HPy_MatrixMultiply', 'space.matmul')

make_binary('HPy_InPlaceAdd', 'space.inplace_add')
make_binary('HPy_InPlaceSubtract', 'space.inplace_sub'),
make_binary('HPy_InPlaceMultiply', 'space.inplace_mul'),
make_binary('HPy_InPlaceFloorDivide', 'space.inplace_floordiv'),
make_binary('HPy_InPlaceTrueDivide', 'space.inplace_truediv'),
make_binary('HPy_InPlaceRemainder', 'space.inplace_mod'),
make_binary('HPy_InPlaceLshift', 'space.inplace_lshift'),
make_binary('HPy_InPlaceRshift', 'space.inplace_rshift'),
make_binary('HPy_InPlaceAnd', 'space.inplace_and'),
make_binary('HPy_InPlaceXor', 'space.inplace_xor'),
make_binary('HPy_InPlaceOr', 'space.inplace_or'),
make_binary('HPy_InPlaceMatrixMultiply', 'space.inplace_matmul')


@API.func("HPy HPy_Long(HPyContext *ctx, HPy h1)")
def HPy_Long(space, handles, ctx, h1):
    w_obj1 = handles.deref(h1)
    w_res = space.call_function(space.w_int, w_obj1)
    return handles.new(w_res)


@API.func("HPy HPy_Float(HPyContext *ctx, HPy h1)")
def HPy_Float(space, handles, ctx, h1):
    w_obj1 = handles.deref(h1)
    w_res = space.call_function(space.w_float, w_obj1)
    return handles.new(w_res)


@API.func("HPy HPy_Power(HPyContext *ctx, HPy h1, HPy h2, HPy h3)")
def HPy_Power(space, handles, ctx, h1, h2, h3):
    w_o1 = handles.deref(h1)
    w_o2 = handles.deref(h2)
    w_o3 = handles.deref(h3)
    w_res = space.pow(w_o1, w_o2, w_o3)
    return handles.new(w_res)


@API.func("HPy HPy_InPlacePower(HPyContext *ctx, HPy h1, HPy h2, HPy h3)")
def HPy_InPlacePower(space, handles, ctx, h1, h2, h3):
    # CPython seems to have a weird semantics for InPlacePower: if __ipow__ is
    # defined, the 3rd argument is always ignored (contrarily to what the
    # documentation says). If now, it falls back to pow, so the 3rd arg is
    # handled correctly. Here we try to be bug-to-bug compatible
    w_o1 = handles.deref(h1)
    w_o2 = handles.deref(h2)
    w_o3 = handles.deref(h3)
    w_ipow = space.lookup(w_o1, '__ipow__')
    if w_ipow is None:
        w_res = space.pow(w_o1, w_o2, w_o3)
    else:
        w_res = space.inplace_pow(w_o1, w_o2)
    return handles.new(w_res)

@API.func("int HPyNumber_Check(HPyContext *ctx, HPy h)", error_value='CANNOT_FAIL')
def HPyNumber_Check(space, handles, ctx, h):
    # XXX: write proper tests
    w_obj = handles.deref(h)
    if (space.lookup(w_obj, '__int__') or space.lookup(w_obj, '__float__') or
        0): # XXX in py3.8: space.lookup(w_obj, '__index__')):
        return API.int(1)
    return API.int(0)

@API.func("HPy HPyBool_FromBool(HPyContext *ctx, int v)")
def HPyBool_FromBool(space, handles, ctx, value):
    if widen(value) != 0:
        return handles.new(space.w_True)
    return handles.new(space.w_False)