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,157 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/04/07
|
4
|
+
# Description: This file defines the BasicBlock class.
|
5
|
+
|
6
|
+
############
|
7
|
+
# Requires #
|
8
|
+
############
|
9
|
+
|
10
|
+
# Ruby Language Toolkit
|
11
|
+
require 'rltk/cg/bindings'
|
12
|
+
require 'rltk/cg/context'
|
13
|
+
require 'rltk/cg/value'
|
14
|
+
|
15
|
+
#######################
|
16
|
+
# Classes and Modules #
|
17
|
+
#######################
|
18
|
+
|
19
|
+
module RLTK::CG
|
20
|
+
|
21
|
+
# A BasicBlock is what instructions are inserted into and what functions
|
22
|
+
# are made of. BasicBlock objects may be created either using
|
23
|
+
# BasicBlock.new or using the {Function::BasicBlockCollection#append}
|
24
|
+
# method.
|
25
|
+
class BasicBlock < Value
|
26
|
+
|
27
|
+
# Create a new BasicBlock object. The way the block is created is
|
28
|
+
# determined by the *overloaded* parameter. If it is a Function
|
29
|
+
# object then the new block is appended to the end of the function.
|
30
|
+
# If *overloaded* is another BasicBlock object the new block will
|
31
|
+
# be inserted before that block.
|
32
|
+
#
|
33
|
+
# A block may be given to this function to be invoked by {#build}.
|
34
|
+
#
|
35
|
+
# @param [FFI::Pointer, Function, BasicBlock] overloaded Overloaded paramater that determines creation behaviour.
|
36
|
+
#
|
37
|
+
# @param [String] name Name of this BasicBlock.
|
38
|
+
# @param [Builder, nil] builder Builder to be used by {#build}.
|
39
|
+
# @param [Context, nil] context Context in which to create the block.
|
40
|
+
# @param [Array<Object>] block_args Arguments to be passed when block is invoked.
|
41
|
+
# @param [Proc] block Block to be invoked by {#build}.
|
42
|
+
def initialize(overloaded, name = '', builder = nil, context = nil, *block_args, &block)
|
43
|
+
check_type(context, Context, 'context') if context
|
44
|
+
|
45
|
+
@ptr =
|
46
|
+
case overloaded
|
47
|
+
when FFI::Pointer
|
48
|
+
overloaded
|
49
|
+
|
50
|
+
when Function
|
51
|
+
if context
|
52
|
+
Bindings.append_basic_block_in_context(context, overloaded, name)
|
53
|
+
else
|
54
|
+
Bindings.append_basic_block(overloaded, name)
|
55
|
+
end
|
56
|
+
|
57
|
+
when BasicBlock
|
58
|
+
if context
|
59
|
+
Bindings.insert_basic_block_in_context(context, overloaded, name)
|
60
|
+
else
|
61
|
+
Bindings.insert_basic_block(overloaded, name)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
self.build(builder, *block_args, &block) if block
|
66
|
+
end
|
67
|
+
|
68
|
+
# Used to add instructions to a BasicBlock. The block given to this
|
69
|
+
# method is executed inside the context of a {Builder} object, either
|
70
|
+
# the one passed in the *builder* parameter or one created for this
|
71
|
+
# call. Arguments may be passed into this block via the *block_args*
|
72
|
+
# parameter.
|
73
|
+
#
|
74
|
+
# @example
|
75
|
+
# fun = Function.new(...)
|
76
|
+
# block.build do
|
77
|
+
# ret add(fun.params[0], fun.params[1])
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# @param [Builder, nil] builder Builder in which to execute this block.
|
81
|
+
# @param [Array<Object>] block_args Arguments to pass into block.
|
82
|
+
# @param [Proc] block Block to execute inside builder.
|
83
|
+
#
|
84
|
+
# @return [Object] Value the block evaluates to. Usually an {Instruction}
|
85
|
+
def build(builder = nil, *block_args, &block)
|
86
|
+
if builder then builder else Builder.new end.build(self, *block_args, &block)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Creates a new BasicBlock inserted immediately before this block.
|
90
|
+
#
|
91
|
+
# @param [String] name Name of this BasicBlock.
|
92
|
+
# @param [Context] context Context in which to create this BasicBlock.
|
93
|
+
#
|
94
|
+
# @return [BasicBlock]
|
95
|
+
def insert_before(name = '', context = nil)
|
96
|
+
BasicBlock.new(self, name, context)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @return [InstructionCollect] Collection of all instructions inside this BasicBlock.
|
100
|
+
def instructions
|
101
|
+
@instructions ||= InstructionCollection.new(self)
|
102
|
+
end
|
103
|
+
|
104
|
+
# @return [BasicBlock, nil] BasicBlock that occures immediately after this block or nil.
|
105
|
+
def next
|
106
|
+
if (ptr = Bindings.get_next_basic_block(@ptr)).null? then nil else BasicBlock.new(ptr) end
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return [Function] Function object that this BasicBlock belongs to.
|
110
|
+
def parent
|
111
|
+
if (ptr = Bindings.get_basic_block_parent(@ptr)).null? then nil else Function.new(ptr) end
|
112
|
+
end
|
113
|
+
|
114
|
+
# @return [BasicBlock, nil] BasicBlock that occures immediately before this block or nil.
|
115
|
+
def previous
|
116
|
+
if (ptr = Bindings.get_previous_basic_block(@ptr)).null? then nil else BasicBlock.new(ptr) end
|
117
|
+
end
|
118
|
+
|
119
|
+
# This class is used to access all of the {Instruction Instructions} that have been added to a {BasicBlock}.
|
120
|
+
class InstructionCollection
|
121
|
+
include Enumerable
|
122
|
+
|
123
|
+
# @param [BasicBlock] bb BasicBlock this collection belongs to.
|
124
|
+
def initialize(bb)
|
125
|
+
@bb = bb
|
126
|
+
end
|
127
|
+
|
128
|
+
# Iterate over each {Instruction} in this collection.
|
129
|
+
#
|
130
|
+
# @yieldparam inst [Instruction]
|
131
|
+
#
|
132
|
+
# @return [Enumerator] An Enumerator is returned if no block is given.
|
133
|
+
def each
|
134
|
+
return to_enum(:each) unless block_given?
|
135
|
+
|
136
|
+
inst = self.first
|
137
|
+
|
138
|
+
while inst
|
139
|
+
yield inst
|
140
|
+
inst = inst.next
|
141
|
+
end
|
142
|
+
|
143
|
+
self
|
144
|
+
end
|
145
|
+
|
146
|
+
# @return [Instruction] First instruction in this collection.
|
147
|
+
def first
|
148
|
+
if (ptr = Bindings.get_first_instruction(@bb)).null? then nil else Instruction.from_ptr(ptr) end
|
149
|
+
end
|
150
|
+
|
151
|
+
# @return [Instruction] Last instruction in this collection.
|
152
|
+
def last
|
153
|
+
if (ptr = Bindings.get_last_instruction(@bb)).null? then nil else Instruction.from_ptr(ptr) end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# Author: Chris Wailes <chris.wailes@gmail.com>
|
2
|
+
# Project: Ruby Language Toolkit
|
3
|
+
# Date: 2012/03/08
|
4
|
+
# Description: This file holds bindings to LLVM.
|
5
|
+
|
6
|
+
#########
|
7
|
+
# Notes #
|
8
|
+
#########
|
9
|
+
|
10
|
+
# 1) initialize_all_target_m_cs -> initialize_all_target_mcs
|
11
|
+
# 2) initialize_obj_carc_opts -> initialize_objc_arc_opts
|
12
|
+
|
13
|
+
############
|
14
|
+
# Requires #
|
15
|
+
############
|
16
|
+
|
17
|
+
# Gems
|
18
|
+
require 'ffi'
|
19
|
+
require 'filigree/boolean'
|
20
|
+
|
21
|
+
# Ruby Language Toolkit
|
22
|
+
require 'rltk/version'
|
23
|
+
require 'rltk/cg'
|
24
|
+
|
25
|
+
#######################
|
26
|
+
# Classes and Modules #
|
27
|
+
#######################
|
28
|
+
|
29
|
+
module RLTK::CG
|
30
|
+
|
31
|
+
# This module provides access to stored FFI::Pointer objects and allows a
|
32
|
+
# class to be passed directly into FFI methods. It also provides a
|
33
|
+
# pointer comparison method.
|
34
|
+
module BindingClass
|
35
|
+
# @return [FFI::Pointer]
|
36
|
+
attr_accessor :ptr
|
37
|
+
alias :to_ptr :ptr
|
38
|
+
|
39
|
+
# Compares one BindingClass object to another.
|
40
|
+
#
|
41
|
+
# @param [BindingClass] other Another BindingClass object to compare to.
|
42
|
+
#
|
43
|
+
# @return [Boolean]
|
44
|
+
def ==(other)
|
45
|
+
self.class == other.class and @ptr == other.ptr
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# This module contains FFI bindings to LLVM.
|
50
|
+
module Bindings
|
51
|
+
extend FFI::Library
|
52
|
+
ffi_lib("LLVM-#{RLTK::LLVM_TARGET_VERSION}")
|
53
|
+
|
54
|
+
# Exception that is thrown when the LLVM target version does not
|
55
|
+
# match the version of LLVM present on the system.
|
56
|
+
class LibraryMismatch < Exception; end
|
57
|
+
|
58
|
+
# Require the generated bindings files while handling errors.
|
59
|
+
require 'rltk/cg/generated_bindings'
|
60
|
+
|
61
|
+
#############
|
62
|
+
# Constants #
|
63
|
+
#############
|
64
|
+
|
65
|
+
# List of architectures supported by LLVM.
|
66
|
+
ARCHS = [
|
67
|
+
:Alpha,
|
68
|
+
:ARM,
|
69
|
+
:Blackfin,
|
70
|
+
:CBackend,
|
71
|
+
:CellSPU,
|
72
|
+
:CppBackend,
|
73
|
+
:MBlaze,
|
74
|
+
:Mips,
|
75
|
+
:MSP430,
|
76
|
+
:PowerPC,
|
77
|
+
:PTX,
|
78
|
+
:Sparc,
|
79
|
+
:SystemZ,
|
80
|
+
:X86,
|
81
|
+
:XCore
|
82
|
+
]
|
83
|
+
|
84
|
+
# List of assembly parsers.
|
85
|
+
ASM_PARSERS = [
|
86
|
+
:ARM,
|
87
|
+
:MBLaze,
|
88
|
+
:X86
|
89
|
+
]
|
90
|
+
|
91
|
+
# List of assembly printers.
|
92
|
+
ASM_PRINTERS = [
|
93
|
+
:Alpha,
|
94
|
+
:ARM,
|
95
|
+
:Blackfin,
|
96
|
+
:CellSPU,
|
97
|
+
:MBLaze,
|
98
|
+
:Mips,
|
99
|
+
:MSP430,
|
100
|
+
:PowerPC,
|
101
|
+
:PTX,
|
102
|
+
:Sparc,
|
103
|
+
:SystemZ,
|
104
|
+
:X86,
|
105
|
+
:XCore
|
106
|
+
]
|
107
|
+
|
108
|
+
###########
|
109
|
+
# Methods #
|
110
|
+
###########
|
111
|
+
|
112
|
+
# Converts a CamelCase string into an underscored string.
|
113
|
+
#
|
114
|
+
# @param [#to_s] name CamelCase string.
|
115
|
+
#
|
116
|
+
# @return [Symbol] Underscored string.
|
117
|
+
def self.get_bname(name)
|
118
|
+
name.to_s.
|
119
|
+
gsub(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2').
|
120
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
121
|
+
downcase.to_sym
|
122
|
+
end
|
123
|
+
|
124
|
+
# A wrapper class for FFI::Library.attach_function
|
125
|
+
#
|
126
|
+
# @param [Symbol] func Function name.
|
127
|
+
# @param [Array<Object>] args Argument types for FFI::Library.attach_function.
|
128
|
+
# @param [Object] returns Return type for FFI::Library.attach_function.
|
129
|
+
def self.add_binding(func, args, returns)
|
130
|
+
attach_function(get_bname(func.to_s[4..-1]), func, args, returns)
|
131
|
+
end
|
132
|
+
|
133
|
+
####################
|
134
|
+
# Missing Bindings #
|
135
|
+
####################
|
136
|
+
|
137
|
+
ARCHS.each do |arch|
|
138
|
+
add_binding("LLVMInitialize#{arch}Target", [], :void)
|
139
|
+
add_binding("LLVMInitialize#{arch}TargetInfo", [], :void)
|
140
|
+
add_binding("LLVMInitialize#{arch}TargetMC", [], :void)
|
141
|
+
end
|
142
|
+
|
143
|
+
ASM_PARSERS.each do |asm|
|
144
|
+
add_binding("LLVMInitialize#{asm}AsmParser", [], :void)
|
145
|
+
end
|
146
|
+
|
147
|
+
ASM_PRINTERS.each do |asm|
|
148
|
+
add_binding("LLVMInitialize#{asm}AsmPrinter", [], :void)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|