File: rrange.py

package info (click to toggle)
pypy 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 107,216 kB
  • sloc: python: 1,201,787; ansic: 62,419; asm: 5,169; cpp: 3,017; sh: 2,534; makefile: 545; xml: 243; lisp: 45; awk: 4
file content (98 lines) | stat: -rw-r--r-- 2,870 bytes parent folder | download | duplicates (8)
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
from rpython.rtyper.lltypesystem.lltype import Ptr, GcStruct, Signed, malloc, Void
from rpython.rtyper.rrange import AbstractRangeRepr, AbstractRangeIteratorRepr
from rpython.rtyper.error import TyperError

# ____________________________________________________________
#
#  Concrete implementation of RPython lists that are returned by range()
#  and never mutated afterwards:
#
#    struct range {
#        Signed start, stop;    // step is always constant
#    }
#
#    struct rangest {
#        Signed start, stop, step;    // rare case, for completeness
#    }

def ll_length(l):
    if l.step > 0:
        lo = l.start
        hi = l.stop
        step = l.step
    else:
        lo = l.stop
        hi = l.start
        step = -l.step
    if hi <= lo:
        return 0
    n = (hi - lo - 1) // step + 1
    return n

def ll_getitem_fast(l, index):
    return l.start + index * l.step

RANGEST = GcStruct("range", ("start", Signed), ("stop", Signed), ("step", Signed),
                    adtmeths = {
                        "ll_length":ll_length,
                        "ll_getitem_fast":ll_getitem_fast,
                    },
                    hints = {'immutable': True})
RANGESTITER = GcStruct("range", ("next", Signed), ("stop", Signed), ("step", Signed))

class RangeRepr(AbstractRangeRepr):

    RANGEST = Ptr(RANGEST)
    RANGESTITER = Ptr(RANGESTITER)

    getfield_opname = "getfield"

    def __init__(self, step, *args):
        self.RANGE = Ptr(GcStruct("range", ("start", Signed), ("stop", Signed),
                adtmeths = {
                    "ll_length":ll_length,
                    "ll_getitem_fast":ll_getitem_fast,
                    "step":step,
                },
                hints = {'immutable': True}))
        self.RANGEITER = Ptr(GcStruct("range", ("next", Signed), ("stop", Signed)))
        AbstractRangeRepr.__init__(self, step, *args)
        self.ll_newrange = ll_newrange
        self.ll_newrangest = ll_newrangest

    def make_iterator_repr(self, variant=None):
        if variant is not None:
            raise TyperError("unsupported %r iterator over a range list" %
                             (variant,))
        return RangeIteratorRepr(self)


def ll_newrange(RANGE, start, stop):
    l = malloc(RANGE.TO)
    l.start = start
    l.stop = stop
    return l

def ll_newrangest(start, stop, step):
    if step == 0:
        raise ValueError
    l = malloc(RANGEST)
    l.start = start
    l.stop = stop
    l.step = step
    return l

class RangeIteratorRepr(AbstractRangeIteratorRepr):

    def __init__(self, *args):
        AbstractRangeIteratorRepr.__init__(self, *args)
        self.ll_rangeiter = ll_rangeiter

def ll_rangeiter(ITERPTR, rng):
    iter = malloc(ITERPTR.TO)
    iter.next = rng.start
    iter.stop = rng.stop
    if ITERPTR.TO is RANGESTITER:
        iter.step = rng.step
    return iter