brainfuck 0.0.1
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.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +33 -0
- data/Rakefile +15 -0
- data/Readme.md +49 -0
- data/bin/brainfuck +3 -0
- data/brainfuck.gemspec +26 -0
- data/examples/hello_world.bf +21 -0
- data/lib/brainfuck.rb +102 -0
- data/lib/brainfuck/version.rb +3 -0
- data/spec/acceptance_spec.rb +107 -0
- data/spec/interpreter_spec.rb +65 -0
- data/spec/spec_helper.rb +18 -0
- metadata +130 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
brainfuck (0.0.1)
|
5
|
+
highline
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.1.2)
|
11
|
+
highline (1.6.1)
|
12
|
+
rspec (2.2.0)
|
13
|
+
rspec-core (~> 2.2)
|
14
|
+
rspec-expectations (~> 2.2)
|
15
|
+
rspec-mocks (~> 2.2)
|
16
|
+
rspec-core (2.2.1)
|
17
|
+
rspec-expectations (2.2.0)
|
18
|
+
diff-lcs (~> 1.1.2)
|
19
|
+
rspec-mocks (2.2.0)
|
20
|
+
simplecov (0.3.7)
|
21
|
+
simplecov-html (>= 0.3.7)
|
22
|
+
simplecov-html (0.3.9)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
java
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
brainfuck!
|
30
|
+
bundler
|
31
|
+
highline
|
32
|
+
rspec
|
33
|
+
simplecov
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start do
|
6
|
+
add_group "Lib", 'lib'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rspec/core'
|
10
|
+
require 'rspec/core/rake_task'
|
11
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
12
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => :spec
|
data/Readme.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# brainfuck
|
2
|
+
|
3
|
+
Just another Brainfuck interpreter in Ruby!
|
4
|
+
(If you don't know what Brainfuck is, you definitely
|
5
|
+
[should][http://en.wikipedia.org/wiki/Brainfuck]).
|
6
|
+
|
7
|
+
This interpreter works with MRI 1.8.7, 1.9.2 and JRuby 1.5.5.
|
8
|
+
|
9
|
+
## Known caveats (yes, before anything)
|
10
|
+
|
11
|
+
Ok, I admit it. Nested loops don't work in an extremely reliable manner, so to
|
12
|
+
speak. I suggest you NOT TO USE THIS IN PRODUCTION APPS. Yes, forget about
|
13
|
+
using this interpreter for that high-security online payment system you wrote in Brainfuck.
|
14
|
+
|
15
|
+
Oh and why are nested loops tricky with this interpreter? I was tired and Civilization 5
|
16
|
+
was installed in my laptop and... You know, forks and pull requests are always welcome! :)
|
17
|
+
|
18
|
+
## Installation and usage
|
19
|
+
|
20
|
+
You just `gem install brainfuck`!
|
21
|
+
|
22
|
+
And then: `brainfuck my_file.bf`
|
23
|
+
|
24
|
+
You can also require the gem and use inline brainfuck in your ruby scripts like this:
|
25
|
+
|
26
|
+
require 'brainfuck'
|
27
|
+
|
28
|
+
interpreter = Brainfuck.new
|
29
|
+
interpreter.compile "+++>+++<---"
|
30
|
+
|
31
|
+
interpreter.cells
|
32
|
+
# => [0, 3]
|
33
|
+
|
34
|
+
It's very basic, and needs *a lot* of refactoring, but for now... there you go! ;)
|
35
|
+
|
36
|
+
## Note on Patches/Pull Requests
|
37
|
+
|
38
|
+
* Fork the project.
|
39
|
+
* Make your feature addition or bug fix.
|
40
|
+
* Add specs for it. This is important so I don't break it in a
|
41
|
+
future version unintentionally.
|
42
|
+
* Commit, do not mess with rakefile, version, or history.
|
43
|
+
If you want to have your own version, that is fine but bump version
|
44
|
+
in a commit by itself I can ignore when I pull.
|
45
|
+
* Send me a pull request. Bonus points for topic branches.
|
46
|
+
|
47
|
+
## Copyright
|
48
|
+
|
49
|
+
Copyright (c) 2010 Josep M. Bach. See LICENSE for details.
|
data/bin/brainfuck
ADDED
data/brainfuck.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "brainfuck/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "brainfuck"
|
7
|
+
s.version = Brainfuck::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Josep M. Bach"]
|
10
|
+
s.email = ["josep.m.bach@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/txus/brainfuck"
|
12
|
+
s.summary = %q{Another Brainfuck interpreter in Ruby}
|
13
|
+
s.description = %q{Another Brainfuck interpreter in Ruby}
|
14
|
+
|
15
|
+
s.rubyforge_project = "brainfuck"
|
16
|
+
|
17
|
+
s.add_runtime_dependency "highline"
|
18
|
+
s.add_development_dependency "rspec"
|
19
|
+
s.add_development_dependency "bundler"
|
20
|
+
s.add_development_dependency "simplecov"
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
+++++ +++++ initialize counter (cell #0) to 10
|
2
|
+
[ use loop to set the next four cells to 70/100/30/10
|
3
|
+
> +++++ ++ add 7 to cell #1
|
4
|
+
> +++++ +++++ add 10 to cell #2
|
5
|
+
> +++ add 3 to cell #3
|
6
|
+
> + add 1 to cell #4
|
7
|
+
<<<< - decrement counter (cell #0)
|
8
|
+
]
|
9
|
+
> ++ . print 'H'
|
10
|
+
> + . print 'e'
|
11
|
+
+++++ ++ . print 'l'
|
12
|
+
. print 'l'
|
13
|
+
+++ . print 'o'
|
14
|
+
> ++ . print ' '
|
15
|
+
<< +++++ +++++ +++++ . print 'W'
|
16
|
+
> . print 'o'
|
17
|
+
+++ . print 'r'
|
18
|
+
----- - . print 'l'
|
19
|
+
----- --- . print 'd'
|
20
|
+
> + . print '!'
|
21
|
+
> . print '\n'
|
data/lib/brainfuck.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'highline/system_extensions'
|
2
|
+
|
3
|
+
module Brainfuck
|
4
|
+
class Interpreter
|
5
|
+
include HighLine::SystemExtensions
|
6
|
+
|
7
|
+
INSTRUCTIONS = %w{> < + - [ ] . ,}
|
8
|
+
|
9
|
+
attr_accessor :cells
|
10
|
+
attr_reader :pointer
|
11
|
+
attr_reader :code
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@cells = [0]
|
15
|
+
@pointer = 0
|
16
|
+
@code = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def current
|
20
|
+
@cells[pointer] ||= 0
|
21
|
+
end
|
22
|
+
def current=(value)
|
23
|
+
@cells[pointer] = (value % 255) rescue 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def forward
|
27
|
+
@pointer += 1
|
28
|
+
initialize_cell_if_nil
|
29
|
+
end
|
30
|
+
def backward
|
31
|
+
@pointer -= 1
|
32
|
+
ensure_pointer_is_above_zero
|
33
|
+
initialize_cell_if_nil
|
34
|
+
end
|
35
|
+
def increase
|
36
|
+
@cells[pointer] = (@cells[pointer] + 1) % 255
|
37
|
+
end
|
38
|
+
def decrease
|
39
|
+
@cells[pointer] = (@cells[pointer] - 1) % 255
|
40
|
+
end
|
41
|
+
|
42
|
+
def compile(code)
|
43
|
+
@code = clean(code)
|
44
|
+
run
|
45
|
+
end
|
46
|
+
|
47
|
+
def run(from = nil, to = nil)
|
48
|
+
index = 0
|
49
|
+
context = 0
|
50
|
+
|
51
|
+
c = code.dup
|
52
|
+
|
53
|
+
if from && to
|
54
|
+
context = from
|
55
|
+
c = c.slice(from...to)
|
56
|
+
end
|
57
|
+
|
58
|
+
c.each_char do |char|
|
59
|
+
index += 1
|
60
|
+
case char
|
61
|
+
when '>'
|
62
|
+
forward
|
63
|
+
when '<'
|
64
|
+
backward
|
65
|
+
when '+'
|
66
|
+
increase
|
67
|
+
when '-'
|
68
|
+
decrease
|
69
|
+
when '.'
|
70
|
+
stdout.print current.chr
|
71
|
+
when ','
|
72
|
+
self.current = get_character
|
73
|
+
when '['
|
74
|
+
@start = index
|
75
|
+
when ']'
|
76
|
+
@end = index unless @end && @start < @end
|
77
|
+
run(@start, @end) unless current == 0
|
78
|
+
@start = context || nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def clean(code)
|
86
|
+
code.chars.select {|c| INSTRUCTIONS.include? c }.join
|
87
|
+
end
|
88
|
+
|
89
|
+
def stdout
|
90
|
+
$stdout
|
91
|
+
end
|
92
|
+
|
93
|
+
def initialize_cell_if_nil
|
94
|
+
@cells[pointer] ||= 0
|
95
|
+
end
|
96
|
+
|
97
|
+
def ensure_pointer_is_above_zero
|
98
|
+
raise "Tried to access cell #{@pointer}." if @pointer < 0
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Brainfuck
|
4
|
+
describe Interpreter, "acceptance specs" do
|
5
|
+
|
6
|
+
describe "without loops nor user input" do
|
7
|
+
let(:code) do
|
8
|
+
<<-EOS
|
9
|
+
++++>++++---.<--.
|
10
|
+
EOS
|
11
|
+
end
|
12
|
+
it "sets two cells to 2 and 1" do
|
13
|
+
subject.should_receive(:code).and_return code
|
14
|
+
subject.compile(code)
|
15
|
+
subject.cells.should == [2,1]
|
16
|
+
end
|
17
|
+
it "prints 2 and 1" do
|
18
|
+
output = double('output')
|
19
|
+
subject.should_receive(:stdout).twice.and_return(output)
|
20
|
+
output.should_receive(:print).with(1.chr).ordered
|
21
|
+
output.should_receive(:print).with(2.chr).ordered
|
22
|
+
|
23
|
+
subject.compile(code)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "with user input" do
|
28
|
+
let(:code) do
|
29
|
+
<<-EOS
|
30
|
+
,++++
|
31
|
+
EOS
|
32
|
+
end
|
33
|
+
it "sets the first cell to a + 4" do
|
34
|
+
input = double('input')
|
35
|
+
subject.should_receive(:get_character).once.and_return 97
|
36
|
+
|
37
|
+
subject.compile(code)
|
38
|
+
subject.current.should == 101
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "with loops" do
|
43
|
+
let(:code) do
|
44
|
+
<<-EOS
|
45
|
+
++++[-]+-+
|
46
|
+
EOS
|
47
|
+
end
|
48
|
+
it "runs the loop 4 times" do
|
49
|
+
subject.compile(code)
|
50
|
+
subject.current.should == 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "cell hopping examples" do
|
55
|
+
|
56
|
+
it "transfers the content from one cell to another" do
|
57
|
+
subject.cells = [10]
|
58
|
+
subject.compile("[>+<-]")
|
59
|
+
subject.cells.should == [0,10]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "transfers the content from one cell to the third" do
|
63
|
+
subject.cells = [10]
|
64
|
+
subject.compile("[>+<-]>[>+<-]")
|
65
|
+
subject.cells.should == [0,0,10]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "transfers the content from one cell to the third and back to the second" do
|
69
|
+
subject.cells = [10]
|
70
|
+
subject.compile("[>+<-]>[>+<-]>[<+>-]")
|
71
|
+
subject.cells.should == [0,10,0]
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "hello world" do
|
77
|
+
|
78
|
+
it "displays hello world" do
|
79
|
+
subject.compile <<-EOS
|
80
|
+
+++++ +++++
|
81
|
+
[
|
82
|
+
> +++++ ++
|
83
|
+
> +++++ +++++
|
84
|
+
> +++
|
85
|
+
> +
|
86
|
+
<<<< -
|
87
|
+
]
|
88
|
+
> ++ .
|
89
|
+
> + .
|
90
|
+
+++++ ++ .
|
91
|
+
.
|
92
|
+
+++ .
|
93
|
+
> ++ .
|
94
|
+
<< +++++ +++++ +++++ .
|
95
|
+
> .
|
96
|
+
+++ .
|
97
|
+
----- - .
|
98
|
+
----- --- .
|
99
|
+
> + .
|
100
|
+
> .
|
101
|
+
EOS
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Brainfuck
|
4
|
+
describe Interpreter do
|
5
|
+
subject { Interpreter.new }
|
6
|
+
|
7
|
+
it "initializes with an array of cells with a single 0 element" do
|
8
|
+
subject.cells.should == [0]
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#clean" do
|
12
|
+
it "cleans the code from comments and whitespace" do
|
13
|
+
subject.send(:clean, " < > h - + ..,hb [lk]f").should == '<>-+..,[]'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#compile" do
|
18
|
+
it "cleans the code first and runs it second" do
|
19
|
+
code = double('code')
|
20
|
+
subject.should_receive(:clean).once.with(code).ordered.and_return("")
|
21
|
+
subject.should_receive(:run).once
|
22
|
+
|
23
|
+
subject.compile(code)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#run" do
|
28
|
+
it "converts > into forward" do
|
29
|
+
subject.stub(:code).and_return ">"
|
30
|
+
subject.should_receive(:forward).once
|
31
|
+
subject.run
|
32
|
+
end
|
33
|
+
it "converts < into backward" do
|
34
|
+
subject.stub(:code).and_return "<"
|
35
|
+
subject.should_receive(:backward).once
|
36
|
+
subject.run
|
37
|
+
end
|
38
|
+
it "converts + into increase" do
|
39
|
+
subject.stub(:code).and_return "+"
|
40
|
+
subject.should_receive(:increase).once
|
41
|
+
subject.run
|
42
|
+
end
|
43
|
+
it "converts - into decrease" do
|
44
|
+
subject.stub(:code).and_return "-"
|
45
|
+
subject.should_receive(:decrease).once
|
46
|
+
subject.run
|
47
|
+
end
|
48
|
+
it "converts , into get_character" do
|
49
|
+
subject.stub(:code).and_return ","
|
50
|
+
subject.should_receive(:get_character).once
|
51
|
+
subject.run
|
52
|
+
end
|
53
|
+
it "converts . into stdout.print" do
|
54
|
+
subject.stub(:code).and_return "."
|
55
|
+
output = double('output')
|
56
|
+
subject.should_receive(:stdout).once.and_return(output)
|
57
|
+
subject.should_receive(:current).once.and_return(117)
|
58
|
+
output.should_receive(:print).once
|
59
|
+
|
60
|
+
subject.run
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start do
|
4
|
+
add_group "Lib", "lib"
|
5
|
+
end
|
6
|
+
|
7
|
+
begin
|
8
|
+
Bundler.setup(:default, :development)
|
9
|
+
rescue Bundler::BundlerError => e
|
10
|
+
$stderr.puts e.message
|
11
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
12
|
+
exit e.status_code
|
13
|
+
end
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
16
|
+
|
17
|
+
require 'brainfuck'
|
18
|
+
require 'rspec'
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: brainfuck
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Josep M. Bach
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-02 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: highline
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :development
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: simplecov
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
type: :development
|
71
|
+
version_requirements: *id004
|
72
|
+
description: Another Brainfuck interpreter in Ruby
|
73
|
+
email:
|
74
|
+
- josep.m.bach@gmail.com
|
75
|
+
executables:
|
76
|
+
- brainfuck
|
77
|
+
extensions: []
|
78
|
+
|
79
|
+
extra_rdoc_files: []
|
80
|
+
|
81
|
+
files:
|
82
|
+
- .gitignore
|
83
|
+
- Gemfile
|
84
|
+
- Gemfile.lock
|
85
|
+
- Rakefile
|
86
|
+
- Readme.md
|
87
|
+
- bin/brainfuck
|
88
|
+
- brainfuck.gemspec
|
89
|
+
- examples/hello_world.bf
|
90
|
+
- lib/brainfuck.rb
|
91
|
+
- lib/brainfuck/version.rb
|
92
|
+
- spec/acceptance_spec.rb
|
93
|
+
- spec/interpreter_spec.rb
|
94
|
+
- spec/spec_helper.rb
|
95
|
+
has_rdoc: true
|
96
|
+
homepage: http://github.com/txus/brainfuck
|
97
|
+
licenses: []
|
98
|
+
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
version: "0"
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
requirements: []
|
121
|
+
|
122
|
+
rubyforge_project: brainfuck
|
123
|
+
rubygems_version: 1.3.7
|
124
|
+
signing_key:
|
125
|
+
specification_version: 3
|
126
|
+
summary: Another Brainfuck interpreter in Ruby
|
127
|
+
test_files:
|
128
|
+
- spec/acceptance_spec.rb
|
129
|
+
- spec/interpreter_spec.rb
|
130
|
+
- spec/spec_helper.rb
|