Skip to content

Commit e973464

Browse files
author
Mike Solomon
committed
Initial commit
0 parents  commit e973464

File tree

3 files changed

+327
-0
lines changed

3 files changed

+327
-0
lines changed

.gitignore

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/bower_components/
2+
/node_modules/
3+
/.pulp-cache/
4+
/output/
5+
/generated-docs/
6+
/.psc-package/
7+
/.psc*
8+
/.purs*
9+
/.psa*
10+
/.spago
11+
/.venv
12+
/.vscode
13+
14+
purescript_aff
15+
16+
# purescript-python
17+
.pure-py/
18+
19+
# purescript-python
20+
.pure-py/
21+
22+
# purescript-python
23+
.pure-py/

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# purescript-avar.py
2+
3+
A port of avar to purescript-python

python-ffi/Effect/AVar.py

+301
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
import threading
2+
3+
4+
class EMPTY:
5+
pass
6+
7+
8+
class MutableQueue:
9+
def __init__(self):
10+
self.head = None
11+
self.last = None
12+
self.size = 0
13+
14+
15+
class MutableCell:
16+
def __init__(self, queue, value):
17+
self.queue = queue
18+
self.value = value
19+
self.next = None
20+
self.prev = None
21+
22+
23+
class AVar:
24+
def __init__(self, value):
25+
self.draining = False
26+
self.error = None
27+
self.value = value
28+
self.takes = MutableQueue()
29+
self.reads = MutableQueue()
30+
self.puts = MutableQueue()
31+
32+
33+
class ____:
34+
@staticmethod
35+
def runEff(eff):
36+
try:
37+
eff()
38+
except Exception as e:
39+
40+
def _throw():
41+
raise e
42+
43+
t = threading.Thread(target=_throw)
44+
t.start()
45+
46+
@staticmethod
47+
def putLast(queue, value):
48+
cell = MutableCell(queue, value)
49+
if queue.size == 0:
50+
queue.head = cell
51+
elif queue.size == 1:
52+
cell.prev = queue.head
53+
queue.head.next = cell
54+
queue.last = cell
55+
56+
else:
57+
cell.prev = queue.last
58+
queue.last.next = cell
59+
queue.last = cell
60+
61+
queue.size += 1
62+
return cell
63+
64+
@staticmethod
65+
def takeLast(queue):
66+
cell = None
67+
if queue.size == 0:
68+
return None
69+
if queue.size == 1:
70+
cell = queue.head
71+
queue.head = None
72+
elif queue.size == 2:
73+
cell = queue.last
74+
queue.head.next = None
75+
queue.last = None
76+
else:
77+
cell = queue.last
78+
queue.last = cell.prev
79+
queue.last.next = None
80+
cell.prev = None
81+
cell.queue = None
82+
queue.size -= 1
83+
return cell.value
84+
85+
@staticmethod
86+
def takeHead(queue):
87+
cell = None
88+
if queue.size == 0:
89+
return None
90+
if queue.size == 1:
91+
cell = queue.head
92+
queue.head = None
93+
elif queue.size == 2:
94+
cell = queue.head
95+
queue.last.prev = None
96+
queue.head = queue.last
97+
queue.last = None
98+
else:
99+
cell = queue.head
100+
queue.head = cell.next
101+
queue.head.prev = None
102+
cell.next = None
103+
cell.queue = None
104+
queue.size -= 1
105+
return cell.value
106+
107+
@staticmethod
108+
def deleteCell(cell):
109+
if cell.queue == None:
110+
return None
111+
if cell.queue.last == cell:
112+
____.takeLast(cell.queue)
113+
return None
114+
if cell.queue.head == cell:
115+
____.takeHead(cell.queue)
116+
return None
117+
if cell.prev:
118+
cell.prev.next = cell.next
119+
if cell.next:
120+
cell.next.prev = cell.prev
121+
cell.queue.size -= 1
122+
cell.queue = None
123+
cell.value = None
124+
cell.next = None
125+
cell.prev = None
126+
127+
@staticmethod
128+
def drainVar(util, avar):
129+
if avar.draining:
130+
return None
131+
ps = avar.puts
132+
ts = avar.takes
133+
rs = avar.reads
134+
p = None
135+
r = None
136+
t = None
137+
value = None
138+
rsize = None
139+
avar.draining = True
140+
while True:
141+
p = None
142+
r = None
143+
t = None
144+
value = avar.value
145+
rsize = rs.size
146+
if avar.error is not None:
147+
value = util["left"](avar.error)
148+
while True:
149+
p = ____.takeHead(ps)
150+
if p is None:
151+
break
152+
____.runEff(p.cb(value))
153+
while True:
154+
r = ____.takeHead(rs)
155+
if r is None:
156+
break
157+
____.runEff(r(value))
158+
while True:
159+
t = ____.takeHead(ts)
160+
if t is None:
161+
break
162+
____.runEff(t(value))
163+
break
164+
if value == EMPTY:
165+
p = ____.takeHead(ps)
166+
if p:
167+
avar.value = p.value
168+
value = p.value
169+
if value != EMPTY:
170+
t = ____.takeHead(ts)
171+
while rsize > 0:
172+
rsize -= 1
173+
r = ____.takeHead(rs)
174+
if not r:
175+
break
176+
____.runEff(r(util["right"](value)))
177+
if t is not None:
178+
avar.value = EMPTY
179+
____.runEff(t(util["right"](value)))
180+
if p is not None:
181+
____.runEff(p.cb(util["right"](None)))
182+
if ((avar.value == EMPTY) and (ps.size == 0)) or (
183+
(avar.value != EMPTY) and (ts.size == 0)
184+
):
185+
break
186+
avar.draining = False
187+
188+
189+
def empty():
190+
return AVar(EMPTY)
191+
192+
193+
def _newVar(value):
194+
def _newVar1():
195+
return AVar(value)
196+
197+
return _newVar1
198+
199+
200+
def _killVar(util, error, avar):
201+
def _killVar1():
202+
if avar.error == None:
203+
avar.error = error
204+
avar.value = EMPTY
205+
____.drainVar(util, avar)
206+
207+
return _killVar1
208+
209+
210+
class Puttable:
211+
def __init__(self, cb, value):
212+
self.cb = cb
213+
self.value = value
214+
215+
216+
def _putVar(util, value, avar, cb):
217+
def _putVar1():
218+
cell = ____.putLast(avar.puts, Puttable(cb, value))
219+
____.drainVar(util, avar)
220+
221+
def _putVar2():
222+
____.deleteCell(cell)
223+
224+
return _putVar2
225+
226+
return _putVar1
227+
228+
229+
def _takeVar(util, avar, cb):
230+
def _takeVar1():
231+
cell = ____.putLast(avar.takes, cb)
232+
____.drainVar(util, avar)
233+
234+
def _takeVar2():
235+
____.deleteCell(cell)
236+
237+
return _takeVar2
238+
239+
return _takeVar1
240+
241+
242+
def _readVar(util, avar, cb):
243+
def _readVar1():
244+
cell = ____.putLast(avar.reads, cb)
245+
____.drainVar(util, avar)
246+
247+
def _readVar2():
248+
____.deleteCell(cell)
249+
250+
return _readVar2
251+
252+
return _readVar1
253+
254+
255+
def _tryPutVar(util, value, avar):
256+
def _tryPutVar1():
257+
if (avar.value == EMPTY) and (avar.error == None):
258+
avar.value = value
259+
____.drainVar(util, avar)
260+
return True
261+
else:
262+
return False
263+
264+
return _tryPutVar1
265+
266+
267+
def _tryTakeVar(util, avar):
268+
def _tryTakeVar1():
269+
value = avar.value
270+
if value == EMPTY:
271+
return util["nothing"]
272+
else:
273+
avar.value = EMPTY
274+
____.drainVar(util, avar)
275+
return util["just"](value)
276+
277+
return _tryTakeVar1
278+
279+
280+
def _tryReadVar(util, avar):
281+
def _tryReadVar1():
282+
if avar.value == EMPTY:
283+
return util["nothing"]
284+
else:
285+
return util["just"](avar.value)
286+
287+
return _tryReadVar1
288+
289+
290+
def _status(util, avar):
291+
def _status1():
292+
if avar.error:
293+
return util["killed"](avar.error)
294+
295+
if avar.value == EMPTY:
296+
return util["empty"]
297+
298+
return util["filled"](avar.value)
299+
300+
return _status1
301+

0 commit comments

Comments
 (0)