orenono 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 20a0cca757f8d3d68d2ff3fcc09cb32c2a41025f
4
+ data.tar.gz: f1e2a7643d9003ce4c9c5bf9776e73d41764b539
5
+ SHA512:
6
+ metadata.gz: fb079fbacde75097834c1c814109173211cc7e11b585268453622b3a5c4e1b558e5d74f9333678f6208c2b096b34500b05247e09bb05eed5188ec617bec03092
7
+ data.tar.gz: 699fc00386583c51220faa9441dfd2a7e4121cc5f19d6669d753c2479cfd282f57bfa8a7f7727e76520e69ee084aab418d0ac6cf3af2d76a93988bbe2a06c068
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem update --system 2.1.11
4
+ - gem --version
5
+ rvm:
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - 2.1.0
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+ gem "rspec", "~> 2.14.1"
5
+ gem "thor", "~> 0.18.1"
6
+ gem "simplecov", "~> 0.8.2"
7
+ group :test do
8
+ gem 'coveralls', require: false
9
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 tbpgr
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,183 @@
1
+ # Orenono
2
+
3
+ [![Build Status](https://travis-ci.org/tbpgr/orenono.png?branch=master)](https://travis-ci.org/tbpgr/orenono)
4
+ [![Coverage Status](https://coveralls.io/repos/tbpgr/orenono/badge.png)](https://coveralls.io/r/tbpgr/orenono)
5
+
6
+ Brainfuck interpreter written in Ruby.
7
+
8
+ You can change basic syntaxes by Orenonofile.
9
+ You can create "New Brainfuck Derivation Language" easily.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'orenono'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install orenono
26
+
27
+ ## Command Line Interface Usage
28
+
29
+ ### Show help
30
+
31
+ ~~~bash
32
+ orenono h
33
+ ~~~
34
+
35
+ ### Generate Orenonofile
36
+
37
+ ~~~bash
38
+ orenono init
39
+ ~~~
40
+
41
+ or
42
+
43
+ ~~~bash
44
+ orenono i
45
+ ~~~
46
+
47
+ Orenonofile contents is...
48
+
49
+ ~~~ruby
50
+ # encoding: utf-8
51
+
52
+ # increment command
53
+ # increment's default value => "+"
54
+ increment "+"
55
+
56
+ # decrement command
57
+ # decrement's default value => "-"
58
+ decrement "-"
59
+
60
+ # start_loop command
61
+ # start_loop's default value => "["
62
+ start_loop "["
63
+
64
+ # end_loop command
65
+ # end_loop's default value => "]"
66
+ end_loop "]"
67
+
68
+ # next_cursol command
69
+ # next_cursol's default value => ">"
70
+ next_cursol ">"
71
+
72
+ # previous_cursol command
73
+ # previous_cursol's default value => "<"
74
+ previous_cursol "<"
75
+
76
+ # display command
77
+ # display's default value => "."
78
+ display "."
79
+
80
+ # read command
81
+ # read's default value => ","
82
+ read ","
83
+ ~~~
84
+
85
+ ### Execute Brainfuck (default Orenonofile)
86
+
87
+ * orenono.bf
88
+
89
+ ~~~
90
+ +++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
91
+ ------------.<++++++++.--------.+++.------.--------.>+.
92
+ ~~~
93
+
94
+ * execute
95
+
96
+ ~~~
97
+ $ orenono execute sample.bf
98
+ Hello, world!
99
+ ~~~
100
+
101
+ or
102
+
103
+ ~~~
104
+ $ orenono e sample.bf
105
+ Hello, world!
106
+ ~~~
107
+
108
+ ## Brainfuck Derivation Language Samples
109
+
110
+ ### Sample Define1
111
+
112
+ * Orenonofile
113
+
114
+ ~~~ruby
115
+ # encoding: utf-8
116
+
117
+ increment "足す"
118
+ decrement "引く"
119
+ start_loop "はじめ"
120
+ end_loop "おわり"
121
+ next_cursol "次"
122
+ previous_cursol "前"
123
+ display "出"
124
+ read "入"
125
+ ~~~
126
+
127
+ * ./samples/pattern1/orenono.bf
128
+
129
+ ~~~ruby
130
+ 足す足す足す足す足す足す足す足す足すはじめ次足す足す足す足す足す足す足す足す次足す足す足す足す足す足す足す足す足す足す足す次足す足す足す足す足す前前前引くおわり次出次足す足す出足す足す足す足す足す足す足す出出足す足す足す出次引く出
131
+ 引く引く引く引く引く引く引く引く引く引く引く引く出前足す足す足す足す足す足す足す足す出引く引く引く引く引く引く引く引く出足す足す足す出引く引く引く引く引く引く出引く引く引く引く引く引く引く引く出次足す出
132
+ ~~~
133
+
134
+ * output
135
+
136
+ ~~~
137
+ $ orenono e orenono.bf
138
+ Hello, world!
139
+ ~~~
140
+
141
+ ### Sample Define2
142
+
143
+ Emoji word only syntax.
144
+
145
+ * Orenonofile
146
+
147
+ ~~~ruby
148
+ # encoding: utf-8
149
+
150
+ increment ":heavy_plus_sign:"
151
+ decrement ":heavy_minus_sign:"
152
+ start_loop ":baby:"
153
+ end_loop ":older_man:"
154
+ next_cursol ":arrow_right:"
155
+ previous_cursol ":arrow_left:"
156
+ display ":blossom:"
157
+ read ":seedling:"
158
+ ~~~
159
+
160
+ * ./samples/pattern2/orenono.bf
161
+
162
+ ~~~
163
+ :heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::baby::arrow_right::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::arrow_right::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::arrow_right::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::arrow_left::arrow_left::arrow_left::heavy_minus_sign::older_man::arrow_right::blossom::arrow_right::heavy_plus_sign::heavy_plus_sign::blossom::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::blossom::blossom::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::blossom::arrow_right::heavy_minus_sign::blossom:
164
+ :heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::blossom::arrow_left::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::blossom::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::blossom::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::blossom::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::blossom::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::blossom::arrow_right::heavy_plus_sign::blossom:
165
+ ~~~
166
+
167
+ * output
168
+
169
+ ~~~
170
+ $ orenono e orenono.bf
171
+ Hello, world!
172
+ ~~~
173
+
174
+ ## History
175
+ * version 0.0.1 : first release.
176
+
177
+ ## Contributing
178
+
179
+ 1. Fork it ( https://github.com/[my-github-username]/orenono/fork )
180
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
181
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
182
+ 4. Push to the branch (`git push origin my-new-feature`)
183
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core'
3
+ require 'rspec/core/rake_task'
4
+ task :default => [:spec]
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = 'spec/**/*_spec.rb'
8
+ end
data/bin/orenono ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'orenono_core'
5
+ require 'orenono/version'
6
+ require 'thor'
7
+
8
+ module Orenono
9
+ # = Orenono CLI
10
+ class CLI < Thor
11
+ class_option :help, type: :boolean, aliases: '-h', desc: 'help message.'
12
+ class_option :version, type: :boolean, desc: 'version'
13
+
14
+ desc 'execute', 'Execute Brainf**k'
15
+ def execute(file)
16
+ exit(1) unless file
17
+ Orenono::Core.new.execute(file)
18
+ exit(0)
19
+ end
20
+
21
+ desc 'init', 'Generate Orenonofile template'
22
+ def init
23
+ Orenono::Core.new.init
24
+ exit(0)
25
+ end
26
+
27
+ desc 'version', 'version'
28
+ def version
29
+ p Orenono::VERSION
30
+ end
31
+ end
32
+ end
33
+
34
+ Orenono::CLI.start(ARGV)
data/lib/brain.rb ADDED
@@ -0,0 +1,108 @@
1
+ # encoding: utf-8
2
+ require 'orenono_dsl'
3
+ require 'orenono_dsl_model'
4
+
5
+ module Orenono
6
+ # Brain
7
+ class Brain
8
+ attr_reader :config, :tokens, :src, :tape
9
+ attr_reader :memory_cursol, :loop_stack, :code_cursol
10
+
11
+ def initialize(config, src = '')
12
+ @config = config
13
+ @src = src
14
+ @tokens = @src.scan(/#{@config.token_patterns}/)
15
+ @tape = Array.new(65_535) { 0 }
16
+ @memory_cursol = 0
17
+ @code_cursol = 0
18
+ @loop_stack = []
19
+ end
20
+
21
+ # rubocop:disable CyclomaticComplexity, MethodLength
22
+ def run
23
+ loop do
24
+ token = @tokens[@code_cursol]
25
+ case token
26
+ when @config.increment
27
+ increment
28
+ @code_cursol += 1
29
+ when @config.decrement
30
+ decrement
31
+ @code_cursol += 1
32
+ when @config.start_loop
33
+ start_loop
34
+ when @config.end_loop
35
+ end_loop
36
+ when @config.next_cursol
37
+ next_cursol
38
+ @code_cursol += 1
39
+ when @config.previous_cursol
40
+ previous_cursol
41
+ @code_cursol += 1
42
+ when @config.display
43
+ display
44
+ @code_cursol += 1
45
+ when @config.read
46
+ read
47
+ @code_cursol += 1
48
+ end
49
+ break if @code_cursol >= @tokens.size
50
+ end
51
+ end
52
+ # rubocop:enable CyclomaticComplexity, MethodLength
53
+
54
+ def increment
55
+ @tape[@memory_cursol] += 1
56
+ end
57
+
58
+ def decrement
59
+ fail InvalidMemoryAccessError if @tape[@memory_cursol].zero?
60
+ @tape[@memory_cursol] -= 1
61
+ end
62
+
63
+ def start_loop
64
+ @loop_stack << @code_cursol
65
+ return goto_end_loop_next if @tape[@memory_cursol] == 0
66
+ @code_cursol += 1
67
+ end
68
+
69
+ def goto_end_loop_next
70
+ hit_cnt = 0
71
+ index = 0
72
+ @tokens[@code_cursol..-1].each_with_index do |token, i|
73
+ hit_cnt += 1 if token == @config.end_loop
74
+ next unless hit_cnt == @loop_stack.size
75
+ index = i + @code_cursol
76
+ break
77
+ end
78
+ @loop_stack.pop
79
+ @code_cursol = index + 1
80
+ end
81
+
82
+ def end_loop
83
+ fail InvalidLoopError, 'Invalid Loop.' if @loop_stack.empty?
84
+ @code_cursol = @loop_stack.pop
85
+ end
86
+
87
+ def next_cursol
88
+ @memory_cursol += 1
89
+ end
90
+
91
+ def previous_cursol
92
+ fail InvalidCursolError, 'Invalid Cursol.' if @memory_cursol.zero?
93
+ @memory_cursol -= 1
94
+ end
95
+
96
+ def display
97
+ putc @tape[@memory_cursol]
98
+ end
99
+
100
+ def read
101
+ @tape[@memory_cursol] = STDIN.readchar.ord
102
+ end
103
+ end
104
+
105
+ class InvalidMemoryAccessError < StandardError; end
106
+ class InvalidLoopError < StandardError; end
107
+ class InvalidCursolError < StandardError; end
108
+ end
@@ -0,0 +1,4 @@
1
+ # Orenono
2
+ module Orenono
3
+ VERSION = '0.0.1'
4
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ require 'brain'
3
+ require 'orenono_dsl'
4
+
5
+ module Orenono
6
+ # Orenono Core
7
+ class Core
8
+ ORENONO_FILE = 'Orenonofile'
9
+ ORENONO_TEMPLATE = <<-EOS
10
+ # encoding: utf-8
11
+
12
+ # increment command
13
+ # increment's default value => "+"
14
+ increment "+"
15
+
16
+ # decrement command
17
+ # decrement's default value => "-"
18
+ decrement "-"
19
+
20
+ # start_loop command
21
+ # start_loop's default value => "["
22
+ start_loop "["
23
+
24
+ # end_loop command
25
+ # end_loop's default value => "]"
26
+ end_loop "]"
27
+
28
+ # next_cursol command
29
+ # next_cursol's default value => ">"
30
+ next_cursol ">"
31
+
32
+ # previous_cursol command
33
+ # previous_cursol's default value => "<"
34
+ previous_cursol "<"
35
+
36
+ # display command
37
+ # display's default value => "."
38
+ display "."
39
+
40
+ # read command
41
+ # read's default value => ","
42
+ read ","
43
+ EOS
44
+
45
+ # Generate Orenonofile to current directory.
46
+ def init
47
+ File.open(ORENONO_FILE, 'w') { |f|f.puts ORENONO_TEMPLATE }
48
+ end
49
+
50
+ # Execute brain f**k
51
+ def execute(file)
52
+ src = read_dsl
53
+ dsl = Orenono::Dsl.new
54
+ dsl.instance_eval src if File.exist?(ORENONO_FILE)
55
+ code = File.open(file, 'r:utf-8') { |f|f.read }
56
+ ob = Orenono::Brain.new(dsl.orenono, code)
57
+ ob.run
58
+ end
59
+
60
+ private
61
+
62
+ def read_dsl
63
+ File.open(ORENONO_FILE) { |f|f.read } if File.exist?(ORENONO_FILE)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ require 'orenono_dsl_model'
3
+
4
+ module Orenono
5
+ # Dsl
6
+ class Dsl
7
+ attr_accessor :orenono
8
+
9
+ # String Define
10
+ [
11
+ :increment, :decrement, :start_loop, :end_loop, :next_cursol,
12
+ :previous_cursol, :display, :read].each do |f|
13
+ define_method f do |value|
14
+ @orenono.send("#{f}=", value)
15
+ end
16
+ end
17
+
18
+ def initialize
19
+ @orenono = Orenono::DslModel.new
20
+ @orenono.increment = '+'
21
+ @orenono.decrement = '-'
22
+ @orenono.start_loop = '['
23
+ @orenono.end_loop = ']'
24
+ @orenono.next_cursol = '>'
25
+ @orenono.previous_cursol = '<'
26
+ @orenono.display = '.'
27
+ @orenono.read = ','
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ # rubocop:disable LineLength
4
+ module Orenono
5
+ # DslModel
6
+ class DslModel
7
+ # increment command
8
+ attr_accessor :increment
9
+ # decrement command
10
+ attr_accessor :decrement
11
+ # start_loop command
12
+ attr_accessor :start_loop
13
+ # end_loop command
14
+ attr_accessor :end_loop
15
+ # next_cursol command
16
+ attr_accessor :next_cursol
17
+ # previous_cursol command
18
+ attr_accessor :previous_cursol
19
+ # display command
20
+ attr_accessor :display
21
+ # read command
22
+ attr_accessor :read
23
+
24
+ def token_patterns
25
+ instance_variables.map do |key|
26
+ sap_key = instance_variable_get(key)
27
+ '+.[]'.split('').include?(sap_key) ? "\\#{sap_key}" : sap_key
28
+ end.join('|')
29
+ end
30
+ end
31
+ end
data/orenono.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'orenono/version'
5
+
6
+ # rubocop:disable LineLength
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'orenono'
9
+ spec.version = Orenono::VERSION
10
+ spec.authors = ['tbpgr']
11
+ spec.email = ['tbpgr@tbpgr.jp']
12
+ spec.summary = %q(New Brainf**k derivation language generator and executor.)
13
+ spec.description = %q(New Brainf**k derivation language generator and executor.)
14
+ spec.homepage = 'https://github.com/tbpgr/orenono'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.6'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec'
25
+ end
26
+ # rubocop:enable LineLength
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ # increment command
4
+ # increment's default value => "+"
5
+ increment "+"
6
+
7
+ # decrement command
8
+ # decrement's default value => "-"
9
+ decrement "-"
10
+
11
+ # start_loop command
12
+ # start_loop's default value => "["
13
+ start_loop "["
14
+
15
+ # end_loop command
16
+ # end_loop's default value => "]"
17
+ end_loop "]"
18
+
19
+ # next_cursol command
20
+ # next_cursol's default value => ">"
21
+ next_cursol ">"
22
+
23
+ # previous_cursol command
24
+ # previous_cursol's default value => "<"
25
+ previous_cursol "<"
26
+
27
+ # display command
28
+ # display's default value => "."
29
+ display "."
30
+
31
+ # read command
32
+ # read's default value => ","
33
+ read ","
@@ -0,0 +1,2 @@
1
+ +++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
2
+ ------------.<++++++++.--------.+++.------.--------.>+.
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ increment "足す"
4
+ decrement "引く"
5
+ start_loop "はじめ"
6
+ end_loop "おわり"
7
+ next_cursol "次"
8
+ previous_cursol "前"
9
+ display "出"
10
+ read "入"
@@ -0,0 +1,2 @@
1
+ 足す足す足す足す足す足す足す足す足すはじめ次足す足す足す足す足す足す足す足す次足す足す足す足す足す足す足す足す足す足す足す次足す足す足す足す足す前前前引くおわり次出次足す足す出足す足す足す足す足す足す足す出出足す足す足す出次引く出
2
+ 引く引く引く引く引く引く引く引く引く引く引く引く出前足す足す足す足す足す足す足す足す出引く引く引く引く引く引く引く引く出足す足す足す出引く引く引く引く引く引く出引く引く引く引く引く引く引く引く出次足す出
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ increment ":heavy_plus_sign:"
4
+ decrement ":heavy_minus_sign:"
5
+ start_loop ":baby:"
6
+ end_loop ":older_man:"
7
+ next_cursol ":arrow_right:"
8
+ previous_cursol ":arrow_left:"
9
+ display ":blossom:"
10
+ read ":seedling:"
@@ -0,0 +1,2 @@
1
+ :heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::baby::arrow_right::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::arrow_right::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::arrow_right::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::arrow_left::arrow_left::arrow_left::heavy_minus_sign::older_man::arrow_right::blossom::arrow_right::heavy_plus_sign::heavy_plus_sign::blossom::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::blossom::blossom::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::blossom::arrow_right::heavy_minus_sign::blossom:
2
+ :heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::blossom::arrow_left::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::blossom::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::blossom::heavy_plus_sign::heavy_plus_sign::heavy_plus_sign::blossom::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::blossom::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::heavy_minus_sign::blossom::arrow_right::heavy_plus_sign::blossom:
@@ -0,0 +1,354 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'brain'
4
+
5
+ # rubocop:disable Eval
6
+ def capture(st)
7
+ begin
8
+ st = st.to_s
9
+ eval "$#{st} = StringIO.new"
10
+ yield
11
+ result = eval("$#{st}").string
12
+ ensure
13
+ eval("$#{st} = #{st.upcase}")
14
+ end
15
+ result
16
+ end
17
+ # rubocop:enable Eval
18
+
19
+ # rubocop:disable Tab, UnusedMethodArgument
20
+ describe Orenono::Brain do
21
+ context :increment do
22
+ cases = [
23
+ {
24
+ case_no: 1,
25
+ case_title: 'valid increment',
26
+ expected: 1
27
+ }
28
+ ]
29
+
30
+ cases.each do |c|
31
+ it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
32
+ begin
33
+ case_before c
34
+
35
+ # -- given --
36
+ brain = Orenono::Brain.new(Orenono::Dsl.new.orenono)
37
+
38
+ # -- when --
39
+ brain.increment
40
+ actual = brain.tape[brain.memory_cursol]
41
+
42
+ # -- then --
43
+ expect(actual).to eq(c[:expected])
44
+ ensure
45
+ case_after c
46
+ end
47
+ end
48
+
49
+ def case_before(c)
50
+ # implement each case before
51
+ end
52
+
53
+ def case_after(c)
54
+ # implement each case after
55
+ end
56
+ end
57
+ end
58
+
59
+ context :decrement do
60
+ cases = [
61
+ {
62
+ case_no: 1,
63
+ case_title: 'decrement exception',
64
+ increment: 0,
65
+ decrement: 1,
66
+ expect_error: true
67
+ },
68
+ {
69
+ case_no: 2,
70
+ case_title: 'valid decrement',
71
+ increment: 1,
72
+ decrement: 1,
73
+ expected: 0
74
+ }
75
+ ]
76
+
77
+ cases.each do |c|
78
+ it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
79
+ begin
80
+ case_before c
81
+
82
+ # -- given --
83
+ brain = Orenono::Brain.new(Orenono::Dsl.new.orenono)
84
+ c[:increment].times { brain.increment }
85
+
86
+ # -- when --
87
+ if c[:expect_error]
88
+ expect { brain.decrement }.to raise_error(StandardError)
89
+ next
90
+ end
91
+ brain.decrement
92
+ actual = brain.tape[brain.memory_cursol]
93
+
94
+ # -- then --
95
+ expect(actual).to eq(c[:expected])
96
+ ensure
97
+ case_after c
98
+ end
99
+ end
100
+
101
+ def case_before(c)
102
+ # implement each case before
103
+ end
104
+
105
+ def case_after(c)
106
+ # implement each case after
107
+ end
108
+ end
109
+ end
110
+
111
+ context :start_loop do
112
+ cases = [
113
+ {
114
+ case_no: 1,
115
+ case_title: 'valid single start_loop',
116
+ loop_stack: [],
117
+ tape: [1],
118
+ memory_cursol: 0,
119
+ code_cursol: 10,
120
+ expected: [10]
121
+ },
122
+ {
123
+ case_no: 2,
124
+ case_title: 'valid multi start_loop',
125
+ loop_stack: [2],
126
+ tape: [1, 1],
127
+ memory_cursol: 1,
128
+ code_cursol: 0,
129
+ code_cursol: 10,
130
+ expected: [2, 10]
131
+ }
132
+ ]
133
+
134
+ cases.each do |c|
135
+ it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
136
+ begin
137
+ case_before c
138
+
139
+ # -- given --
140
+ brain = Orenono::Brain.new(Orenono::Dsl.new.orenono)
141
+ brain.instance_variable_set(:@loop_stack, c[:loop_stack])
142
+ brain.instance_variable_set(:@memory_cursol, c[:memory_cursol])
143
+ brain.instance_variable_set(:@tape, c[:tape])
144
+ brain.instance_variable_set(:@code_cursol, c[:code_cursol])
145
+
146
+ # -- when --
147
+ brain.start_loop
148
+ actual = brain.loop_stack
149
+
150
+ # -- then --
151
+ expect(actual).to eq(c[:expected])
152
+ ensure
153
+ case_after c
154
+ end
155
+ end
156
+
157
+ def case_before(c)
158
+ # implement each case before
159
+ end
160
+
161
+ def case_after(c)
162
+ # implement each case after
163
+ end
164
+ end
165
+ end
166
+
167
+ context :end_loop do
168
+ cases = [
169
+ {
170
+ case_no: 1,
171
+ case_title: 'end_loop exception',
172
+ loop_stack: [],
173
+ expect_error: true
174
+ },
175
+ {
176
+ case_no: 2,
177
+ case_title: 'reloop',
178
+ tape: [0, 1, 2, 1],
179
+ loop_stack: [2],
180
+ expected: 2
181
+ },
182
+ {
183
+ case_no: 3,
184
+ case_title: 'end loop',
185
+ tape: [0, 1, 2, 0, 0],
186
+ loop_stack: [2],
187
+ expected: 2
188
+ }
189
+ ]
190
+
191
+ cases.each do |c|
192
+ it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
193
+ begin
194
+ case_before c
195
+
196
+ # -- given --
197
+ brain = Orenono::Brain.new(Orenono::Dsl.new.orenono)
198
+ brain.instance_variable_set(:@loop_stack, c[:loop_stack])
199
+ brain.instance_variable_set(:@tape, c[:tape])
200
+
201
+ # -- when --
202
+ if c[:expect_error]
203
+ expect { brain.end_loop }.to raise_error(StandardError)
204
+ next
205
+ end
206
+ brain.end_loop
207
+ actual = brain.code_cursol
208
+
209
+ # -- then --
210
+ expect(actual).to eq(c[:expected])
211
+ ensure
212
+ case_after c
213
+ end
214
+ end
215
+
216
+ def case_before(c)
217
+ # implement each case before
218
+ end
219
+
220
+ def case_after(c)
221
+ # implement each case after
222
+ end
223
+ end
224
+ end
225
+
226
+ context :next_cursol do
227
+ cases = [
228
+ {
229
+ case_no: 1,
230
+ case_title: 'valid move',
231
+ memory_cursol: 0,
232
+ expected: 1
233
+ }
234
+ ]
235
+
236
+ cases.each do |c|
237
+ it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
238
+ begin
239
+ case_before c
240
+
241
+ # -- given --
242
+ brain = Orenono::Brain.new(Orenono::Dsl.new.orenono)
243
+ brain.instance_variable_set(:@memory_cursol, c[:memory_cursol])
244
+
245
+ # -- when --
246
+ brain.next_cursol
247
+ actual = brain.memory_cursol
248
+
249
+ # -- then --
250
+ expect(actual).to eq(c[:expected])
251
+ ensure
252
+ case_after c
253
+ end
254
+ end
255
+
256
+ def case_before(c)
257
+ # implement each case before
258
+ end
259
+
260
+ def case_after(c)
261
+ # implement each case after
262
+ end
263
+ end
264
+ end
265
+
266
+ context :previous_cursol do
267
+ cases = [
268
+ {
269
+ case_no: 1,
270
+ case_title: 'previous memory_cursol exception',
271
+ memory_cursol: 0,
272
+ expect_error: true
273
+ },
274
+ {
275
+ case_no: 2,
276
+ case_title: 'valid move',
277
+ memory_cursol: 1,
278
+ expected: 0
279
+ }
280
+ ]
281
+
282
+ cases.each do |c|
283
+ it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
284
+ begin
285
+ case_before c
286
+
287
+ # -- given --
288
+ brain = Orenono::Brain.new(Orenono::Dsl.new.orenono)
289
+ brain.instance_variable_set(:@memory_cursol, c[:memory_cursol])
290
+
291
+ # -- when --
292
+ if c[:expect_error]
293
+ expect { brain.previous_cursol }.to raise_error(StandardError)
294
+ next
295
+ end
296
+ brain.previous_cursol
297
+ actual = brain.memory_cursol
298
+
299
+ # -- then --
300
+ expect(actual).to eq(c[:expected])
301
+ ensure
302
+ case_after c
303
+ end
304
+ end
305
+
306
+ def case_before(c)
307
+ # implement each case before
308
+ end
309
+
310
+ def case_after(c)
311
+ # implement each case after
312
+ end
313
+ end
314
+ end
315
+
316
+ context :display do
317
+ cases = [
318
+ {
319
+ case_no: 1,
320
+ case_title: 'case_title',
321
+ tape: [65],
322
+ memory_cursol: 0,
323
+ expected: 'A'
324
+ }
325
+ ]
326
+
327
+ cases.each do |c|
328
+ it "|case_no=#{c[:case_no]}|case_title=#{c[:case_title]}" do
329
+ begin
330
+ case_before c
331
+
332
+ # -- given --
333
+ brain = Orenono::Brain.new(Orenono::Dsl.new.orenono)
334
+ brain.instance_variable_set(:@tape, c[:tape])
335
+ brain.instance_variable_set(:@memory_cursol, c[:memory_cursol])
336
+
337
+ # -- when & then --
338
+ capture(:stdout) { brain.display }.should == c[:expected]
339
+ ensure
340
+ case_after c
341
+ end
342
+ end
343
+
344
+ def case_before(c)
345
+ # implement each case before
346
+ end
347
+
348
+ def case_after(c)
349
+ # implement each case after
350
+ end
351
+ end
352
+ end
353
+ end
354
+ # rubocop:enable Tab, UnusedMethodArgument
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+ Coveralls.wear!
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ Coveralls::SimpleCov::Formatter
8
+ ]
9
+ SimpleCov.start do
10
+ add_filter '/spec/'
11
+ end
12
+ RSpec.configure do |config|
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: orenono
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - tbpgr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: New Brainf**k derivation language generator and executor.
56
+ email:
57
+ - tbpgr@tbpgr.jp
58
+ executables:
59
+ - orenono
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .coveralls.yml
64
+ - .gitignore
65
+ - .rspec
66
+ - .travis.yml
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/orenono
72
+ - lib/brain.rb
73
+ - lib/orenono/version.rb
74
+ - lib/orenono_core.rb
75
+ - lib/orenono_dsl.rb
76
+ - lib/orenono_dsl_model.rb
77
+ - orenono.gemspec
78
+ - samples/default/Orenonofile
79
+ - samples/default/sample.bf
80
+ - samples/pattern1/Orenonofile
81
+ - samples/pattern1/orenono.bf
82
+ - samples/pattern2/Orenonofile
83
+ - samples/pattern2/orenono.bf
84
+ - spec/brain_spec.rb
85
+ - spec/spec_helper.rb
86
+ homepage: https://github.com/tbpgr/orenono
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.3.0
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: New Brainf**k derivation language generator and executor.
110
+ test_files:
111
+ - spec/brain_spec.rb
112
+ - spec/spec_helper.rb