rltk 2.2.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +12 -12
- data/README.md +458 -285
- data/Rakefile +99 -92
- data/lib/rltk/ast.rb +221 -126
- data/lib/rltk/cfg.rb +218 -239
- data/lib/rltk/cg/basic_block.rb +1 -1
- data/lib/rltk/cg/bindings.rb +9 -26
- data/lib/rltk/cg/builder.rb +40 -8
- data/lib/rltk/cg/context.rb +1 -1
- data/lib/rltk/cg/contractor.rb +51 -0
- data/lib/rltk/cg/execution_engine.rb +45 -8
- data/lib/rltk/cg/function.rb +12 -2
- data/lib/rltk/cg/generated_bindings.rb +2541 -575
- data/lib/rltk/cg/generic_value.rb +2 -2
- data/lib/rltk/cg/instruction.rb +104 -83
- data/lib/rltk/cg/llvm.rb +44 -3
- data/lib/rltk/cg/memory_buffer.rb +22 -5
- data/lib/rltk/cg/module.rb +85 -36
- data/lib/rltk/cg/old_generated_bindings.rb +6152 -0
- data/lib/rltk/cg/pass_manager.rb +87 -43
- data/lib/rltk/cg/support.rb +2 -4
- data/lib/rltk/cg/target.rb +158 -28
- data/lib/rltk/cg/triple.rb +8 -8
- data/lib/rltk/cg/type.rb +69 -25
- data/lib/rltk/cg/value.rb +107 -66
- data/lib/rltk/cg.rb +16 -17
- data/lib/rltk/lexer.rb +21 -11
- data/lib/rltk/lexers/calculator.rb +1 -1
- data/lib/rltk/lexers/ebnf.rb +8 -7
- data/lib/rltk/parser.rb +300 -247
- data/lib/rltk/parsers/infix_calc.rb +1 -1
- data/lib/rltk/parsers/postfix_calc.rb +2 -2
- data/lib/rltk/parsers/prefix_calc.rb +2 -2
- data/lib/rltk/token.rb +1 -2
- data/lib/rltk/version.rb +3 -3
- data/lib/rltk.rb +6 -6
- 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 +105 -8
- data/test/tc_cfg.rb +63 -48
- data/test/tc_lexer.rb +84 -96
- data/test/tc_parser.rb +224 -52
- data/test/tc_token.rb +6 -6
- data/test/ts_rltk.rb +12 -15
- metadata +149 -75
- data/lib/rltk/cg/generated_extended_bindings.rb +0 -287
- data/lib/rltk/util/abstract_class.rb +0 -25
- data/lib/rltk/util/monkeys.rb +0 -129
data/lib/rltk/cg/module.rb
CHANGED
@@ -15,7 +15,7 @@ require 'rltk/cg/context'
|
|
15
15
|
# Classes and Modules #
|
16
16
|
#######################
|
17
17
|
|
18
|
-
module RLTK::CG
|
18
|
+
module RLTK::CG
|
19
19
|
|
20
20
|
# This class represents a collection of functions, constants, and global
|
21
21
|
# variables.
|
@@ -31,33 +31,49 @@ module RLTK::CG # :nodoc:
|
|
31
31
|
|
32
32
|
# Load a module from LLVM bitcode.
|
33
33
|
#
|
34
|
-
# @
|
35
|
-
#
|
36
|
-
# @param [MemoryBuffer, FFI::Pointer, String, nil] overloaded Where to read the bitecode from.
|
34
|
+
# @param [MemoryBuffer, String] overloaded Where to read the bitecode from
|
35
|
+
# @param [Context, nil] context Context in which to parse bitcode
|
37
36
|
#
|
38
37
|
# @return [Module]
|
39
|
-
def self.read_bitcode(overloaded)
|
40
|
-
buffer =
|
38
|
+
def self.read_bitcode(overloaded, context = nil)
|
39
|
+
buffer = overloaded.is_a?(MemoryBuffer) ? overloaded : MemoryBuffer.new(overloaded)
|
41
40
|
|
42
41
|
mod_ptr = FFI::MemoryPointer.new(:pointer)
|
43
42
|
msg_ptr = FFI::MemoryPointer.new(:pointer)
|
44
43
|
|
45
|
-
status =
|
46
|
-
|
47
|
-
|
48
|
-
raise msg_ptr.get_pointer(0).get_string(0)
|
44
|
+
status =
|
45
|
+
if context
|
46
|
+
Bindings.parse_bitcode_in_context(context, buffer, mod_ptr, msg_ptr)
|
49
47
|
else
|
48
|
+
Bindings.parse_bitcode(buffer, mod_ptr, msg_ptr)
|
49
|
+
end
|
50
|
+
|
51
|
+
if status.zero?
|
50
52
|
Module.new(mod_ptr.get_pointer(0))
|
53
|
+
else
|
54
|
+
raise msg_ptr.get_pointer(0).get_string(0)
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
# Load a Module form an LLVM IR
|
58
|
+
# Load a Module form an LLVM IR.
|
55
59
|
#
|
56
|
-
# @param [String]
|
60
|
+
# @param [MemoryBuffer, String] overloaded Where to read the IR from
|
61
|
+
# @param [Context] context Context in which to parse IR
|
57
62
|
#
|
58
63
|
# @return [Module]
|
59
|
-
def self.
|
60
|
-
|
64
|
+
def self.read_ir(overloaded, context = Context.global)
|
65
|
+
buffer = overloaded.is_a?(MemoryBuffer) ? overloaded : MemoryBuffer.new(overloaded)
|
66
|
+
|
67
|
+
mod_ptr = FFI::MemoryPointer.new(:pointer)
|
68
|
+
msg_ptr = FFI::MemoryPointer.new(:pointer)
|
69
|
+
|
70
|
+
status = Bindings.parse_ir_in_context(context, buffer, mod_ptr, msg_ptr)
|
71
|
+
|
72
|
+
if status.zero?
|
73
|
+
Module.new(mod_ptr.get_pointer(0))
|
74
|
+
else
|
75
|
+
raise msg_ptr.get_pointer(0).get_string(0)
|
76
|
+
end
|
61
77
|
end
|
62
78
|
|
63
79
|
# Create a new LLVM module.
|
@@ -77,6 +93,9 @@ module RLTK::CG # :nodoc:
|
|
77
93
|
else
|
78
94
|
Bindings.module_create_with_name(overloaded)
|
79
95
|
end
|
96
|
+
|
97
|
+
else
|
98
|
+
raise 'Argument `overloaded` must be a FFI::Pointer of String.'
|
80
99
|
end
|
81
100
|
|
82
101
|
# Define a finalizer to free the memory used by LLVM for this
|
@@ -88,15 +107,15 @@ module RLTK::CG # :nodoc:
|
|
88
107
|
|
89
108
|
# Compile this module to an assembly or object file.
|
90
109
|
#
|
91
|
-
# @param [String]
|
92
|
-
# @param [:
|
93
|
-
# @param [TargetMachine]
|
94
|
-
# @param [0, 1, 2, 3] opt_level Optimization level to use during compilation.
|
95
|
-
# @param [Boolean] verify Verify the module before compilation or not.
|
110
|
+
# @param [String] file_name File to emit code to
|
111
|
+
# @param [:assembly, :object] emit_type Type of code to emit
|
112
|
+
# @param [TargetMachine] machine TargetMachine used to generate code
|
96
113
|
#
|
97
114
|
# @return [void]
|
98
|
-
|
99
|
-
|
115
|
+
#
|
116
|
+
# @raise LLVM error message if unable to emit code for module
|
117
|
+
def compile(file_name, emit_type = :object, machine = TargetMachine.host)
|
118
|
+
machine.emite_module(self, file_name, emit_type)
|
100
119
|
end
|
101
120
|
|
102
121
|
# @return [Context] Context in which this module exists.
|
@@ -121,29 +140,52 @@ module RLTK::CG # :nodoc:
|
|
121
140
|
end
|
122
141
|
alias :fpm :function_pass_manager
|
123
142
|
|
143
|
+
# Link another module into this one, taking ownership of it. You may
|
144
|
+
# not access the other module again once linking it.
|
145
|
+
#
|
146
|
+
# @param [Module] other Module to be linked
|
147
|
+
#
|
148
|
+
# @raise Errors encountered during linking
|
149
|
+
def link(other)
|
150
|
+
error = FFI::MemoryPointer.new(:pointer)
|
151
|
+
status = Bindings.link_modules(@ptr, other, :linker_destroy_source, error)
|
152
|
+
|
153
|
+
if not status.zero?
|
154
|
+
errorp = error.read_pointer
|
155
|
+
message = errorp.null? ? 'Unknown' : errorp.read_string
|
156
|
+
|
157
|
+
error.autorelease = false
|
158
|
+
|
159
|
+
Bindings.dispose_message(error)
|
160
|
+
|
161
|
+
raise "Error linking modules: #{message}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
124
165
|
# @return [PassManager] Pass manager for this module.
|
125
166
|
def pass_manager
|
126
167
|
@pass_manager ||= PassManager.new(self)
|
127
168
|
end
|
128
169
|
alias :pm :pass_manager
|
129
170
|
|
130
|
-
# Print the LLVM IR representation of this module to a file.
|
131
|
-
# file may be specified via a file name (which will be created or
|
132
|
-
# truncated) or an object that responds to #fileno.
|
171
|
+
# Print the LLVM IR representation of this module to a file.
|
133
172
|
#
|
134
|
-
# @
|
135
|
-
#
|
136
|
-
# @param [String, #fileno] io File name or object with a file descriptor to print to.
|
173
|
+
# @param [String] file_name Name of file to print to
|
137
174
|
#
|
138
175
|
# @return [void]
|
139
|
-
def print(
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
176
|
+
def print(file_name)
|
177
|
+
error = FFI::MemoryPointer.new(:pointer)
|
178
|
+
status = Bindings.print_module_to_file(@ptr, file_name, error)
|
179
|
+
|
180
|
+
if not status.zero?
|
181
|
+
errorp = error.read_pointer
|
182
|
+
message = errorp.null? ? 'Unknown' : errorp.read_string
|
183
|
+
|
184
|
+
error.autorelease = false
|
185
|
+
|
186
|
+
Bindings.dispose_message(error)
|
187
|
+
|
188
|
+
raise "Error printing module: #{message}"
|
147
189
|
end
|
148
190
|
end
|
149
191
|
|
@@ -174,6 +216,13 @@ module RLTK::CG # :nodoc:
|
|
174
216
|
Bindings.get_target(@ptr)
|
175
217
|
end
|
176
218
|
|
219
|
+
# Return a LLVM IR representation of this file as a string.
|
220
|
+
#
|
221
|
+
# @return [String]
|
222
|
+
def to_s
|
223
|
+
Bindings.print_module_to_string(@ptr)
|
224
|
+
end
|
225
|
+
|
177
226
|
# Write the module as LLVM bitcode to a file.
|
178
227
|
#
|
179
228
|
# @param [#path, #fileno, Integer, String] overloaded Where to write the bitcode.
|
@@ -214,7 +263,7 @@ module RLTK::CG # :nodoc:
|
|
214
263
|
str_ptr = FFI::MemoryPointer.new(:pointer)
|
215
264
|
status = Bindings.verify_module(@ptr, action, str_ptr)
|
216
265
|
|
217
|
-
|
266
|
+
status == 1 ? str_ptr.read_string : nil
|
218
267
|
end
|
219
268
|
private :do_verification
|
220
269
|
|