Skip to content

Commit f12d6ee

Browse files
authored
make cps work with new nimskull again (#332)
1 parent 7e6ed65 commit f12d6ee

15 files changed

+125
-25
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ jobs:
6464

6565
- name: nimskull
6666
version: "*"
67-
broken: true
67+
broken: false
6868

6969
- name: nimskull
70-
version: "<0.1.0-dev.21268"
70+
version: "0.1.0-dev.21407"
7171
broken: false
7272

7373
name: "${{ matrix.os }} (${{ matrix.compiler.name }} ${{ matrix.compiler.version }}${{ matrix.compiler.broken && ', broken' || '' }})"

cps/spec.nim

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ boring utilities likely useful to multiple pieces of cps machinery
55
]##
66

77
import std/[hashes, sequtils, deques]
8-
import std/macros except newStmtList, newTree
8+
import std/macros except newStmtList, newTree, quote, stamp
99

1010
when (NimMajor, NimMinor) < (1, 5):
1111
{.fatal: "requires nim-1.5".}
@@ -99,6 +99,14 @@ proc `=destroy`(dest: var ContinuationObj) =
9999
for key, value in dest.fieldPairs:
100100
reset value
101101

102+
# quote() shim for nimskull
103+
when declared(macros.stamp):
104+
template quote(body: untyped): NimNode =
105+
macros.stamp(body)
106+
else:
107+
template quote(body: untyped): NimNode =
108+
macros.quote(body)
109+
102110
template dot*(a, b: NimNode): NimNode =
103111
## for constructing foo.bar
104112
{.line: instantiationInfo().}:

tests/killer.nim

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,32 @@ type
66
final: int
77
n: int
88

9-
proc `=destroy`*(k: var Killer) {.raises: [FailError].} =
9+
proc failMsg(k: Killer): string =
10+
case k.n
11+
of 0: "uninitialized"
12+
of 1: "unused"
13+
else: "misused; " & $(k.n - 1) & " uses, expected " & $(k.final - 1)
14+
15+
proc `=destroy`*(k: var Killer) {.raises: [].} =
16+
## Raise a `Defect` if `k` has errors.
17+
##
18+
## `check()` should be used to have errors raised as test failures.
19+
##
20+
## This destructor is a last-ditch effort for when `check()` is not
21+
## run.
22+
# Only crash if there's no exception running
23+
if k.final != k.n and getCurrentException() == nil:
24+
raise newException(Defect, k.failMsg)
25+
26+
proc check*(k: Killer) {.raises: [FailError].} =
27+
## Check `k` for errors.
1028
if k.final != k.n:
11-
let e = getCurrentException()
12-
# don't obliterate current exception
13-
when defined(ExpectedError):
14-
let shouldFail = e.isNil or e isnot FailError or e isnot ExpectedError
15-
else:
16-
let shouldFail = e.isNil or e isnot FailError
17-
if shouldFail:
18-
fail:
19-
case k.n
20-
of 0: "uninitialized"
21-
of 1: "unused"
22-
else: "misused; " & $(k.n - 1) & " uses, expected " & $(k.final - 1)
29+
fail k.failMsg
30+
31+
proc clear*(k: var Killer) =
32+
## Clear and defuse `k`. `k` is not reusable after this.
33+
k.final = 0
34+
k.n = 0
2335

2436
proc initKiller*(final = 1): Killer =
2537
Killer(n: 1, final: final + 1)
@@ -31,7 +43,15 @@ proc newKiller*(final = 1): Killer =
3143
proc inc*(k: var Killer) = system.inc k.n
3244
template step*(k: Killer): int = k.n - 1
3345

34-
template step*(i: int) {.dirty.} =
46+
template step*(k: var Killer, i: int) =
47+
bind check
48+
3549
check k.n == i, "expected step " & $k.n & " but hit " & $i
3650
inc k.n
3751
k.final = max(i, k.final)
52+
53+
template step*(i: int) =
54+
mixin k
55+
bind step
56+
57+
step k, i

tests/t10_loops.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,4 @@ suite "loops":
182182
break
183183
step 7
184184
foo()
185+
check k

tests/t20_api.nim

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ suite "cps api":
1616
var i = bootstrap()
1717
check i is int, "bootstrap's output is not an int"
1818
check i == 3, "bootstrap's output has the wrong value"
19+
check k
1920

2021
block:
2122
## whelp
@@ -29,6 +30,7 @@ suite "cps api":
2930
var c = whelp whelped()
3031
check "whelp's output is bogus":
3132
c is Cont
33+
check k
3234

3335
block:
3436
## state symbols and trampoline
@@ -51,6 +53,7 @@ suite "cps api":
5153
c.state == State.Finished
5254
c.finished
5355
not c.running
56+
check k
5457

5558
block:
5659
## trampolineIt
@@ -69,6 +72,7 @@ suite "cps api":
6972
check "state post-trampolineIt is " & $c.state:
7073
not c.dismissed
7174
c.finished
75+
check k
7276

7377
block:
7478
## magic voodoo
@@ -99,6 +103,7 @@ suite "cps api":
99103
return 3
100104

101105
check foo() == 3
106+
check k
102107

103108
block:
104109
## exporting CPS procedures works
@@ -113,6 +118,7 @@ suite "cps api":
113118
step 2
114119

115120
foo()
121+
check k
116122

117123
block:
118124
## one can whelp a cps'd proc that was borrowed
@@ -146,6 +152,7 @@ suite "cps api":
146152
step 3
147153

148154
foo()
155+
check k
149156

150157
block:
151158
## calling magic that is not defined for the base type should not compile
@@ -158,25 +165,23 @@ suite "cps api":
158165

159166
block:
160167
## calling magic/voodoo with generics continuation parameter works
161-
# XXX: Not sure why, but Killer doesn't work here, complaining about
162-
# `k` not in scope.
163-
var r = 0
168+
var k = newKiller 3
164169

165170
type AnotherCont = ref object of Continuation
166171
proc magic(c: Cont or AnotherCont): auto {.cpsMagic.} =
167-
inc r
172+
k.step 3
168173
c
169174

170175
proc voodoo(c: Cont or AnotherCont) {.cpsVoodoo.} =
171-
inc r
176+
k.step 2
172177

173178
proc foo() {.cps: Cont.} =
174-
inc r
179+
step 1
175180
voodoo()
176181
magic()
177182

178183
foo()
179-
check r == 3
184+
check k
180185

181186
block:
182187
## magic/voodoo can be defined with `using`
@@ -209,6 +214,7 @@ suite "cps api":
209214
return 3
210215

211216
check foo() == 3
217+
check k
212218

213219
block:
214220
## parent-child voodoo works correctly
@@ -245,3 +251,4 @@ suite "cps api":
245251

246252
var a = whelp level_one()
247253
trampoline a
254+
check k

tests/t30_cc.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ suite "calling convention":
9292
step 7
9393

9494
foo: whelp bar
95+
check k
9596

9697
block:
9798
## whelp helps disambiguate cps callbacks at instantiation
@@ -116,6 +117,7 @@ suite "calling convention":
116117
check x == 8
117118

118119
foo: whelp(ContCall, bar)
120+
check k
119121

120122
block:
121123
## run a callback in cps with natural syntax
@@ -140,6 +142,7 @@ suite "calling convention":
140142
step 3
141143

142144
foo: whelp bar
145+
check k
143146

144147
block:
145148
## run a callback with no return value in cps
@@ -162,6 +165,7 @@ suite "calling convention":
162165
step 3
163166

164167
foo: whelp bar
168+
check k
165169

166170
block:
167171
## callback illustration

tests/t50_hooks.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,4 @@ suite "hooks":
334334
335335
expect IOError:
336336
foo()
337+
check k

tests/t60_returns.nim

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ suite "returns and results":
1919
check x == 8
2020

2121
foo()
22+
check k
2223

2324
block:
2425
## continuations can return values via bootstrap
@@ -30,6 +31,7 @@ suite "returns and results":
3031

3132
let x = foo(3)
3233
check x == 9
34+
check k
3335

3436
block:
3537
## continuations can return values via whelp
@@ -43,6 +45,7 @@ suite "returns and results":
4345
trampoline c
4446
check "recover operator works correctly":
4547
recover(c) == 25
48+
check k
4649

4750
block:
4851
## assignments to the special result symbol work
@@ -55,6 +58,7 @@ suite "returns and results":
5558

5659
let x = foo(3)
5760
check x == 9
61+
check k
5862

5963
block:
6064
var k = newKiller 1
@@ -65,6 +69,7 @@ suite "returns and results":
6569

6670
var c = whelp foo(5)
6771
trampoline c
72+
check k
6873

6974
block:
7075
## naked returns in continuations with a complication are fine
@@ -77,6 +82,7 @@ suite "returns and results":
7782
step 2
7883

7984
foo()
85+
check k
8086

8187
block:
8288
## dismissing a child continuation is fun
@@ -94,6 +100,7 @@ suite "returns and results":
94100
check x == 8
95101

96102
foo()
103+
check k
97104

98105
block:
99106
## assignment to a continuation return value
@@ -111,6 +118,7 @@ suite "returns and results":
111118
check x == 8
112119

113120
foo()
121+
check k
114122

115123
block:
116124
## local assignment tuple unpacking a continution return value
@@ -132,6 +140,7 @@ suite "returns and results":
132140
trampoline c
133141
check "recover operator works correctly":
134142
6 == recover c
143+
check k
135144

136145
block:
137146
## discarding a continuation return value works
@@ -145,6 +154,7 @@ suite "returns and results":
145154
step 2
146155

147156
foo()
157+
check k
148158

149159
block:
150160
## returning a continuation return value works
@@ -157,6 +167,7 @@ suite "returns and results":
157167
return bar()
158168

159169
check foo() == "test"
170+
check k
160171

161172
block:
162173
## returning an anonymous tuple declaration type
@@ -173,6 +184,7 @@ suite "returns and results":
173184
check (x, y) == (10, 20)
174185

175186
foo()
187+
check k
176188

177189
block:
178190
## returning a named tuple type
@@ -192,6 +204,7 @@ suite "returns and results":
192204
check (x, y) == (10, 20)
193205

194206
foo()
207+
check k
195208

196209
block:
197210
## converting a cps return value
@@ -220,6 +233,7 @@ suite "returns and results":
220233
step 3
221234

222235
foo()
236+
check k
223237

224238
block:
225239
## calling continuation with variant object access as parameter

tests/t70_locals.nim

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,8 @@ suite "tuples":
403403
check r == 2
404404

405405
type
406-
K = distinct object
406+
KObj = object
407+
K = distinct KObj
407408

408409
var k = initKiller 9
409410

@@ -463,6 +464,7 @@ suite "lifetimes":
463464
# destroy bar.m; eg. step == 11
464465

465466
foo()
467+
check k
466468

467469
block:
468470
## lifetime canary for distinct objects
@@ -501,6 +503,7 @@ suite "lifetimes":
501503
# destroy bar.m; eg. step == 9
502504

503505
foo()
506+
check k
504507

505508
import std/sugar
506509

0 commit comments

Comments
 (0)