windstorm 0.1.0
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/.gitignore +5 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +236 -0
- data/Rakefile +9 -0
- data/lib/windstorm.rb +12 -0
- data/lib/windstorm/executor.rb +88 -0
- data/lib/windstorm/machine.rb +254 -0
- data/lib/windstorm/parser.rb +64 -0
- data/lib/windstorm/version.rb +3 -0
- data/spec/fixtures/bf.yml +31 -0
- data/spec/fixtures/invalid.yml +6 -0
- data/spec/fixtures/source.txt +17 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/windstorm/executor_spec.rb +203 -0
- data/spec/windstorm/machine_execute_spec.rb +911 -0
- data/spec/windstorm/machine_spec.rb +571 -0
- data/spec/windstorm/parser_spec.rb +133 -0
- data/windstorm.gemspec +24 -0
- metadata +83 -0
@@ -0,0 +1,571 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require "stringio"
|
4
|
+
|
5
|
+
describe Windstorm::Machine do
|
6
|
+
|
7
|
+
describe '#finish?' do
|
8
|
+
before { @machine = Machine.create([:inc, :inc, :inc]) }
|
9
|
+
it { @machine.finish?.should be_false }
|
10
|
+
it { 2.times{ @machine.add_index }; @machine.finish?.should be_false }
|
11
|
+
it { 3.times{ @machine.add_index }; @machine.finish?.should be_true }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#parse_jump' do
|
15
|
+
context 'normal :jmp and :ret' do
|
16
|
+
before do
|
17
|
+
@coms = [:inc, :jmp, :inc, :ret, :jmp, :dec, :dec, :ret, :pinc]
|
18
|
+
@expect = {1 => 3, 3 => 1, 4 => 7, 7 => 4}
|
19
|
+
@machine = Machine.create(@coms)
|
20
|
+
@machine.parse_jump
|
21
|
+
end
|
22
|
+
it { @machine.jump_table.should == @expect }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'nested :jmp' do
|
26
|
+
before do
|
27
|
+
@coms = [:inc, :jmp, :inc, :jmp, :dec, :dec, :ret, :pinc, :ret]
|
28
|
+
@expect = {3 => 6, 6 => 3, 1 => 8, 8 => 1}
|
29
|
+
@machine = Machine.create(@coms)
|
30
|
+
@machine.parse_jump
|
31
|
+
end
|
32
|
+
it { @machine.jump_table.should == @expect }
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'no :jmp or :ret' do
|
36
|
+
before do
|
37
|
+
@coms = [:inc, :inc, :dec, :dec, :pinc, :pdec]
|
38
|
+
@machine = Machine.create(@coms)
|
39
|
+
@machine.parse_jump
|
40
|
+
end
|
41
|
+
it { @machine.jump_table.should be_empty }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'lack :jmp' do
|
45
|
+
before do
|
46
|
+
@coms = [:inc, :jmp, :inc, :dec, :dec, :ret, :pinc, :ret]
|
47
|
+
@machine = Machine.create(@coms)
|
48
|
+
end
|
49
|
+
it { lambda{ @machine.parse_jump }.should raise_error }
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'lack :ret' do
|
53
|
+
before do
|
54
|
+
@coms = [:inc, :jmp, :inc, :jmp, :dec, :dec, :pinc, :ret]
|
55
|
+
@machine = Machine.create(@coms)
|
56
|
+
end
|
57
|
+
it { lambda{ @machine.parse_jump }.should raise_error }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#jump_index' do
|
62
|
+
before do
|
63
|
+
@machine = Machine.create([:inc,:inc,:inc,:inc,:inc])
|
64
|
+
@machine.add_index
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'strict mode' do
|
68
|
+
context 'in-range' do
|
69
|
+
it { @machine.jump_index(0); @machine.index.should == 0 }
|
70
|
+
it { @machine.jump_index(4); @machine.index.should == 4 }
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'out-range' do
|
74
|
+
it { lambda{ @machine.jump_index(-1) }.should raise_error }
|
75
|
+
it { lambda{ @machine.jump_index(5) }.should raise_error }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'loose mode' do
|
80
|
+
before { @machine.loose = true }
|
81
|
+
|
82
|
+
context 'in-range' do
|
83
|
+
it { @machine.jump_index(0); @machine.index.should == 0 }
|
84
|
+
it { @machine.jump_index(4); @machine.index.should == 4 }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'out-range' do
|
88
|
+
it { @machine.jump_index(-1); @machine.index.should == -1 }
|
89
|
+
it { @machine.jump_index(5); @machine.index.should == 5 }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'invalid index' do
|
94
|
+
it { lambda{ @machine.jump_index(nil) }.should raise_error }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#jump' do
|
99
|
+
def jump_check(ind, rsl)
|
100
|
+
ind.times{ @machine.add_index }
|
101
|
+
|
102
|
+
case rsl
|
103
|
+
when :err
|
104
|
+
lambda{ @machine.jump }.should raise_error
|
105
|
+
else
|
106
|
+
@machine.jump
|
107
|
+
@machine.index.should == rsl
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
before do
|
112
|
+
@coms = [:inc, :jmp, :inc, :jmp, :dec, :dec, :ret, :pinc, :ret]
|
113
|
+
@machine = Machine.create(@coms)
|
114
|
+
@machine.parse_jump
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'exist index in table' do
|
118
|
+
it { jump_check(1, 8) }
|
119
|
+
it { jump_check(3, 6) }
|
120
|
+
it { jump_check(6, 3) }
|
121
|
+
it { jump_check(8, 1) }
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'non exist index in table' do
|
125
|
+
it { jump_check(0, :err) }
|
126
|
+
it { jump_check(4, :err) }
|
127
|
+
it { jump_check(9, :err) }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#size' do
|
132
|
+
before do
|
133
|
+
@machine = Machine.new
|
134
|
+
@default = BUFFER_DEFAULT_SIZE
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'set size' do
|
138
|
+
it { @machine.size = 200; @machine.size.should == 200 }
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'default size if not seted' do
|
142
|
+
it { @machine.size.should == @default }
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'default size if invalid size set' do
|
146
|
+
it { @machine.size = -1; @machine.size.should == @default }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '#move_point_inc' do
|
151
|
+
before do
|
152
|
+
@machine = Machine.new
|
153
|
+
@size = 10
|
154
|
+
@machine.size = @size
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'strict mode' do
|
158
|
+
it 'in-range' do
|
159
|
+
(0...(@size-1)).each do |i|
|
160
|
+
@machine.move_point_inc
|
161
|
+
@machine.point.should == i+1
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'out-range' do
|
166
|
+
before do
|
167
|
+
(@size-1).times { @machine.move_point_inc }
|
168
|
+
end
|
169
|
+
it { lambda { @machine.move_point_inc }.should raise_error }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'loose mode' do
|
174
|
+
before { @machine.loose = true }
|
175
|
+
|
176
|
+
it 'in-range' do
|
177
|
+
(0...(@size-1)).each do |i|
|
178
|
+
@machine.move_point_inc
|
179
|
+
@machine.point.should == i+1
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'out-range' do
|
184
|
+
before do
|
185
|
+
(@size-1).times { @machine.move_point_inc }
|
186
|
+
end
|
187
|
+
it { @machine.move_point_inc; @machine.point.should == @size }
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe '#move_point_dec' do
|
193
|
+
before do
|
194
|
+
@machine = Machine.new
|
195
|
+
@size = 10
|
196
|
+
@machine.size = @size
|
197
|
+
(@size-1).times { @machine.move_point_inc }
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'strict mode' do
|
201
|
+
it 'in-range' do
|
202
|
+
(0...(@size-1)).each do |i|
|
203
|
+
@machine.move_point_dec
|
204
|
+
@machine.point.should == @size - 2 - i
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'out-range' do
|
209
|
+
before { (@size-1).times { @machine.move_point_dec } }
|
210
|
+
it { lambda { @machine.move_point_dec }.should raise_error }
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'loose mode' do
|
215
|
+
before { @machine.loose = true }
|
216
|
+
|
217
|
+
it 'in-range' do
|
218
|
+
(0...(@size-1)).each do |i|
|
219
|
+
@machine.move_point_dec
|
220
|
+
@machine.point.should == @size - 2 - i
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context 'out-range' do
|
225
|
+
before do
|
226
|
+
(@size-1).times { @machine.move_point_dec }
|
227
|
+
end
|
228
|
+
it { @machine.move_point_dec; @machine.point.should == -1 }
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe '#value' do
|
234
|
+
before do
|
235
|
+
@machine = Machine.new
|
236
|
+
@size = 10
|
237
|
+
@machine.size = @size
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'strict mode' do
|
241
|
+
context 'default value is 0' do
|
242
|
+
it do
|
243
|
+
(@size-1).times do
|
244
|
+
@machine.value.should == 0
|
245
|
+
@machine.move_point_inc
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
it do
|
250
|
+
(@size-1).times do |i|
|
251
|
+
@machine.value(i).should == 0
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
context 'over point' do
|
257
|
+
it { lambda{ @machine.value(-1) }.should raise_error }
|
258
|
+
it { lambda{ @machine.value(@size) }.should raise_error }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
context 'loose mode' do
|
263
|
+
before { @machine.loose = true }
|
264
|
+
|
265
|
+
context 'default value is 0' do
|
266
|
+
it do
|
267
|
+
(@size-1).times do
|
268
|
+
@machine.value.should == 0
|
269
|
+
@machine.move_point_inc
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
it do
|
274
|
+
(@size-1).times do |i|
|
275
|
+
@machine.value(i).should == 0
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
context 'over point' do
|
281
|
+
it { lambda{ @machine.value(-1) }.should_not raise_error }
|
282
|
+
it { lambda{ @machine.value(@size) }.should_not raise_error }
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
describe '#replace_value' do
|
288
|
+
before do
|
289
|
+
@machine = Machine.new
|
290
|
+
@size = 10
|
291
|
+
@machine.size = @size
|
292
|
+
end
|
293
|
+
|
294
|
+
context 'strict mode' do
|
295
|
+
context 'in-range' do
|
296
|
+
it do
|
297
|
+
(@size-1).times do |i|
|
298
|
+
@machine.replace_value(i+1).should == i+1
|
299
|
+
@machine.value.should == i+1
|
300
|
+
@machine.move_point_inc
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
it do
|
305
|
+
(@size-1).times do |i|
|
306
|
+
@machine.replace_value(i+1, i).should == i+1
|
307
|
+
@machine.value(i).should == i+1
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context 'out-range' do
|
313
|
+
it { lambda{ @machine.replace_value(1, -1)}.should raise_error }
|
314
|
+
it { lambda{ @machine.replace_value(1, @size)}.should raise_error }
|
315
|
+
end
|
316
|
+
|
317
|
+
context 'value under 0' do
|
318
|
+
it { lambda{ @machine.replace_value(-1)}.should raise_error }
|
319
|
+
it { lambda{ @machine.replace_value(-1, 1)}.should raise_error }
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'loose mode' do
|
324
|
+
before { @machine.loose = true }
|
325
|
+
|
326
|
+
context 'in-range' do
|
327
|
+
it do
|
328
|
+
(@size-1).times do |i|
|
329
|
+
@machine.replace_value(i+1).should == i+1
|
330
|
+
@machine.value.should == i+1
|
331
|
+
@machine.move_point_inc
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
it do
|
336
|
+
(@size-1).times do |i|
|
337
|
+
@machine.replace_value(i+1, i).should == i+1
|
338
|
+
@machine.value(i).should == i+1
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
context 'out-range' do
|
344
|
+
it { lambda{ @machine.replace_value(1, -1)}.should raise_error(IndexError) }
|
345
|
+
it { lambda{ @machine.replace_value(1, @size)}.should_not raise_error }
|
346
|
+
end
|
347
|
+
|
348
|
+
context 'value under 0' do
|
349
|
+
it { lambda{ @machine.replace_value(-1)}.should_not raise_error }
|
350
|
+
it { lambda{ @machine.replace_value(-1, 1)}.should_not raise_error }
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe '#increment' do
|
356
|
+
before { @machine = Machine.new }
|
357
|
+
|
358
|
+
it 'increment value' do
|
359
|
+
10.times do |i|
|
360
|
+
@machine.increment
|
361
|
+
@machine.value.should == i+1
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context 'another point' do
|
366
|
+
before do
|
367
|
+
2.times { @machine.increment }
|
368
|
+
@machine.move_point_inc
|
369
|
+
4.times { @machine.increment }
|
370
|
+
end
|
371
|
+
it { @machine.value(0).should == 2 }
|
372
|
+
it { @machine.value(1).should == 4 }
|
373
|
+
it { @machine.value(2).should == 0 }
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
describe '#decrement' do
|
378
|
+
before do
|
379
|
+
@machine = Machine.new
|
380
|
+
5.times{ @machine.increment }
|
381
|
+
@machine.move_point_inc
|
382
|
+
5.times{ @machine.increment }
|
383
|
+
@machine.move_point_dec
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'decrement value' do
|
387
|
+
5.times do |i|
|
388
|
+
@machine.decrement
|
389
|
+
@machine.value.should == 4 - i
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
context 'another point' do
|
394
|
+
before do
|
395
|
+
2.times { @machine.decrement }
|
396
|
+
@machine.move_point_inc
|
397
|
+
4.times { @machine.decrement }
|
398
|
+
end
|
399
|
+
it { @machine.value(0).should == 3 }
|
400
|
+
it { @machine.value(1).should == 1 }
|
401
|
+
it { @machine.value(2).should == 0 }
|
402
|
+
end
|
403
|
+
|
404
|
+
context 'value under 0' do
|
405
|
+
before do
|
406
|
+
5.times { @machine.decrement }
|
407
|
+
end
|
408
|
+
|
409
|
+
context 'strict mode' do
|
410
|
+
it { lambda { @machine.decrement }.should raise_error }
|
411
|
+
end
|
412
|
+
|
413
|
+
context 'loose mode' do
|
414
|
+
before { @machine.loose = true }
|
415
|
+
it { @machine.decrement; @machine.value.should == -1 }
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
describe '#output' do
|
421
|
+
before do
|
422
|
+
@out = StringIO.new
|
423
|
+
@org_out = $stdout
|
424
|
+
$stdout = @out
|
425
|
+
@machine = Machine.new
|
426
|
+
end
|
427
|
+
|
428
|
+
context 'normal mode' do
|
429
|
+
it do
|
430
|
+
'a'.bytes.first.times{ @machine.increment }
|
431
|
+
@machine.output
|
432
|
+
@machine.cache.should == 'a'
|
433
|
+
@machine.result.should == 'a'
|
434
|
+
@out.string.should be_empty
|
435
|
+
|
436
|
+
@machine.increment
|
437
|
+
@machine.output
|
438
|
+
@machine.cache.should == 'ab'
|
439
|
+
@machine.result.should == 'ab'
|
440
|
+
@out.string.should be_empty
|
441
|
+
|
442
|
+
@machine.decrement
|
443
|
+
@machine.output
|
444
|
+
@machine.cache.should == 'aba'
|
445
|
+
@machine.result.should == 'aba'
|
446
|
+
@out.string.should be_empty
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
context 'flash mode' do
|
451
|
+
before { @machine.flash = true }
|
452
|
+
|
453
|
+
it do
|
454
|
+
'a'.bytes.first.times{ @machine.increment }
|
455
|
+
@machine.output
|
456
|
+
@machine.cache.should == 'a'
|
457
|
+
@machine.result.should == 'a'
|
458
|
+
@out.string.should == 'a'
|
459
|
+
|
460
|
+
@machine.increment
|
461
|
+
@machine.output
|
462
|
+
@machine.cache.should == 'ab'
|
463
|
+
@machine.result.should == 'ab'
|
464
|
+
@out.string.should == 'ab'
|
465
|
+
|
466
|
+
@machine.decrement
|
467
|
+
@machine.output
|
468
|
+
@machine.cache.should == 'aba'
|
469
|
+
@machine.result.should == 'aba'
|
470
|
+
@out.string.should == 'aba'
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
after { $stdout = @org_out }
|
475
|
+
end
|
476
|
+
|
477
|
+
describe '#input' do
|
478
|
+
before do
|
479
|
+
@in = StringIO.new('aba')
|
480
|
+
@org_in = $stdin
|
481
|
+
$stdin = @in
|
482
|
+
@machine = Machine.new
|
483
|
+
end
|
484
|
+
|
485
|
+
it do
|
486
|
+
@machine.input
|
487
|
+
@machine.value.should == 'a'.bytes.first
|
488
|
+
@machine.value(0).should == 'a'.bytes.first
|
489
|
+
|
490
|
+
@machine.input
|
491
|
+
@machine.value.should == 'b'.bytes.first
|
492
|
+
@machine.value(0).should == 'b'.bytes.first
|
493
|
+
|
494
|
+
@machine.move_point_inc
|
495
|
+
@machine.input
|
496
|
+
@machine.value.should == 'a'.bytes.first
|
497
|
+
@machine.value(0).should == 'b'.bytes.first
|
498
|
+
@machine.value(1).should == 'a'.bytes.first
|
499
|
+
end
|
500
|
+
|
501
|
+
after { $stdin = @org_in }
|
502
|
+
end
|
503
|
+
|
504
|
+
describe '#clip_value/#replace_clip_value' do
|
505
|
+
before { @machine = Machine.new }
|
506
|
+
|
507
|
+
context 'strict mode' do
|
508
|
+
context 'return 0 if not cliped' do
|
509
|
+
it { @machine.clip_value.should == 0 }
|
510
|
+
end
|
511
|
+
|
512
|
+
context 'clip and get' do
|
513
|
+
context 'valid value' do
|
514
|
+
it do
|
515
|
+
@machine.replace_clip_value(10).should == 10
|
516
|
+
@machine.clip_value.should == 10
|
517
|
+
@machine.clip_value.should == 10
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
context 'value under 0' do
|
522
|
+
it { lambda{ @machine.replace_clip_value(-1) }.should raise_error }
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
context 'overwrite value' do
|
527
|
+
it do
|
528
|
+
@machine.replace_clip_value(10).should == 10
|
529
|
+
@machine.clip_value.should == 10
|
530
|
+
@machine.replace_clip_value(20).should == 20
|
531
|
+
@machine.clip_value.should == 20
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
context 'loose mode' do
|
537
|
+
before { @machine.loose = true }
|
538
|
+
|
539
|
+
context 'return 0 if not cliped' do
|
540
|
+
it { @machine.clip_value.should == 0 }
|
541
|
+
end
|
542
|
+
|
543
|
+
context 'clip and get' do
|
544
|
+
context 'valid value' do
|
545
|
+
it do
|
546
|
+
@machine.replace_clip_value(10).should == 10
|
547
|
+
@machine.clip_value.should == 10
|
548
|
+
@machine.clip_value.should == 10
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
context 'value under 0' do
|
553
|
+
it do
|
554
|
+
@machine.replace_clip_value(-1).should == -1
|
555
|
+
@machine.clip_value.should == -1
|
556
|
+
end
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
context 'overwrite value' do
|
561
|
+
it do
|
562
|
+
@machine.replace_clip_value(10).should == 10
|
563
|
+
@machine.clip_value.should == 10
|
564
|
+
@machine.replace_clip_value(20).should == 20
|
565
|
+
@machine.clip_value.should == 20
|
566
|
+
end
|
567
|
+
end
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
end
|