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,43 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2011/03/04
|
4
|
+
# Description: This file contains a parser for a simple infix calculator.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/parser'
|
12
|
+
|
13
|
+
#######################
|
14
|
+
# Classes and Modules #
|
15
|
+
#######################
|
16
|
+
|
17
|
+
module RLTK
|
18
|
+
|
19
|
+
# The RLTK::Parsers module contains the parsers that are included as part
|
20
|
+
# of the RLKT project.
|
21
|
+
module Parsers
|
22
|
+
|
23
|
+
# A parser for a simple infix calculator.
|
24
|
+
class InfixCalc < Parser
|
25
|
+
|
26
|
+
left :PLS, :SUB
|
27
|
+
right :MUL, :DIV
|
28
|
+
|
29
|
+
production(:e) do
|
30
|
+
clause('NUM') { |n| n }
|
31
|
+
|
32
|
+
clause('LPAREN e RPAREN') { |_, e, _| e }
|
33
|
+
|
34
|
+
clause('e PLS e') { |e0, _, e1| e0 + e1 }
|
35
|
+
clause('e SUB e') { |e0, _, e1| e0 - e1 }
|
36
|
+
clause('e MUL e') { |e0, _, e1| e0 * e1 }
|
37
|
+
clause('e DIV e') { |e0, _, e1| e0 / e1 }
|
38
|
+
end
|
39
|
+
|
40
|
+
finalize
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2011/04/06
|
4
|
+
# Description: This file contains a parser for a simple postfix calculator.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/parser'
|
12
|
+
|
13
|
+
#######################
|
14
|
+
# Classes and Modules #
|
15
|
+
#######################
|
16
|
+
|
17
|
+
module RLTK
|
18
|
+
module Parsers
|
19
|
+
|
20
|
+
# A parser for a simple post-fix calculator.
|
21
|
+
class PostfixCalc < Parser
|
22
|
+
production(:e) do
|
23
|
+
clause('NUM') { |n| n }
|
24
|
+
|
25
|
+
clause('e e PLS') { |e0, e1, _| e0 + e1 }
|
26
|
+
clause('e e SUB') { |e0, e1, _| e0 - e1 }
|
27
|
+
clause('e e MUL') { |e0, e1, _| e0 * e1 }
|
28
|
+
clause('e e DIV') { |e0, e1, _| e0 / e1 }
|
29
|
+
end
|
30
|
+
|
31
|
+
finalize
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2011/04/06
|
4
|
+
# Description: This file contains a parser for a simple prefix calculator.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/parser'
|
12
|
+
|
13
|
+
#######################
|
14
|
+
# Classes and Modules #
|
15
|
+
#######################
|
16
|
+
|
17
|
+
module RLTK
|
18
|
+
module Parsers
|
19
|
+
|
20
|
+
# A parser for a simple prefix calculator.
|
21
|
+
class PrefixCalc < Parser
|
22
|
+
production(:e) do
|
23
|
+
clause('NUM') { |n| n }
|
24
|
+
|
25
|
+
clause('PLS e e') { |_, e0, e1| e0 + e1 }
|
26
|
+
clause('SUB e e') { |_, e0, e1| e0 - e1 }
|
27
|
+
clause('MUL e e') { |_, e0, e1| e0 * e1 }
|
28
|
+
clause('DIV e e') { |_, e0, e1| e0 / e1 }
|
29
|
+
end
|
30
|
+
|
31
|
+
finalize
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/rltk/token.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2011/01/17
|
4
|
+
# Description: This file contains code having to do with tokens.
|
5
|
+
|
6
|
+
#######################
|
7
|
+
# Classes and Modules #
|
8
|
+
#######################
|
9
|
+
|
10
|
+
module RLTK
|
11
|
+
# The StreamPosition class is used to indicate the position of a token or
|
12
|
+
# other text inside a stream.
|
13
|
+
class StreamPosition
|
14
|
+
# @return [Integer]
|
15
|
+
attr_accessor :stream_offset
|
16
|
+
|
17
|
+
# @return [Integer]
|
18
|
+
attr_accessor :line_number
|
19
|
+
|
20
|
+
# @return [Integer]
|
21
|
+
attr_accessor :line_offset
|
22
|
+
|
23
|
+
# @return [Integer]
|
24
|
+
attr_accessor :length
|
25
|
+
|
26
|
+
# @return [String]
|
27
|
+
attr_accessor :file_name
|
28
|
+
|
29
|
+
alias :start :line_offset
|
30
|
+
|
31
|
+
# Instantiates a new StreamPosition object with the values specified.
|
32
|
+
#
|
33
|
+
# @param [Integer] stream_offset The position from the beginning of the stream.
|
34
|
+
# @param [Integer] line_number The number of newlines since the beginning of the file.
|
35
|
+
# @param [Integer] line_offset The offset of this token from the beginning of the current line.
|
36
|
+
# @param [Integer] length The length of the text of the token.
|
37
|
+
# @param [String, nil] file_name The name of the file being lexed.
|
38
|
+
def initialize(stream_offset = 0, line_number = 0, line_offset = 0, length = 0, file_name = nil)
|
39
|
+
@stream_offset = stream_offset
|
40
|
+
@line_number = line_number
|
41
|
+
@line_offset = line_offset
|
42
|
+
@length = length
|
43
|
+
@file_name = file_name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# The Token class is used to represent the output of a RLTK::Lexer and the
|
48
|
+
# input of a RLTK::Parser.
|
49
|
+
class Token
|
50
|
+
# @return [Symbol]
|
51
|
+
attr_reader :type
|
52
|
+
|
53
|
+
# @return [Symbol]
|
54
|
+
attr_reader :value
|
55
|
+
|
56
|
+
# @return [StreamPosition] StreamPosition object associated with this token.
|
57
|
+
attr_reader :position
|
58
|
+
|
59
|
+
# Instantiates a new Token object with the values specified.
|
60
|
+
#
|
61
|
+
# @param [Symbol] type A symbol representing the type of this Token.
|
62
|
+
# @param [Object, nil] value A value associated with this token.
|
63
|
+
# @param [StreamPosition, nil] position The position of the token in a stream.
|
64
|
+
def initialize(type, value = nil, position = nil)
|
65
|
+
@type = type
|
66
|
+
@value = value
|
67
|
+
|
68
|
+
@position = position
|
69
|
+
end
|
70
|
+
|
71
|
+
# Compares one token to another. This only tests the token's *type*
|
72
|
+
# and *value* and not the location of the token in its source.
|
73
|
+
#
|
74
|
+
# @param [Token] other Another Token to compare to.
|
75
|
+
#
|
76
|
+
# @return [Boolean]
|
77
|
+
def ==(other)
|
78
|
+
self.type == other.type and self.value == other.value
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [String] String representing the tokens *type* and *value*.
|
82
|
+
def to_s
|
83
|
+
if value
|
84
|
+
"#{self.type}(#{self.value})"
|
85
|
+
else
|
86
|
+
self.type.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/rltk/version.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/03/08
|
4
|
+
# Description: This file specifies the version number of RLTK.
|
5
|
+
|
6
|
+
module RLTK
|
7
|
+
# The version number of the RLTK library.
|
8
|
+
VERSION = '3.0.2'
|
9
|
+
# The version of LLVM targeted by RLTK.
|
10
|
+
LLVM_TARGET_VERSION = '3.4'
|
11
|
+
end
|
data/lib/rltk.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2011/03/27
|
4
|
+
# Description: This file sets up autoloads for the RLTK module.
|
5
|
+
|
6
|
+
# The RLTK module provides a collection of useful tools for dealing with
|
7
|
+
# context-free grammars and code generation. This includes a class for
|
8
|
+
# representing CFGs, lexers, parsers, and generating code using LLVM.
|
9
|
+
module RLTK
|
10
|
+
autoload :AST, 'rltk/ast'
|
11
|
+
autoload :CFG, 'rltk/cfg'
|
12
|
+
autoload :CG, 'rltk/cg'
|
13
|
+
autoload :Lexer, 'rltk/lexer'
|
14
|
+
autoload :Parser, 'rltk/parser'
|
15
|
+
autoload :Token, 'rltk/token'
|
16
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/05/13
|
4
|
+
# Description: This file contains unit tests for the RLTK::CG::BasicBlock
|
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
|
+
|
18
|
+
class BasicBlockTester < Minitest::Test
|
19
|
+
def setup
|
20
|
+
RLTK::CG::LLVM.init(:X86)
|
21
|
+
|
22
|
+
@mod = RLTK::CG::Module.new('Testing Module')
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_basic_block
|
26
|
+
fun = @mod.functions.add('basic_block_tester', RLTK::CG::VoidType, [])
|
27
|
+
bb0 = fun.blocks.append
|
28
|
+
bb1 = fun.blocks.append
|
29
|
+
|
30
|
+
assert_equal(fun, bb0.parent)
|
31
|
+
assert_equal(fun, bb1.parent)
|
32
|
+
|
33
|
+
assert_equal(bb1, bb0.next)
|
34
|
+
assert_equal(bb0, bb1.previous)
|
35
|
+
|
36
|
+
bb0.build { br(bb1) }
|
37
|
+
bb1.build { ret_void }
|
38
|
+
|
39
|
+
assert_equal(bb0.instructions.first, bb0.instructions.last)
|
40
|
+
assert_equal(bb1.instructions.first, bb1.instructions.last)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_basic_block_collection
|
44
|
+
fun = @mod.functions.add('basic_block_collection_tester', RLTK::CG::VoidType, [])
|
45
|
+
bb0 = fun.blocks.append
|
46
|
+
|
47
|
+
assert_instance_of(RLTK::CG::BasicBlock, bb0)
|
48
|
+
|
49
|
+
assert_equal(1, fun.blocks.size)
|
50
|
+
assert_equal(fun.blocks.first, fun.blocks.last)
|
51
|
+
assert_equal(fun.blocks.first, fun.blocks.entry)
|
52
|
+
|
53
|
+
bb1 = fun.blocks.append
|
54
|
+
|
55
|
+
assert_equal(2, fun.blocks.size)
|
56
|
+
assert_equal(bb0, fun.blocks.first)
|
57
|
+
assert_equal(bb1, fun.blocks.last)
|
58
|
+
|
59
|
+
[fun.blocks.each.to_a, fun.blocks.to_a].each do |blocks|
|
60
|
+
assert_equal(2, blocks.size)
|
61
|
+
assert_equal(bb0, blocks[0])
|
62
|
+
assert_equal(bb1, blocks[1])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_basic_block_enumeration
|
67
|
+
fun = @mod.functions.add('basic_block_enumeration_tester', RLTK::CG::DoubleType, [RLTK::CG::DoubleType])
|
68
|
+
bb0 = fun.blocks.append
|
69
|
+
|
70
|
+
[bb0.instructions.each.to_a, bb0.instructions.to_a].each do |insts|
|
71
|
+
assert_equal(0, insts.size)
|
72
|
+
end
|
73
|
+
|
74
|
+
bb0.build { ret(fadd(fun.params[0], RLTK::CG::Double.new(1.0))) }
|
75
|
+
|
76
|
+
[bb0.instructions.each.to_a, bb0.instructions.to_a].each do |insts|
|
77
|
+
assert_equal(2, insts.size)
|
78
|
+
|
79
|
+
assert_equal(bb0.instructions.first, insts[0])
|
80
|
+
assert_equal(bb0.instructions.last, insts[1])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,191 @@
|
|
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 control flow 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/execution_engine'
|
16
|
+
require 'rltk/cg/module'
|
17
|
+
require 'rltk/cg/function'
|
18
|
+
require 'rltk/cg/type'
|
19
|
+
|
20
|
+
class ControlFlowTester < Minitest::Test
|
21
|
+
def setup
|
22
|
+
RLTK::CG::LLVM.init(:X86)
|
23
|
+
|
24
|
+
@mod = RLTK::CG::Module.new('Testing Module')
|
25
|
+
@jit = RLTK::CG::JITCompiler.new(@mod)
|
26
|
+
end
|
27
|
+
|
28
|
+
##############
|
29
|
+
# Call Tests #
|
30
|
+
##############
|
31
|
+
|
32
|
+
def test_external_call
|
33
|
+
extern = @mod.functions.add('abs', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType])
|
34
|
+
|
35
|
+
fun = @mod.functions.add('external_call_tester', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType]) do |fun|
|
36
|
+
blocks.append { ret call(extern, fun.params[0]) }
|
37
|
+
end
|
38
|
+
|
39
|
+
assert_equal(10, @jit.run_function(fun, -10).to_i)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_external_string_call
|
43
|
+
global = @mod.globals.add(RLTK::CG::ArrayType.new(RLTK::CG::Int8Type, 5), "path")
|
44
|
+
global.linkage = :internal
|
45
|
+
global.initializer = RLTK::CG::ConstantString.new('PATH')
|
46
|
+
|
47
|
+
external = @mod.functions.add('getenv', RLTK::CG::PointerType.new(RLTK::CG::Int8Type), [RLTK::CG::PointerType.new(RLTK::CG::Int8Type)])
|
48
|
+
|
49
|
+
fun = @mod.functions.add('external_string_call_tester', RLTK::CG::PointerType.new(RLTK::CG::Int8Type), []) do
|
50
|
+
blocks.append do
|
51
|
+
param = gep(global, [RLTK::CG::NativeInt.new(0), RLTK::CG::NativeInt.new(0)])
|
52
|
+
|
53
|
+
ret call(external, param)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal(ENV['PATH'], @jit.run_function(fun).ptr.read_pointer.read_string)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_nested_call
|
61
|
+
fun0 = @mod.functions.add('simple_call_tester0', RLTK::CG::NativeIntType, []) do
|
62
|
+
blocks.append { ret RLTK::CG::NativeInt.new(1) }
|
63
|
+
end
|
64
|
+
|
65
|
+
fun1 = @mod.functions.add('simple_call_tester1', RLTK::CG::NativeIntType, []) do
|
66
|
+
blocks.append { ret call(fun0) }
|
67
|
+
end
|
68
|
+
|
69
|
+
assert_equal(1, @jit.run_function(fun1).to_i)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_recursive_call
|
73
|
+
fun = @mod.functions.add('recursive_call_tester', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType]) do |fun|
|
74
|
+
entry = blocks.append
|
75
|
+
recurse = blocks.append
|
76
|
+
exit = blocks.append
|
77
|
+
|
78
|
+
entry.build do
|
79
|
+
cond(icmp(:uge, fun.params[0], RLTK::CG::NativeInt.new(5)), exit, recurse)
|
80
|
+
end
|
81
|
+
|
82
|
+
result =
|
83
|
+
recurse.build do
|
84
|
+
call(fun, add(fun.params[0], RLTK::CG::NativeInt.new(1))).tap { br exit }
|
85
|
+
end
|
86
|
+
|
87
|
+
exit.build do
|
88
|
+
ret(phi(RLTK::CG::NativeIntType, {entry => fun.params[0], recurse => result}))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
assert_equal(5, @jit.run_function(fun, 1).to_i)
|
93
|
+
assert_equal(6, @jit.run_function(fun, 6).to_i)
|
94
|
+
end
|
95
|
+
|
96
|
+
##############
|
97
|
+
# Jump Tests #
|
98
|
+
##############
|
99
|
+
|
100
|
+
def test_cond_jump
|
101
|
+
fun = @mod.functions.add('direct_jump_tester', RLTK::CG::NativeIntType, []) do |fun|
|
102
|
+
entry = blocks.append
|
103
|
+
|
104
|
+
bb0 = blocks.append { ret RLTK::CG::NativeInt.new(1) }
|
105
|
+
bb1 = blocks.append { ret RLTK::CG::NativeInt.new(0) }
|
106
|
+
|
107
|
+
entry.build do
|
108
|
+
cond(icmp(:eq, RLTK::CG::NativeInt.new(1), RLTK::CG::NativeInt.new(2)), bb0, bb1)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
assert_equal(0, @jit.run_function(fun).to_i)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_direct_jump
|
116
|
+
fun = @mod.functions.add('direct_jump_tester', RLTK::CG::NativeIntType, []) do |fun|
|
117
|
+
entry = blocks.append
|
118
|
+
|
119
|
+
bb0 = blocks.append { ret(RLTK::CG::NativeInt.new(1)) }
|
120
|
+
bb1 = blocks.append { ret(RLTK::CG::NativeInt.new(0)) }
|
121
|
+
|
122
|
+
entry.build { br bb1 }
|
123
|
+
end
|
124
|
+
|
125
|
+
assert_equal(0, @jit.run_function(fun).to_i)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_switched_jump
|
129
|
+
fun = @mod.functions.add('direct_jump_tester', RLTK::CG::NativeIntType, []) do |fun|
|
130
|
+
entry = blocks.append
|
131
|
+
|
132
|
+
bb0 = blocks.append { ret RLTK::CG::NativeInt.new(1) }
|
133
|
+
bb1 = blocks.append { ret RLTK::CG::NativeInt.new(0) }
|
134
|
+
|
135
|
+
entry.build do
|
136
|
+
switch(RLTK::CG::NativeInt.new(1), bb0, {RLTK::CG::NativeInt.new(1) => bb1})
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
assert_equal(0, @jit.run_function(fun).to_i)
|
141
|
+
end
|
142
|
+
|
143
|
+
##############
|
144
|
+
# Misc Tests #
|
145
|
+
##############
|
146
|
+
|
147
|
+
def test_select
|
148
|
+
fun = @mod.functions.add('select_tester', RLTK::CG::Int1Type, [RLTK::CG::NativeIntType]) do |fun|
|
149
|
+
blocks.append do
|
150
|
+
ret select(fun.params[0], RLTK::CG::Int1.new(0), RLTK::CG::Int1.new(1))
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
assert_equal(0, @jit.run_function(fun, 1).to_i(false))
|
155
|
+
assert_equal(1, @jit.run_function(fun, 0).to_i(false))
|
156
|
+
end
|
157
|
+
|
158
|
+
#############
|
159
|
+
# Phi Tests #
|
160
|
+
#############
|
161
|
+
|
162
|
+
def test_phi
|
163
|
+
fun = @mod.functions.add('phi_tester', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType]) do |fun|
|
164
|
+
entry = blocks.append('entry')
|
165
|
+
block0 = blocks.append('block0')
|
166
|
+
block1 = blocks.append('block1')
|
167
|
+
exit = blocks.append('exit')
|
168
|
+
|
169
|
+
entry.build do
|
170
|
+
cond(icmp(:eq, fun.params[0], RLTK::CG::NativeInt.new(0)), block0, block1)
|
171
|
+
end
|
172
|
+
|
173
|
+
result0 =
|
174
|
+
block0.build do
|
175
|
+
add(fun.params[0], RLTK::CG::NativeInt.new(1)).tap { br(exit) }
|
176
|
+
end
|
177
|
+
|
178
|
+
result1 =
|
179
|
+
block1.build do
|
180
|
+
sub(fun.params[0], RLTK::CG::NativeInt.new(1)).tap { br(exit) }
|
181
|
+
end
|
182
|
+
|
183
|
+
exit.build do
|
184
|
+
ret(phi(RLTK::CG::NativeIntType, {block0 => result0, block1 => result1}))
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
assert_equal(1, @jit.run_function(fun, 0).to_i)
|
189
|
+
assert_equal(0, @jit.run_function(fun, 1).to_i)
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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::Function class.
|
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/function'
|
17
|
+
require 'rltk/cg/type'
|
18
|
+
|
19
|
+
class FunctionTester < Minitest::Test
|
20
|
+
def setup
|
21
|
+
@mod = RLTK::CG::Module.new('Testing Module')
|
22
|
+
@fun = @mod.functions.add('testing_function', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])
|
23
|
+
|
24
|
+
@fun.params[0].name = 'foo'
|
25
|
+
@fun.params[1].name = 'bar'
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_equality
|
29
|
+
fun0 = @mod.functions.add('fun0', RLTK::CG::NativeIntType, [])
|
30
|
+
fun1 = @mod.functions.add('fun0', RLTK::CG::FloatType, [])
|
31
|
+
fun2 = RLTK::CG::Function.new(fun0.ptr)
|
32
|
+
|
33
|
+
assert_equal(fun0, fun2)
|
34
|
+
refute_equal(fun0, fun1)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_positive_index_in_range
|
38
|
+
assert_equal('foo', @fun.params[0].name)
|
39
|
+
assert_equal('bar', @fun.params[1].name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_negative_index_in_range
|
43
|
+
assert_equal('bar', @fun.params[-1].name)
|
44
|
+
assert_equal('foo', @fun.params[-2].name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_positive_index_out_of_range
|
48
|
+
assert_nil(@fun.params[2])
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_negative_index_out_of_range
|
52
|
+
assert_nil(@fun.params[-3])
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,33 @@
|
|
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::GenericValue
|
5
|
+
# class.
|
6
|
+
|
7
|
+
############
|
8
|
+
# Requires #
|
9
|
+
############
|
10
|
+
|
11
|
+
# Gems
|
12
|
+
require 'minitest/autorun'
|
13
|
+
|
14
|
+
# Ruby Language Toolkit
|
15
|
+
require 'rltk/cg/generic_value'
|
16
|
+
|
17
|
+
class GenericValueTester < Minitest::Test
|
18
|
+
def setup
|
19
|
+
RLTK::CG::LLVM.init(:X86)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_integer
|
23
|
+
assert_equal(2, RLTK::CG::GenericValue.new(2).to_i)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_float
|
27
|
+
assert_in_delta(3.1415926, RLTK::CG::GenericValue.new(3.1415926).to_f, 1e-6)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_double
|
31
|
+
assert_in_delta(3.1415926, RLTK::CG::GenericValue.new(3.1415926, RLTK::CG::DoubleType).to_f(RLTK::CG::DoubleType), 1e-6)
|
32
|
+
end
|
33
|
+
end
|