mojikun 1.0.0

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 ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mojikun.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Steve Klabnik
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,47 @@
1
+ # Mojikun
2
+
3
+ A Brainfuck based on Emoji.
4
+
5
+ Instructions:
6
+
7
+ 👉 Move the pointer to the right
8
+ 👈 Move the pointer to the left
9
+ 👍 Increment the memory cell under the pointer
10
+ 👎 Decrement the memory cell under the pointer
11
+ 💻 Output the character signified by the cell at the pointer
12
+ 💾 Input a character and store it in the cell at the pointer
13
+ 🔃 Jump past the matching 🔙 if the cell under the pointer is 0
14
+ 🔙 Jump back to the matching 🔃 if the cell under the pointer is nonzero
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ gem 'mojikun'
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install mojikun
29
+
30
+ ## Usage
31
+
32
+ A `mojikun` binary is provided to let you run programs. There is an examples
33
+ directory which has some examples. Use `mojikun` like any other interpreter:
34
+
35
+ ```
36
+ mokikun examples/hello.moji
37
+ ```
38
+
39
+ `.moji` is the preferred file ending for Mojikun.
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/*_test.rb']
8
+ t.ruby_opts = ['-r./test/test_helper.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
data/bin/mojikun ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mojikun'
4
+
5
+ source_code = ARGF.read.chomp
6
+
7
+ tokens = Mojikun::Lexer.new(source_code).call
8
+
9
+ ast = Mojikun::Parser.new(tokens).call
10
+
11
+ runtime = Mojikun::Runtime.new
12
+ interpreter = Mojikun::Interpreter.new(runtime)
13
+
14
+ interpreter.evaluate(ast)
@@ -0,0 +1 @@
1
+ 👍👍👍👍👍👍👍👍👍👍🔃👉👍👍👍👍👍👍👍👉👍👍👍👍👍👍👍👍👍👍👉👍👍👍👉👍👈👈👈👈👎🔙👉👍👍💻👉👍💻👍👍👍👍👍👍👍💻💻👍👍👍💻👉👍👍💻👈👈👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍💻👉💻👍👍👍💻👎👎👎👎👎👎💻👎👎👎👎👎👎👎👎💻👉👍💻👉💻
@@ -0,0 +1,5 @@
1
+ module Mojikun
2
+ class DisplayNode
3
+ end
4
+ end
5
+
@@ -0,0 +1,5 @@
1
+ module Mojikun
2
+ class EndLoopNode
3
+ end
4
+ end
5
+
@@ -0,0 +1,3 @@
1
+ module Mojikun
2
+ MismatchedBracketError = Class.new(StandardError)
3
+ end
@@ -0,0 +1,73 @@
1
+ require 'io/console'
2
+
3
+ require 'mojikun/errors'
4
+
5
+ require 'mojikun/point_right_node'
6
+ require 'mojikun/point_left_node'
7
+ require 'mojikun/thumbs_up_node'
8
+ require 'mojikun/thumbs_down_node'
9
+ require 'mojikun/display_node'
10
+ require 'mojikun/save_node'
11
+ require 'mojikun/loop_node'
12
+ require 'mojikun/end_loop_node'
13
+
14
+
15
+ module Mojikun
16
+ class Interpreter
17
+ attr_reader :runtime, :loop_map
18
+
19
+ def initialize(runtime)
20
+ @runtime = runtime
21
+ @loop_map = {}
22
+ end
23
+
24
+ def evaluate(ast)
25
+ # first, update the loop map so we know positions of LoopNode/EndLoopNode
26
+ loop_counter = 0
27
+ loop_stack = []
28
+
29
+ ast.each_with_index do |node, index|
30
+ case node
31
+ when LoopNode
32
+ loop_stack << index
33
+ when EndLoopNode
34
+ raise MismatchedBracketError if loop_stack.empty?
35
+
36
+ @loop_map[loop_stack.pop] = index
37
+ end
38
+ end
39
+
40
+ raise MismatchedBracketError unless loop_stack.empty?
41
+
42
+ # then, evaluate the nodes
43
+ until(runtime.instruction_pointer == ast.count)
44
+ case ast[runtime.instruction_pointer]
45
+ when PointRightNode
46
+ runtime.increment_data_pointer
47
+ when PointLeftNode
48
+ runtime.decrement_data_pointer
49
+ when ThumbsUpNode
50
+ runtime.increment_data
51
+ when ThumbsDownNode
52
+ runtime.decrement_data
53
+ when DisplayNode
54
+ STDOUT.print(runtime.current_data.chr)
55
+ when SaveNode
56
+ runtime.set_current_data(STDIN.getch.ord)
57
+ when LoopNode
58
+ if runtime.current_data == 0
59
+ runtime.set_instruction_pointer(@loop_map[runtime.instruction_pointer])
60
+ end
61
+ when EndLoopNode
62
+ if runtime.current_data != 0
63
+ runtime.set_instruction_pointer(@loop_map.key(runtime.instruction_pointer))
64
+ end
65
+ end
66
+
67
+ runtime.increment_instruction_pointer
68
+ end
69
+
70
+ self
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,12 @@
1
+ module Mojikun
2
+ class Lexer
3
+ def initialize(source)
4
+ @source = source
5
+ end
6
+
7
+ # omg easiest lexer ever
8
+ def call
9
+ @source.split(//)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module Mojikun
2
+ class LoopNode
3
+ end
4
+ end
5
+
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ module Mojikun
3
+ class Parser
4
+ def initialize(tokens)
5
+ @tokens = tokens
6
+ end
7
+
8
+ def call
9
+ @tokens.collect do |token|
10
+ case token
11
+ when "👈"
12
+ PointLeftNode.new
13
+ when "👉"
14
+ PointRightNode.new
15
+ when "👍"
16
+ ThumbsUpNode.new
17
+ when "👎"
18
+ ThumbsDownNode.new
19
+ when "💾"
20
+ SaveNode.new
21
+ when "💻"
22
+ DisplayNode.new
23
+ when "🔃"
24
+ LoopNode.new
25
+ when "🔙"
26
+ EndLoopNode.new
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,4 @@
1
+ module Mojikun
2
+ class PointLeftNode
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Mojikun
2
+ class PointRightNode
3
+ end
4
+ end
5
+
@@ -0,0 +1,55 @@
1
+ module Mojikun
2
+ class Runtime
3
+ attr_reader :instruction_pointer,
4
+ :data_pointer,
5
+ :data
6
+
7
+ def initialize
8
+ @instruction_pointer = 0
9
+ @data_pointer = 0
10
+ @data = [0] * 30000 # original interpreter had 30,000 cells
11
+ end
12
+
13
+ def increment_data_pointer
14
+ @data_pointer += 1
15
+ self
16
+ end
17
+
18
+ def decrement_data_pointer
19
+ @data_pointer -= 1
20
+ self
21
+ end
22
+
23
+ def current_data
24
+ data[data_pointer]
25
+ end
26
+
27
+ def set_current_data(val)
28
+ data[data_pointer] = val
29
+
30
+ self
31
+ end
32
+
33
+ def increment_data
34
+ data[data_pointer] += 1
35
+ self
36
+ end
37
+
38
+ def decrement_data
39
+ data[data_pointer] -= 1
40
+ self
41
+ end
42
+
43
+ def set_instruction_pointer(num)
44
+ @instruction_pointer = num
45
+
46
+ self
47
+ end
48
+
49
+ def increment_instruction_pointer
50
+ @instruction_pointer += 1
51
+
52
+ self
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ module Mojikun
2
+ class SaveNode
3
+ end
4
+ end
5
+
@@ -0,0 +1,5 @@
1
+ module Mojikun
2
+ class ThumbsDownNode
3
+ end
4
+ end
5
+
@@ -0,0 +1,5 @@
1
+ module Mojikun
2
+ class ThumbsUpNode
3
+ end
4
+ end
5
+
@@ -0,0 +1,3 @@
1
+ module Mojikun
2
+ VERSION = "1.0.0"
3
+ end
data/lib/mojikun.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'mojikun/version'
2
+
3
+ require 'mojikun/interpreter'
4
+ require 'mojikun/lexer'
5
+ require 'mojikun/parser'
6
+ require 'mojikun/runtime'
data/mojikun.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mojikun/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "mojikun"
8
+ gem.version = Mojikun::VERSION
9
+ gem.authors = ["Steve Klabnik"]
10
+ gem.email = ["steve@steveklabnik.com"]
11
+ gem.description = %q{A simple programming language, using emoji.}
12
+ gem.summary = %q{A simple programming language, using emoji.}
13
+ gem.homepage = "https://github.com/steveklabnik/mojikun"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,131 @@
1
+ require 'mojikun/interpreter'
2
+ require 'mojikun/runtime'
3
+
4
+ require 'minitest/autorun'
5
+
6
+ class InterpreterTest < Minitest::Unit::TestCase
7
+ def setup
8
+ @runtime = Mojikun::Runtime.new
9
+ @interpreter = Mojikun::Interpreter.new(@runtime)
10
+ end
11
+
12
+ def test_runtime
13
+ assert_equal @runtime, @interpreter.runtime
14
+ end
15
+
16
+ def test_eval_point_right_node
17
+ ast = [Mojikun::PointRightNode.new]
18
+ assert_equal 1, @interpreter.evaluate(ast).runtime.data_pointer
19
+ end
20
+
21
+ def test_eval_point_left_node
22
+ ast = [Mojikun::PointLeftNode.new]
23
+ assert_equal -1, @interpreter.evaluate(ast).runtime.data_pointer
24
+ end
25
+
26
+ def test_eval_thumbs_up_node
27
+ ast = [Mojikun::ThumbsUpNode.new]
28
+ assert_equal 1, @interpreter.evaluate(ast).runtime.current_data
29
+ end
30
+
31
+ def test_eval_thumbs_down_node
32
+ ast = [Mojikun::ThumbsDownNode.new]
33
+ assert_equal -1, @interpreter.evaluate(ast).runtime.current_data
34
+ end
35
+
36
+ def test_eval_display_node
37
+ mock = MiniTest::Mock.new.expect(:print, nil, ["H"])
38
+
39
+ redefine_constant("STDOUT", mock) do
40
+
41
+ ast = 72.times.collect { Mojikun::ThumbsUpNode.new }
42
+ ast << Mojikun::DisplayNode.new
43
+
44
+ @interpreter.evaluate(ast)
45
+ end
46
+
47
+ mock.verify
48
+ end
49
+
50
+ def test_eval_save_node
51
+ STDIN.stub :getch, "a" do
52
+ ast = [Mojikun::SaveNode.new]
53
+
54
+ @interpreter.evaluate(ast)
55
+
56
+ assert_equal 97, @interpreter.runtime.current_data
57
+ end
58
+ end
59
+
60
+ def test_eval_loop_node
61
+ ast = [Mojikun::LoopNode.new, Mojikun::ThumbsUpNode.new, Mojikun::EndLoopNode.new]
62
+ @interpreter.evaluate(ast)
63
+
64
+ assert_equal 0, @interpreter.runtime.current_data
65
+ end
66
+
67
+ def test_eval_end_loop_node
68
+ # so we enter the loop
69
+ ast = [Mojikun::ThumbsUpNode.new,
70
+ Mojikun::LoopNode.new,
71
+
72
+ # move right once, increment, move left
73
+ Mojikun::PointRightNode.new,
74
+ Mojikun::ThumbsUpNode.new,
75
+ Mojikun::PointLeftNode.new,
76
+
77
+ # decrement so we leave the loop
78
+ Mojikun::ThumbsDownNode.new,
79
+ Mojikun::EndLoopNode.new,
80
+
81
+ # move right so we can see the 1 we did in the loop
82
+ Mojikun::PointRightNode.new,
83
+ ]
84
+ @interpreter.evaluate(ast)
85
+
86
+ assert_equal 1, @interpreter.runtime.current_data
87
+ end
88
+
89
+ def test_loop_map
90
+ ast = [Mojikun::LoopNode.new, Mojikun::EndLoopNode.new]
91
+
92
+ @interpreter.evaluate(ast)
93
+
94
+ map = {}
95
+ map[0] = 1
96
+
97
+ assert_equal map, @interpreter.loop_map
98
+ end
99
+
100
+ def test_nested_loop_map
101
+ ast = [Mojikun::LoopNode.new, Mojikun::LoopNode.new, Mojikun::EndLoopNode.new, Mojikun::EndLoopNode.new]
102
+
103
+ @interpreter.evaluate(ast)
104
+
105
+ map = {}
106
+ map[0] = 3
107
+ map[1] = 2
108
+
109
+ assert_equal map, @interpreter.loop_map
110
+ end
111
+
112
+ def test_uneven_loop
113
+ ast = [Mojikun::LoopNode.new]
114
+ begin
115
+ @interpreter.evaluate(ast)
116
+ flunk "Did not throw MismatchedBracketError"
117
+ rescue Mojikun::MismatchedBracketError
118
+ pass
119
+ end
120
+ end
121
+
122
+ def test_uneven_end_loop
123
+ ast = [Mojikun::EndLoopNode.new]
124
+ begin
125
+ @interpreter.evaluate(ast)
126
+ flunk "Did not throw MismatchedBracketError"
127
+ rescue Mojikun::MismatchedBracketError
128
+ pass
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ require 'mojikun/lexer'
4
+
5
+ require 'minitest/autorun'
6
+
7
+ class TestLexer < MiniTest::Unit::TestCase
8
+ def test_lexing
9
+ source = "👍"
10
+ assert_equal ["👍"], Mojikun::Lexer.new(source).call
11
+ end
12
+
13
+ def test_lexing
14
+ source = "👍👍"
15
+ assert_equal ["👍", "👍"], Mojikun::Lexer.new(source).call
16
+ end
17
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+
3
+ require 'mojikun/parser'
4
+
5
+ require 'mojikun/display_node'
6
+ require 'mojikun/end_loop_node'
7
+ require 'mojikun/loop_node'
8
+ require 'mojikun/point_left_node'
9
+ require 'mojikun/point_right_node'
10
+ require 'mojikun/save_node'
11
+ require 'mojikun/thumbs_down_node'
12
+ require 'mojikun/thumbs_up_node'
13
+
14
+ require 'minitest/autorun'
15
+
16
+ class TestParser < MiniTest::Unit::TestCase
17
+ def test_point_right
18
+ tokens = ["👉"]
19
+ assert_kind_of Mojikun::PointRightNode, Mojikun::Parser.new(tokens).call.first
20
+ end
21
+
22
+ def test_point_left
23
+ tokens = ["👈"]
24
+ assert_kind_of Mojikun::PointLeftNode, Mojikun::Parser.new(tokens).call.first
25
+ end
26
+
27
+ def test_thumbs_up
28
+ tokens = ["👍"]
29
+ assert_kind_of Mojikun::ThumbsUpNode, Mojikun::Parser.new(tokens).call.first
30
+ end
31
+
32
+ def test_thumbs_down
33
+ tokens = ["👎"]
34
+ assert_kind_of Mojikun::ThumbsDownNode, Mojikun::Parser.new(tokens).call.first
35
+ end
36
+
37
+ def test_display
38
+ tokens = ["💻"]
39
+ assert_kind_of Mojikun::DisplayNode, Mojikun::Parser.new(tokens).call.first
40
+ end
41
+
42
+ def test_save
43
+ tokens = ["💾"]
44
+ assert_kind_of Mojikun::SaveNode, Mojikun::Parser.new(tokens).call.first
45
+ end
46
+
47
+ def test_loop
48
+ tokens = ["🔃"]
49
+ assert_kind_of Mojikun::LoopNode, Mojikun::Parser.new(tokens).call.first
50
+ end
51
+
52
+ def test_end_loop
53
+ tokens = ["🔙"]
54
+ assert_kind_of Mojikun::EndLoopNode, Mojikun::Parser.new(tokens).call.first
55
+ end
56
+ end
@@ -0,0 +1,60 @@
1
+ require 'mojikun/runtime'
2
+
3
+ require 'minitest/autorun'
4
+
5
+ class RuntimeTest < MiniTest::Unit::TestCase
6
+ def setup
7
+ @runtime = Mojikun::Runtime.new
8
+ end
9
+
10
+ def test_instruction_pointer
11
+ assert_equal 0, @runtime.instruction_pointer
12
+ end
13
+
14
+ def test_data_pointer
15
+ assert_equal 0, @runtime.data_pointer
16
+ end
17
+
18
+ def test_data
19
+ assert_equal [0] * 30000, @runtime.data
20
+ end
21
+
22
+ def test_increment_data_pointer
23
+ runtime = @runtime.increment_data_pointer
24
+ assert_equal 1, runtime.data_pointer
25
+ end
26
+
27
+ def test_decrement_data_pointer
28
+ runtime = @runtime.decrement_data_pointer
29
+ assert_equal -1, runtime.data_pointer
30
+ end
31
+
32
+ def test_current_data
33
+ assert_equal 0, @runtime.current_data
34
+ end
35
+
36
+ def test_increment_data
37
+ runtime = @runtime.increment_data
38
+ assert_equal 1, runtime.current_data
39
+ end
40
+
41
+ def test_decrement_data
42
+ runtime = @runtime.decrement_data
43
+ assert_equal -1, runtime.current_data
44
+ end
45
+
46
+ def test_set_current_data
47
+ runtime = @runtime.set_current_data(1337)
48
+ assert_equal 1337, runtime.current_data
49
+ end
50
+
51
+ def test_set_instruction_pointer
52
+ runtime = @runtime.set_instruction_pointer(2)
53
+ assert_equal 2, runtime.instruction_pointer
54
+ end
55
+
56
+ def test_increment_instruction_pointer
57
+ runtime = @runtime.increment_instruction_pointer
58
+ assert_equal 1, runtime.instruction_pointer
59
+ end
60
+ end
@@ -0,0 +1,11 @@
1
+ def redefine_constant(const, value)
2
+ orig = eval(const).dup
3
+
4
+ Object.send(:remove_const, const)
5
+ Object.const_set(const, value)
6
+
7
+ yield
8
+
9
+ Object.send(:remove_const, const)
10
+ Object.const_set(const, orig)
11
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mojikun
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Steve Klabnik
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-09 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A simple programming language, using emoji.
15
+ email:
16
+ - steve@steveklabnik.com
17
+ executables:
18
+ - mojikun
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - bin/mojikun
28
+ - examples/hello.moji
29
+ - lib/mojikun.rb
30
+ - lib/mojikun/display_node.rb
31
+ - lib/mojikun/end_loop_node.rb
32
+ - lib/mojikun/errors.rb
33
+ - lib/mojikun/interpreter.rb
34
+ - lib/mojikun/lexer.rb
35
+ - lib/mojikun/loop_node.rb
36
+ - lib/mojikun/parser.rb
37
+ - lib/mojikun/point_left_node.rb
38
+ - lib/mojikun/point_right_node.rb
39
+ - lib/mojikun/runtime.rb
40
+ - lib/mojikun/save_node.rb
41
+ - lib/mojikun/thumbs_down_node.rb
42
+ - lib/mojikun/thumbs_up_node.rb
43
+ - lib/mojikun/version.rb
44
+ - mojikun.gemspec
45
+ - test/interpreter_test.rb
46
+ - test/lexer_test.rb
47
+ - test/parser_test.rb
48
+ - test/runtime_test.rb
49
+ - test/test_helper.rb
50
+ homepage: https://github.com/steveklabnik/mojikun
51
+ licenses: []
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.24
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: A simple programming language, using emoji.
74
+ test_files:
75
+ - test/interpreter_test.rb
76
+ - test/lexer_test.rb
77
+ - test/parser_test.rb
78
+ - test/runtime_test.rb
79
+ - test/test_helper.rb
80
+ has_rdoc: