bfrb 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +3 -3
- data/VERSION +1 -1
- data/bfrb.gemspec +3 -3
- data/lib/bfrb/interpreter.rb +11 -6
- data/test/test_interpreter.rb +100 -0
- metadata +12 -12
- data/test/test_bfrb.rb +0 -7
data/README.rdoc
CHANGED
@@ -24,9 +24,9 @@ You can also start an interactive interpreter by running bfrb without any parame
|
|
24
24
|
== Things To Do
|
25
25
|
|
26
26
|
* Compiler
|
27
|
-
* Unit Testing
|
28
27
|
|
29
28
|
== History
|
30
29
|
|
31
|
-
|
32
|
-
|
30
|
+
* 0.1.2 - Added unit tests
|
31
|
+
* 0.1.1 - Added REPL.
|
32
|
+
* 0.1.0 - Initial release. Allows running code passed in or from a file.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/bfrb.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bfrb}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Chris ONeal"]
|
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
"lib/bfrb/interpreter.rb",
|
31
31
|
"lib/bfrb/memory.rb",
|
32
32
|
"test/helper.rb",
|
33
|
-
"test/
|
33
|
+
"test/test_interpreter.rb"
|
34
34
|
]
|
35
35
|
s.homepage = %q{http://github.com/ctoneal/bfrb}
|
36
36
|
s.licenses = ["MIT"]
|
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
|
|
39
39
|
s.summary = %q{A simple brainfuck interpreter in Ruby}
|
40
40
|
s.test_files = [
|
41
41
|
"test/helper.rb",
|
42
|
-
"test/
|
42
|
+
"test/test_interpreter.rb"
|
43
43
|
]
|
44
44
|
|
45
45
|
if s.respond_to? :specification_version then
|
data/lib/bfrb/interpreter.rb
CHANGED
@@ -5,11 +5,14 @@ module BfRb
|
|
5
5
|
class Interpreter
|
6
6
|
|
7
7
|
attr_reader :program_counter, :memory_counter
|
8
|
+
attr_accessor :input_stream, :output_stream
|
8
9
|
|
9
10
|
# initialize the interpreter
|
10
11
|
def initialize
|
11
12
|
@memory = Memory.new
|
12
13
|
initialize_environment
|
14
|
+
@input_stream = $stdin
|
15
|
+
@output_stream = $stdout
|
13
16
|
end
|
14
17
|
|
15
18
|
# cleans the memory and initializes member variables
|
@@ -30,13 +33,13 @@ module BfRb
|
|
30
33
|
# evaluate each instruction in the current code
|
31
34
|
def evaluate_code
|
32
35
|
while ((0 <= @program_counter) and (@program_counter < @code.length))
|
33
|
-
evaluate_instruction
|
36
|
+
evaluate_instruction(@code[@program_counter])
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
37
40
|
# evaluate an individual instruction
|
38
|
-
def evaluate_instruction
|
39
|
-
case
|
41
|
+
def evaluate_instruction(instruction)
|
42
|
+
case instruction
|
40
43
|
when ">"
|
41
44
|
@memory_counter += 1
|
42
45
|
when "<"
|
@@ -48,11 +51,13 @@ module BfRb
|
|
48
51
|
when "+"
|
49
52
|
@memory.set(@memory_counter, current_memory + 1)
|
50
53
|
when "-"
|
51
|
-
|
54
|
+
unless current_memory == 0
|
55
|
+
@memory.set(@memory_counter, current_memory - 1)
|
56
|
+
end
|
52
57
|
when "."
|
53
|
-
print current_memory.chr
|
58
|
+
@output_stream.print current_memory.chr
|
54
59
|
when ","
|
55
|
-
input =
|
60
|
+
input = @input_stream.gets.getbyte(0)
|
56
61
|
@memory.set(@memory_counter, input)
|
57
62
|
when "["
|
58
63
|
if current_memory != 0
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module BfRb
|
4
|
+
class TestInterpreter < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@interpreter = Interpreter.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context ">" do
|
10
|
+
should "increment the memory counter" do
|
11
|
+
initial_mc = @interpreter.memory_counter
|
12
|
+
@interpreter.evaluate_instruction(">")
|
13
|
+
assert_equal(initial_mc + 1, @interpreter.memory_counter)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
context "<" do
|
19
|
+
should "decrement the memory counter" do
|
20
|
+
@interpreter.evaluate_instruction(">")
|
21
|
+
initial_mc = @interpreter.memory_counter
|
22
|
+
@interpreter.evaluate_instruction("<")
|
23
|
+
assert_equal(initial_mc - 1, @interpreter.memory_counter)
|
24
|
+
end
|
25
|
+
|
26
|
+
should "not decrement below zero" do
|
27
|
+
@interpreter.evaluate_instruction("<")
|
28
|
+
assert_equal(0, @interpreter.memory_counter)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "+" do
|
33
|
+
should "increment the current value in memory" do
|
34
|
+
initial_value = @interpreter.current_memory
|
35
|
+
@interpreter.evaluate_instruction("+")
|
36
|
+
assert_equal(initial_value + 1, @interpreter.current_memory)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "-" do
|
41
|
+
should "decrement the current value in memory" do
|
42
|
+
@interpreter.evaluate_instruction("+")
|
43
|
+
initial_value = @interpreter.current_memory
|
44
|
+
@interpreter.evaluate_instruction("-")
|
45
|
+
assert_equal(initial_value - 1, @interpreter.current_memory)
|
46
|
+
end
|
47
|
+
|
48
|
+
should "not decrement below zero" do
|
49
|
+
@interpreter.evaluate_instruction("-")
|
50
|
+
assert_equal(0, @interpreter.current_memory)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "[]" do
|
55
|
+
should "loop properly if value in memory is not zero" do
|
56
|
+
@interpreter.evaluate_instruction("+")
|
57
|
+
initial_value = @interpreter.program_counter
|
58
|
+
@interpreter.evaluate_instruction("[")
|
59
|
+
@interpreter.evaluate_instruction("+")
|
60
|
+
@interpreter.evaluate_instruction("]")
|
61
|
+
assert_equal(initial_value, @interpreter.program_counter)
|
62
|
+
end
|
63
|
+
|
64
|
+
should "break out of the loop if value in memory is zero" do
|
65
|
+
@interpreter.evaluate_instruction("+")
|
66
|
+
initial_value = @interpreter.program_counter
|
67
|
+
@interpreter.evaluate_instruction("[")
|
68
|
+
@interpreter.evaluate_instruction("-")
|
69
|
+
@interpreter.evaluate_instruction("]")
|
70
|
+
assert_not_equal(initial_value, @interpreter.program_counter)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "." do
|
75
|
+
should "output the intended character to the screen" do
|
76
|
+
@interpreter.evaluate_instruction("+")
|
77
|
+
output, input = IO.pipe
|
78
|
+
@interpreter.output_stream = input
|
79
|
+
@interpreter.evaluate_instruction(".")
|
80
|
+
input.close
|
81
|
+
value = output.getbyte
|
82
|
+
output.close
|
83
|
+
assert_equal(value, @interpreter.current_memory)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "," do
|
88
|
+
should "place the intended character in memory" do
|
89
|
+
output, input = IO.pipe
|
90
|
+
character = "a"
|
91
|
+
@interpreter.input_stream = output
|
92
|
+
input.write character
|
93
|
+
input.close
|
94
|
+
@interpreter.evaluate_instruction(",")
|
95
|
+
output.close
|
96
|
+
assert_equal(character.getbyte(0), @interpreter.current_memory)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bfrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -14,7 +14,7 @@ default_executable: bfrb
|
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: shoulda
|
17
|
-
requirement: &
|
17
|
+
requirement: &9363720 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *9363720
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: bundler
|
28
|
-
requirement: &
|
28
|
+
requirement: &9362928 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 1.0.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *9362928
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: jeweler
|
39
|
-
requirement: &
|
39
|
+
requirement: &9362280 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: 1.5.2
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *9362280
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: rcov
|
50
|
-
requirement: &
|
50
|
+
requirement: &9361608 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,7 +55,7 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *9361608
|
59
59
|
description: bfrb is a brainfuck interpreter written in Ruby.
|
60
60
|
email: ctoneal@gmail.com
|
61
61
|
executables:
|
@@ -76,7 +76,7 @@ files:
|
|
76
76
|
- lib/bfrb/interpreter.rb
|
77
77
|
- lib/bfrb/memory.rb
|
78
78
|
- test/helper.rb
|
79
|
-
- test/
|
79
|
+
- test/test_interpreter.rb
|
80
80
|
has_rdoc: true
|
81
81
|
homepage: http://github.com/ctoneal/bfrb
|
82
82
|
licenses:
|
@@ -93,7 +93,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
93
93
|
version: '0'
|
94
94
|
segments:
|
95
95
|
- 0
|
96
|
-
hash:
|
96
|
+
hash: 624886557
|
97
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
98
|
none: false
|
99
99
|
requirements:
|
@@ -108,4 +108,4 @@ specification_version: 3
|
|
108
108
|
summary: A simple brainfuck interpreter in Ruby
|
109
109
|
test_files:
|
110
110
|
- test/helper.rb
|
111
|
-
- test/
|
111
|
+
- test/test_interpreter.rb
|