rltk 2.2.1 → 3.0.0
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/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
|
|