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.
@@ -0,0 +1,64 @@
1
+ # coding: utf-8
2
+ module Windstorm
3
+ class Parser
4
+
5
+ class << self
6
+
7
+ def create(t)
8
+ ps = self.new
9
+ ps.table = t
10
+ ps
11
+ end
12
+
13
+ end
14
+
15
+ def table=(t)
16
+ raise 'definition blank' if t.nil? || t.empty?
17
+ @table = {}
18
+ COMMANDS.each do |c|
19
+ li = [t[c]].flatten.compact.uniq
20
+ next if li.empty?
21
+ @table[c] = li
22
+ end
23
+ raise 'definition not found' if @table.empty?
24
+ @dict = nil
25
+ @table
26
+ end
27
+
28
+ def table
29
+ raise 'definition not found' if @table.nil? || @table.empty?
30
+ @table
31
+ end
32
+
33
+ def dict
34
+ @dict ||= lambda do
35
+ dic = {}
36
+ table.each do |c, s|
37
+ [s].flatten.each{|t| dic[t] = c}
38
+ end
39
+ dic
40
+ end.call
41
+ @dict
42
+ end
43
+
44
+ def filter(source)
45
+ return [] unless source
46
+ reg = /#{dict.keys.map{|k| Regexp.escape(k)}.join('|')}/
47
+ ret = []
48
+ source.lines do |l|
49
+ next if l.start_with?('#') || l.start_with?('//')
50
+ ret << l.scan(reg).flatten
51
+ end
52
+ ret.flatten
53
+ end
54
+
55
+ def convert(fs)
56
+ [fs].flatten.map{|s| dict[s]}.compact
57
+ end
58
+
59
+ def build(source)
60
+ convert(filter(source))
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module Windstorm
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,31 @@
1
+ ---
2
+ :pinc:
3
+ - ! '>'
4
+ - 'a'
5
+ :pdec:
6
+ - '<'
7
+ - 'b'
8
+ :inc:
9
+ - '+'
10
+ - 'c'
11
+ :dec:
12
+ - ! '-'
13
+ - 'd'
14
+ :out:
15
+ - '.'
16
+ - 'e'
17
+ :inp:
18
+ - ! ','
19
+ - 'f'
20
+ :jmp:
21
+ - ! '['
22
+ - 'g'
23
+ :ret:
24
+ - ! ']'
25
+ - 'h'
26
+ :clip:
27
+ - '%'
28
+ - 'i'
29
+ :paste:
30
+ - '&'
31
+ - 'j'
@@ -0,0 +1,6 @@
1
+ ---
2
+ :hoge:
3
+ - 'a'
4
+ - 'b'
5
+ :piyo:
6
+ - 'c'
@@ -0,0 +1,17 @@
1
+ # cccccccccccc
2
+ acccccccccc
3
+ // cccdddccc
4
+ gxznbrull
5
+ cccccccccc
6
+ q@lopamnlkdwwwwwwh
7
+ bropki
8
+ |||||c|||||e~~~~~
9
+ a1c2c3c4
10
+ 5g6b7
11
+ 00000000000c=====c######c//////
12
+ zzzzzzzzzzzayyyyyyyyyydxxxxxxxxhwwwwww
13
+ qbe
14
+ #### コメントですよ
15
+ jez
16
+ (´・ω・`)
17
+ おわり
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'windstorm'
5
+
6
+ include Windstorm
7
+
8
+ # Requires supporting files with custom matchers and macros, etc,
9
+ # in ./support/ and its subdirectories.
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
11
+
12
+ RSpec.configure do |config|
13
+ config.color_enabled = true
14
+ end
@@ -0,0 +1,203 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ FIXTURES_PATH = File.join(File.dirname(__FILE__), '..', 'fixtures')
5
+
6
+ def file_from_fixtures(file)
7
+ File.join(FIXTURES_PATH, file)
8
+ end
9
+
10
+ describe Windstorm::Executor do
11
+
12
+ describe '.create' do
13
+ context 'with parser' do
14
+ before do
15
+ @table = {:inc => ['a', 'z'], :dec => ['b']}
16
+ @parser = Parser.create(@table)
17
+ end
18
+
19
+ subject { Executor.create(@parser) }
20
+
21
+ its(:parser){ should == @parser }
22
+ it { subject.parser.table.should == @table }
23
+ end
24
+
25
+ context 'given nil' do
26
+ it { Executor.create(nil).should be_nil }
27
+ end
28
+ end
29
+
30
+ describe '.create_from_table' do
31
+ context 'with table' do
32
+ before { @table = {:inc => ['a', 'z'], :dec => ['b']} }
33
+ subject { Executor.create_from_table(@table) }
34
+ it { subject.parser.table.should == @table }
35
+ end
36
+
37
+ context 'invalid table' do
38
+ before { @table = {:hoge => 'a'} }
39
+ it { lambda{ Executor.create_from_table(@table) }.should raise_error }
40
+ end
41
+
42
+ context 'given nil' do
43
+ it { lambda{ Executor.create_from_table(nil) }.should raise_error }
44
+ end
45
+ end
46
+
47
+ describe '.create_from_file' do
48
+ context 'with file' do
49
+ before do
50
+ @file = file_from_fixtures('bf.yml')
51
+ @expect = YAML.load(File.read(@file))
52
+ end
53
+
54
+ subject { Executor.create_from_file(@file) }
55
+ it { subject.parser.table.should == @expect }
56
+ end
57
+
58
+ context 'file not found' do
59
+ it { lambda{ Executor.create_from_file('hogepiyo') }.should raise_error }
60
+ end
61
+
62
+ context 'invalid definition' do
63
+ it { lambda{ Executor.create_from_file(file_from_fixtures('invalid.yml')) }.should raise_error }
64
+ end
65
+ end
66
+
67
+ describe '#parser' do
68
+ context 'parser not seted' do
69
+ it { lambda{ Executor.new.parser }.should raise_error }
70
+ end
71
+ end
72
+
73
+ describe 'instance method' do
74
+ before do
75
+ @exec = Executor.create_from_file(file_from_fixtures('bf.yml'))
76
+ @source_file = file_from_fixtures('source.txt')
77
+ end
78
+
79
+ describe '#filter' do
80
+ it { @exec.filter('steins gate').should == ['e', 'i', 'g', 'a', 'e'] }
81
+ end
82
+
83
+ describe '#filter_from_file' do
84
+ it { @exec.filter_from_file(@source_file).should_not be_empty }
85
+ end
86
+
87
+ describe '#build' do
88
+ it { @exec.build('steins gate').should == [:out, :clip, :jmp, :pinc, :out] }
89
+ end
90
+
91
+ describe '#build_from_file' do
92
+ it { @exec.build_from_file(@source_file).should_not be_empty }
93
+ end
94
+
95
+ describe 'each execute method' do
96
+ before do
97
+ @out = StringIO.new
98
+ @org_out = $stdout
99
+ $stdout = @out
100
+
101
+ @source = @exec.filter_from_file(@source_file).join('')
102
+ end
103
+
104
+ describe '#execute' do
105
+ context 'non params' do
106
+ it { @exec.execute(@source).should == 'end' }
107
+ end
108
+
109
+ context 'with params' do
110
+ before { @exec.execute(@source, :flash => true) }
111
+ it { @out.string.should == 'end' }
112
+ end
113
+ end
114
+
115
+ describe '#execute_from_file' do
116
+ context 'non params' do
117
+ it { @exec.execute_from_file(@source_file).should == 'end' }
118
+ end
119
+
120
+ context 'with params' do
121
+ before { @exec.execute_from_file(@source_file, :flash => true) }
122
+ it { @out.string.should == 'end' }
123
+ end
124
+ end
125
+
126
+ describe '#machine' do
127
+ context 'not executed yet' do
128
+ it { lambda{ @exec.machine }.should raise_error }
129
+ end
130
+
131
+ context 'executed machine' do
132
+ before { @exec.execute(@source) }
133
+ subject{ @exec.machine }
134
+ it { should be_instance_of(Machine) }
135
+ its(:result){ should == 'end' }
136
+ end
137
+ end
138
+
139
+ describe '#debug_execute' do
140
+ context 'non params' do
141
+ before do
142
+ @result = @exec.debug_execute(@source)
143
+ @lines = @out.string.each_line.to_a
144
+ @jump = @lines.delete_at(0) # "jump table"
145
+ @lines.shift # jump table data
146
+ end
147
+ it { @result.should == 'end' }
148
+ it { @jump.should match(/\Ajump/) }
149
+ it 'only debug outout in normal-mode' do
150
+ @lines.all?{|l| l.match(/\Astep:/)}.should be_true
151
+ end
152
+ end
153
+
154
+ context 'with params' do
155
+ before do
156
+ @result = @exec.debug_execute(@source, :flash => true)
157
+ @lines = @out.string.each_line.to_a
158
+ @jump = @lines.delete_at(0) # "jump table"
159
+ @lines.shift # jump table data
160
+ end
161
+ it { @result.should == 'end' }
162
+ it { @jump.should match(/\Ajump/) }
163
+ it 'each "e","n","d" include output in flash-mode' do
164
+ @lines.all?{|l| l.match(/\Astep:/)}.should be_false
165
+ end
166
+ end
167
+ end
168
+
169
+ describe '#debug_execute_from_file' do
170
+ context 'non params' do
171
+ before do
172
+ @result = @exec.debug_execute_from_file(@source_file)
173
+ @lines = @out.string.each_line.to_a
174
+ @jump = @lines.delete_at(0) # "jump table"
175
+ @lines.shift # jump table data
176
+ end
177
+ it { @result.should == 'end' }
178
+ it { @jump.should match(/\Ajump/) }
179
+ it 'only debug outout in normal-mode' do
180
+ @lines.all?{|l| l.match(/\Astep:/)}.should be_true
181
+ end
182
+ end
183
+
184
+ context 'with params' do
185
+ before do
186
+ @result = @exec.debug_execute_from_file(@source_file, :flash => true)
187
+ @lines = @out.string.each_line.to_a
188
+ @jump = @lines.delete_at(0) # "jump table"
189
+ @lines.shift # jump table data
190
+ end
191
+ it { @result.should == 'end' }
192
+ it { @jump.should match(/\Ajump/) }
193
+ it 'each "e","n","d" include output in flash-mode' do
194
+ @lines.all?{|l| l.match(/\Astep:/)}.should be_false
195
+ end
196
+ end
197
+ end
198
+
199
+ after { $stdout = @org_out }
200
+ end
201
+ end
202
+
203
+ end
@@ -0,0 +1,911 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+ require 'stringio'
4
+
5
+ describe Windstorm::Machine do
6
+
7
+ describe '#step_execute' do
8
+ before do
9
+ @machine = Machine.new
10
+ @size = 10
11
+ @machine.size = @size
12
+ end
13
+
14
+ describe ':pinc' do
15
+ context 'in-range' do
16
+ before { @machine.commands = [:pinc, :pinc, :pinc] }
17
+
18
+ it do
19
+ @machine.step.should == 0
20
+ @machine.index.should == 0
21
+ @machine.point.should == 0
22
+ @machine.buffer.should be_empty
23
+ @machine.clip_value.should == 0
24
+ @machine.result.should be_empty
25
+
26
+ 3.times do |i|
27
+ @machine.step_execute
28
+
29
+ @machine.step.should == i+1
30
+ @machine.index.should == i+1
31
+ @machine.point.should == i+1
32
+ @machine.buffer.should be_empty
33
+ @machine.clip_value.should == 0
34
+ @machine.result.should be_empty
35
+ end
36
+
37
+ @machine.should be_finish
38
+ end
39
+ end
40
+
41
+ context 'out-range' do
42
+ before do
43
+ @machine.commands = [:pinc] * @size
44
+ (@size - 1).times{ @machine.step_execute }
45
+ end
46
+
47
+ context 'strict mode' do
48
+ it { lambda{ @machine.step_execute }.should raise_error }
49
+ end
50
+
51
+ context 'loose mode' do
52
+ before { @machine.loose = true }
53
+
54
+ it do
55
+ @machine.step_execute
56
+
57
+ @machine.step.should == @size
58
+ @machine.index.should == @size
59
+ @machine.point.should == @size
60
+ @machine.buffer.should be_empty
61
+ @machine.clip_value.should == 0
62
+ @machine.result.should be_empty
63
+
64
+ @machine.should be_finish
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ describe ':pdec' do
71
+ context 'in-range' do
72
+ before do
73
+ @machine.commands = [:pinc] * 3 + [:pdec] * 3
74
+ 3.times { @machine.step_execute }
75
+ end
76
+
77
+ it do
78
+ @machine.step.should == 3
79
+ @machine.index.should == 3
80
+ @machine.point.should == 3
81
+ @machine.buffer.should be_empty
82
+ @machine.clip_value.should == 0
83
+ @machine.result.should be_empty
84
+
85
+ 3.times do |i|
86
+ @machine.step_execute
87
+
88
+ @machine.step.should == i+4
89
+ @machine.index.should == i+4
90
+ @machine.point.should == 2-i
91
+ @machine.buffer.should be_empty
92
+ @machine.clip_value.should == 0
93
+ @machine.result.should be_empty
94
+ end
95
+
96
+ @machine.should be_finish
97
+ end
98
+ end
99
+
100
+ context 'out-range' do
101
+ before do
102
+ @machine.commands = [:pinc] * 2 + [:pdec] * 3
103
+ 4.times{ @machine.step_execute }
104
+ end
105
+
106
+ context 'strict mode' do
107
+ it { lambda{ @machine.step_execute }.should raise_error }
108
+ end
109
+
110
+ context 'loose mode' do
111
+ before { @machine.loose = true }
112
+
113
+ it do
114
+ @machine.step_execute
115
+
116
+ @machine.step.should == 5
117
+ @machine.index.should == 5
118
+ @machine.point.should == -1
119
+ @machine.buffer.should be_empty
120
+ @machine.clip_value.should == 0
121
+ @machine.result.should be_empty
122
+
123
+ @machine.should be_finish
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ describe ':inc' do
130
+ before { @machine.commands = [:inc, :inc, :pinc, :inc, :pdec, :inc] }
131
+
132
+ it do
133
+ @machine.step.should == 0
134
+ @machine.index.should == 0
135
+ @machine.point.should == 0
136
+ @machine.buffer.should be_empty
137
+ @machine.clip_value.should == 0
138
+ @machine.result.should be_empty
139
+
140
+ 2.times do |i|
141
+ @machine.step_execute
142
+
143
+ @machine.step.should == i+1
144
+ @machine.index.should == i+1
145
+ @machine.point.should == 0
146
+ @machine.buffer.should == [i+1]
147
+ @machine.clip_value.should == 0
148
+ @machine.result.should be_empty
149
+ end
150
+
151
+ @machine.step_execute
152
+
153
+ @machine.step.should == 3
154
+ @machine.index.should == 3
155
+ @machine.point.should == 1
156
+ @machine.buffer.should == [2]
157
+ @machine.clip_value.should == 0
158
+ @machine.result.should be_empty
159
+
160
+ @machine.step_execute
161
+
162
+ @machine.step.should == 4
163
+ @machine.index.should == 4
164
+ @machine.point.should == 1
165
+ @machine.buffer.should == [2, 1]
166
+ @machine.clip_value.should == 0
167
+ @machine.result.should be_empty
168
+
169
+ @machine.step_execute
170
+
171
+ @machine.step.should == 5
172
+ @machine.index.should == 5
173
+ @machine.point.should == 0
174
+ @machine.buffer.should == [2, 1]
175
+ @machine.clip_value.should == 0
176
+ @machine.result.should be_empty
177
+
178
+ @machine.step_execute
179
+
180
+ @machine.step.should == 6
181
+ @machine.index.should == 6
182
+ @machine.point.should == 0
183
+ @machine.buffer.should == [3, 1]
184
+ @machine.clip_value.should == 0
185
+ @machine.result.should be_empty
186
+
187
+ @machine.should be_finish
188
+ end
189
+ end
190
+
191
+ describe ':dec' do
192
+ context 'in-range' do
193
+ before do
194
+ com_init = [:inc, :inc, :inc, :pinc] * 3 + [:pdec] * 3
195
+ com = com_init + [:dec, :pinc, :dec, :dec, :pdec, :dec ]
196
+ @init_size = com_init.size
197
+ @machine.commands = com
198
+ @init_size.times{ @machine.step_execute }
199
+ end
200
+
201
+ it do
202
+ @machine.step.should == @init_size
203
+ @machine.index.should == @init_size
204
+ @machine.point.should == 0
205
+ @machine.buffer.should == [3, 3, 3]
206
+ @machine.clip_value.should == 0
207
+ @machine.result.should be_empty
208
+
209
+ @machine.step_execute
210
+
211
+ @machine.step.should == @init_size + 1
212
+ @machine.index.should == @init_size + 1
213
+ @machine.point.should == 0
214
+ @machine.buffer.should == [2, 3, 3]
215
+ @machine.clip_value.should == 0
216
+ @machine.result.should be_empty
217
+
218
+ @machine.step_execute
219
+
220
+ @machine.step.should == @init_size + 2
221
+ @machine.index.should == @init_size + 2
222
+ @machine.point.should == 1
223
+ @machine.buffer.should == [2, 3, 3]
224
+ @machine.clip_value.should == 0
225
+ @machine.result.should be_empty
226
+
227
+ 2.times do |i|
228
+ @machine.step_execute
229
+
230
+ @machine.step.should == @init_size + 3 + i
231
+ @machine.index.should == @init_size + 3 + i
232
+ @machine.point.should == 1
233
+ @machine.buffer.should == [2, 2 - i, 3]
234
+ @machine.clip_value.should == 0
235
+ @machine.result.should be_empty
236
+ end
237
+
238
+ @machine.step_execute
239
+
240
+ @machine.step.should == @init_size + 5
241
+ @machine.index.should == @init_size + 5
242
+ @machine.point.should == 0
243
+ @machine.buffer.should == [2, 1, 3]
244
+ @machine.clip_value.should == 0
245
+ @machine.result.should be_empty
246
+
247
+ @machine.step_execute
248
+
249
+ @machine.step.should == @init_size + 6
250
+ @machine.index.should == @init_size + 6
251
+ @machine.point.should == 0
252
+ @machine.buffer.should == [1, 1, 3]
253
+ @machine.clip_value.should == 0
254
+ @machine.result.should be_empty
255
+
256
+ @machine.should be_finish
257
+ end
258
+ end
259
+
260
+ context 'out-range' do
261
+ before do
262
+ @machine.commands = [:inc] * 2 + [:dec] * 3
263
+ 4.times{ @machine.step_execute }
264
+ end
265
+
266
+ context 'strict mode' do
267
+ it { lambda{ @machine.step_execute }.should raise_error }
268
+ end
269
+
270
+ context 'loose mode' do
271
+ before { @machine.loose = true }
272
+
273
+ it do
274
+ @machine.step_execute
275
+
276
+ @machine.step.should == 5
277
+ @machine.index.should == 5
278
+ @machine.point.should == 0
279
+ @machine.buffer.should == [-1]
280
+ @machine.clip_value.should == 0
281
+ @machine.result.should be_empty
282
+
283
+ @machine.should be_finish
284
+ end
285
+ end
286
+ end
287
+ end
288
+
289
+ describe ':out' do
290
+ before(:all) do
291
+ @out = StringIO.new
292
+ @org_out = $stdout
293
+ $stdout = @out
294
+ end
295
+
296
+ before do
297
+ @num_a = 'a'.bytes.first
298
+ com_init = [:inc] * @num_a
299
+ com = com_init + [:out, :inc, :out, :dec, :out]
300
+ @machine.commands = com
301
+ @num_a.times{ @machine.step_execute }
302
+ end
303
+
304
+ context 'normal mode' do
305
+ it do
306
+ @machine.step.should == @num_a
307
+ @machine.index.should == @num_a
308
+ @machine.point.should == 0
309
+ @machine.buffer.should == [@num_a]
310
+ @machine.clip_value.should == 0
311
+ @machine.result.should be_empty
312
+ @out.string.should be_empty
313
+
314
+ @machine.step_execute
315
+
316
+ @machine.step.should == @num_a + 1
317
+ @machine.index.should == @num_a + 1
318
+ @machine.point.should == 0
319
+ @machine.buffer.should == [@num_a]
320
+ @machine.clip_value.should == 0
321
+ @machine.result.should == 'a'
322
+ @out.string.should be_empty
323
+
324
+ @machine.step_execute
325
+
326
+ @machine.step.should == @num_a + 2
327
+ @machine.index.should == @num_a + 2
328
+ @machine.point.should == 0
329
+ @machine.buffer.should == [@num_a+1]
330
+ @machine.clip_value.should == 0
331
+ @machine.result.should == 'a'
332
+ @out.string.should be_empty
333
+
334
+ @machine.step_execute
335
+
336
+ @machine.step.should == @num_a + 3
337
+ @machine.index.should == @num_a + 3
338
+ @machine.point.should == 0
339
+ @machine.buffer.should == [@num_a+1]
340
+ @machine.clip_value.should == 0
341
+ @machine.result.should == 'ab'
342
+ @out.string.should be_empty
343
+
344
+ @machine.step_execute
345
+
346
+ @machine.step.should == @num_a + 4
347
+ @machine.index.should == @num_a + 4
348
+ @machine.point.should == 0
349
+ @machine.buffer.should == [@num_a]
350
+ @machine.clip_value.should == 0
351
+ @machine.result.should == 'ab'
352
+ @out.string.should be_empty
353
+
354
+ @machine.step_execute
355
+
356
+ @machine.step.should == @num_a + 5
357
+ @machine.index.should == @num_a + 5
358
+ @machine.point.should == 0
359
+ @machine.buffer.should == [@num_a]
360
+ @machine.clip_value.should == 0
361
+ @machine.result.should == 'aba'
362
+ @out.string.should be_empty
363
+
364
+ @machine.should be_finish
365
+ end
366
+ end
367
+
368
+ context 'flash mode' do
369
+ before{ @machine.flash = true }
370
+
371
+ it do
372
+ @machine.step.should == @num_a
373
+ @machine.index.should == @num_a
374
+ @machine.point.should == 0
375
+ @machine.buffer.should == [@num_a]
376
+ @machine.clip_value.should == 0
377
+ @machine.result.should be_empty
378
+ @out.string.should be_empty
379
+
380
+ @machine.step_execute
381
+
382
+ @machine.step.should == @num_a + 1
383
+ @machine.index.should == @num_a + 1
384
+ @machine.point.should == 0
385
+ @machine.buffer.should == [@num_a]
386
+ @machine.clip_value.should == 0
387
+ @machine.result.should == 'a'
388
+ @out.string.should == 'a'
389
+
390
+ @machine.step_execute
391
+
392
+ @machine.step.should == @num_a + 2
393
+ @machine.index.should == @num_a + 2
394
+ @machine.point.should == 0
395
+ @machine.buffer.should == [@num_a+1]
396
+ @machine.clip_value.should == 0
397
+ @machine.result.should == 'a'
398
+ @out.string.should == 'a'
399
+
400
+ @machine.step_execute
401
+
402
+ @machine.step.should == @num_a + 3
403
+ @machine.index.should == @num_a + 3
404
+ @machine.point.should == 0
405
+ @machine.buffer.should == [@num_a+1]
406
+ @machine.clip_value.should == 0
407
+ @machine.result.should == 'ab'
408
+ @out.string.should == 'ab'
409
+
410
+ @machine.step_execute
411
+
412
+ @machine.step.should == @num_a + 4
413
+ @machine.index.should == @num_a + 4
414
+ @machine.point.should == 0
415
+ @machine.buffer.should == [@num_a]
416
+ @machine.clip_value.should == 0
417
+ @machine.result.should == 'ab'
418
+ @out.string.should == 'ab'
419
+
420
+ @machine.step_execute
421
+
422
+ @machine.step.should == @num_a + 5
423
+ @machine.index.should == @num_a + 5
424
+ @machine.point.should == 0
425
+ @machine.buffer.should == [@num_a]
426
+ @machine.clip_value.should == 0
427
+ @machine.result.should == 'aba'
428
+ @out.string.should == 'aba'
429
+
430
+ @machine.should be_finish
431
+ end
432
+ end
433
+
434
+ after(:all) { $stdout = @org_out }
435
+ end
436
+
437
+ describe ':inp' do
438
+ before(:all) do
439
+ @in = StringIO.new('orz')
440
+ @org_in = $stdin
441
+ $stdin = @in
442
+ end
443
+
444
+ before do
445
+ @ins = 'orz'.bytes.to_a
446
+ @machine.commands = [:inp, :pinc, :inp, :pinc, :inp, :dec]
447
+ end
448
+
449
+ it do
450
+ @machine.step.should == 0
451
+ @machine.index.should == 0
452
+ @machine.point.should == 0
453
+ @machine.buffer.should be_empty
454
+ @machine.clip_value.should == 0
455
+ @machine.result.should be_empty
456
+
457
+ @machine.step_execute
458
+
459
+ @machine.step.should == 1
460
+ @machine.index.should == 1
461
+ @machine.point.should == 0
462
+ @machine.buffer.should == [@ins[0]]
463
+ @machine.clip_value.should == 0
464
+ @machine.result.should be_empty
465
+
466
+ @machine.step_execute
467
+
468
+ @machine.step.should == 2
469
+ @machine.index.should == 2
470
+ @machine.point.should == 1
471
+ @machine.buffer.should == [@ins[0]]
472
+ @machine.clip_value.should == 0
473
+ @machine.result.should be_empty
474
+
475
+ @machine.step_execute
476
+
477
+ @machine.step.should == 3
478
+ @machine.index.should == 3
479
+ @machine.point.should == 1
480
+ @machine.buffer.should == [@ins[0], @ins[1]]
481
+ @machine.clip_value.should == 0
482
+ @machine.result.should be_empty
483
+
484
+ @machine.step_execute
485
+
486
+ @machine.step.should == 4
487
+ @machine.index.should == 4
488
+ @machine.point.should == 2
489
+ @machine.buffer.should == [@ins[0], @ins[1]]
490
+ @machine.clip_value.should == 0
491
+ @machine.result.should be_empty
492
+
493
+ @machine.step_execute
494
+
495
+ @machine.step.should == 5
496
+ @machine.index.should == 5
497
+ @machine.point.should == 2
498
+ @machine.buffer.should == [@ins[0], @ins[1], @ins[2]]
499
+ @machine.clip_value.should == 0
500
+ @machine.result.should be_empty
501
+
502
+ @machine.step_execute
503
+
504
+ @machine.step.should == 6
505
+ @machine.index.should == 6
506
+ @machine.point.should == 2
507
+ @machine.buffer.should == [@ins[0], @ins[1], @ins[2]-1]
508
+ @machine.clip_value.should == 0
509
+ @machine.result.should be_empty
510
+
511
+ @machine.should be_finish
512
+ end
513
+
514
+ after(:all) { $stdin = @org_in }
515
+ end
516
+
517
+ describe ':jmp/:ret' do
518
+ context 'jump commands' do
519
+ before do
520
+ @machine.commands = [:inc, :dec, :jmp, :inc, :inc, :ret, :inc]
521
+ @machine.parse_jump
522
+ end
523
+
524
+ it do
525
+ @machine.jump_table.should == {2 => 5, 5 => 2}
526
+
527
+ 2.times{ @machine.step_execute }
528
+
529
+ @machine.step.should == 2
530
+ @machine.index.should == 2
531
+ @machine.point.should == 0
532
+ @machine.buffer.should == [0]
533
+ @machine.clip_value.should == 0
534
+ @machine.result.should be_empty
535
+
536
+ @machine.step_execute
537
+
538
+ @machine.step.should == 3
539
+ @machine.index.should == 6
540
+ @machine.point.should == 0
541
+ @machine.buffer.should == [0]
542
+ @machine.clip_value.should == 0
543
+ @machine.result.should be_empty
544
+
545
+ @machine.step_execute
546
+
547
+ @machine.step.should == 4
548
+ @machine.index.should == 7
549
+ @machine.point.should == 0
550
+ @machine.buffer.should == [1]
551
+ @machine.clip_value.should == 0
552
+ @machine.result.should be_empty
553
+
554
+ @machine.should be_finish
555
+ end
556
+ end
557
+
558
+ context 'loop' do
559
+ before do
560
+ @machine.commands = [:inc, :inc, :jmp, :dec, :ret, :inc]
561
+ @machine.parse_jump
562
+ end
563
+
564
+ it do
565
+ @machine.jump_table.should == {2 => 4, 4 => 2}
566
+
567
+ 2.times{ @machine.step_execute }
568
+
569
+ @machine.step.should == 2
570
+ @machine.index.should == 2
571
+ @machine.point.should == 0
572
+ @machine.buffer.should == [2]
573
+ @machine.clip_value.should == 0
574
+ @machine.result.should be_empty
575
+
576
+ @machine.step_execute
577
+
578
+ @machine.step.should == 3
579
+ @machine.index.should == 3
580
+ @machine.point.should == 0
581
+ @machine.buffer.should == [2]
582
+ @machine.clip_value.should == 0
583
+ @machine.result.should be_empty
584
+
585
+ @machine.step_execute
586
+
587
+ @machine.step.should == 4
588
+ @machine.index.should == 4
589
+ @machine.point.should == 0
590
+ @machine.buffer.should == [1]
591
+ @machine.clip_value.should == 0
592
+ @machine.result.should be_empty
593
+
594
+ @machine.step_execute
595
+
596
+ @machine.step.should == 5
597
+ @machine.index.should == 3
598
+ @machine.point.should == 0
599
+ @machine.buffer.should == [1]
600
+ @machine.clip_value.should == 0
601
+ @machine.result.should be_empty
602
+
603
+ @machine.step_execute
604
+
605
+ @machine.step.should == 6
606
+ @machine.index.should == 4
607
+ @machine.point.should == 0
608
+ @machine.buffer.should == [0]
609
+ @machine.clip_value.should == 0
610
+ @machine.result.should be_empty
611
+
612
+ @machine.step_execute
613
+
614
+ @machine.step.should == 7
615
+ @machine.index.should == 5
616
+ @machine.point.should == 0
617
+ @machine.buffer.should == [0]
618
+ @machine.clip_value.should == 0
619
+ @machine.result.should be_empty
620
+
621
+ @machine.step_execute
622
+
623
+ @machine.step.should == 8
624
+ @machine.index.should == 6
625
+ @machine.point.should == 0
626
+ @machine.buffer.should == [1]
627
+ @machine.clip_value.should == 0
628
+ @machine.result.should be_empty
629
+
630
+ @machine.should be_finish
631
+ end
632
+ end
633
+
634
+ context 'nested' do
635
+ before do
636
+ @machine.commands = [:inc, :jmp, :dec, :jmp, :pinc, :inc, :ret, :ret, :inc]
637
+ @machine.parse_jump
638
+ end
639
+
640
+ it do
641
+ @machine.jump_table.should == {1 => 7, 7 => 1, 3 => 6, 6 => 3}
642
+
643
+ @machine.step_execute
644
+
645
+ @machine.step.should == 1
646
+ @machine.index.should == 1
647
+ @machine.point.should == 0
648
+ @machine.buffer.should == [1]
649
+ @machine.clip_value.should == 0
650
+ @machine.result.should be_empty
651
+
652
+ @machine.step_execute
653
+
654
+ @machine.step.should == 2
655
+ @machine.index.should == 2
656
+ @machine.point.should == 0
657
+ @machine.buffer.should == [1]
658
+ @machine.clip_value.should == 0
659
+ @machine.result.should be_empty
660
+
661
+ @machine.step_execute
662
+
663
+ @machine.step.should == 3
664
+ @machine.index.should == 3
665
+ @machine.point.should == 0
666
+ @machine.buffer.should == [0]
667
+ @machine.clip_value.should == 0
668
+ @machine.result.should be_empty
669
+
670
+ @machine.step_execute
671
+
672
+ @machine.step.should == 4
673
+ @machine.index.should == 7
674
+ @machine.point.should == 0
675
+ @machine.buffer.should == [0]
676
+ @machine.clip_value.should == 0
677
+ @machine.result.should be_empty
678
+
679
+ @machine.step_execute
680
+
681
+ @machine.step.should == 5
682
+ @machine.index.should == 8
683
+ @machine.point.should == 0
684
+ @machine.buffer.should == [0]
685
+ @machine.clip_value.should == 0
686
+ @machine.result.should be_empty
687
+
688
+ @machine.step_execute
689
+
690
+ @machine.step.should == 6
691
+ @machine.index.should == 9
692
+ @machine.point.should == 0
693
+ @machine.buffer.should == [1]
694
+ @machine.clip_value.should == 0
695
+ @machine.result.should be_empty
696
+
697
+ @machine.should be_finish
698
+ end
699
+ end
700
+ end
701
+
702
+ describe ':clip' do
703
+ before { @machine.commands = [:inc, :clip, :pinc, :clip] }
704
+
705
+ it do
706
+ @machine.step_execute
707
+
708
+ @machine.step.should == 1
709
+ @machine.index.should == 1
710
+ @machine.point.should == 0
711
+ @machine.buffer.should == [1]
712
+ @machine.clip_value.should == 0
713
+ @machine.result.should be_empty
714
+
715
+ @machine.step_execute
716
+
717
+ @machine.step.should == 2
718
+ @machine.index.should == 2
719
+ @machine.point.should == 0
720
+ @machine.buffer.should == [1]
721
+ @machine.clip_value.should == 1
722
+ @machine.result.should be_empty
723
+
724
+ @machine.step_execute
725
+
726
+ @machine.step.should == 3
727
+ @machine.index.should == 3
728
+ @machine.point.should == 1
729
+ @machine.buffer.should == [1]
730
+ @machine.clip_value.should == 1
731
+ @machine.result.should be_empty
732
+
733
+ @machine.step_execute
734
+
735
+ @machine.step.should == 4
736
+ @machine.index.should == 4
737
+ @machine.point.should == 1
738
+ @machine.buffer.should == [1]
739
+ @machine.clip_value.should == 0
740
+ @machine.result.should be_empty
741
+
742
+ @machine.should be_finish
743
+ end
744
+ end
745
+
746
+ describe ':paste' do
747
+ before { @machine.commands = [:paste, :inc, :clip, :pinc, :paste] }
748
+
749
+ it do
750
+ @machine.step_execute
751
+
752
+ @machine.step.should == 1
753
+ @machine.index.should == 1
754
+ @machine.point.should == 0
755
+ @machine.buffer.should == [0]
756
+ @machine.clip_value.should == 0
757
+ @machine.result.should be_empty
758
+
759
+ @machine.step_execute
760
+
761
+ @machine.step.should == 2
762
+ @machine.index.should == 2
763
+ @machine.point.should == 0
764
+ @machine.buffer.should == [1]
765
+ @machine.clip_value.should == 0
766
+ @machine.result.should be_empty
767
+
768
+ @machine.step_execute
769
+
770
+ @machine.step.should == 3
771
+ @machine.index.should == 3
772
+ @machine.point.should == 0
773
+ @machine.buffer.should == [1]
774
+ @machine.clip_value.should == 1
775
+ @machine.result.should be_empty
776
+
777
+ @machine.step_execute
778
+
779
+ @machine.step.should == 4
780
+ @machine.index.should == 4
781
+ @machine.point.should == 1
782
+ @machine.buffer.should == [1]
783
+ @machine.clip_value.should == 1
784
+ @machine.result.should be_empty
785
+
786
+ @machine.step_execute
787
+
788
+ @machine.step.should == 5
789
+ @machine.index.should == 5
790
+ @machine.point.should == 1
791
+ @machine.buffer.should == [1, 1]
792
+ @machine.clip_value.should == 1
793
+ @machine.result.should be_empty
794
+
795
+ @machine.should be_finish
796
+ end
797
+ end
798
+
799
+ context 'unknown command' do
800
+ before { @machine.commands = [:inc, :hoge, :pinc, :piyo, :pdec] }
801
+
802
+ it do
803
+ @machine.step_execute
804
+
805
+ @machine.step.should == 1
806
+ @machine.index.should == 1
807
+ @machine.point.should == 0
808
+ @machine.buffer.should == [1]
809
+ @machine.clip_value.should == 0
810
+ @machine.result.should be_empty
811
+
812
+ @machine.step_execute
813
+
814
+ @machine.step.should == 2
815
+ @machine.index.should == 2
816
+ @machine.point.should == 0
817
+ @machine.buffer.should == [1]
818
+ @machine.clip_value.should == 0
819
+ @machine.result.should be_empty
820
+
821
+ @machine.step_execute
822
+
823
+ @machine.step.should == 3
824
+ @machine.index.should == 3
825
+ @machine.point.should == 1
826
+ @machine.buffer.should == [1]
827
+ @machine.clip_value.should == 0
828
+ @machine.result.should be_empty
829
+
830
+ @machine.step_execute
831
+
832
+ @machine.step.should == 4
833
+ @machine.index.should == 4
834
+ @machine.point.should == 1
835
+ @machine.buffer.should == [1]
836
+ @machine.clip_value.should == 0
837
+ @machine.result.should be_empty
838
+
839
+ @machine.step_execute
840
+
841
+ @machine.step.should == 5
842
+ @machine.index.should == 5
843
+ @machine.point.should == 0
844
+ @machine.buffer.should == [1]
845
+ @machine.clip_value.should == 0
846
+ @machine.result.should be_empty
847
+
848
+ @machine.should be_finish
849
+ end
850
+ end
851
+ end
852
+
853
+ describe '#execute' do
854
+ before do
855
+ coms = [
856
+ :pinc, [:inc] * 10,
857
+ :jmp, :pdec,
858
+ [:inc] * 10,
859
+ :pinc, :dec, :ret,
860
+ :pdec, :clip,
861
+ :inc, :out,
862
+ :pinc, [:inc] * 3,
863
+ :jmp, :pdec,
864
+ [:inc] * 3,
865
+ :pinc, :dec, :ret,
866
+ :pdec, :out,
867
+ :paste, :out
868
+ ].flatten
869
+ @machine = Machine.create(coms)
870
+ end
871
+
872
+ context 'normal mode' do
873
+ it do
874
+ @machine.execute.should == 'end'
875
+ @machine.result.should == 'end'
876
+ end
877
+ end
878
+
879
+ context 'flash mode' do
880
+ before do
881
+ @out = StringIO.new
882
+ @org_out = $stdout
883
+ $stdout = @out
884
+ @machine.flash = true
885
+ end
886
+
887
+ it do
888
+ @machine.execute.should == 'end'
889
+ @machine.result.should == 'end'
890
+ @out.string.should == 'end'
891
+ end
892
+
893
+ after { $stdout = @org_out }
894
+ end
895
+
896
+ context 'not execute if machine has result already' do
897
+ before do
898
+ @result = @machine.execute
899
+ @index = @machine.index
900
+ @step = @machine.step
901
+ end
902
+
903
+ it do
904
+ @machine.execute.should == @result
905
+ @machine.index.should == @index
906
+ @machine.step.should == @step
907
+ end
908
+ end
909
+ end
910
+
911
+ end