mame-dynamicwind 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +6 -0
- data/lib/dynamicwind.rb +13 -4
- data/test/test_dynamicwind.rb +331 -1
- metadata +2 -2
data/History.txt
CHANGED
data/lib/dynamicwind.rb
CHANGED
@@ -4,7 +4,7 @@ rescue LoadError
|
|
4
4
|
end
|
5
5
|
|
6
6
|
module DynamicWind
|
7
|
-
VERSION = '1.0.
|
7
|
+
VERSION = '1.0.1'
|
8
8
|
|
9
9
|
Stack = Struct.new(:fst, :snd, :next)
|
10
10
|
|
@@ -18,8 +18,17 @@ module DynamicWind
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def dynamicwind(before, thunk, after)
|
21
|
+
before_ = after_ = nil
|
22
|
+
if ctn_before = __callcc_orig {|c| before_ = c; false }
|
23
|
+
before.call
|
24
|
+
ctn_before.call
|
25
|
+
end
|
26
|
+
if ctn_after = __callcc_orig {|c| after_ = c; false }
|
27
|
+
after.call
|
28
|
+
ctn_after.call
|
29
|
+
end
|
21
30
|
mark = __top
|
22
|
-
__switch(Stack[[
|
31
|
+
__switch(Stack[[before_, nil], [nil, after_], mark])
|
23
32
|
thunk.call ensure __switch(mark)
|
24
33
|
end
|
25
34
|
|
@@ -35,7 +44,7 @@ module DynamicWind
|
|
35
44
|
return if __top.equal?(mark)
|
36
45
|
__switch(mark.next)
|
37
46
|
fst, snd = mark.fst, mark.snd
|
38
|
-
fst.first.call if fst.first
|
47
|
+
__callcc_orig {|c| fst.first.call(c) } if fst.first
|
39
48
|
__top.fst = snd
|
40
49
|
__top.snd = fst
|
41
50
|
__top.next = mark
|
@@ -43,7 +52,7 @@ module DynamicWind
|
|
43
52
|
__top.fst = nil
|
44
53
|
__top.snd = nil
|
45
54
|
__top.next = nil
|
46
|
-
fst.last.call if fst.last
|
55
|
+
__callcc_orig {|c| fst.last.call(c) } if fst.last
|
47
56
|
end
|
48
57
|
end
|
49
58
|
|
data/test/test_dynamicwind.rb
CHANGED
@@ -73,7 +73,172 @@ class TestDynamicWind < Test::Unit::TestCase
|
|
73
73
|
assert_equal([:before, :thunk1, :thunk2, :after, :end, :before, :thunk3, :after, :end], ary)
|
74
74
|
end
|
75
75
|
|
76
|
-
def
|
76
|
+
def test_jump_from_before_to_before
|
77
|
+
ary = []
|
78
|
+
ctn = nil
|
79
|
+
i = 0
|
80
|
+
while i <= 1
|
81
|
+
dynamicwind(
|
82
|
+
proc do
|
83
|
+
ary << :before1
|
84
|
+
ctn.call if ctn
|
85
|
+
ary << :before2
|
86
|
+
callcc {|c| ctn = c }
|
87
|
+
ary << :before3
|
88
|
+
end,
|
89
|
+
proc { ary << :thunk },
|
90
|
+
proc { ary << :after }
|
91
|
+
)
|
92
|
+
ary << :end
|
93
|
+
i += 1
|
94
|
+
end
|
95
|
+
assert_equal([:before1, :before2, :before3, :thunk, :after, :end, :before1, :before3, :thunk, :after, :end], ary)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_jump_from_before_to_thunk
|
99
|
+
ary = []
|
100
|
+
ctn = nil
|
101
|
+
flag = true
|
102
|
+
i = 0
|
103
|
+
while i <= 1
|
104
|
+
dynamicwind(
|
105
|
+
proc do
|
106
|
+
ary << :before1
|
107
|
+
(flag = false; ctn.call) if ctn && flag
|
108
|
+
ary << :before2
|
109
|
+
end,
|
110
|
+
proc do
|
111
|
+
ary << :thunk1
|
112
|
+
callcc {|c| ctn = c }
|
113
|
+
ary << :thunk2
|
114
|
+
end,
|
115
|
+
proc { ary << :after }
|
116
|
+
)
|
117
|
+
ary << :end
|
118
|
+
i += 1
|
119
|
+
end
|
120
|
+
assert_equal([:before1, :before2, :thunk1, :thunk2, :after, :end, :before1, :before1, :before2, :thunk2, :after, :end], ary)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_jump_from_before_to_after
|
124
|
+
ary = []
|
125
|
+
ctn = nil
|
126
|
+
i = 0
|
127
|
+
while i <= 1
|
128
|
+
dynamicwind(
|
129
|
+
proc do
|
130
|
+
ary << :before1
|
131
|
+
ctn.call if ctn
|
132
|
+
ary << :before2
|
133
|
+
end,
|
134
|
+
proc { ary << :thunk },
|
135
|
+
proc do
|
136
|
+
ary << :after1
|
137
|
+
callcc {|c| ctn = c }
|
138
|
+
ary << :after2
|
139
|
+
end
|
140
|
+
)
|
141
|
+
ary << :end
|
142
|
+
i += 1
|
143
|
+
end
|
144
|
+
assert_equal([:before1, :before2, :thunk, :after1, :after2, :end, :before1, :after2, :end], ary)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_jump_from_thunk_to_before
|
148
|
+
ary = []
|
149
|
+
ctn = nil
|
150
|
+
flag = true
|
151
|
+
dynamicwind(
|
152
|
+
proc do
|
153
|
+
ary << :before1
|
154
|
+
callcc {|c| ctn = c }
|
155
|
+
ary << :before2
|
156
|
+
end,
|
157
|
+
proc do
|
158
|
+
ary << :thunk1
|
159
|
+
(flag = false; ctn.call) if flag
|
160
|
+
ary << :thunk2
|
161
|
+
end,
|
162
|
+
proc { ary << :after }
|
163
|
+
)
|
164
|
+
assert_equal([:before1, :before2, :thunk1, :after, :before2, :thunk1, :thunk2, :after], ary)
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_jump_from_thunk_to_before_2
|
168
|
+
ary = []
|
169
|
+
ctn = nil
|
170
|
+
flag = true
|
171
|
+
i = 0
|
172
|
+
while i <= 1
|
173
|
+
dynamicwind(
|
174
|
+
proc do
|
175
|
+
ary << :before1
|
176
|
+
callcc {|c| ctn = c } if i == 0
|
177
|
+
ary << :before2
|
178
|
+
end,
|
179
|
+
proc do
|
180
|
+
ary << :thunk1
|
181
|
+
(flag = false; ctn.call) if i == 1 && flag
|
182
|
+
ary << :thunk2
|
183
|
+
end,
|
184
|
+
proc { ary << :after }
|
185
|
+
)
|
186
|
+
ary << :end
|
187
|
+
i += 1
|
188
|
+
end
|
189
|
+
assert_equal([:before1, :before2, :thunk1, :thunk2, :after, :end, :before1, :before2, :thunk1, :after, :before2, :thunk1, :thunk2, :after, :end], ary)
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_jump_from_thunk_to_thunk
|
193
|
+
ary = []
|
194
|
+
ctn = nil
|
195
|
+
flag = true
|
196
|
+
i = 0
|
197
|
+
while i <= 1
|
198
|
+
dynamicwind(
|
199
|
+
proc do
|
200
|
+
ary << :before1
|
201
|
+
callcc {|c| ctn = c } if i == 0
|
202
|
+
ary << :before2
|
203
|
+
end,
|
204
|
+
proc do
|
205
|
+
ary << :thunk1
|
206
|
+
(flag = false; ctn.call) if i == 1 && flag
|
207
|
+
ary << :thunk2
|
208
|
+
end,
|
209
|
+
proc { ary << :after }
|
210
|
+
)
|
211
|
+
ary << :end
|
212
|
+
i += 1
|
213
|
+
end
|
214
|
+
assert_equal([:before1, :before2, :thunk1, :thunk2, :after, :end, :before1, :before2, :thunk1, :after, :before2, :thunk1, :thunk2, :after, :end], ary)
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_jump_from_thunk_to_after
|
218
|
+
ary = []
|
219
|
+
ctn = nil
|
220
|
+
i = 0
|
221
|
+
while i <= 1
|
222
|
+
dynamicwind(
|
223
|
+
proc { ary << :before },
|
224
|
+
proc do
|
225
|
+
ary << :thunk1
|
226
|
+
ctn.call if ctn
|
227
|
+
ary << :thunk2
|
228
|
+
end,
|
229
|
+
proc do
|
230
|
+
ary << :after1
|
231
|
+
callcc {|c| ctn = c }
|
232
|
+
ary << :after2
|
233
|
+
end
|
234
|
+
)
|
235
|
+
ary << :end
|
236
|
+
i += 1
|
237
|
+
end
|
238
|
+
assert_equal([:before, :thunk1, :thunk2, :after1, :after2, :end, :before, :thunk1, :after1, :after2, :after2, :end], ary)
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_jump_from_after_to_before
|
77
242
|
ary = []
|
78
243
|
ctn = nil
|
79
244
|
flag = true
|
@@ -93,6 +258,98 @@ class TestDynamicWind < Test::Unit::TestCase
|
|
93
258
|
assert_equal([:before1, :before2, :thunk, :after1, :before2, :thunk, :after1, :after2], ary)
|
94
259
|
end
|
95
260
|
|
261
|
+
def test_jump_from_after_to_before_2
|
262
|
+
ary = []
|
263
|
+
ctn = nil
|
264
|
+
flag = true
|
265
|
+
i = 0
|
266
|
+
while i <= 1
|
267
|
+
dynamicwind(
|
268
|
+
proc do
|
269
|
+
ary << :before1
|
270
|
+
callcc {|c| ctn = c } if i == 0
|
271
|
+
ary << :before2
|
272
|
+
end,
|
273
|
+
proc { ary << :thunk },
|
274
|
+
proc do
|
275
|
+
ary << :after1
|
276
|
+
(flag = false; ctn.call) if i == 1 && flag
|
277
|
+
ary << :after2
|
278
|
+
end
|
279
|
+
)
|
280
|
+
ary << :end
|
281
|
+
i += 1
|
282
|
+
end
|
283
|
+
assert_equal([:before1, :before2, :thunk, :after1, :after2, :end, :before1, :before2, :thunk, :after1, :before2, :thunk, :after1, :after2, :end], ary)
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_jump_from_after_to_thunk
|
287
|
+
ary = []
|
288
|
+
ctn = nil
|
289
|
+
flag = true
|
290
|
+
dynamicwind(
|
291
|
+
proc { ary << :before },
|
292
|
+
proc do
|
293
|
+
ary << :thunk1
|
294
|
+
callcc {|c| ctn = c }
|
295
|
+
ary << :thunk2
|
296
|
+
end,
|
297
|
+
proc do
|
298
|
+
ary << :after1
|
299
|
+
(flag = false; ctn.call) if flag
|
300
|
+
ary << :after2
|
301
|
+
end
|
302
|
+
)
|
303
|
+
assert_equal([:before, :thunk1, :thunk2, :after1, :before, :thunk2, :after1, :after2], ary)
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_jump_from_after_to_thunk_2
|
307
|
+
ary = []
|
308
|
+
ctn = nil
|
309
|
+
flag = true
|
310
|
+
i = 0
|
311
|
+
while i <= 1
|
312
|
+
dynamicwind(
|
313
|
+
proc { ary << :before },
|
314
|
+
proc do
|
315
|
+
ary << :thunk1
|
316
|
+
callcc {|c| ctn = c } if i == 0
|
317
|
+
ary << :thunk2
|
318
|
+
end,
|
319
|
+
proc do
|
320
|
+
ary << :after1
|
321
|
+
(flag = false; ctn.call) if i == 1 && flag
|
322
|
+
ary << :after2
|
323
|
+
end
|
324
|
+
)
|
325
|
+
ary << :end
|
326
|
+
i += 1
|
327
|
+
end
|
328
|
+
assert_equal([:before, :thunk1, :thunk2, :after1, :after2, :end, :before, :thunk1, :thunk2, :after1, :before, :thunk2, :after1, :after2, :end], ary)
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_jump_from_after_to_after
|
332
|
+
ary = []
|
333
|
+
ctn = nil
|
334
|
+
i = 0
|
335
|
+
while i <= 1
|
336
|
+
dynamicwind(
|
337
|
+
proc { ary << :before },
|
338
|
+
proc { ary << :thunk },
|
339
|
+
proc do
|
340
|
+
ary << :after1
|
341
|
+
ctn.call if ctn
|
342
|
+
ary << :after2
|
343
|
+
callcc {|c| ctn = c }
|
344
|
+
ary << :after3
|
345
|
+
end
|
346
|
+
)
|
347
|
+
ary << :end
|
348
|
+
i += 1
|
349
|
+
end
|
350
|
+
assert_equal([:before, :thunk, :after1, :after2, :after3, :end, :before, :thunk, :after1, :after3, :end], ary)
|
351
|
+
end
|
352
|
+
|
96
353
|
def test_raise
|
97
354
|
ary = []
|
98
355
|
assert_raise(RuntimeError) do
|
@@ -185,4 +442,77 @@ class TestDynamicWind < Test::Unit::TestCase
|
|
185
442
|
(flag = false; c2.call) if flag
|
186
443
|
assert_equal([:before1, :before2, :thunk1, :after2, :after1, :end, :before1, :before2, :thunk2, :after2, :after1, :end], ary)
|
187
444
|
end
|
445
|
+
|
446
|
+
def test_raise_in_before
|
447
|
+
ary = []
|
448
|
+
ctn = nil
|
449
|
+
flag = true
|
450
|
+
begin
|
451
|
+
dynamicwind(
|
452
|
+
proc do
|
453
|
+
ary << :before
|
454
|
+
raise if ctn
|
455
|
+
end,
|
456
|
+
proc do
|
457
|
+
ary << :thunk1
|
458
|
+
callcc {|c| ctn = c }
|
459
|
+
ary << :thunk2
|
460
|
+
end,
|
461
|
+
proc { ary << :after }
|
462
|
+
)
|
463
|
+
ary << :normal
|
464
|
+
rescue
|
465
|
+
ary << :exception
|
466
|
+
end
|
467
|
+
ary << :end
|
468
|
+
assert_nothing_raised { flag = false; ctn.call } if flag
|
469
|
+
assert_equal([:before, :thunk1, :thunk2, :after, :normal, :end, :before, :exception, :end], ary)
|
470
|
+
end
|
471
|
+
|
472
|
+
def test_raise_in_after
|
473
|
+
ary = []
|
474
|
+
ctn = nil
|
475
|
+
assert_nothing_raised do
|
476
|
+
dynamicwind(
|
477
|
+
proc { ary << :before1 },
|
478
|
+
proc do
|
479
|
+
ary << :thunk1
|
480
|
+
callcc {|c| ctn = c }
|
481
|
+
ary << :thunk2
|
482
|
+
end,
|
483
|
+
proc { ary << :after1 }
|
484
|
+
)
|
485
|
+
end
|
486
|
+
ary << :between
|
487
|
+
begin
|
488
|
+
dynamicwind(
|
489
|
+
proc { ary << :before2 },
|
490
|
+
proc do
|
491
|
+
ary << :thunk3
|
492
|
+
assert_nothing_raised { ctn.call }
|
493
|
+
end,
|
494
|
+
proc { ary << :after2; raise }
|
495
|
+
)
|
496
|
+
rescue
|
497
|
+
ary << :exception
|
498
|
+
end
|
499
|
+
ary << :end
|
500
|
+
assert_equal([:before1, :thunk1, :thunk2, :after1, :between, :before2, :thunk3, :after2, :exception, :end], ary)
|
501
|
+
end
|
502
|
+
|
503
|
+
def test_callcc_in_thunk
|
504
|
+
ary = []
|
505
|
+
dynamicwind(
|
506
|
+
proc { ary << :before },
|
507
|
+
proc do
|
508
|
+
callcc do |c|
|
509
|
+
ary << :thunk1
|
510
|
+
c.call
|
511
|
+
ary << :thunk2
|
512
|
+
end
|
513
|
+
end,
|
514
|
+
proc { ary << :after }
|
515
|
+
)
|
516
|
+
assert_equal([:before, :thunk1, :after], ary)
|
517
|
+
end
|
188
518
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mame-dynamicwind
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yusuke Endoh
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-11-
|
12
|
+
date: 2008-11-21 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|