-
Notifications
You must be signed in to change notification settings - Fork 128
Expand file tree
/
Copy pathpersistent_list.py
More file actions
161 lines (118 loc) · 3.52 KB
/
persistent_list.py
File metadata and controls
161 lines (118 loc) · 3.52 KB
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
import pixie.vm.object as object
from pixie.vm.primitives import nil, true, false
import pixie.vm.stdlib as proto
from pixie.vm.code import extend, as_var
from pixie.vm.numbers import Integer
from rpython.rlib.rarithmetic import r_uint, intmask
import pixie.vm.rt as rt
class PersistentList(object.Object):
_type = object.Type(u"pixie.stdlib.PersistentList")
def type(self):
return PersistentList._type
def __init__(self, head, tail, cnt, meta=nil):
self._first = head
self._next = tail
self._cnt = cnt
self._meta = meta
def first(self):
return self._first
def next(self):
return self._next
def meta(self):
return self._meta
def with_meta(self, meta):
return PersistentList(self._first, self._next, self._cnt, meta)
@extend(proto._first, PersistentList)
def _first(self):
assert isinstance(self, PersistentList)
return self._first
@extend(proto._next, PersistentList)
def _next(self):
assert isinstance(self, PersistentList)
return self._next
@extend(proto._seq, PersistentList)
def _seq(self):
assert isinstance(self, PersistentList)
return self
@extend(proto._count, PersistentList)
def _count(self):
assert isinstance(self, PersistentList)
return rt.wrap(intmask(self._cnt))
@extend(proto._conj, PersistentList)
def _conj(self, itm):
assert isinstance(self, PersistentList)
return PersistentList(itm, self, self._cnt + 1, nil)
@extend(_conj, nil._type)
def _conj(_, itm):
return PersistentList(itm, nil, 1, nil)
def count(self):
cnt = 0
while self is not nil:
self = self.next()
cnt += 1
return cnt
@as_var("list")
def list__args(args):
if len(args) == 0:
return EmptyList()
i = r_uint(len(args))
acc = nil
while i > 0:
acc = PersistentList(args[i - 1], acc, len(args) - i + 1, nil)
i -= 1
return acc
@extend(proto._meta, PersistentList)
def _meta(self):
assert isinstance(self, PersistentList)
return self.meta()
@extend(proto._with_meta, PersistentList)
def _with_meta(self, meta):
assert isinstance(self, PersistentList)
return self.with_meta(meta)
class EmptyList(object.Object):
_type = object.Type(u"pixie.stdlib.EmptyList")
def type(self):
return EmptyList._type
def __init__(self, meta=nil):
self._meta = meta
def meta(self):
return self._meta
def with_meta(self, meta):
return EmptyList(meta)
@extend(proto._first, EmptyList)
def _first(self):
assert isinstance(self, EmptyList)
return nil
@extend(proto._next, EmptyList)
def _next(self):
assert isinstance(self, EmptyList)
return nil
@extend(proto._seq, EmptyList)
def _seq(self):
assert isinstance(self, EmptyList)
return nil
@extend(proto._count, EmptyList)
def _count(self):
assert isinstance(self, EmptyList)
return rt.wrap(0)
@extend(proto._conj, EmptyList)
def _conj(self, itm):
assert isinstance(self, EmptyList)
return PersistentList(itm, nil, 1)
@extend(proto._meta, EmptyList)
def _meta(self):
assert isinstance(self, EmptyList)
return self.meta()
@extend(proto._with_meta, EmptyList)
def _with_meta(self, meta):
assert isinstance(self, EmptyList)
return self.with_meta(meta)
@extend(proto._str, EmptyList)
def _str(self):
return rt.wrap(u"()")
@extend(proto._repr, EmptyList)
def _str(self):
return rt.wrap(u"()")
@extend(proto._reduce, EmptyList)
def _str(self, f, init):
return init