rltk 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,58 @@
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Ruby Language Toolkit
3
+ # Date: 2012/06/13
4
+ # Description: This file defines the Triple class.
5
+
6
+ ############
7
+ # Requires #
8
+ ############
9
+
10
+ # Ruby Language Toolkit
11
+ require 'rltk/cg/bindings'
12
+
13
+ #######################
14
+ # Classes and Modules #
15
+ #######################
16
+
17
+ module RLTK::CG # :nodoc:
18
+
19
+ # Class binding for the LLVM Triple class.
20
+ class Triple
21
+ include BindingClass
22
+
23
+ #################
24
+ # Class Methods #
25
+ #################
26
+
27
+ # @return [Triple] Object representing the host architecture, vendor, OS, and environment.
28
+ def self.host
29
+ @host ||= self.new(Bindings.get_host_triple)
30
+ end
31
+
32
+ # @return [String] String representation of the host architecture, vendor, OS, and environment.
33
+ def self.host_string
34
+ @host_string ||= Bindings.get_host_triple_string
35
+ end
36
+
37
+ ####################
38
+ # Instance Methods #
39
+ ####################
40
+
41
+ # Create a new triple describing the host architecture, vendor, OS,
42
+ # and (optionally) environment.
43
+ #
44
+ # @param [FFI::Pointer, String] overloaded
45
+ def initialize(overloaded)
46
+ @ptr =
47
+ case overloaded
48
+ when FFI::Pointer then overloaded
49
+ when String then Bindings.triple_create(overloaded)
50
+ end
51
+ end
52
+
53
+ # @return [String] String representation of this triple.
54
+ def to_s
55
+ Bindings.get_triple_string(@ptr)
56
+ end
57
+ end
58
+ end
data/lib/rltk/cg/type.rb CHANGED
@@ -442,7 +442,7 @@ end
442
442
  # @param [String] blame Variable name to blame for failed type checks.
443
443
  # @param [Boolean] strict Strict or non-strict checking. Uses `instance_of?` and `is_a?` respectively.
444
444
  #
445
- # @raise [RuntimeError] An error is raise if a class is passed in parameter *o*
445
+ # @raise [ArgumentError] An error is raise if a class is passed in parameter *o*
446
446
  # that hasn't included the Singleton class, if the class passed in parameter
447
447
  # *type* isn't a sub-class of {RLTK::CG::Type Type}, or if the type check
448
448
  # fails.
@@ -456,10 +456,10 @@ def check_cg_type(o, type = RLTK::CG::Type, blame = 'type', strict = false)
456
456
  if o.includes_module?(Singleton)
457
457
  o.instance
458
458
  else
459
- raise "The #{o.name} class (passed as parameter #{blame}) must be instantiated directly."
459
+ raise ArgumentError, "The #{o.name} class (passed as parameter #{blame}) must be instantiated directly."
460
460
  end
461
461
  else
462
- raise "The #{o.name} class (passed as parameter #{blame} does not inherit from the #{type.name} class."
462
+ raise ArgumentError, "The #{o.name} class (passed as parameter #{blame} does not inherit from the #{type.name} class."
463
463
  end
464
464
  else
465
465
  check_type(o, type, blame, strict)
@@ -476,7 +476,7 @@ end
476
476
  # @param [String] blame Variable name to blame for failed type checks.
477
477
  # @param [Boolean] strict Strict or non-strict checking. Uses `instance_of?` and `is_a?` respectively.
478
478
  #
479
- # @raise [RuntimeError] An error is raise if a class is passed in *array* that
479
+ # @raise [ArgumentError] An error is raise if a class is passed in *array* that
480
480
  # hasn't included the Singleton class, if the class passed in parameter
481
481
  # *type* isn't a sub-class of {RLTK::CG::Type Type}, or if the type check
482
482
  # fails.
@@ -491,10 +491,10 @@ def check_cg_array_type(array, type = RLTK::CG::Type, blame = 'el_types', strict
491
491
  if o.includes_module?(Singleton)
492
492
  o.instance
493
493
  else
494
- raise "The #{o.name} class (passed in parameter #{blame}) must be instantiated directly."
494
+ raise ArgumentError, "The #{o.name} class (passed in parameter #{blame}) must be instantiated directly."
495
495
  end
496
496
  else
497
- raise "The #{o.name} class (passed in parameter #{blame}) does not inherit from the #{type.name} class."
497
+ raise ArgumentError, "The #{o.name} class (passed in parameter #{blame}) does not inherit from the #{type.name} class."
498
498
  end
499
499
 
500
500
  else
@@ -503,7 +503,7 @@ def check_cg_array_type(array, type = RLTK::CG::Type, blame = 'el_types', strict
503
503
  if type_ok
504
504
  o
505
505
  else
506
- raise "Parameter #{blame} must contain instances of the #{type.name} class."
506
+ raise ArgumentError, "Parameter #{blame} must contain instances of the #{type.name} class."
507
507
  end
508
508
  end
509
509
  end
data/lib/rltk/cg/value.rb CHANGED
@@ -60,7 +60,11 @@ module RLTK::CG # :nodoc:
60
60
  Bindings.is_constant(@ptr).to_bool
61
61
  end
62
62
 
63
- # Print the LLVM IR representation of this value to standard out.
63
+ # Print the LLVM IR representation of this value to standard error.
64
+ # This function is the debugging version of the more general purpose
65
+ # {#print} method.
66
+ #
67
+ # @see #print
64
68
  #
65
69
  # @return [void]
66
70
  def dump
@@ -91,6 +95,26 @@ module RLTK::CG # :nodoc:
91
95
  Bindings.is_null(@ptr).to_bool
92
96
  end
93
97
 
98
+ # Print the LLVM IR representation of this value to a file. The file
99
+ # may be specified via a file name (which will be created or
100
+ # truncated) or an object that responds to #fileno.
101
+ #
102
+ # @LLVMECB
103
+ #
104
+ # @param [String, #fileno] io File name or object with a file descriptor to print to.
105
+ #
106
+ # @return [void]
107
+ def print(io = $stdout)
108
+ case io
109
+ when String
110
+ File.open(io, 'w') do |f|
111
+ Bindings.print_value(@ptr, f.fileno)
112
+ end
113
+ else
114
+ Bindings.print_value(@ptr, io.fileno)
115
+ end
116
+ end
117
+
94
118
  # Truncate a value to a given type.
95
119
  #
96
120
  # @param [Type] type Type to truncate to.
data/lib/rltk/cg.rb CHANGED
@@ -14,7 +14,7 @@ module RLTK # :nodoc:
14
14
  # generation functionality is provided by bindings to
15
15
  # [LLVM](http://llvm.org).
16
16
  module CG
17
- autoload :BasicBloc, 'rltk/cg/basic_block'
17
+ autoload :BasicBlock, 'rltk/cg/basic_block'
18
18
  autoload :Bindings, 'rltk/cg/bindings'
19
19
  autoload :Builder, 'rltk/cg/builder'
20
20
  autoload :Context, 'rltk/cg/context'
data/lib/rltk/parser.rb CHANGED
@@ -100,25 +100,41 @@ module RLTK # :nodoc:
100
100
 
101
101
  @grammar.callback do |p, type, num|
102
102
  @procs[p.id] =
103
- [if type == :*
104
- if num == :first
105
- Proc.new { || [] }
106
- else
107
- Proc.new { |o, os| [o] + os }
108
- end
109
- elsif type == :+
110
- if num == :first
111
- Proc.new { |o| [o] }
112
- else
113
- Proc.new { |o, os| [o] + os }
114
- end
115
- elsif type == :'?'
116
- if num == :first
117
- Proc.new { || nil }
118
- else
119
- Proc.new { |o| o }
120
- end
121
- end, p.rhs.length]
103
+ [
104
+ case type
105
+ when :*
106
+ case num
107
+ when :first then Proc.new { || [] }
108
+ else Proc.new { |os, o| os << o }
109
+ end
110
+
111
+ when :+
112
+ case num
113
+ when :first then Proc.new { |o| [o] }
114
+ else Proc.new { |os, o| os << o }
115
+ end
116
+
117
+ when :'?'
118
+ case num
119
+ when :first then Proc.new { || nil }
120
+ else Proc.new { |o| o }
121
+ end
122
+
123
+ when :elp
124
+ case num
125
+ when :first then Proc.new { || [] }
126
+ else Proc.new { |prime| prime }
127
+ end
128
+
129
+ when :nelp
130
+ case num
131
+ when :first then Proc.new { |el| [el] }
132
+ when :second then Proc.new { |els, _, el| els + [el] }
133
+ else Proc.new { |*el| if el.length == 1 then el.first else el end }
134
+ end
135
+ end,
136
+ p.rhs.length
137
+ ]
122
138
 
123
139
  @production_precs[p.id] = p.last_terminal
124
140
  end
@@ -163,25 +179,41 @@ module RLTK # :nodoc:
163
179
 
164
180
  @grammar.callback do |p, type, num|
165
181
  @procs[p.id] =
166
- [if type == :*
167
- if num == :first
168
- Proc.new { |v| [] }
169
- else
170
- Proc.new { |v| [v[0]] + v[1] }
171
- end
172
- elsif type == :+
173
- if num == :first
174
- Proc.new { |v| v[0] }
175
- else
176
- Proc.new { |v| [v[0]] + v[1] }
177
- end
178
- elsif type == :'?'
179
- if num == :first
180
- Proc.new { |v| nil }
181
- else
182
- Proc.new { |v| v[0] }
183
- end
184
- end, p.rhs.length]
182
+ [
183
+ case type
184
+ when :*
185
+ case num
186
+ when :first then Proc.new { |v| [] }
187
+ else Proc.new { |v| v[0] << v[1] }
188
+ end
189
+
190
+ when :+
191
+ case num
192
+ when :first then Proc.new { |v| [v[0]] }
193
+ else Proc.new { |v| v[0] << v[1] }
194
+ end
195
+
196
+ when :'?'
197
+ case num
198
+ when :first then Proc.new { |v| nil }
199
+ else Proc.new { |v| v[0] }
200
+ end
201
+
202
+ when :elp
203
+ case num
204
+ when :first then Proc.new { |v| [] }
205
+ else Proc.new { |v| v[0] }
206
+ end
207
+
208
+ when :nelp
209
+ case num
210
+ when :first then Proc.new { |v| v }
211
+ when :second then Proc.new { |v| v[0] + [v[2]] }
212
+ else Proc.new { |v| if v.length == 1 then v.first else v end }
213
+ end
214
+ end,
215
+ p.rhs.length
216
+ ]
185
217
 
186
218
  @production_precs[p.id] = p.last_terminal
187
219
  end
@@ -365,6 +397,14 @@ module RLTK # :nodoc:
365
397
  @states.each { |state| state.clean }
366
398
  end
367
399
 
400
+ # Adds productions and actions for parsing empty lists.
401
+ #
402
+ # @see CFG#empty_list_production
403
+ def empty_list_production(symbol, list_elements, separator)
404
+ @grammar.empty_list(symbol, list_elements, separator)
405
+ end
406
+ alias :empty_list :empty_list_production
407
+
368
408
  # This function will print a description of the parser to the
369
409
  # provided IO object.
370
410
  #
@@ -507,7 +547,9 @@ module RLTK # :nodoc:
507
547
  opts = build_finalize_opts(opts)
508
548
 
509
549
  # Get the name of the file in which the parser is defined.
510
- def_file = caller()[2].split(':')[0]
550
+ #
551
+ # FIXME: See why this is failing for the simple ListParser example.
552
+ def_file = caller()[2].split(':')[0] if opts[:use]
511
553
 
512
554
  # Check to make sure we can load the necessary information
513
555
  # from the specified object.
@@ -725,6 +767,14 @@ module RLTK # :nodoc:
725
767
  end
726
768
  end
727
769
 
770
+ # Adds productions and actions for parsing nonempty lists.
771
+ #
772
+ # @see CFG#nonempty_list_production
773
+ def nonempty_list_production(symbol, list_elements, separator)
774
+ @grammar.nonempty_list(symbol, list_elements, separator)
775
+ end
776
+ alias :nonempty_list :nonempty_list_production
777
+
728
778
  # This function is where actual parsing takes place. The
729
779
  # _tokens_ argument must be an array of Token objects, the last
730
780
  # of which has type EOS. By default this method will return the
@@ -772,9 +822,7 @@ module RLTK # :nodoc:
772
822
  tokens.each do |token|
773
823
  # Check to make sure this token was seen in the
774
824
  # grammar definition.
775
- if not @symbols.include?(token.type)
776
- raise BadToken
777
- end
825
+ raise BadToken if not @symbols.include?(token.type)
778
826
 
779
827
  v.puts("Current token: #{token.type}#{if token.value then "(#{token.value})" end}") if v
780
828
 
@@ -1265,7 +1313,7 @@ module RLTK # :nodoc:
1265
1313
  @state_stack << state
1266
1314
  @output_stack << o
1267
1315
  @node_stack << @labels.length
1268
- @labels << node0
1316
+ @labels << if CFG::is_terminal?(node0) and o then node0.to_s + "(#{o})" else node0 end
1269
1317
  @positions << position
1270
1318
 
1271
1319
  if CFG::is_nonterminal?(node0)
@@ -18,6 +18,8 @@
18
18
  # @param [String, nil] blame Variable name to blame for failed type checks.
19
19
  # @param [Boolean] strict Strict or non-strict checking. Uses `instance_of?` and `is_a?` respectively.
20
20
  #
21
+ # @raise [ArgumentError] An error is raise if the type checking fails.
22
+ #
21
23
  # @return [Object] The object passed as parameter o.
22
24
  def check_type(o, type, blame = nil, strict = false)
23
25
  type_ok = if strict then o.instance_of?(type) else o.is_a?(type) end
@@ -26,9 +28,9 @@ def check_type(o, type, blame = nil, strict = false)
26
28
  o
27
29
  else
28
30
  if blame
29
- raise "Parameter #{blame} must be an instance of the #{type.name} class. Received an instance of #{o.class.name}."
31
+ raise ArgumentError, "Parameter #{blame} must be an instance of the #{type.name} class. Received an instance of #{o.class.name}."
30
32
  else
31
- raise "Expected an object of type #{type.name}. Received an instance of #{o.class.name}."
33
+ raise ArgumentError, "Expected an object of type #{type.name}. Received an instance of #{o.class.name}."
32
34
  end
33
35
  end
34
36
  end
@@ -40,6 +42,8 @@ end
40
42
  # @param [String, nil] blame Variable name to blame for failed type checks.
41
43
  # @param [Boolean] strict Strict or non-strict checking. Uses `instance_of?` and `is_a?` respectively.
42
44
  #
45
+ # @raise [ArgumentError] An error is raise if the type checking fails.
46
+ #
43
47
  # @return [Object] The object passed in parameter o.
44
48
  def check_array_type(array, type, blame = nil, strict = false)
45
49
  array.each do |o|
@@ -47,9 +51,9 @@ def check_array_type(array, type, blame = nil, strict = false)
47
51
 
48
52
  if not type_ok
49
53
  if blame
50
- raise "Parameter #{blame} must contain instances of the #{type.name} class."
54
+ raise ArgumentError, "Parameter #{blame} must contain instances of the #{type.name} class."
51
55
  else
52
- raise "Expected an object of type #{type.name}."
56
+ raise ArgumentError, "Expected an object of type #{type.name}."
53
57
  end
54
58
  end
55
59
  end
data/lib/rltk/version.rb CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  module RLTK # :nodoc:
7
7
  # The version number of the RLTK library.
8
- VERSION = '2.0.0'
8
+ VERSION = '2.1.0'
9
9
  # The version of LLVM targeted by RLTK.
10
10
  LLVM_TARGET_VERSION = '3.0'
11
11
  end
data/test/tc_ast.rb CHANGED
@@ -29,34 +29,88 @@ class ASTNodeTester < Test::Unit::TestCase
29
29
 
30
30
  class DNode < RLTK::ASTNode; end
31
31
 
32
+ class SNode < RLTK::ASTNode
33
+ value :string, String
34
+
35
+ child :left, SNode
36
+ child :right, SNode
37
+ end
38
+
32
39
  def setup
33
- @leaf0 = CNode.new(nil, nil)
34
- @tree0 = ANode.new(BNode.new(@leaf0, nil), BNode.new(nil, nil))
40
+ @leaf0 = CNode.new
41
+ @tree0 = ANode.new(BNode.new(@leaf0), BNode.new)
42
+
43
+ @tree1 = ANode.new(BNode.new(CNode.new), BNode.new)
44
+ @tree2 = ANode.new(BNode.new, BNode.new(CNode.new))
35
45
 
36
- @tree1 = ANode.new(BNode.new(CNode.new(nil, nil), nil), BNode.new(nil, nil))
37
- @tree2 = ANode.new(BNode.new(nil, nil), BNode.new(CNode.new(nil, nil), nil))
46
+ @tree3 = SNode.new('F',
47
+ SNode.new('B',
48
+ SNode.new('A'),
49
+ SNode.new('D',
50
+ SNode.new('C'),
51
+ SNode.new('E')
52
+ ),
53
+ ),
54
+ SNode.new('G',
55
+ nil,
56
+ SNode.new('I',
57
+ SNode.new('H')
58
+ )
59
+ )
60
+ )
38
61
  end
39
62
 
40
63
  def test_children
41
- node = ANode.new(nil, nil)
64
+ node = ANode.new
42
65
 
43
66
  assert_equal(node.children, [nil, nil])
44
67
 
45
- node.children = (expected_children = [BNode.new(nil, nil), CNode.new(nil, nil)])
68
+ node.children = (expected_children = [BNode.new, CNode.new])
46
69
 
47
70
  assert_equal(node.children, expected_children)
48
71
 
49
72
  node.map do |child|
50
73
  if child.is_a?(BNode)
51
- CNode.new(nil, nil)
74
+ CNode.new
52
75
  else
53
- BNode.new(nil, nil)
76
+ BNode.new
54
77
  end
55
78
  end
56
79
 
57
80
  assert_equal(node.children, expected_children.reverse)
58
81
  end
59
82
 
83
+ def test_dump
84
+ tree0_string = @tree0.dump
85
+
86
+ reloaded_tree = Marshal.load(tree0_string)
87
+
88
+ assert_equal(@tree0, reloaded_tree)
89
+ end
90
+
91
+ def test_each
92
+ # Test pre-order
93
+ nodes = []
94
+ expected = ['F', 'B', 'A', 'D', 'C', 'E', 'G', 'I', 'H']
95
+ @tree3.each(:pre) { |n| nodes << n.string }
96
+
97
+ assert_equal(expected, nodes)
98
+
99
+ # Test post-order
100
+ nodes = []
101
+ expected = ['A', 'C', 'E', 'D', 'B', 'H', 'I', 'G', 'F']
102
+ @tree3.each(:post) { |n| nodes << n.string }
103
+
104
+ assert_equal(expected, nodes)
105
+
106
+ # Test level-order
107
+ nodes = []
108
+ expected = ['F', 'B', 'G', 'A', 'D', 'I', 'C', 'E', 'H']
109
+ @tree3.each(:level) { |n| nodes << n.string }
110
+
111
+ assert_equal(expected, nodes)
112
+ end
113
+
60
114
  def test_equal
61
115
  assert_equal(@tree0, @tree1)
62
116
  assert_not_equal(@tree0, @tree2)
data/test/tc_parser.rb CHANGED
@@ -31,6 +31,14 @@ class ParserTester < Test::Unit::TestCase
31
31
  rule(/\s/)
32
32
  end
33
33
 
34
+ class AlphaLexer < RLTK::Lexer
35
+ rule(/[A-Za-z]/) { |t| [t.upcase.to_sym, t] }
36
+
37
+ rule(/,/) { :COMMA }
38
+
39
+ rule(/\s/)
40
+ end
41
+
34
42
  class APlusBParser < RLTK::Parser
35
43
  production(:a, 'A+ B') { |a, _| a.length }
36
44
 
@@ -77,6 +85,44 @@ class ParserTester < Test::Unit::TestCase
77
85
  finalize
78
86
  end
79
87
 
88
+ class EmptyListParser0 < RLTK::Parser
89
+ empty_list('list', :A, :COMMA)
90
+
91
+ finalize
92
+ end
93
+
94
+ class EmptyListParser1 < RLTK::Parser
95
+ array_args
96
+
97
+ empty_list('list', ['A', 'B', 'C D'], :COMMA)
98
+
99
+ finalize
100
+ end
101
+
102
+ class NonEmptyListParser0 < RLTK::Parser
103
+ nonempty_list('list', :A, :COMMA)
104
+
105
+ finalize
106
+ end
107
+
108
+ class NonEmptyListParser1 < RLTK::Parser
109
+ nonempty_list('list', [:A, :B], :COMMA)
110
+
111
+ finalize
112
+ end
113
+
114
+ class NonEmptyListParser2 < RLTK::Parser
115
+ nonempty_list('list', ['A', 'B', 'C D'], :COMMA)
116
+
117
+ finalize
118
+ end
119
+
120
+ class NonEmptyListParser3 < RLTK::Parser
121
+ nonempty_list('list', 'A+', :COMMA)
122
+
123
+ finalize
124
+ end
125
+
80
126
  class DummyError1 < StandardError; end
81
127
  class DummyError2 < StandardError; end
82
128
 
@@ -193,6 +239,24 @@ class ParserTester < Test::Unit::TestCase
193
239
  assert_equal(4, AStarBParser.parse(ABLexer.lex('aaaab')))
194
240
  end
195
241
 
242
+ def test_empty_list
243
+ ####################
244
+ # EmptyListParser0 #
245
+ ####################
246
+
247
+ expected = []
248
+ actual = EmptyListParser0.parse(AlphaLexer.lex(''))
249
+ assert_equal(expected, actual)
250
+
251
+ ####################
252
+ # EmptyListParser1 #
253
+ ####################
254
+
255
+ expected = ['a', 'b', ['c', 'd']]
256
+ actual = EmptyListParser1.parse(AlphaLexer.lex('a, b, c d'))
257
+ assert_equal(expected, actual)
258
+ end
259
+
196
260
  def test_environment
197
261
  actual = RotatingCalc.parse(RLTK::Lexers::Calculator.lex('+ 1 2'))
198
262
  assert_equal(3, actual)
@@ -247,6 +311,79 @@ class ParserTester < Test::Unit::TestCase
247
311
  assert_raise(RLTK::BadToken) { RLTK::Parsers::InfixCalc.parse(RLTK::Lexers::EBNF.lex('A B C')) }
248
312
  end
249
313
 
314
+ def test_nonempty_list
315
+ #######################
316
+ # NonEmptyListParser0 #
317
+ #######################
318
+
319
+ expected = ['a']
320
+ actual = NonEmptyListParser0.parse(AlphaLexer.lex('a'))
321
+ assert_equal(expected, actual)
322
+
323
+ expected = ['a', 'a']
324
+ actual = NonEmptyListParser0.parse(AlphaLexer.lex('a, a'))
325
+ assert_equal(expected, actual)
326
+
327
+ assert_raise(RLTK::NotInLanguage) { NonEmptyListParser0.parse(AlphaLexer.lex('')) }
328
+ assert_raise(RLTK::NotInLanguage) { NonEmptyListParser0.parse(AlphaLexer.lex(',')) }
329
+ assert_raise(RLTK::NotInLanguage) { NonEmptyListParser0.parse(AlphaLexer.lex('aa')) }
330
+ assert_raise(RLTK::NotInLanguage) { NonEmptyListParser0.parse(AlphaLexer.lex('a,')) }
331
+ assert_raise(RLTK::NotInLanguage) { NonEmptyListParser0.parse(AlphaLexer.lex(',a')) }
332
+
333
+ #######################
334
+ # NonEmptyListParser1 #
335
+ #######################
336
+
337
+ expected = ['a']
338
+ actual = NonEmptyListParser1.parse(AlphaLexer.lex('a'))
339
+ assert_equal(expected, actual)
340
+
341
+ expected = ['b']
342
+ actual = NonEmptyListParser1.parse(AlphaLexer.lex('b'))
343
+ assert_equal(expected, actual)
344
+
345
+ expected = ['a', 'b', 'a', 'b']
346
+ actual = NonEmptyListParser1.parse(AlphaLexer.lex('a, b, a, b'))
347
+ assert_equal(expected, actual)
348
+
349
+ assert_raise(RLTK::NotInLanguage) { NonEmptyListParser1.parse(AlphaLexer.lex('a b')) }
350
+
351
+ #######################
352
+ # NonEmptyListParser2 #
353
+ #######################
354
+
355
+ expected = ['a']
356
+ actual = NonEmptyListParser2.parse(AlphaLexer.lex('a'))
357
+ assert_equal(expected, actual)
358
+
359
+ expected = ['b']
360
+ actual = NonEmptyListParser2.parse(AlphaLexer.lex('b'))
361
+ assert_equal(expected, actual)
362
+
363
+ expected = [['c', 'd']]
364
+ actual = NonEmptyListParser2.parse(AlphaLexer.lex('c d'))
365
+ assert_equal(expected, actual)
366
+
367
+ expected = [['c', 'd'], ['c', 'd']]
368
+ actual = NonEmptyListParser2.parse(AlphaLexer.lex('c d, c d'))
369
+ assert_equal(expected, actual)
370
+
371
+ expected = ['a', 'b', ['c', 'd']]
372
+ actual = NonEmptyListParser2.parse(AlphaLexer.lex('a, b, c d'))
373
+ assert_equal(expected, actual)
374
+
375
+ assert_raise(RLTK::NotInLanguage) { NonEmptyListParser2.parse(AlphaLexer.lex('c')) }
376
+ assert_raise(RLTK::NotInLanguage) { NonEmptyListParser2.parse(AlphaLexer.lex('d')) }
377
+
378
+ #######################
379
+ # NonEmptyListParser3 #
380
+ #######################
381
+
382
+ expected = [['a'], ['a', 'a'], ['a', 'a', 'a']]
383
+ actual = NonEmptyListParser3.parse(AlphaLexer.lex('a, aa, aaa'))
384
+ assert_equal(expected, actual)
385
+ end
386
+
250
387
  def test_postfix_calc
251
388
  actual = RLTK::Parsers::PostfixCalc.parse(RLTK::Lexers::Calculator.lex('1 2 +'))
252
389
  assert_equal(3, actual)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rltk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-07 00:00:00.000000000 Z
12
+ date: 2012-08-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
@@ -192,6 +192,8 @@ files:
192
192
  - lib/rltk/cg/value.rb
193
193
  - lib/rltk/cg/bindings.rb
194
194
  - lib/rltk/cg/llvm.rb
195
+ - lib/rltk/cg/target.rb
196
+ - lib/rltk/cg/triple.rb
195
197
  - lib/rltk/cg/generated_bindings.rb
196
198
  - lib/rltk/parsers/postfix_calc.rb
197
199
  - lib/rltk/parsers/infix_calc.rb