-
Notifications
You must be signed in to change notification settings - Fork 17
/
lua_coroutines.nim
53 lines (42 loc) · 1.31 KB
/
lua_coroutines.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
###########################################################################
#
# Lua-style assymetrical coroutines
#
# resume(co, val):
#
# Starts or continues the execution of coroutine co. The first time you
# resume a coroutine, it starts running its body. If the coroutine has
# yielded, resume() restarts it; the value `val` is passed as the results
# from the yield().
#
# send(val):
# yield():
#
# Suspends the execution of the calling coroutine. The value `val`
# passed to sent is returned as results from resume().
#
###########################################################################
import cps, options, deques
type
Coroutine = ref object of Continuation
val: int
# Magic procs for yielding and receiving. Note: we actually want
# to have yield() and receive() in one single operation so we can
# do `vlaOut = yield(valIn)`
proc jield(c: Coroutine, val: int): Coroutine {.cpsMagic.} =
c.val = val
proc recv(c: Coroutine): int {.cpsVoodoo.} =
return c.val
proc resume(c: Coroutine, val: int): int =
c.val = val
discard c.trampoline()
return c.val
# This coroutine calculates the running total of the passed numbers
proc fn_coro1() {.cps:Coroutine.} =
var sum = 0
while true:
sum += recv()
jield(sum)
var coro = whelp fn_coro1()
for i in 0..10:
echo coro.resume(i)