yarbf 0.0.1 → 0.0.2
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.
- 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
|