yarbf 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -2
- data/bin/yarbf +55 -1
- data/lib/yarbf.rb +104 -25
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c50a097c05b4592a3af56541e41e1ce016f8aaef
|
4
|
+
data.tar.gz: de0acce92f5167ce6fd1c3597bd925010205407b
|
2
5
|
SHA512:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf7026eaece5ff3bdc25cfcd1d7293208ed6ede199807103b931da68bfbbeb57429e34d46b41fb62fdf9f164377f79d4f191eab144b8258efd466eb415d941ef
|
7
|
+
data.tar.gz: 8289e0617d9b293a03d1e9971ebeaea728a250cc5fd6f39de7ffb65e220b5cdc3a69daf39cfe6fe3c7f03916261c6e4e63c81150383b8d1b0a499d35922e1119
|
data/bin/yarbf
CHANGED
@@ -1,6 +1,60 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
# for parsing command line arguments
|
4
|
+
require 'optparse'
|
5
|
+
|
3
6
|
require 'yarbf'
|
4
7
|
|
5
|
-
|
8
|
+
# set default values
|
9
|
+
options = Hash.new
|
10
|
+
options[:debug] = false
|
11
|
+
options[:wrap_around] = false
|
12
|
+
options[:cell_size] = 8
|
13
|
+
|
14
|
+
parser = OptionParser.new do |opts|
|
15
|
+
opts.banner = 'yarbf - Yet another Brainfuck interpreter in Ruby'
|
16
|
+
opts.separator ''
|
17
|
+
opts.separator 'Usage: yarbf [options] <source>'
|
18
|
+
opts.separator ''
|
19
|
+
opts.separator 'Options:'
|
20
|
+
|
21
|
+
# debug
|
22
|
+
opts.on('-d', '--debug', 'Use debug mode') { options[:debug] = true }
|
23
|
+
|
24
|
+
# wrap around
|
25
|
+
opts.on('-w', '--wrap', 'Enable wrap around') { options[:wrap_around] = true }
|
26
|
+
|
27
|
+
# cell size
|
28
|
+
opts.on('-s', '--size SIZE', OptionParser::DecimalInteger,
|
29
|
+
'Set cell size') { |size| options[:cell_size] = size }
|
30
|
+
|
31
|
+
# version
|
32
|
+
opts.on('-V', '--version', 'show version and exit') do
|
33
|
+
puts 'yarbf 0.0.1'
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
|
37
|
+
# help
|
38
|
+
opts.on('-h', '--help', 'Show this message and exit') do
|
39
|
+
puts opts
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.separator ''
|
44
|
+
end
|
45
|
+
|
46
|
+
# do parse
|
47
|
+
begin
|
48
|
+
parser.parse!
|
49
|
+
rescue OptionParser::ParseError => e
|
50
|
+
STDERR.puts $0 + ': ' + e.to_s
|
51
|
+
exit false
|
52
|
+
end
|
53
|
+
|
54
|
+
if ARGV[0] == nil
|
55
|
+
STDERR.puts $0 + ': no source file specified'
|
56
|
+
exit false
|
57
|
+
end
|
58
|
+
|
59
|
+
interpreter = BfInterpreter.new(options)
|
6
60
|
interpreter.run(ARGV[0])
|
data/lib/yarbf.rb
CHANGED
@@ -1,43 +1,93 @@
|
|
1
1
|
require 'io/console'
|
2
2
|
|
3
|
+
##
|
4
|
+
# == BfInterpreter
|
5
|
+
#
|
6
|
+
# BfInterpreter is the main class of yarbf.
|
7
|
+
#
|
8
|
+
# === Options
|
9
|
+
#
|
10
|
+
# Options to interpreter can be specified via passing a #Hash object to
|
11
|
+
# the constructor or just calling attribute writers. Supported options are:
|
12
|
+
#
|
13
|
+
# - debug:: Debug mode switch. Setting this option to true will print out
|
14
|
+
# each Brainfuck instruction when interpreting. Default is false.
|
15
|
+
# - wrap_around:: Wrap around switch. Setting this option to true will
|
16
|
+
# ignore cell value overflow or underflow. Default is false.
|
17
|
+
# - cell_size:: Size of each cell in bit. Default is 8.
|
18
|
+
#
|
19
|
+
# === Examples
|
20
|
+
#
|
21
|
+
# Following is a brief example.
|
22
|
+
#
|
23
|
+
# require 'yarbf'
|
24
|
+
#
|
25
|
+
# interpreter = BfInterpreter.new({:debug => true, :cell_size => 16})
|
26
|
+
# interpreter.run('/path/to/Brainfuck/source')
|
27
|
+
#
|
3
28
|
class BfInterpreter
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@option = Hash.new
|
12
|
-
@option[KEY_DEBUG] = debug
|
13
|
-
@option[KEY_WRAP] = wrap_around
|
14
|
-
@option[KEY_CELL] = cell_size
|
29
|
+
##
|
30
|
+
# Initialize the instance.
|
31
|
+
#
|
32
|
+
# +hash+:: A Hash containing options to the interpreter.
|
33
|
+
#
|
34
|
+
def initialize(hash)
|
35
|
+
@option = hash
|
15
36
|
end
|
16
37
|
|
38
|
+
##
|
39
|
+
# Returns whether the interpreter is in debug mode.
|
40
|
+
#
|
17
41
|
def debug?
|
18
|
-
@option[
|
42
|
+
@option[:debug]
|
19
43
|
end
|
20
44
|
|
45
|
+
##
|
46
|
+
# Sets the interpreter to debug mode
|
47
|
+
#
|
48
|
+
# +debug+:: A boolean value.
|
49
|
+
#
|
21
50
|
def debug=(debug)
|
22
|
-
@option[
|
51
|
+
@option[:debug] = debug
|
23
52
|
end
|
24
53
|
|
54
|
+
##
|
55
|
+
# Returns whether the interpreter accepts wrap around.
|
56
|
+
#
|
25
57
|
def wrap_around?
|
26
|
-
@option[
|
58
|
+
@option[:wrap_around]
|
27
59
|
end
|
28
60
|
|
61
|
+
##
|
62
|
+
# Sets whether the interpreter should accept wrap around.
|
63
|
+
#
|
64
|
+
# +wrap_around+:: A boolean value.
|
65
|
+
#
|
29
66
|
def wrap_around=(wrap_around)
|
30
|
-
@option[
|
67
|
+
@option[:wrap_around] = wrap_around
|
31
68
|
end
|
32
69
|
|
70
|
+
##
|
71
|
+
# Returns the size of each tape cell.
|
72
|
+
#
|
33
73
|
def cell_size?
|
34
|
-
@option[
|
74
|
+
@option[:cell_size]
|
35
75
|
end
|
36
76
|
|
77
|
+
##
|
78
|
+
# Sets the size of each tape cell.
|
79
|
+
#
|
80
|
+
# +cell_size+:: An integer.
|
81
|
+
#
|
37
82
|
def cell_size=(cell_size)
|
38
|
-
@option[
|
83
|
+
@option[:cell_size] = cell_size
|
39
84
|
end
|
40
85
|
|
86
|
+
##
|
87
|
+
# Interpret a Brainfuck source file.
|
88
|
+
#
|
89
|
+
# +src+:: Path of the source.
|
90
|
+
#
|
41
91
|
def run(src)
|
42
92
|
units = []
|
43
93
|
|
@@ -54,7 +104,7 @@ class BfInterpreter
|
|
54
104
|
position = 0
|
55
105
|
unit = units[0]
|
56
106
|
while unit != nil
|
57
|
-
tape[position] = BfCell.new(
|
107
|
+
tape[position] = BfCell.new(cell_size?) if tape[position] == nil
|
58
108
|
|
59
109
|
STDERR.printf('%s', unit.instruction) if debug?
|
60
110
|
|
@@ -85,6 +135,11 @@ class BfInterpreter
|
|
85
135
|
end
|
86
136
|
end
|
87
137
|
|
138
|
+
##
|
139
|
+
# Constructs and returns the program units of class #BfProgramUnit.
|
140
|
+
#
|
141
|
+
# +file+:: The #File object of source file.
|
142
|
+
#
|
88
143
|
def construct_program_units(file)
|
89
144
|
units = Array.new
|
90
145
|
position = 0
|
@@ -104,6 +159,11 @@ class BfInterpreter
|
|
104
159
|
units
|
105
160
|
end
|
106
161
|
|
162
|
+
##
|
163
|
+
# Matches each bracket '[' and ']' in the source.
|
164
|
+
#
|
165
|
+
# +units+:: An #Array of program units.
|
166
|
+
#
|
107
167
|
def match_brackets(units)
|
108
168
|
units.each_index do |i|
|
109
169
|
if units[i].instruction == '['
|
@@ -129,27 +189,46 @@ class BfInterpreter
|
|
129
189
|
|
130
190
|
private :construct_program_units, :match_brackets
|
131
191
|
|
192
|
+
##
|
193
|
+
# Cell of the Brainfuck tape.
|
194
|
+
#
|
132
195
|
class BfCell
|
133
|
-
attr_accessor :
|
196
|
+
attr_accessor :cell_size, :value
|
134
197
|
|
135
|
-
def initialize(
|
136
|
-
@
|
198
|
+
def initialize(cell_size = 8, value = 0)
|
199
|
+
@cell_size = cell_size
|
137
200
|
@value = value
|
138
201
|
end
|
139
202
|
|
140
|
-
|
141
|
-
|
203
|
+
##
|
204
|
+
# Increase the value of a cell.
|
205
|
+
#
|
206
|
+
# +increment+:: Value to increase by. Default is 1.
|
207
|
+
# +wrap_around+:: Whether to wrap around. Default is false.
|
208
|
+
#
|
209
|
+
def increase(increment = 1, wrap_around = false)
|
210
|
+
if !wrap_around &&
|
211
|
+
(@value + increment < 0 || @value + increment >= (1 << @cell_size))
|
142
212
|
fail 'Overflow or underflow happened while forbidden!'
|
143
213
|
else
|
144
|
-
@value = (@value + increment) %
|
214
|
+
@value = (@value + increment) % (1 << @cell_size)
|
145
215
|
end
|
146
216
|
end
|
147
217
|
|
148
|
-
|
218
|
+
##
|
219
|
+
# Decrease the value of a cell.
|
220
|
+
#
|
221
|
+
# +decrement+:: Value to decrease by. Default is 1.
|
222
|
+
# +wrap_around+:: Whether to wrap around. Default is false.
|
223
|
+
#
|
224
|
+
def decrease(decrement = 1, wrap_around = false)
|
149
225
|
self.increase(-decrement, wrap_around)
|
150
226
|
end
|
151
227
|
end
|
152
228
|
|
229
|
+
##
|
230
|
+
# Program unit of Brainfuck.
|
231
|
+
#
|
153
232
|
class BfProgramUnit
|
154
233
|
attr_reader :instruction
|
155
234
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yarbf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chaos Shen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.4'
|
27
|
-
description: yarbf
|
27
|
+
description: yarbf is a simple Brainfuck interpreter in Ruby.
|
28
28
|
email: chaosdefinition@hotmail.com
|
29
29
|
executables:
|
30
30
|
- yarbf
|