rltk 2.2.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +12 -12
  3. data/README.md +458 -285
  4. data/Rakefile +99 -92
  5. data/lib/rltk/ast.rb +221 -126
  6. data/lib/rltk/cfg.rb +218 -239
  7. data/lib/rltk/cg/basic_block.rb +1 -1
  8. data/lib/rltk/cg/bindings.rb +9 -26
  9. data/lib/rltk/cg/builder.rb +40 -8
  10. data/lib/rltk/cg/context.rb +1 -1
  11. data/lib/rltk/cg/contractor.rb +51 -0
  12. data/lib/rltk/cg/execution_engine.rb +45 -8
  13. data/lib/rltk/cg/function.rb +12 -2
  14. data/lib/rltk/cg/generated_bindings.rb +2541 -575
  15. data/lib/rltk/cg/generic_value.rb +2 -2
  16. data/lib/rltk/cg/instruction.rb +104 -83
  17. data/lib/rltk/cg/llvm.rb +44 -3
  18. data/lib/rltk/cg/memory_buffer.rb +22 -5
  19. data/lib/rltk/cg/module.rb +85 -36
  20. data/lib/rltk/cg/old_generated_bindings.rb +6152 -0
  21. data/lib/rltk/cg/pass_manager.rb +87 -43
  22. data/lib/rltk/cg/support.rb +2 -4
  23. data/lib/rltk/cg/target.rb +158 -28
  24. data/lib/rltk/cg/triple.rb +8 -8
  25. data/lib/rltk/cg/type.rb +69 -25
  26. data/lib/rltk/cg/value.rb +107 -66
  27. data/lib/rltk/cg.rb +16 -17
  28. data/lib/rltk/lexer.rb +21 -11
  29. data/lib/rltk/lexers/calculator.rb +1 -1
  30. data/lib/rltk/lexers/ebnf.rb +8 -7
  31. data/lib/rltk/parser.rb +300 -247
  32. data/lib/rltk/parsers/infix_calc.rb +1 -1
  33. data/lib/rltk/parsers/postfix_calc.rb +2 -2
  34. data/lib/rltk/parsers/prefix_calc.rb +2 -2
  35. data/lib/rltk/token.rb +1 -2
  36. data/lib/rltk/version.rb +3 -3
  37. data/lib/rltk.rb +6 -6
  38. data/test/cg/tc_basic_block.rb +83 -0
  39. data/test/cg/tc_control_flow.rb +191 -0
  40. data/test/cg/tc_function.rb +54 -0
  41. data/test/cg/tc_generic_value.rb +33 -0
  42. data/test/cg/tc_instruction.rb +256 -0
  43. data/test/cg/tc_llvm.rb +25 -0
  44. data/test/cg/tc_math.rb +88 -0
  45. data/test/cg/tc_module.rb +89 -0
  46. data/test/cg/tc_transforms.rb +68 -0
  47. data/test/cg/tc_type.rb +69 -0
  48. data/test/cg/tc_value.rb +151 -0
  49. data/test/cg/ts_cg.rb +23 -0
  50. data/test/tc_ast.rb +105 -8
  51. data/test/tc_cfg.rb +63 -48
  52. data/test/tc_lexer.rb +84 -96
  53. data/test/tc_parser.rb +224 -52
  54. data/test/tc_token.rb +6 -6
  55. data/test/ts_rltk.rb +12 -15
  56. metadata +149 -75
  57. data/lib/rltk/cg/generated_extended_bindings.rb +0 -287
  58. data/lib/rltk/util/abstract_class.rb +0 -25
  59. data/lib/rltk/util/monkeys.rb +0 -129
data/test/tc_cfg.rb CHANGED
@@ -7,8 +7,8 @@
7
7
  # Requires #
8
8
  ############
9
9
 
10
- # Standard Library
11
- require 'test/unit'
10
+ # Gems
11
+ require 'minitest/autorun'
12
12
 
13
13
  # Ruby Language Toolkit
14
14
  require 'rltk/cfg'
@@ -17,7 +17,7 @@ require 'rltk/cfg'
17
17
  # Classes and Modules #
18
18
  #######################
19
19
 
20
- class CFGTester < Test::Unit::TestCase
20
+ class CFGTester < Minitest::Test
21
21
  def setup
22
22
  @grammar = RLTK::CFG.new
23
23
 
@@ -35,59 +35,74 @@ class CFGTester < Test::Unit::TestCase
35
35
  def test_callback
36
36
  grammar = RLTK::CFG.new
37
37
 
38
- first = true
39
- grammar.callback do |p, type, num|
40
- assert_not_nil(p)
41
- assert_equal(type, :'?')
38
+ call_count = 0
39
+ grammar.callback do |type, which, p|
40
+ refute_nil(p)
41
+ assert_equal(type, :optional)
42
42
 
43
- if first
44
- assert_equal(num, :first)
45
- first = false
46
- else
47
- assert_equal(num, :second)
43
+ case call_count
44
+ when 0 then assert_equal(:empty, which)
45
+ when 1 then assert_equal(:nonempty, which)
48
46
  end
47
+
48
+ call_count += 1
49
49
  end
50
50
 
51
51
  grammar.production(:a, 'A?') { |a| a }
52
+ assert_equal(2, call_count)
52
53
 
53
- first = true
54
- grammar.callback do |p, type, num|
55
- assert_not_nil(p)
56
- assert_equal(type, :*)
54
+ call_count = 0
55
+ grammar.callback do |type, which, p|
56
+ refute_nil(p)
57
57
 
58
- if first
59
- assert_equal(num, :first)
60
- first = false
61
- else
62
- assert_equal(num, :second)
58
+ case call_count
59
+ when 0
60
+ assert_equal(:elp, type)
61
+ assert_equal(:empty, which)
62
+
63
+ when 1
64
+ assert_equal(:elp, type)
65
+ assert_equal(:nonempty, which)
66
+
67
+ when 2
68
+ assert_equal(:nelp, type)
69
+ assert_equal(:single, which)
70
+
71
+ when 3
72
+ assert_equal(:nelp, type)
73
+ assert_equal(:multiple, which)
63
74
  end
75
+
76
+ call_count += 1
64
77
  end
65
78
 
66
79
  grammar.production(:a, 'A*') { |a| a }
80
+ assert_equal(4, call_count)
67
81
 
68
- first = true
69
- grammar.callback do |p, type, num|
70
- assert_not_nil(p)
71
- assert_equal(type, :+)
82
+ call_count = 0
83
+ grammar.callback do |type, which, p|
84
+ refute_nil(p)
85
+ assert_equal(type, :nelp)
72
86
 
73
- if first
74
- assert_equal(num, :first)
75
- first = false
76
- else
77
- assert_equal(num, :second)
87
+ case call_count
88
+ when 0 then assert_equal(:single, which)
89
+ when 1 then assert_equal(:multiple, which)
78
90
  end
91
+
92
+ call_count += 1
79
93
  end
80
94
 
81
95
  grammar.production(:a, 'A+') { |a| a }
96
+ assert_equal(2, call_count)
82
97
  end
83
98
 
84
99
  def test_first_set
85
100
  @grammar.first_set(:s).each do |sym|
86
- assert([:A, :B].include?(sym))
101
+ assert_includes([:A, :B], sym)
87
102
  end
88
103
 
89
- assert_equal(@grammar.first_set(:b), [:G])
90
- assert_equal(@grammar.first_set(:a), [:G])
104
+ assert_equal([:G], @grammar.first_set(:b))
105
+ assert_equal([:G], @grammar.first_set(:a))
91
106
  end
92
107
 
93
108
  def test_follow_set
@@ -103,13 +118,13 @@ class CFGTester < Test::Unit::TestCase
103
118
  end
104
119
 
105
120
  def test_is_nonterminal
106
- assert_equal(RLTK::CFG::is_nonterminal?(:lowercase), true)
107
- assert_equal(RLTK::CFG::is_nonterminal?(:UPERCASE), false)
121
+ assert(RLTK::CFG::is_nonterminal?(:lowercase))
122
+ assert(!RLTK::CFG::is_nonterminal?(:UPERCASE))
108
123
  end
109
124
 
110
125
  def test_is_terminal
111
- assert_equal(RLTK::CFG::is_terminal?(:lowercase), false)
112
- assert_equal(RLTK::CFG::is_terminal?(:UPERCASE), true)
126
+ assert(!RLTK::CFG::is_terminal?(:lowercase))
127
+ assert(RLTK::CFG::is_terminal?(:UPERCASE))
113
128
  end
114
129
 
115
130
  def test_item
@@ -117,25 +132,25 @@ class CFGTester < Test::Unit::TestCase
117
132
  i1 = i0.copy
118
133
 
119
134
  assert_equal(i0, i1)
120
- assert_equal(i0.at_end?, false)
121
- assert_equal(i0.next_symbol, :b)
135
+ assert(!i0.at_end?)
136
+ assert_equal(:b, i0.next_symbol)
122
137
 
123
138
  i0.advance
124
139
 
125
- assert_not_equal(i0, i1)
126
- assert_equal(i0.at_end?, false)
127
- assert_equal(i0.next_symbol, :C)
140
+ refute_equal(i0, i1)
141
+ assert(!i0.at_end?)
142
+ assert_equal(:C, i0.next_symbol)
128
143
 
129
144
  i0.advance
130
- assert_equal(i0.at_end?, false)
131
- assert_equal(i0.next_symbol, :D)
145
+ assert(!i0.at_end?)
146
+ assert_equal(:D, i0.next_symbol)
132
147
 
133
148
  i0.advance
134
- assert_equal(i0.at_end?, false)
135
- assert_equal(i0.next_symbol, :e)
149
+ assert(!i0.at_end?)
150
+ assert_equal(:e, i0.next_symbol)
136
151
 
137
152
  i0.advance
138
- assert_equal(i0.at_end?, true)
153
+ assert(i0.at_end?)
139
154
  assert_nil(i0.next_symbol)
140
155
  end
141
156
 
@@ -144,6 +159,6 @@ class CFGTester < Test::Unit::TestCase
144
159
  p1 = p0.copy
145
160
 
146
161
  assert_equal(p0, p1)
147
- assert_equal(p0.last_terminal, :D)
162
+ assert_equal(:D, p0.last_terminal)
148
163
  end
149
164
  end
data/test/tc_lexer.rb CHANGED
@@ -7,8 +7,8 @@
7
7
  # Requires #
8
8
  ############
9
9
 
10
- # Standard Library
11
- require 'test/unit'
10
+ # Gems
11
+ require 'minitest/autorun'
12
12
 
13
13
  # Ruby Language Toolkit
14
14
  require 'rltk/token'
@@ -20,21 +20,21 @@ require 'rltk/lexers/ebnf'
20
20
  # Classes and Modules #
21
21
  #######################
22
22
 
23
- class LexerTester < Test::Unit::TestCase
23
+ class LexerTester < Minitest::Test
24
24
  class ABLongest < RLTK::Lexer
25
- rule(/a+/) { :APLUS }
26
- rule(/b+/) { :BPLUS }
25
+ rule(/a+/) { :APLUS }
26
+ rule(/b+/) { :BPLUS }
27
27
 
28
- rule(/a+b+/) { :APLUSBPLUS }
28
+ rule(/a+b+/) { :APLUSBPLUS }
29
29
  end
30
30
 
31
31
  class ABFirst < RLTK::Lexer
32
32
  match_first
33
33
 
34
- rule(/a+/) { :APLUS }
35
- rule(/b+/) { :BPLUS }
34
+ rule(/a+/) { :APLUS }
35
+ rule(/b+/) { :BPLUS }
36
36
 
37
- rule(/a+b+/) { :APLUSBPLUS }
37
+ rule(/a+b+/) { :APLUSBPLUS }
38
38
  end
39
39
 
40
40
  class ENVLexer < RLTK::Lexer
@@ -53,21 +53,21 @@ class LexerTester < Test::Unit::TestCase
53
53
  end
54
54
 
55
55
  class FlagLexer < RLTK::Lexer
56
- rule(/a/) { set_flag(:a); :A }
56
+ rule(/a/) { set_flag(:a); :A }
57
57
  rule(/\s/)
58
58
 
59
- rule(/b/, :default, [:a]) { set_flag(:b); :B }
60
- rule(/c/, :default, [:a, :b]) { :C }
59
+ rule(/b/, :default, [:a]) { set_flag(:b); :B }
60
+ rule(/c/, :default, [:a, :b]) { :C }
61
61
  end
62
62
 
63
63
  class StateLexer < RLTK::Lexer
64
- rule(/a/) { :A }
64
+ rule(/a/) { :A }
65
65
  rule(/\s/)
66
66
 
67
- rule(/\(\*/) { push_state(:comment) }
67
+ rule(/\(\*/) { push_state(:comment) }
68
68
 
69
- rule(/\(\*/, :comment) { push_state(:comment) }
70
- rule(/\*\)/, :comment) { pop_state }
69
+ rule(/\(\*/, :comment) { push_state(:comment) }
70
+ rule(/\*\)/, :comment) { pop_state }
71
71
  rule(/./, :comment)
72
72
  end
73
73
 
@@ -76,19 +76,18 @@ class LexerTester < Test::Unit::TestCase
76
76
  end
77
77
 
78
78
  def test_calc
79
- expected =
80
- [
81
- RLTK::Token.new(:NUM, 1),
82
-
83
- RLTK::Token.new(:PLS),
84
- RLTK::Token.new(:SUB),
85
- RLTK::Token.new(:MUL),
86
- RLTK::Token.new(:DIV),
87
-
88
- RLTK::Token.new(:LPAREN),
89
- RLTK::Token.new(:RPAREN),
90
- RLTK::Token.new(:EOS)
91
- ]
79
+ expected = [
80
+ RLTK::Token.new(:NUM, 1),
81
+
82
+ RLTK::Token.new(:PLS),
83
+ RLTK::Token.new(:SUB),
84
+ RLTK::Token.new(:MUL),
85
+ RLTK::Token.new(:DIV),
86
+
87
+ RLTK::Token.new(:LPAREN),
88
+ RLTK::Token.new(:RPAREN),
89
+ RLTK::Token.new(:EOS)
90
+ ]
92
91
 
93
92
  actual = RLTK::Lexers::Calculator.lex('1 + - * / ( )')
94
93
 
@@ -96,16 +95,15 @@ class LexerTester < Test::Unit::TestCase
96
95
  end
97
96
 
98
97
  def test_ebnf
99
- expected =
100
- [
101
- RLTK::Token.new(:NONTERM, :aaa),
102
- RLTK::Token.new(:TERM, :BBB),
103
-
104
- RLTK::Token.new(:*),
105
- RLTK::Token.new(:+),
106
- RLTK::Token.new(:'?'),
107
- RLTK::Token.new(:EOS)
108
- ]
98
+ expected = [
99
+ RLTK::Token.new(:NONTERM, :aaa),
100
+ RLTK::Token.new(:TERM, :BBB),
101
+
102
+ RLTK::Token.new(:STAR),
103
+ RLTK::Token.new(:PLUS),
104
+ RLTK::Token.new(:QUESTION),
105
+ RLTK::Token.new(:EOS)
106
+ ]
109
107
 
110
108
  actual = RLTK::Lexers::EBNF.lex('aaa BBB * + ?')
111
109
 
@@ -113,13 +111,12 @@ class LexerTester < Test::Unit::TestCase
113
111
  end
114
112
 
115
113
  def test_environment
116
- expected =
117
- [
118
- RLTK::Token.new(:A, 0),
119
- RLTK::Token.new(:A, 1),
120
- RLTK::Token.new(:A, 2),
121
- RLTK::Token.new(:EOS)
122
- ]
114
+ expected = [
115
+ RLTK::Token.new(:A, 0),
116
+ RLTK::Token.new(:A, 1),
117
+ RLTK::Token.new(:A, 2),
118
+ RLTK::Token.new(:EOS)
119
+ ]
123
120
 
124
121
  actual = ENVLexer.lex('aaa')
125
122
 
@@ -129,24 +126,22 @@ class LexerTester < Test::Unit::TestCase
129
126
 
130
127
  assert_equal(expected, lexer.lex('aaa'))
131
128
 
132
- expected =
133
- [
134
- RLTK::Token.new(:A, 3),
135
- RLTK::Token.new(:A, 4),
136
- RLTK::Token.new(:A, 5),
137
- RLTK::Token.new(:EOS)
138
- ]
129
+ expected = [
130
+ RLTK::Token.new(:A, 3),
131
+ RLTK::Token.new(:A, 4),
132
+ RLTK::Token.new(:A, 5),
133
+ RLTK::Token.new(:EOS)
134
+ ]
139
135
 
140
136
  assert_equal(expected, lexer.lex('aaa'))
141
137
  end
142
138
 
143
139
  def test_first_match
144
- expected =
145
- [
146
- RLTK::Token.new(:APLUS),
147
- RLTK::Token.new(:BPLUS),
148
- RLTK::Token.new(:EOS)
149
- ]
140
+ expected = [
141
+ RLTK::Token.new(:APLUS),
142
+ RLTK::Token.new(:BPLUS),
143
+ RLTK::Token.new(:EOS)
144
+ ]
150
145
 
151
146
  actual = ABFirst.lex('aaabbb')
152
147
 
@@ -155,49 +150,43 @@ class LexerTester < Test::Unit::TestCase
155
150
 
156
151
  def test_flags
157
152
 
158
- assert_raise(RLTK::LexingError) { FlagLexer.lex('b') }
159
- assert_raise(RLTK::LexingError) { FlagLexer.lex('ac') }
153
+ assert_raises(RLTK::LexingError) { FlagLexer.lex('b') }
154
+ assert_raises(RLTK::LexingError) { FlagLexer.lex('ac') }
160
155
 
161
- expected =
162
- [
163
- RLTK::Token.new(:A),
164
- RLTK::Token.new(:B),
165
- RLTK::Token.new(:C),
166
- RLTK::Token.new(:EOS)
167
- ]
156
+ expected = [
157
+ RLTK::Token.new(:A),
158
+ RLTK::Token.new(:B),
159
+ RLTK::Token.new(:C),
160
+ RLTK::Token.new(:EOS)
161
+ ]
168
162
 
169
163
  actual = FlagLexer.lex('abc')
170
164
  assert_equal(expected, actual)
171
165
 
172
- expected =
173
- [
174
- RLTK::Token.new(:A),
175
- RLTK::Token.new(:B),
176
- RLTK::Token.new(:C),
177
- RLTK::Token.new(:A),
178
- RLTK::Token.new(:B),
179
- RLTK::Token.new(:C),
180
- RLTK::Token.new(:EOS)
181
- ]
166
+ expected = [
167
+ RLTK::Token.new(:A),
168
+ RLTK::Token.new(:B),
169
+ RLTK::Token.new(:C),
170
+ RLTK::Token.new(:A),
171
+ RLTK::Token.new(:B),
172
+ RLTK::Token.new(:C),
173
+ RLTK::Token.new(:EOS)
174
+ ]
182
175
 
183
176
  actual = FlagLexer.lex('abcabc')
184
177
  assert_equal(expected, actual)
185
178
  end
186
179
 
187
180
  def test_lex
188
- assert_raise(RLTK::LexingError) { ABFirst.lex('aaabbbCCC') }
189
- assert_raise(RLTK::LexingError) { ABLongest.lex('aaabbbCCC') }
190
-
191
- assert_nothing_raised(RLTK::LexingError) { ABFirst.lex('aaabbb') }
192
- assert_nothing_raised(RLTK::LexingError) { ABLongest.lex('aaabbb') }
181
+ assert_raises(RLTK::LexingError) { ABFirst.lex('aaabbbCCC') }
182
+ assert_raises(RLTK::LexingError) { ABLongest.lex('aaabbbCCC') }
193
183
  end
194
184
 
195
185
  def test_longest_match
196
- expected =
197
- [
198
- RLTK::Token.new(:APLUSBPLUS),
199
- RLTK::Token.new(:EOS)
200
- ]
186
+ expected = [
187
+ RLTK::Token.new(:APLUSBPLUS),
188
+ RLTK::Token.new(:EOS)
189
+ ]
201
190
 
202
191
  actual = ABLongest.lex('aaabbb')
203
192
 
@@ -205,19 +194,18 @@ class LexerTester < Test::Unit::TestCase
205
194
  end
206
195
 
207
196
  def test_match_data
208
- expected = [RLTK::Token.new(:FOO, ['', 'ccc']), RLTK::Token.new(:EOS)]
209
- actual = MatchDataLexer.lex('accc')
197
+ expected = [RLTK::Token.new(:FOO, ['', 'ccc']), RLTK::Token.new(:EOS)]
198
+ actual = MatchDataLexer.lex('accc')
210
199
 
211
200
  assert_equal(expected, actual)
212
201
  end
213
202
 
214
203
  def test_state
215
- expected =
216
- [
217
- RLTK::Token.new(:A),
218
- RLTK::Token.new(:A),
219
- RLTK::Token.new(:EOS)
220
- ]
204
+ expected = [
205
+ RLTK::Token.new(:A),
206
+ RLTK::Token.new(:A),
207
+ RLTK::Token.new(:EOS)
208
+ ]
221
209
 
222
210
  actual = StateLexer.lex('a (* bbb *) a')
223
211
  assert_equal(expected, actual)