-
Notifications
You must be signed in to change notification settings - Fork 17
/
cpscps.nim
84 lines (68 loc) · 1.85 KB
/
cpscps.nim
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
import cps, deques
###########################################################################
# Implementation of a minimal scheduler, just a dequeue of work
###########################################################################
type
Work = ref object of Continuation
pool: Pool
Pool = ref object
workQueue: Deque[Work]
yields: int
proc push(pool: Pool, c: Work) =
if c.running:
echo "pool was supplied to push"
c.pool = pool
pool.workQueue.addLast(c)
proc jield(c: Work): Work {.cpsMagic.} =
inc c.pool.yields
c.pool.push c
proc run(pool: Pool) =
while pool.workQueue.len > 0:
var c = Continuation: pool.workQueue.popFirst
c = trampoline c
pool.push c.Work
proc tail(mom: Continuation; c: Work): Work =
echo "tail copied the pool"
result = c
result.mom = mom
result.pool = mom.Work.pool
###########################################################################
# Main code
###########################################################################
var total: int
proc deeper(b: ref int) {.cps:Work.} =
echo " deeper() in, b: ", b[]
jield()
inc total, b[]
echo " deeper() out"
proc foo(a: int) {.cps:Work.} =
echo " foo() in a: ", a
echo " foo() yield()"
jield()
echo " foo() yield done()"
echo " foo() calls deeper()"
# CPS does not support var parameters yet. We can box an int tho
var b = new int;
b[] = a * 2
deeper(b)
echo " foo() returned from deeper(), b: ", b[]
echo " foo() out"
proc bar() {.cps:Work.} =
echo "bar() in"
echo "bar() yield"
jield()
echo "bar() yield done"
echo "bar() calls foo(1)"
foo(1)
echo "bar() returned from foo()"
echo "bar() calls foo(2)"
foo(2)
echo "bar() returned from foo()"
echo "bar() out"
var pool = Pool()
pool.push: Work whelp bar()
pool.run()
echo pool.yields
doAssert pool.yields == 5
echo total
doAssert total == 6