windstorm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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