koi-reference-parser 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ *.gemspec
3
+ *.swp
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Aaron Gough (http://thingsaaronmade.com/)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,44 @@
1
+ = koi-reference-parser
2
+
3
+ This is the reference parser implementation for the programming language {Koi}[http://github.com/aarongough/koi]. The parser is implemented using a {Parsing Expression Grammar (PEG)}[http://en.wikipedia.org/wiki/Parsing_expression_grammar] that is run by a PEG engine called {Treetop}[http://treetop.rubyforge.org/].
4
+
5
+ === Example
6
+
7
+ The parser takes a text string containing a program like:
8
+
9
+ test = 1 + 2
10
+
11
+ And turns it into an {Abstract Syntax Tree (AST)}[http://en.wikipedia.org/wiki/Abstract_syntax_tree] that unambiguously represents the program's structure and meaning. The AST is represented as a series of Ruby objects that subclass a generic SyntaxNode class. The code above transformed into AST would look like:
12
+
13
+ <Block "test = 1 + 2">
14
+ <Statement "test = 1 + 2">
15
+ <Assignment "test = 1 + 2">
16
+ <Identifier "test">
17
+ <AssignmentOperator "=">
18
+ <Expression "1 + 2">
19
+ <AdditiveExpression "1 + 2">
20
+ <IntegerLiteral "1">
21
+ <AdditionOperator "+">
22
+ <IntegerLiteral "2">
23
+
24
+
25
+ === Installation
26
+
27
+ This parser is normally installed as part of Koi's default toolchain. However if you would like to install it on it's own you can do so by installing the gem like so:
28
+
29
+ gem install koi-reference-parser
30
+
31
+ === Usage
32
+
33
+ require 'rubygems'
34
+ require 'koi-reference-parser'
35
+
36
+ include KoiReferenceParser
37
+
38
+ ast = Parser.parse( program_text )
39
+
40
+ === Author & Credits
41
+
42
+ Author:: {Aaron Gough}[mailto:aaron@aarongough.com]
43
+
44
+ Copyright (c) 2010 {Aaron Gough}[http://thingsaaronmade.com/] ({thingsaaronmade.com}[http://thingsaaronmade.com/]), released under the MIT license
@@ -0,0 +1,43 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ begin
9
+ require 'jeweler'
10
+ Jeweler::Tasks.new do |gemspec|
11
+ gemspec.name = "koi-reference-parser"
12
+ gemspec.summary = "A reference parser for the Koi language."
13
+ gemspec.description = "A reference parser for the Koi language."
14
+ gemspec.email = "aaron@aarongough.com"
15
+ gemspec.homepage = "http://github.com/aarongough/koi-reference-parser"
16
+ gemspec.authors = ["Aaron Gough"]
17
+ gemspec.rdoc_options << '--line-numbers' << '--inline-source'
18
+ gemspec.extra_rdoc_files = ['README.rdoc', 'MIT-LICENSE']
19
+ gemspec.add_dependency('treetop')
20
+ end
21
+ rescue LoadError
22
+ puts "Jeweler not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+
26
+ desc 'Test koi-reference-parser.'
27
+ Rake::TestTask.new(:test) do |t|
28
+ t.libs << 'lib/*.rb'
29
+ t.libs << 'test'
30
+ t.pattern = 'test/**/*_test.rb'
31
+ t.verbose = true
32
+ end
33
+
34
+
35
+ desc 'Generate documentation for koi-reference-parser.'
36
+ Rake::RDocTask.new(:rdoc) do |rdoc|
37
+ rdoc.rdoc_dir = 'rdoc'
38
+ rdoc.title = 'koi-reference-parser'
39
+ rdoc.options << '--line-numbers' << '--inline-source'
40
+ rdoc.rdoc_files.include('README.rdoc')
41
+ rdoc.rdoc_files.include('lib/**/*.rb')
42
+ rdoc.rdoc_files.include('app/**/*.rb')
43
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+
3
+ require_files = []
4
+ require_files.concat Dir[File.join(File.dirname(__FILE__), 'parser', '**', '*.rb')]
5
+
6
+ require_files.each do |file|
7
+ require File.expand_path(file)
8
+ end
@@ -0,0 +1,2 @@
1
+ class ParseError < Exception
2
+ end
@@ -0,0 +1,197 @@
1
+ grammar KoiReferenceParser
2
+
3
+ rule block
4
+ statement+ <Block>
5
+ end
6
+
7
+ rule statement
8
+ space? ( hash_assignment / assignment / if / unless / function_call ) ';'? space? <Statement>
9
+ end
10
+
11
+ rule nil
12
+ "nil" <NilLiteral>
13
+ end
14
+
15
+ rule true
16
+ "true" <TrueLiteral>
17
+ end
18
+
19
+ rule false
20
+ "false" <FalseLiteral>
21
+ end
22
+
23
+ rule integer
24
+ ('+' / '-')? [0-9]+ <IntegerLiteral>
25
+ end
26
+
27
+ rule float
28
+ ('+' / '-')? [0-9]+ '.' [0-9]+ <FloatLiteral>
29
+ end
30
+
31
+ rule string
32
+ '"' ([^"\\] / "\\" . )* '"' <StringLiteral>
33
+ end
34
+
35
+ rule identifier
36
+ '$'? [a-zA-Z] [a-zA-Z0-9_]* <Identifier>
37
+ end
38
+
39
+ rule hash_assignment
40
+ identifier hash_accessor_list space? assignment_operator space? ( hash / function_definition / expression ) <HashAssignment>
41
+ end
42
+
43
+ rule assignment
44
+ identifier space? assignment_operator space? ( hash / function_definition / expression ) <Assignment>
45
+ end
46
+
47
+ ##################
48
+ # Flow control
49
+
50
+ rule if
51
+ 'if(' space? expression space? ')' space
52
+ block
53
+ space? 'end' space? <If>
54
+ end
55
+
56
+ rule unless
57
+ 'unless(' space? expression space? ')' space
58
+ block
59
+ space? 'end' space? <Unless>
60
+ end
61
+
62
+ ##################
63
+ # Functions
64
+
65
+ rule function_call
66
+ identifier space? '(' space? expression? space? ','? expression? space? ')' <FunctionCall>
67
+ end
68
+
69
+ rule function_definition
70
+ 'function(' space? identifier space? ')'
71
+ block
72
+ space? 'end' <FunctionDefinition>
73
+ end
74
+
75
+ ##################
76
+ # Whitespace
77
+
78
+ rule space
79
+ [\s]+ <Whitespace>
80
+ end
81
+
82
+ ##################
83
+ # Hashes
84
+
85
+ rule hash_accessor_list
86
+ hash_accessor+ <HashAccessorList>
87
+ end
88
+
89
+ rule hash_accessor
90
+ '[' expression ']' <HashAccessor>
91
+ end
92
+
93
+ rule hash
94
+ '{' key_value_list? '}' <HashLiteral>
95
+ end
96
+
97
+ rule key_value_list
98
+ key_value+ <KeyValueList>
99
+ end
100
+
101
+ rule key_value
102
+ space? expression space? '=>' space? expression space? ','? <KeyValue>
103
+ end
104
+
105
+ rule key
106
+ space? expression space? <Key>
107
+ end
108
+
109
+ rule value
110
+ space? expression space? <Value>
111
+ end
112
+
113
+ ##################
114
+ # Expressions
115
+
116
+ rule expression
117
+ space? (hash_access / comparative / additive) <Expression>
118
+ end
119
+
120
+ rule hash_access
121
+ identifier hash_accessor_list <HashAccess>
122
+ end
123
+
124
+ rule comparative
125
+ additive space? (equality_operator / inequality_operator / greater_than_operator / less_than_operator) space? additive <ComparativeExpression>
126
+ end
127
+
128
+ rule additive
129
+ multitive space? additive_operator space? additive <AdditiveExpression>
130
+ /
131
+ multitive
132
+ end
133
+
134
+ rule additive_operator
135
+ addition_operator
136
+ /
137
+ subtraction_operator
138
+ end
139
+
140
+ rule multitive
141
+ primary space? multitive_operator space? multitive <MultitiveExpression>
142
+ /
143
+ primary
144
+ end
145
+
146
+ rule multitive_operator
147
+ multiplication_operator
148
+ /
149
+ division_operator
150
+ end
151
+
152
+ rule primary
153
+ function_call / nil / false / true / identifier / float / integer / string
154
+ /
155
+ '(' space? expression space? ')' <Expression>
156
+ end
157
+
158
+ ##################
159
+ # Operators
160
+
161
+ rule assignment_operator
162
+ '=' <AssignmentOperator>
163
+ end
164
+
165
+ rule addition_operator
166
+ '+' <AdditionOperator>
167
+ end
168
+
169
+ rule subtraction_operator
170
+ '-' <SubtractionOperator>
171
+ end
172
+
173
+ rule multiplication_operator
174
+ '*' <MultiplicationOperator>
175
+ end
176
+
177
+ rule division_operator
178
+ '/' <DivisionOperator>
179
+ end
180
+
181
+ rule equality_operator
182
+ '==' <EqualityOperator>
183
+ end
184
+
185
+ rule inequality_operator
186
+ '!=' <InequalityOperator>
187
+ end
188
+
189
+ rule greater_than_operator
190
+ '>' <GreaterThanOperator>
191
+ end
192
+
193
+ rule less_than_operator
194
+ '<' <LessThanOperator>
195
+ end
196
+
197
+ end
@@ -0,0 +1,43 @@
1
+ class Parser
2
+
3
+ require 'treetop'
4
+ Treetop.load(File.expand_path(File.join(File.dirname(__FILE__), 'koi-reference-parser.treetop')))
5
+ @@parser = KoiReferenceParserParser.new
6
+
7
+ def self.parse(data)
8
+ tree = @@parser.parse(data)
9
+
10
+ if(tree.nil?)
11
+ if( data.length > 80 )
12
+ error_detail = "\n\n" + data.slice(@@parser.index - 120, 80).gsub("\n", ";")
13
+ error_detail += "\n" + data.slice(@@parser.index - 40, 80).gsub("\n", ";")
14
+ error_detail += "\n" + " "*40 + "^\n"
15
+ else
16
+ error_detail = "\n\n" + data.gsub("\n", ";")
17
+ error_detail += "\n" + " " * @@parser.index + "^\n"
18
+ end
19
+ raise ParseError, "Parse error at index: #{@@parser.index}#{error_detail}"
20
+ end
21
+
22
+ # clean up the tree by removing all nodes of default type 'SyntaxNode'
23
+ self.clean_tree(tree)
24
+ # clean up the tree further by removing all whitespace nodes
25
+ self.clean_whitespace(tree)
26
+ return tree
27
+ end
28
+
29
+ private
30
+
31
+ def self.clean_tree(root_node)
32
+ return if(root_node.elements.nil?)
33
+ root_node.elements.delete_if{|node| node.class.name == "Treetop::Runtime::SyntaxNode" }
34
+ root_node.elements.each {|node| self.clean_tree(node) }
35
+ end
36
+
37
+ def self.clean_whitespace(root_node)
38
+ return if(root_node.elements.nil?)
39
+ root_node.elements.delete_if{|node| node.class.name == "KoiReferenceParser::Whitespace" }
40
+ root_node.elements.each {|node| self.clean_whitespace(node) }
41
+ end
42
+
43
+ end
@@ -0,0 +1,114 @@
1
+ module KoiReferenceParser
2
+
3
+ class Block < Treetop::Runtime::SyntaxNode
4
+ end
5
+
6
+ class Statement < Treetop::Runtime::SyntaxNode
7
+ end
8
+
9
+ class HashAssignment < Treetop::Runtime::SyntaxNode
10
+ end
11
+
12
+ class Assignment < Treetop::Runtime::SyntaxNode
13
+ end
14
+
15
+ class FunctionDefinition < Treetop::Runtime::SyntaxNode
16
+ end
17
+
18
+ class If < Treetop::Runtime::SyntaxNode
19
+ end
20
+
21
+ class Unless < Treetop::Runtime::SyntaxNode
22
+ end
23
+
24
+ class FunctionCall < Treetop::Runtime::SyntaxNode
25
+ end
26
+
27
+ class NilLiteral < Treetop::Runtime::SyntaxNode
28
+ end
29
+
30
+ class TrueLiteral < Treetop::Runtime::SyntaxNode
31
+ end
32
+
33
+ class FalseLiteral < Treetop::Runtime::SyntaxNode
34
+ end
35
+
36
+ class IntegerLiteral < Treetop::Runtime::SyntaxNode
37
+ end
38
+
39
+ class FloatLiteral < Treetop::Runtime::SyntaxNode
40
+ end
41
+
42
+ class StringLiteral < Treetop::Runtime::SyntaxNode
43
+ end
44
+
45
+ class HashAccessorList < Treetop::Runtime::SyntaxNode
46
+ end
47
+
48
+ class HashAccessor < Treetop::Runtime::SyntaxNode
49
+ end
50
+
51
+ class HashLiteral < Treetop::Runtime::SyntaxNode
52
+ end
53
+
54
+ class KeyValueList < Treetop::Runtime::SyntaxNode
55
+ end
56
+
57
+ class KeyValue < Treetop::Runtime::SyntaxNode
58
+ end
59
+
60
+ class Key < Treetop::Runtime::SyntaxNode
61
+ end
62
+
63
+ class Value < Treetop::Runtime::SyntaxNode
64
+ end
65
+
66
+ class Identifier < Treetop::Runtime::SyntaxNode
67
+ end
68
+
69
+ class Whitespace < Treetop::Runtime::SyntaxNode
70
+ end
71
+
72
+ class AssignmentOperator < Treetop::Runtime::SyntaxNode
73
+ end
74
+
75
+ class EqualityOperator < Treetop::Runtime::SyntaxNode
76
+ end
77
+
78
+ class InequalityOperator < Treetop::Runtime::SyntaxNode
79
+ end
80
+
81
+ class GreaterThanOperator < Treetop::Runtime::SyntaxNode
82
+ end
83
+
84
+ class LessThanOperator < Treetop::Runtime::SyntaxNode
85
+ end
86
+
87
+ class AdditionOperator < Treetop::Runtime::SyntaxNode
88
+ end
89
+
90
+ class SubtractionOperator < Treetop::Runtime::SyntaxNode
91
+ end
92
+
93
+ class MultiplicationOperator < Treetop::Runtime::SyntaxNode
94
+ end
95
+
96
+ class DivisionOperator < Treetop::Runtime::SyntaxNode
97
+ end
98
+
99
+ class Expression < Treetop::Runtime::SyntaxNode
100
+ end
101
+
102
+ class HashAccess < Treetop::Runtime::SyntaxNode
103
+ end
104
+
105
+ class ComparativeExpression < Treetop::Runtime::SyntaxNode
106
+ end
107
+
108
+ class AdditiveExpression < Treetop::Runtime::SyntaxNode
109
+ end
110
+
111
+ class MultitiveExpression < Treetop::Runtime::SyntaxNode
112
+ end
113
+
114
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class FunctionCallAsArgumentTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse statement with function call as argument" do
8
+ assert_nothing_raised do
9
+ Parser.parse(<<-EOD)
10
+
11
+ print( to_string( 1 ))
12
+
13
+ EOD
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class SimpleProgramTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse simple program with 'if' flow control" do
8
+ assert_nothing_raised do
9
+ Parser.parse(<<-EOD)
10
+
11
+ test = 1
12
+
13
+ if(test == 1)
14
+ test = "yay"
15
+ end
16
+
17
+ EOD
18
+ end
19
+ end
20
+
21
+ test "should parse simple program with 'unless' flow control" do
22
+ assert_nothing_raised do
23
+ Parser.parse(<<-EOD)
24
+
25
+ test = 1
26
+
27
+ unless(test == 1)
28
+ test = "yay"
29
+ end
30
+
31
+ EOD
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,115 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class AssignmentTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "assignment of integer" do
8
+ tree = Parser.parse('test = 1')
9
+ assert_assigns_expression(IntegerLiteral, '1', tree)
10
+ end
11
+
12
+ test "assignment of explicitly positive integer" do
13
+ tree = Parser.parse('test = +1')
14
+ assert_assigns_expression(IntegerLiteral, '+1', tree)
15
+ end
16
+
17
+ test "assignment of explicitly negative integer" do
18
+ tree = Parser.parse('test = -1')
19
+ assert_assigns_expression(IntegerLiteral, '-1', tree)
20
+ end
21
+
22
+ test "assignment of float" do
23
+ tree = Parser.parse('test = 99.0009')
24
+ assert_assigns_expression(FloatLiteral, '99.0009', tree)
25
+ end
26
+
27
+ test "assignment of explicitly positive float" do
28
+ tree = Parser.parse('test = +99.0009')
29
+ assert_assigns_expression(FloatLiteral, '+99.0009', tree)
30
+ end
31
+
32
+ test "assignment of explicitly negative float" do
33
+ tree = Parser.parse('test = -99.0009')
34
+ assert_assigns_expression(FloatLiteral, '-99.0009', tree)
35
+ end
36
+
37
+ test "assignment of string" do
38
+ tree = Parser.parse('test = "test_string"')
39
+ assert_assigns_expression(StringLiteral, '"test_string"', tree)
40
+ end
41
+
42
+ test "assignment of string containing escaped quote" do
43
+ tree = Parser.parse('test = "test_\"string"')
44
+ assert_assigns_expression(StringLiteral, '"test_\"string"', tree)
45
+ end
46
+
47
+ test "assignment of function definition" do
48
+ tree = Parser.parse('test = function(args) blah = 1 end')
49
+ assert_assigns(FunctionDefinition, nil, tree)
50
+ end
51
+
52
+ test "assignment of result of function call" do
53
+ tree = Parser.parse('test = function(args)')
54
+ assert_assigns_expression(FunctionCall, nil, tree)
55
+ end
56
+
57
+ test "assignment of nil" do
58
+ tree = Parser.parse('test = nil')
59
+ assert_assigns_expression(NilLiteral, nil, tree)
60
+ end
61
+
62
+ test "assignment of boolean true" do
63
+ tree = Parser.parse('test = true')
64
+ assert_assigns_expression(TrueLiteral, nil, tree)
65
+ end
66
+
67
+ test "assignment of boolean false" do
68
+ tree = Parser.parse('test = false')
69
+ assert_assigns_expression(FalseLiteral, nil, tree)
70
+ end
71
+
72
+ test "assignment of empty hash literal" do
73
+ tree = Parser.parse('test = {}')
74
+ assert_assigns(HashLiteral, nil, tree)
75
+ end
76
+
77
+ test "assignment of hash literal with single key-value pair" do
78
+ tree = Parser.parse('test = { 1 => 2 }')
79
+ assert_assigns(HashLiteral, nil, tree)
80
+ end
81
+
82
+ test "assignment of hash literal with 2 key-value pairs" do
83
+ tree = Parser.parse('test = { 1 => 2, 2 => 2 }')
84
+ assert_assigns(HashLiteral, nil, tree)
85
+ end
86
+
87
+ test "assignment of hash literal with 3 key-value pairs" do
88
+ tree = Parser.parse('test = { 1 => 2, 2 => 2, 3 => 2 }')
89
+ assert_assigns(HashLiteral, nil, tree)
90
+ end
91
+
92
+ private
93
+
94
+ def assert_assigns(node_type, value, tree)
95
+ assert_kind_of Block, tree
96
+ assert_kind_of Statement, tree.elements.last
97
+ assert_kind_of Assignment, tree.elements.last.elements.last
98
+ assert_kind_of Identifier, tree.elements.last.elements.last.elements[0]
99
+ assert_kind_of AssignmentOperator, tree.elements.last.elements.last.elements[1]
100
+ assert_kind_of node_type, tree.elements.last.elements.last.elements[2]
101
+ assert_equal value, tree.elements.last.elements.last.elements[2].text_value unless(value.nil?)
102
+ end
103
+
104
+ def assert_assigns_expression(node_type, value, tree)
105
+ assert_kind_of Block, tree
106
+ assert_kind_of Statement, tree.elements.last
107
+ assert_kind_of Assignment, tree.elements.last.elements.last
108
+ assert_kind_of Identifier, tree.elements.last.elements.last.elements[0]
109
+ assert_kind_of AssignmentOperator, tree.elements.last.elements.last.elements[1]
110
+ assert_kind_of Expression, tree.elements.last.elements.last.elements[2]
111
+ assert_kind_of node_type, tree.elements.last.elements.last.elements[2].elements.first
112
+ assert_equal value, tree.elements.last.elements.last.elements[2].elements.first.text_value unless(value.nil?)
113
+ end
114
+
115
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class SimpleExpressionTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse expression that contains function call as value" do
8
+ tree = Parser.parse('test = blah(1) + 1')
9
+ assert_kind_of Assignment, tree.elements.first.elements.last
10
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[2]
11
+ assert_kind_of AdditiveExpression, tree.elements.first.elements.last.elements[2].elements.first
12
+ assert_kind_of FunctionCall, tree.elements.first.elements.last.elements[2].elements.first.elements.first
13
+ end
14
+
15
+ test "should parse expression that contains sub-expression as value" do
16
+ tree = Parser.parse('test = 2 * 3 * 2')
17
+ assert_kind_of Assignment, tree.elements.first.elements.last
18
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[2]
19
+ assert_kind_of MultitiveExpression, tree.elements.first.elements.last.elements[2].elements.first
20
+ assert_kind_of IntegerLiteral, tree.elements.first.elements.last.elements[2].elements.first.elements[0]
21
+ assert_kind_of MultiplicationOperator, tree.elements.first.elements.last.elements[2].elements.first.elements[1]
22
+ assert_kind_of MultitiveExpression, tree.elements.first.elements.last.elements[2].elements.first.elements[2]
23
+ end
24
+
25
+ test "should parse expression that contains parenthesized sub-expression as value" do
26
+ tree = Parser.parse('test = (2 * 3) * 2')
27
+ assert_kind_of Assignment, tree.elements.first.elements.last
28
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[2]
29
+ assert_kind_of MultitiveExpression, tree.elements.first.elements.last.elements[2].elements.first
30
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[2].elements.first.elements[0]
31
+ assert_kind_of MultiplicationOperator, tree.elements.first.elements.last.elements[2].elements.first.elements[1]
32
+ assert_kind_of IntegerLiteral, tree.elements.first.elements.last.elements[2].elements.first.elements[2]
33
+ end
34
+
35
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class FunctionCallTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse function call with no arguments" do
8
+ tree = Parser.parse('test()')
9
+ assert_kind_of Block, tree
10
+ assert_kind_of Statement, tree.elements.first
11
+ assert_kind_of FunctionCall, tree.elements.first.elements.last
12
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements.first
13
+ end
14
+
15
+ test "should parse function call with identifier as argument" do
16
+ tree = Parser.parse('test(blah)')
17
+ assert_kind_of Block, tree
18
+ assert_kind_of Statement, tree.elements.first
19
+ assert_kind_of FunctionCall, tree.elements.first.elements.last
20
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements[0]
21
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[1]
22
+ end
23
+
24
+ test "should parse function call with multiple arguments" do
25
+ tree = Parser.parse('test(blah, blah2)')
26
+ assert_kind_of Block, tree
27
+ assert_kind_of Statement, tree.elements.first
28
+ assert_kind_of FunctionCall, tree.elements.first.elements.last
29
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements[0]
30
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[1]
31
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[2]
32
+ end
33
+
34
+ test "should parse function call with expression as argument" do
35
+ tree = Parser.parse('test(1 * 2)')
36
+ assert_kind_of Block, tree
37
+ assert_kind_of Statement, tree.elements.first
38
+ assert_kind_of FunctionCall, tree.elements.first.elements.last
39
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements[0]
40
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[1]
41
+ end
42
+
43
+ test "should parse function call with function call as argument" do
44
+ tree = Parser.parse('test( call())')
45
+ assert_kind_of Block, tree
46
+ assert_kind_of Statement, tree.elements.first
47
+ assert_kind_of FunctionCall, tree.elements.first.elements.last
48
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements[0]
49
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[1]
50
+ end
51
+
52
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class FunctionDefinitionTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse function definition including it's statements" do
8
+ tree = Parser.parse("test = function(args)\n teest1 = 1\n test2 = 2\nend")
9
+ assert_kind_of Block, tree
10
+ assert_kind_of Statement, tree.elements.first
11
+ assert_kind_of Assignment, tree.elements.first.elements.first
12
+ assert_kind_of FunctionDefinition, tree.elements.first.elements.first.elements.last
13
+ assert_kind_of Identifier, tree.elements.first.elements.first.elements.last.elements.first
14
+ assert_kind_of Block, tree.elements.first.elements.first.elements.last.elements.last
15
+ assert_kind_of Statement, tree.elements.first.elements.first.elements.last.elements.last.elements[0]
16
+ assert_kind_of Statement, tree.elements.first.elements.first.elements.last.elements.last.elements[1]
17
+ end
18
+
19
+ end
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class HashAccessorTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "assignment to hash key" do
8
+ tree = Parser.parse('test[1] = 1')
9
+ assert_kind_of Block, tree
10
+ assert_kind_of Statement, tree.elements.first
11
+ assert_kind_of HashAssignment, tree.elements.first.elements.first
12
+ assert_kind_of Identifier, tree.elements.first.elements.first.elements.first
13
+ assert_kind_of HashAccessorList, tree.elements.first.elements.first.elements[1]
14
+ assert_kind_of HashAccessor, tree.elements.first.elements.first.elements[1].elements.first
15
+ assert_equal 1, tree.elements.first.elements.first.elements[1].elements.length
16
+ end
17
+
18
+ test "assignment to a chain of hash key" do
19
+ tree = Parser.parse('test[1][2][3] = 1')
20
+ assert_kind_of Block, tree
21
+ assert_kind_of Statement, tree.elements.first
22
+ assert_kind_of HashAssignment, tree.elements.first.elements.first
23
+ assert_kind_of Identifier, tree.elements.first.elements.first.elements.first
24
+ assert_kind_of HashAccessorList, tree.elements.first.elements.first.elements[1]
25
+ assert_kind_of HashAccessor, tree.elements.first.elements.first.elements[1].elements.first
26
+ assert_equal 3, tree.elements.first.elements.first.elements[1].elements.length
27
+ end
28
+
29
+ test "assignment of hash key" do
30
+ tree = Parser.parse('test = test[1]')
31
+ assert_kind_of Block, tree
32
+ assert_kind_of Statement, tree.elements.first
33
+ assert_kind_of Assignment, tree.elements.first.elements.first
34
+ assert_kind_of Identifier, tree.elements.first.elements.first.elements[0]
35
+ assert_kind_of Expression, tree.elements.first.elements.first.elements[2]
36
+ assert_kind_of HashAccess, tree.elements.first.elements.first.elements[2].elements.first
37
+ assert_kind_of Identifier, tree.elements.first.elements.first.elements[2].elements.first.elements[0]
38
+ assert_kind_of HashAccessorList, tree.elements.first.elements.first.elements[2].elements.first.elements[1]
39
+ end
40
+
41
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class FunctionCallTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse all lowercase identifier" do
8
+ tree = Parser.parse('test = "test"')
9
+ assert_kind_of Block, tree
10
+ assert_kind_of Statement, tree.elements.first
11
+ assert_kind_of Assignment, tree.elements.first.elements.last
12
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements.first
13
+ end
14
+
15
+ test "should parse identifier with trailing numeral" do
16
+ tree = Parser.parse('test1 = "test"')
17
+ assert_kind_of Block, tree
18
+ assert_kind_of Statement, tree.elements.first
19
+ assert_kind_of Assignment, tree.elements.first.elements.last
20
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements.first
21
+ end
22
+
23
+ test "should parse identifier with leading capital letter" do
24
+ tree = Parser.parse('Test = "test"')
25
+ assert_kind_of Block, tree
26
+ assert_kind_of Statement, tree.elements.first
27
+ assert_kind_of Assignment, tree.elements.first.elements.last
28
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements.first
29
+ end
30
+
31
+ test "should parse identifier that contains an underscore" do
32
+ tree = Parser.parse('test_test = "test"')
33
+ assert_kind_of Block, tree
34
+ assert_kind_of Statement, tree.elements.first
35
+ assert_kind_of Assignment, tree.elements.first.elements.last
36
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements.first
37
+ end
38
+
39
+ test "should parse single character identifier" do
40
+ tree = Parser.parse('x = "test"')
41
+ assert_kind_of Block, tree
42
+ assert_kind_of Statement, tree.elements.first
43
+ assert_kind_of Assignment, tree.elements.first.elements.last
44
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements.first
45
+ end
46
+
47
+ test "should parse identifier with leading $" do
48
+ tree = Parser.parse('$test = "test"')
49
+ assert_kind_of Block, tree
50
+ assert_kind_of Statement, tree.elements.first
51
+ assert_kind_of Assignment, tree.elements.first.elements.last
52
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements.first
53
+ end
54
+
55
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class IfTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse if statement" do
8
+ tree = Parser.parse("if(1 == 1)\n test = 1\nend")
9
+ assert_kind_of Block, tree
10
+ assert_kind_of Statement, tree.elements.first
11
+ assert_kind_of If, tree.elements.first.elements.first
12
+ assert_kind_of Expression, tree.elements.first.elements.first.elements.first
13
+ assert_kind_of Block, tree.elements.first.elements.first.elements.last
14
+ end
15
+
16
+ test "should parse single line if statement" do
17
+ tree = Parser.parse("if(1 == 1) test = 1; end")
18
+ assert_kind_of Block, tree
19
+ assert_kind_of Statement, tree.elements.first
20
+ assert_kind_of If, tree.elements.first.elements.first
21
+ assert_kind_of Expression, tree.elements.first.elements.first.elements.first
22
+ assert_kind_of Block, tree.elements.first.elements.first.elements.last
23
+ end
24
+
25
+ end
@@ -0,0 +1,212 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class SimpleExpressionTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ ###############
8
+ # ADDITION
9
+
10
+ test "should parse simple addition expression with integers" do
11
+ tree = Parser.parse('test = 1 + 1')
12
+ assert_expression(tree, AdditionOperator)
13
+ end
14
+
15
+ test "should parse simple addition expression with floats" do
16
+ tree = Parser.parse('test = 1.0 + 1.0')
17
+ assert_expression(tree, AdditionOperator)
18
+ end
19
+
20
+ test "should parse simple addition expression with strings" do
21
+ tree = Parser.parse('test = "1" + "1"')
22
+ assert_expression(tree, AdditionOperator)
23
+ end
24
+
25
+ test "should parse simple addition expression with identifiers" do
26
+ tree = Parser.parse('test = test1 + test2')
27
+ assert_expression(tree, AdditionOperator)
28
+ end
29
+
30
+
31
+ ###############
32
+ # SUBTRACTION
33
+
34
+ test "should parse simple subtraction expression with integers" do
35
+ tree = Parser.parse('test = 1 - 1')
36
+ assert_expression(tree, SubtractionOperator)
37
+ end
38
+
39
+ test "should parse simple subtraction expression with floats" do
40
+ tree = Parser.parse('test = 1.0 - 1.0')
41
+ assert_expression(tree, SubtractionOperator)
42
+ end
43
+
44
+ test "should parse simple subtraction expression with strings" do
45
+ tree = Parser.parse('test = "1" - "1"')
46
+ assert_expression(tree, SubtractionOperator)
47
+ end
48
+
49
+ test "should parse simple subtraction expression with identifiers" do
50
+ tree = Parser.parse('test = test1 - test2')
51
+ assert_expression(tree, SubtractionOperator)
52
+ end
53
+
54
+
55
+ ###############
56
+ # MULTIPLICATION
57
+
58
+ test "should parse simple multiplication expression with integers" do
59
+ tree = Parser.parse('test = 1 * 1')
60
+ assert_expression(tree, MultiplicationOperator)
61
+ end
62
+
63
+ test "should parse simple multiplication expression with floats" do
64
+ tree = Parser.parse('test = 1.0 * 1.0')
65
+ assert_expression(tree, MultiplicationOperator)
66
+ end
67
+
68
+ test "should parse simple multiplication expression with strings" do
69
+ tree = Parser.parse('test = "1" * "1"')
70
+ assert_expression(tree, MultiplicationOperator)
71
+ end
72
+
73
+ test "should parse simple multiplication expression with identifiers" do
74
+ tree = Parser.parse('test = test1 * test2')
75
+ assert_expression(tree, MultiplicationOperator)
76
+ end
77
+
78
+
79
+ ###############
80
+ # DIVISION
81
+
82
+ test "should parse simple division expression with integers" do
83
+ tree = Parser.parse('test = 1 / 1')
84
+ assert_expression(tree, DivisionOperator)
85
+ end
86
+
87
+ test "should parse simple division expression with floats" do
88
+ tree = Parser.parse('test = 1.0 / 1.0')
89
+ assert_expression(tree, DivisionOperator)
90
+ end
91
+
92
+ test "should parse simple division expression with strings" do
93
+ tree = Parser.parse('test = "1" / "1"')
94
+ assert_expression(tree, DivisionOperator)
95
+ end
96
+
97
+ test "should parse simple division expression with identifiers" do
98
+ tree = Parser.parse('test = test1 / test2')
99
+ assert_expression(tree, DivisionOperator)
100
+ end
101
+
102
+
103
+ ###############
104
+ # EQUALITY
105
+
106
+ test "should parse simple equality expression with integers" do
107
+ tree = Parser.parse('test = 1 == 1')
108
+ assert_expression(tree, EqualityOperator)
109
+ end
110
+
111
+ test "should parse simple equality expression with floats" do
112
+ tree = Parser.parse('test = 1.0 == 1.0')
113
+ assert_expression(tree, EqualityOperator)
114
+ end
115
+
116
+ test "should parse simple equality expression with strings" do
117
+ tree = Parser.parse('test = "1" == "1"')
118
+ assert_expression(tree, EqualityOperator)
119
+ end
120
+
121
+ test "should parse simple equality expression with identifiers" do
122
+ tree = Parser.parse('test = test1 == test2')
123
+ assert_expression(tree, EqualityOperator)
124
+ end
125
+
126
+
127
+ ###############
128
+ # INEQUALITY
129
+
130
+ test "should parse simple inequality expression with integers" do
131
+ tree = Parser.parse('test = 1 != 1')
132
+ assert_expression(tree, InequalityOperator)
133
+ end
134
+
135
+ test "should parse simple inequality expression with floats" do
136
+ tree = Parser.parse('test = 1.0 != 1.0')
137
+ assert_expression(tree, InequalityOperator)
138
+ end
139
+
140
+ test "should parse simple inequality expression with strings" do
141
+ tree = Parser.parse('test = "1" != "1"')
142
+ assert_expression(tree, InequalityOperator)
143
+ end
144
+
145
+ test "should parse simple inequality expression with identifiers" do
146
+ tree = Parser.parse('test = test1 != test2')
147
+ assert_expression(tree, InequalityOperator)
148
+ end
149
+
150
+
151
+ ###############
152
+ # GREATER THAN
153
+
154
+ test "should parse simple 'greater than' expression with integers" do
155
+ tree = Parser.parse('test = 1 > 1')
156
+ assert_expression(tree, GreaterThanOperator)
157
+ end
158
+
159
+ test "should parse simple 'greater than' expression with floats" do
160
+ tree = Parser.parse('test = 1.0 > 1.0')
161
+ assert_expression(tree, GreaterThanOperator)
162
+ end
163
+
164
+ test "should parse simple 'greater than' expression with strings" do
165
+ tree = Parser.parse('test = "1" > "1"')
166
+ assert_expression(tree, GreaterThanOperator)
167
+ end
168
+
169
+ test "should parse simple 'greater than' expression with identifiers" do
170
+ tree = Parser.parse('test = test1 > test2')
171
+ assert_expression(tree, GreaterThanOperator)
172
+ end
173
+
174
+
175
+ ###############
176
+ # LESS THAN
177
+
178
+ test "should parse simple 'less than' expression with integers" do
179
+ tree = Parser.parse('test = 1 < 1')
180
+ assert_expression(tree, LessThanOperator)
181
+ end
182
+
183
+ test "should parse simple 'less than' expression with floats" do
184
+ tree = Parser.parse('test = 1.0 < 1.0')
185
+ assert_expression(tree, LessThanOperator)
186
+ end
187
+
188
+ test "should parse simple 'less than' expression with strings" do
189
+ tree = Parser.parse('test = "1" < "1"')
190
+ assert_expression(tree, LessThanOperator)
191
+ end
192
+
193
+ test "should parse simple 'less than' expression with identifiers" do
194
+ tree = Parser.parse('test = test1 < test2')
195
+ assert_expression(tree, LessThanOperator)
196
+ end
197
+
198
+
199
+ private
200
+
201
+ def assert_expression(tree, operator = nil)
202
+ assert_kind_of Block, tree
203
+ assert_kind_of Statement, tree.elements.first
204
+ assert_kind_of Assignment, tree.elements.first.elements.last
205
+ assert_kind_of Identifier, tree.elements.first.elements.last.elements[0]
206
+ assert_kind_of AssignmentOperator, tree.elements.first.elements.last.elements[1]
207
+ assert_kind_of Expression, tree.elements.first.elements.last.elements[2]
208
+ assert_equal 3, tree.elements.first.elements.last.elements[2].elements.first.elements.size
209
+ assert_kind_of operator, tree.elements.first.elements.last.elements[2].elements.first.elements[1] unless(operator.nil?)
210
+ end
211
+
212
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class StatementTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse statments on separate lines as separate" do
8
+ tree = Parser.parse("test = 1\ntest = 1")
9
+ assert_kind_of Block, tree
10
+ assert_kind_of Statement, tree.elements[0]
11
+ assert_kind_of Statement, tree.elements[1]
12
+ end
13
+
14
+ test "should parse statements on same line separated by ';' as separate" do
15
+ tree = Parser.parse("test = 1;test = 1")
16
+ assert_kind_of Block, tree
17
+ assert_kind_of Statement, tree.elements[0]
18
+ assert_kind_of Statement, tree.elements[1]
19
+ end
20
+
21
+
22
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper.rb'))
2
+
3
+ class UnlessTest < Test::Unit::TestCase
4
+
5
+ include KoiReferenceParser
6
+
7
+ test "should parse unless statement" do
8
+ tree = Parser.parse("unless(1 == 1)\n test = 1\nend")
9
+ assert_kind_of Block, tree
10
+ assert_kind_of Statement, tree.elements.first
11
+ assert_kind_of Unless, tree.elements.first.elements.first
12
+ assert_kind_of Expression, tree.elements.first.elements.first.elements.first
13
+ assert_kind_of Block, tree.elements.first.elements.first.elements.last
14
+ end
15
+
16
+ test "should parse single line unless statement" do
17
+ tree = Parser.parse("unless(1 == 1) test = 1; end")
18
+ assert_kind_of Block, tree
19
+ assert_kind_of Statement, tree.elements.first
20
+ assert_kind_of Unless, tree.elements.first.elements.first
21
+ assert_kind_of Expression, tree.elements.first.elements.first.elements.first
22
+ assert_kind_of Block, tree.elements.first.elements.first.elements.last
23
+ end
24
+
25
+ end
@@ -0,0 +1,21 @@
1
+ module Test::Unit
2
+ # Used to fix a minor minitest/unit incompatibility in flexmock
3
+ AssertionFailedError = Class.new(StandardError)
4
+
5
+ class TestCase
6
+
7
+ def self.test(name, &block)
8
+ test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
9
+ defined = instance_method(test_name) rescue false
10
+ raise "#{test_name} is already defined in #{self}" if defined
11
+ if block_given?
12
+ define_method(test_name, &block)
13
+ else
14
+ define_method(test_name) do
15
+ flunk "No implementation provided for #{name}"
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ require_files = []
5
+ require_files << File.join(File.dirname(__FILE__), '..', 'lib', 'koi-reference-parser.rb')
6
+ require_files.concat Dir[File.join(File.dirname(__FILE__), 'setup', '*.rb')]
7
+
8
+ require_files.each do |file|
9
+ require File.expand_path(file)
10
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: koi-reference-parser
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
+ - Aaron Gough
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-08-30 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: treetop
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description: A reference parser for the Koi language.
33
+ email: aaron@aarongough.com
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - MIT-LICENSE
40
+ - README.rdoc
41
+ files:
42
+ - .gitignore
43
+ - MIT-LICENSE
44
+ - README.rdoc
45
+ - Rakefile
46
+ - lib/koi-reference-parser.rb
47
+ - lib/parser/exceptions.rb
48
+ - lib/parser/koi-reference-parser.treetop
49
+ - lib/parser/parser.rb
50
+ - lib/parser/syntax_nodes.rb
51
+ - test/parser/functional/function_call_as_argument.rb
52
+ - test/parser/functional/simple_program_test.rb
53
+ - test/parser/unit/assignment_test.rb
54
+ - test/parser/unit/compound_expression_test.rb
55
+ - test/parser/unit/function_call_test.rb
56
+ - test/parser/unit/function_definition_test.rb
57
+ - test/parser/unit/hash_accessor_test.rb
58
+ - test/parser/unit/identifier_test.rb
59
+ - test/parser/unit/if_test.rb
60
+ - test/parser/unit/simple_expression_test.rb
61
+ - test/parser/unit/statement_test.rb
62
+ - test/parser/unit/unless_test.rb
63
+ - test/setup/test_unit_extensions.rb
64
+ - test/test_helper.rb
65
+ has_rdoc: true
66
+ homepage: http://github.com/aarongough/koi-reference-parser
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options:
71
+ - --charset=UTF-8
72
+ - --line-numbers
73
+ - --inline-source
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project:
93
+ rubygems_version: 1.3.6
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: A reference parser for the Koi language.
97
+ test_files:
98
+ - test/parser/functional/function_call_as_argument.rb
99
+ - test/parser/functional/simple_program_test.rb
100
+ - test/parser/unit/assignment_test.rb
101
+ - test/parser/unit/compound_expression_test.rb
102
+ - test/parser/unit/function_call_test.rb
103
+ - test/parser/unit/function_definition_test.rb
104
+ - test/parser/unit/hash_accessor_test.rb
105
+ - test/parser/unit/identifier_test.rb
106
+ - test/parser/unit/if_test.rb
107
+ - test/parser/unit/simple_expression_test.rb
108
+ - test/parser/unit/statement_test.rb
109
+ - test/parser/unit/unless_test.rb
110
+ - test/setup/test_unit_extensions.rb
111
+ - test/test_helper.rb