rltk3 3.0.2
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.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/LICENSE +27 -0
- data/README.md +852 -0
- data/Rakefile +197 -0
- data/lib/rltk/ast.rb +573 -0
- data/lib/rltk/cfg.rb +683 -0
- data/lib/rltk/cg/basic_block.rb +157 -0
- data/lib/rltk/cg/bindings.rb +151 -0
- data/lib/rltk/cg/builder.rb +1127 -0
- data/lib/rltk/cg/context.rb +48 -0
- data/lib/rltk/cg/contractor.rb +51 -0
- data/lib/rltk/cg/execution_engine.rb +194 -0
- data/lib/rltk/cg/function.rb +237 -0
- data/lib/rltk/cg/generated_bindings.rb +8118 -0
- data/lib/rltk/cg/generic_value.rb +95 -0
- data/lib/rltk/cg/instruction.rb +519 -0
- data/lib/rltk/cg/llvm.rb +150 -0
- data/lib/rltk/cg/memory_buffer.rb +75 -0
- data/lib/rltk/cg/module.rb +451 -0
- data/lib/rltk/cg/pass_manager.rb +252 -0
- data/lib/rltk/cg/support.rb +29 -0
- data/lib/rltk/cg/target.rb +230 -0
- data/lib/rltk/cg/triple.rb +58 -0
- data/lib/rltk/cg/type.rb +554 -0
- data/lib/rltk/cg/value.rb +1272 -0
- data/lib/rltk/cg.rb +32 -0
- data/lib/rltk/lexer.rb +372 -0
- data/lib/rltk/lexers/calculator.rb +44 -0
- data/lib/rltk/lexers/ebnf.rb +38 -0
- data/lib/rltk/parser.rb +1702 -0
- data/lib/rltk/parsers/infix_calc.rb +43 -0
- data/lib/rltk/parsers/postfix_calc.rb +34 -0
- data/lib/rltk/parsers/prefix_calc.rb +34 -0
- data/lib/rltk/token.rb +90 -0
- data/lib/rltk/version.rb +11 -0
- data/lib/rltk.rb +16 -0
- data/test/cg/tc_basic_block.rb +83 -0
- data/test/cg/tc_control_flow.rb +191 -0
- data/test/cg/tc_function.rb +54 -0
- data/test/cg/tc_generic_value.rb +33 -0
- data/test/cg/tc_instruction.rb +256 -0
- data/test/cg/tc_llvm.rb +25 -0
- data/test/cg/tc_math.rb +88 -0
- data/test/cg/tc_module.rb +89 -0
- data/test/cg/tc_transforms.rb +68 -0
- data/test/cg/tc_type.rb +69 -0
- data/test/cg/tc_value.rb +151 -0
- data/test/cg/ts_cg.rb +23 -0
- data/test/tc_ast.rb +332 -0
- data/test/tc_cfg.rb +164 -0
- data/test/tc_lexer.rb +216 -0
- data/test/tc_parser.rb +711 -0
- data/test/tc_token.rb +34 -0
- data/test/ts_rltk.rb +47 -0
- metadata +317 -0
@@ -0,0 +1,256 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/05/09
|
4
|
+
# Description: This file contains unit tests for the RLTK::CG::Instruction
|
5
|
+
# class.
|
6
|
+
|
7
|
+
############
|
8
|
+
# Requires #
|
9
|
+
############
|
10
|
+
|
11
|
+
# Gems
|
12
|
+
require 'minitest/autorun'
|
13
|
+
|
14
|
+
# Ruby Language Toolkit
|
15
|
+
require 'rltk/cg/llvm'
|
16
|
+
require 'rltk/cg/module'
|
17
|
+
require 'rltk/cg/instruction'
|
18
|
+
|
19
|
+
class InstructionTester < Minitest::Test
|
20
|
+
def setup
|
21
|
+
RLTK::CG::LLVM.init(:X86)
|
22
|
+
|
23
|
+
@mod = RLTK::CG::Module.new('Testing Module')
|
24
|
+
@jit = RLTK::CG::JITCompiler.new(@mod)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_float_comparison
|
28
|
+
fcmp_assert(:oeq, 1.0, 1.0, true )
|
29
|
+
fcmp_assert(:one, 1.0, 1.0, false)
|
30
|
+
fcmp_assert(:ogt, 2.0, 2.0, false)
|
31
|
+
fcmp_assert(:oge, 2.0, 1.0, true )
|
32
|
+
fcmp_assert(:olt, 1.0, 1.0, false)
|
33
|
+
fcmp_assert(:ole, 1.0, 2.0, true )
|
34
|
+
fcmp_assert(:ord, 1.0, 2.0, true )
|
35
|
+
fcmp_assert(:ueq, 1.0, 1.0, true )
|
36
|
+
fcmp_assert(:une, 1.0, 1.0, false)
|
37
|
+
fcmp_assert(:ugt, 2.0, 2.0, false)
|
38
|
+
fcmp_assert(:uge, 2.0, 1.0, true )
|
39
|
+
fcmp_assert(:ult, 1.0, 1.0, false)
|
40
|
+
fcmp_assert(:ule, 1.0, 2.0, true )
|
41
|
+
fcmp_assert(:uno, 1.0, 2.0, false)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_instruction
|
45
|
+
fun = @mod.functions.add('instruction_tester', RLTK::CG::DoubleType, [RLTK::CG::DoubleType]) do |fun|
|
46
|
+
blocks.append do
|
47
|
+
ret(fadd(fun.params[0], RLTK::CG::Double.new(3.0)))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
entry = fun.blocks.entry
|
52
|
+
|
53
|
+
inst0 = entry.instructions.first
|
54
|
+
inst1 = entry.instructions.last
|
55
|
+
|
56
|
+
assert_kind_of(RLTK::CG::Instruction, inst0)
|
57
|
+
assert_kind_of(RLTK::CG::Instruction, inst1)
|
58
|
+
|
59
|
+
assert_equal(inst1, inst0.next)
|
60
|
+
assert_equal(inst0, inst1.previous)
|
61
|
+
|
62
|
+
assert_equal(entry, inst0.parent)
|
63
|
+
assert_equal(entry, inst1.parent)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_integer_comparison
|
67
|
+
icmp_assert(:eq, 1, 1, true, true )
|
68
|
+
icmp_assert(:ne, 1, 1, true, false)
|
69
|
+
icmp_assert(:ugt, 2, 2, false, false)
|
70
|
+
icmp_assert(:uge, 2, 1, false, true )
|
71
|
+
icmp_assert(:ult, 1, 1, false, false)
|
72
|
+
icmp_assert(:ule, 1, 2, false, true )
|
73
|
+
icmp_assert(:sgt, -2, 2, true, false)
|
74
|
+
icmp_assert(:sge, -2, 1, true, false)
|
75
|
+
icmp_assert(:slt, -1, 2, true, true )
|
76
|
+
icmp_assert(:sle, -1, 2, true, true )
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_array_memory_access
|
80
|
+
fun = @mod.functions.add('array_memory_access_tester', RLTK::CG::NativeIntType,
|
81
|
+
[RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do |fun|
|
82
|
+
|
83
|
+
blocks.append do
|
84
|
+
ptr = array_alloca(RLTK::CG::NativeIntType, RLTK::CG::NativeInt.new(2))
|
85
|
+
|
86
|
+
store(fun.params[0], gep(ptr, [RLTK::CG::NativeInt.new(0)]))
|
87
|
+
store(fun.params[1], gep(ptr, [RLTK::CG::NativeInt.new(1)]))
|
88
|
+
|
89
|
+
ret(add(load(gep(ptr, [RLTK::CG::NativeInt.new(0)])), load(gep(ptr, [RLTK::CG::NativeInt.new(1)]))))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
assert_equal(3, @jit.run_function(fun, 1, 2).to_i)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_simple_memory_access
|
97
|
+
fun = @mod.functions.add('simple_memory_access_tester', RLTK::CG::NativeIntType,
|
98
|
+
[RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do |fun|
|
99
|
+
|
100
|
+
blocks.append do
|
101
|
+
p0 = alloca(RLTK::CG::NativeIntType)
|
102
|
+
p1 = alloca(RLTK::CG::NativeIntType)
|
103
|
+
|
104
|
+
store(fun.params[0], p0)
|
105
|
+
store(fun.params[1], p1)
|
106
|
+
|
107
|
+
ret(add(load(p0), load(p1)))
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
assert_equal(3, @jit.run_function(fun, 1, 2).to_i)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_struct_access
|
115
|
+
fun = @mod.functions.add('struct_access_tester', RLTK::CG::FloatType, [RLTK::CG::NativeIntType, RLTK::CG::FloatType]) do |fun|
|
116
|
+
blocks.append do
|
117
|
+
st0 = RLTK::CG::StructType.new([RLTK::CG::NativeIntType, RLTK::CG::FloatType])
|
118
|
+
st1 = RLTK::CG::StructType.new([RLTK::CG::FloatType, st0, RLTK::CG::NativeIntType])
|
119
|
+
|
120
|
+
ptr = alloca(st1)
|
121
|
+
|
122
|
+
store(fun.params[0], gep(ptr, [RLTK::CG::NativeInt.new(0), RLTK::CG::NativeInt.new(1), RLTK::CG::NativeInt.new(0)]))
|
123
|
+
store(fun.params[1], gep(ptr, [RLTK::CG::NativeInt.new(0), RLTK::CG::NativeInt.new(1), RLTK::CG::NativeInt.new(1)]))
|
124
|
+
|
125
|
+
addr0 = gep(ptr, [RLTK::CG::NativeInt.new(0), RLTK::CG::NativeInt.new(1), RLTK::CG::NativeInt.new(0)])
|
126
|
+
addr1 = gep(ptr, [RLTK::CG::NativeInt.new(0), RLTK::CG::NativeInt.new(1), RLTK::CG::NativeInt.new(1)])
|
127
|
+
|
128
|
+
ret(fadd(ui2fp(load(addr0), RLTK::CG::FloatType), load(addr1)))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
assert_in_delta(5.3, @jit.run_function(fun, 2, 3.3).to_f, 0.001)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_struct_values
|
136
|
+
fun = @mod.functions.add('struct_values_tester', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do |fun|
|
137
|
+
blocks.append do
|
138
|
+
ptr = alloca(RLTK::CG::StructType.new([RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]))
|
139
|
+
|
140
|
+
struct = load(ptr)
|
141
|
+
struct = insert_value(struct, fun.params[0], 0)
|
142
|
+
struct = insert_value(struct, fun.params[1], 1)
|
143
|
+
|
144
|
+
ret(add(extract_value(struct, 0), extract_value(struct, 1)))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
assert_equal(5, @jit.run_function(fun, 2, 3).to_i)
|
149
|
+
end
|
150
|
+
|
151
|
+
####################
|
152
|
+
# Conversion Tests #
|
153
|
+
####################
|
154
|
+
|
155
|
+
def test_bitcast
|
156
|
+
difftype_assert(:bitcast, RLTK::CG::Int8.new(255), RLTK::CG::Int8Type, :integer, -1)
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_fp2ui
|
160
|
+
difftype_assert(:fp2ui, RLTK::CG::Double.new(123.3), RLTK::CG::Int32Type, :integer, 123)
|
161
|
+
difftype_assert(:fp2ui, RLTK::CG::Double.new(0.7), RLTK::CG::Int32Type, :integer, 0)
|
162
|
+
difftype_assert(:fp2ui, RLTK::CG::Double.new(1.7), RLTK::CG::Int32Type, :integer, 1)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_fp2si
|
166
|
+
difftype_assert(:fp2si, RLTK::CG::Double.new(-123.3), RLTK::CG::Int32Type, :integer, -123)
|
167
|
+
difftype_assert(:fp2si, RLTK::CG::Double.new(0.7), RLTK::CG::Int32Type, :integer, 0)
|
168
|
+
difftype_assert(:fp2si, RLTK::CG::Double.new(1.7), RLTK::CG::Int32Type, :integer, 1)
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_fpext
|
172
|
+
fconv_assert(:fp_ext, RLTK::CG::Float.new(123.0), RLTK::CG::DoubleType, 123.0)
|
173
|
+
fconv_assert(:fp_ext, RLTK::CG::Float.new(123.0), RLTK::CG::FloatType, 123.0)
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_fptrunc
|
177
|
+
fconv_assert(:fp_trunc, RLTK::CG::Double.new(123.0), RLTK::CG::FloatType, 123.0)
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_int64
|
181
|
+
iconv_assert(:zext, RLTK::CG::Int64.new( 2**62 + 123), RLTK::CG::Int64Type, true, 2**62 + 123)
|
182
|
+
iconv_assert(:zext, RLTK::CG::Int64.new(-2**62 - 123), RLTK::CG::Int64Type, true, -2**62 - 123)
|
183
|
+
iconv_assert(:zext, RLTK::CG::Int64.new( 2**63 + 123), RLTK::CG::Int64Type, false, 2**63 + 123)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_sext
|
187
|
+
iconv_assert(:sext, RLTK::CG::Int1.new(1), RLTK::CG::Int32Type, true, -1)
|
188
|
+
iconv_assert(:sext, RLTK::CG::Int8.new(-1), RLTK::CG::Int16Type, false, 65535)
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_si2fp
|
192
|
+
difftype_assert(:si2fp, RLTK::CG::Int32.new(257), RLTK::CG::FloatType, :float, 257.0)
|
193
|
+
difftype_assert(:si2fp, RLTK::CG::Int8.new(-1), RLTK::CG::DoubleType, :float, -1.0)
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_truncate
|
197
|
+
iconv_assert(:trunc, RLTK::CG::Int32.new(257), RLTK::CG::Int8Type, false, 1)
|
198
|
+
iconv_assert(:trunc, RLTK::CG::Int32.new(123), RLTK::CG::Int1Type, false, 1)
|
199
|
+
iconv_assert(:trunc, RLTK::CG::Int32.new(122), RLTK::CG::Int1Type, false, 0)
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_ui2fp
|
203
|
+
difftype_assert(:ui2fp, RLTK::CG::Int32.new(257), RLTK::CG::FloatType, :float, 257.0)
|
204
|
+
difftype_assert(:ui2fp, RLTK::CG::Int8.new(-1), RLTK::CG::DoubleType, :float, 255.0)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_zext
|
208
|
+
iconv_assert(:zext, RLTK::CG::Int16.new(257), RLTK::CG::Int32Type, false, 257)
|
209
|
+
end
|
210
|
+
|
211
|
+
##################
|
212
|
+
# Helper Methods #
|
213
|
+
##################
|
214
|
+
|
215
|
+
def difftype_assert(op, operand, ret_type, assert_type, expected)
|
216
|
+
res = run_convert(op, operand, ret_type)
|
217
|
+
|
218
|
+
if assert_type == :integer then assert_equal(expected, res.to_i) else assert_in_delta(expected, res.to_f(ret_type), 0.001) end
|
219
|
+
end
|
220
|
+
|
221
|
+
def fcmp_assert(mode, operand0, operand1, expected)
|
222
|
+
res = run_cmp(:fcmp, mode, RLTK::CG::Float.new(operand0), RLTK::CG::Float.new(operand1), RLTK::CG::Int1Type).to_i(false)
|
223
|
+
assert_equal(expected.to_i, res)
|
224
|
+
end
|
225
|
+
|
226
|
+
def icmp_assert(mode, operand0, operand1, signed, expected)
|
227
|
+
res = run_cmp(:icmp, mode, RLTK::CG::NativeInt.new(operand0, signed),
|
228
|
+
RLTK::CG::NativeInt.new(operand1, signed), RLTK::CG::Int1Type).to_i(false)
|
229
|
+
|
230
|
+
assert_equal(expected.to_i, res)
|
231
|
+
end
|
232
|
+
|
233
|
+
def fconv_assert(op, operand, ret_type, expected)
|
234
|
+
assert_in_delta(expected, run_convert(op, operand, ret_type).to_f(ret_type), 0.001)
|
235
|
+
end
|
236
|
+
|
237
|
+
def iconv_assert(op, operand, ret_type, signed, expected)
|
238
|
+
assert_equal(expected, run_convert(op, operand, ret_type).to_i(signed))
|
239
|
+
end
|
240
|
+
|
241
|
+
def run_cmp(op, mode, operand0, operand1, ret_type)
|
242
|
+
fun = @mod.functions.add("#{op}_#{mode}_tester", ret_type, []) do
|
243
|
+
blocks.append { ret(self.send(op, mode, operand0, operand1)) }
|
244
|
+
end
|
245
|
+
|
246
|
+
@jit.run_function(fun)
|
247
|
+
end
|
248
|
+
|
249
|
+
def run_convert(op, operand, ret_type)
|
250
|
+
fun = @mod.functions.add("#{op}_tester", ret_type, []) do
|
251
|
+
blocks.append { ret(self.send(op, operand, ret_type)) }
|
252
|
+
end
|
253
|
+
|
254
|
+
@jit.run_function(fun)
|
255
|
+
end
|
256
|
+
end
|
data/test/cg/tc_llvm.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/05/04
|
4
|
+
# Description: This file contains unit tests for rltk/cg/llvm.rb file.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Gems
|
11
|
+
require 'minitest/autorun'
|
12
|
+
|
13
|
+
# Ruby Language Toolkit
|
14
|
+
require 'rltk/version'
|
15
|
+
require 'rltk/cg/llvm'
|
16
|
+
|
17
|
+
#######################
|
18
|
+
# Classes and Modules #
|
19
|
+
#######################
|
20
|
+
|
21
|
+
class LLVMTester < Minitest::Test
|
22
|
+
def test_init
|
23
|
+
assert_raises(ArgumentError) { RLTK::CG::LLVM.init(:foo) }
|
24
|
+
end
|
25
|
+
end
|
data/test/cg/tc_math.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/05/09
|
4
|
+
# Description: This file contains unit tests for various math instructions.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Gems
|
11
|
+
require 'minitest/autorun'
|
12
|
+
|
13
|
+
# Ruby Language Toolkit
|
14
|
+
require 'rltk/cg/llvm'
|
15
|
+
require 'rltk/cg/module'
|
16
|
+
require 'rltk/cg/execution_engine'
|
17
|
+
require 'rltk/cg/type'
|
18
|
+
require 'rltk/cg/value'
|
19
|
+
|
20
|
+
#######################
|
21
|
+
# Classes and Modules #
|
22
|
+
#######################
|
23
|
+
|
24
|
+
class MathTester < Minitest::Test
|
25
|
+
def setup
|
26
|
+
RLTK::CG::LLVM.init(:X86)
|
27
|
+
|
28
|
+
@mod = RLTK::CG::Module.new('Testing Module')
|
29
|
+
@jit = RLTK::CG::JITCompiler.new(@mod)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_integer_binary_operations
|
33
|
+
int_binop_assert(:add, 3, 2, 3 + 2)
|
34
|
+
int_binop_assert(:sub, 3, 2, 3 - 2)
|
35
|
+
int_binop_assert(:mul, 3, 2, 3 * 2)
|
36
|
+
int_binop_assert(:udiv, 10, 2, 10 / 2)
|
37
|
+
int_binop_assert(:sdiv, 10, 2, 10 / 2)
|
38
|
+
int_binop_assert(:urem, 10, 3, 10 % 3)
|
39
|
+
int_binop_assert(:srem, 10, 3, 10 % 3)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_integer_bitwise_binary_operations
|
43
|
+
int_binop_assert(:shl, 2, 3, 2 << 3)
|
44
|
+
int_binop_assert(:lshr, 16, 3, 16 >> 3)
|
45
|
+
int_binop_assert(:ashr, 16, 3, 16 >> 3)
|
46
|
+
int_binop_assert(:and, 2, 1, 2 & 1)
|
47
|
+
int_binop_assert(:or, 2, 1, 2 | 1)
|
48
|
+
int_binop_assert(:xor, 3, 2, 3 ^ 2)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_float_binary_operations
|
52
|
+
float_binop_assert(:fadd, 3.1, 2.2, 3.1 + 2.2)
|
53
|
+
float_binop_assert(:fsub, 3.1, 2.2, 3.1 - 2.2)
|
54
|
+
float_binop_assert(:fmul, 3.1, 2.2, 3.1 * 2.2)
|
55
|
+
float_binop_assert(:fdiv, 3.1, 2.2, 3.1 / 2.2)
|
56
|
+
float_binop_assert(:frem, 3.1, 2.2, 3.1 % 2.2)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_simple_math_fun
|
60
|
+
fun = @mod.functions.add('simple_math_tester', RLTK::CG::FloatType, [RLTK::CG::FloatType]) do |fun|
|
61
|
+
blocks.append do
|
62
|
+
ret(fadd(fun.params[0], RLTK::CG::Float.new(1.0)))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
assert_equal(6.0, @jit.run_function(fun, 5.0).to_f)
|
67
|
+
end
|
68
|
+
|
69
|
+
##################
|
70
|
+
# Helper Methods #
|
71
|
+
##################
|
72
|
+
|
73
|
+
def float_binop_assert(op, operand0, operand1, expected)
|
74
|
+
assert_in_delta(expected, run_binop(op, RLTK::CG::Float.new(operand0), RLTK::CG::Float.new(operand1), RLTK::CG::FloatType).to_f, 0.001)
|
75
|
+
end
|
76
|
+
|
77
|
+
def int_binop_assert(op, operand0, operand1, expected)
|
78
|
+
assert_equal(expected, run_binop(op, RLTK::CG::NativeInt.new(operand0), RLTK::CG::NativeInt.new(operand1), RLTK::CG::NativeIntType).to_i)
|
79
|
+
end
|
80
|
+
|
81
|
+
def run_binop(op, operand0, operand1, ret_type)
|
82
|
+
fun = @mod.functions.add(op.to_s + '_tester', ret_type, []) do
|
83
|
+
blocks.append { ret(self.send(op, operand0, operand1)) }
|
84
|
+
end
|
85
|
+
|
86
|
+
@jit.run_function(fun)
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/05/04
|
4
|
+
# Description: This file contains unit tests for the RLTK::CG::Module class.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Standard Library
|
11
|
+
require 'tempfile'
|
12
|
+
|
13
|
+
# Gems
|
14
|
+
require 'minitest/autorun'
|
15
|
+
|
16
|
+
# Ruby Language Toolkit
|
17
|
+
require 'rltk/cg/llvm'
|
18
|
+
require 'rltk/cg/module'
|
19
|
+
require 'rltk/cg/execution_engine'
|
20
|
+
require 'rltk/cg/type'
|
21
|
+
require 'rltk/cg/value'
|
22
|
+
|
23
|
+
#######################
|
24
|
+
# Classes and Modules #
|
25
|
+
#######################
|
26
|
+
|
27
|
+
class ModuleTester < Minitest::Test
|
28
|
+
def setup
|
29
|
+
RLTK::CG::LLVM.init(:X86)
|
30
|
+
|
31
|
+
@mod = RLTK::CG::Module.new('Testing Module')
|
32
|
+
@jit = RLTK::CG::JITCompiler.new(@mod)
|
33
|
+
|
34
|
+
@mod.functions.add('int_function_tester', RLTK::CG::NativeIntType, []) do
|
35
|
+
blocks.append { ret RLTK::CG::NativeInt.new(1) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_bitcode
|
40
|
+
Tempfile.open('bitcode') do |tmp|
|
41
|
+
assert(@mod.write_bitcode(tmp))
|
42
|
+
|
43
|
+
new_mod = RLTK::CG::Module.read_bitcode(tmp.path)
|
44
|
+
new_jit = RLTK::CG::JITCompiler.new(new_mod)
|
45
|
+
|
46
|
+
assert_equal(1, new_jit.run_function(new_mod.functions['int_function_tester']).to_i)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_equality
|
51
|
+
mod0 = RLTK::CG::Module.new('foo')
|
52
|
+
mod1 = RLTK::CG::Module.new('bar')
|
53
|
+
mod2 = RLTK::CG::Module.new(mod0.ptr)
|
54
|
+
|
55
|
+
assert_equal(mod0, mod2)
|
56
|
+
refute_equal(mod0, mod1)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_external_fun
|
60
|
+
fun = @mod.functions.add(:sin, RLTK::CG::DoubleType, [RLTK::CG::DoubleType])
|
61
|
+
res = @jit.run_function(fun, RLTK::CG::GenericValue.new(1.0, RLTK::CG::DoubleType)).to_f(RLTK::CG::DoubleType)
|
62
|
+
|
63
|
+
assert_in_delta(Math.sin(1.0), res, 1e-10)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_simple_int_fun
|
67
|
+
assert_equal(1, @jit.run_function(@mod.functions['int_function_tester']).to_i)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_simple_float_fun
|
71
|
+
fun = @mod.functions.add('float_function_tester', RLTK::CG::FloatType, []) do
|
72
|
+
blocks.append do
|
73
|
+
ret RLTK::CG::Float.new(1.5)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
assert_equal(1.5, @jit.run_function(fun).to_f(RLTK::CG::FloatType))
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_simple_double_fun
|
81
|
+
fun = @mod.functions.add('double_function_tester', RLTK::CG::DoubleType, []) do
|
82
|
+
blocks.append do
|
83
|
+
ret RLTK::CG::Double.new(1.6)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
assert_equal(1.6, @jit.run_function(fun).to_f(RLTK::CG::DoubleType))
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/05/11
|
4
|
+
# Description: This file contains unit tests for the mechanics beind
|
5
|
+
# transformation passes.
|
6
|
+
|
7
|
+
############
|
8
|
+
# Requires #
|
9
|
+
############
|
10
|
+
|
11
|
+
# Gems
|
12
|
+
require 'minitest/autorun'
|
13
|
+
|
14
|
+
# Ruby Language Toolkit
|
15
|
+
require 'rltk/cg/llvm'
|
16
|
+
require 'rltk/cg/module'
|
17
|
+
require 'rltk/cg/execution_engine'
|
18
|
+
require 'rltk/cg/type'
|
19
|
+
require 'rltk/cg/value'
|
20
|
+
|
21
|
+
class TransformTester < Minitest::Test
|
22
|
+
def setup
|
23
|
+
RLTK::CG::LLVM.init(:X86)
|
24
|
+
|
25
|
+
@mod = RLTK::CG::Module.new('Testing Module')
|
26
|
+
@jit = RLTK::CG::JITCompiler.new(@mod)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_gdce
|
30
|
+
fn0 = @mod.functions.add('fn0', RLTK::CG::VoidType, []) do |fun|
|
31
|
+
fun.linkage = :internal
|
32
|
+
|
33
|
+
blocks.append do
|
34
|
+
ret_void
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
fn1 = @mod.functions.add('fn1', RLTK::CG::VoidType, []) do |fun|
|
39
|
+
fun.linkage = :internal
|
40
|
+
|
41
|
+
blocks.append do
|
42
|
+
ret_void
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
main = @mod.functions.add('main', RLTK::CG::VoidType, []) do
|
47
|
+
blocks.append do
|
48
|
+
call(fn0)
|
49
|
+
ret_void
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
funs = @mod.functions.to_a
|
54
|
+
|
55
|
+
assert(funs.include?(fn0))
|
56
|
+
assert(funs.include?(fn1))
|
57
|
+
assert(funs.include?(main))
|
58
|
+
|
59
|
+
@mod.pass_manager << :GDCE
|
60
|
+
assert(@mod.pass_manager.run)
|
61
|
+
|
62
|
+
funs = @mod.functions.to_a
|
63
|
+
|
64
|
+
assert( funs.include?(fn0))
|
65
|
+
assert(!funs.include?(fn1))
|
66
|
+
assert( funs.include?(main))
|
67
|
+
end
|
68
|
+
end
|
data/test/cg/tc_type.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/05/09
|
4
|
+
# Description: This file contains unit tests for the RLTK::CG::Type class and
|
5
|
+
# its subclasses.
|
6
|
+
|
7
|
+
############
|
8
|
+
# Requires #
|
9
|
+
############
|
10
|
+
|
11
|
+
# Gems
|
12
|
+
require 'minitest/autorun'
|
13
|
+
|
14
|
+
# Ruby Language Toolkit
|
15
|
+
require 'rltk/cg/type'
|
16
|
+
|
17
|
+
class TypeTester < Minitest::Test
|
18
|
+
def setup
|
19
|
+
@pointee = RLTK::CG::NativeIntType.instance
|
20
|
+
@pointer = RLTK::CG::PointerType.new(@pointee)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_deferrent_element_type_stuct_type
|
24
|
+
type = RLTK::CG::StructType.new([], 'test_struct')
|
25
|
+
type.element_types = [RLTK::CG::NativeIntType, RLTK::CG::FloatType]
|
26
|
+
|
27
|
+
assert_equal(2, type.element_types.size)
|
28
|
+
assert_equal(RLTK::CG::NativeIntType.instance, type.element_types[0])
|
29
|
+
assert_equal(RLTK::CG::FloatType.instance, type.element_types[1])
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_element_type
|
34
|
+
assert_equal(@pointee, @pointer.element_type)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_equality
|
38
|
+
assert_equal(RLTK::CG::NativeIntType, RLTK::CG::NativeIntType)
|
39
|
+
refute_equal(RLTK::CG::NativeIntType, RLTK::CG::FloatType)
|
40
|
+
|
41
|
+
at0 = RLTK::CG::ArrayType.new(RLTK::CG::NativeIntType, 2)
|
42
|
+
at1 = RLTK::CG::ArrayType.new(RLTK::CG::NativeIntType, 2)
|
43
|
+
at2 = RLTK::CG::ArrayType.new(RLTK::CG::FloatType, 2)
|
44
|
+
|
45
|
+
assert_equal(at0, at1)
|
46
|
+
refute_equal(at0, at2)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_kind
|
50
|
+
assert_equal(:pointer, @pointer.kind)
|
51
|
+
assert_equal(:integer, @pointee.kind)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_named_struct_type
|
55
|
+
type = RLTK::CG::StructType.new([RLTK::CG::NativeIntType, RLTK::CG::FloatType], 'test_struct')
|
56
|
+
|
57
|
+
assert_instance_of(RLTK::CG::StructType, type)
|
58
|
+
assert_equal('test_struct', type.name)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_simple_struct_type
|
62
|
+
type = RLTK::CG::StructType.new([RLTK::CG::NativeIntType, RLTK::CG::FloatType])
|
63
|
+
|
64
|
+
assert_instance_of(RLTK::CG::StructType, type)
|
65
|
+
assert_equal(2, type.element_types.size)
|
66
|
+
assert_equal(RLTK::CG::NativeIntType.instance, type.element_types[0])
|
67
|
+
assert_equal(RLTK::CG::FloatType.instance, type.element_types[1])
|
68
|
+
end
|
69
|
+
end
|