rltk 2.0.0 → 2.1.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.
@@ -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