rltk 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +21 -22
  3. data/lib/rltk/ast.rb +185 -118
  4. data/lib/rltk/cfg.rb +157 -103
  5. data/lib/rltk/cg/basic_block.rb +19 -19
  6. data/lib/rltk/cg/bindings.rb +16 -16
  7. data/lib/rltk/cg/builder.rb +129 -129
  8. data/lib/rltk/cg/context.rb +7 -7
  9. data/lib/rltk/cg/contractor.rb +7 -7
  10. data/lib/rltk/cg/execution_engine.rb +30 -30
  11. data/lib/rltk/cg/function.rb +37 -37
  12. data/lib/rltk/cg/generated_bindings.rb +3932 -3932
  13. data/lib/rltk/cg/generic_value.rb +17 -17
  14. data/lib/rltk/cg/instruction.rb +116 -116
  15. data/lib/rltk/cg/llvm.rb +22 -22
  16. data/lib/rltk/cg/memory_buffer.rb +7 -7
  17. data/lib/rltk/cg/module.rb +73 -73
  18. data/lib/rltk/cg/pass_manager.rb +35 -35
  19. data/lib/rltk/cg/target.rb +41 -41
  20. data/lib/rltk/cg/triple.rb +7 -7
  21. data/lib/rltk/cg/type.rb +75 -75
  22. data/lib/rltk/cg/value.rb +161 -161
  23. data/lib/rltk/lexer.rb +57 -57
  24. data/lib/rltk/lexers/calculator.rb +7 -7
  25. data/lib/rltk/lexers/ebnf.rb +5 -5
  26. data/lib/rltk/parser.rb +338 -295
  27. data/lib/rltk/parsers/infix_calc.rb +7 -7
  28. data/lib/rltk/parsers/postfix_calc.rb +3 -3
  29. data/lib/rltk/parsers/prefix_calc.rb +3 -3
  30. data/lib/rltk/token.rb +13 -13
  31. data/lib/rltk/version.rb +6 -6
  32. data/test/cg/tc_basic_block.rb +17 -17
  33. data/test/cg/tc_control_flow.rb +41 -41
  34. data/test/cg/tc_function.rb +4 -4
  35. data/test/cg/tc_generic_value.rb +3 -3
  36. data/test/cg/tc_instruction.rb +53 -53
  37. data/test/cg/tc_math.rb +12 -12
  38. data/test/cg/tc_module.rb +14 -14
  39. data/test/cg/tc_transforms.rb +11 -11
  40. data/test/cg/tc_type.rb +12 -12
  41. data/test/cg/tc_value.rb +35 -35
  42. data/test/cg/ts_cg.rb +5 -5
  43. data/test/tc_ast.rb +137 -60
  44. data/test/tc_cfg.rb +34 -34
  45. data/test/tc_lexer.rb +42 -42
  46. data/test/tc_parser.rb +250 -173
  47. data/test/tc_token.rb +2 -2
  48. data/test/ts_rltk.rb +8 -8
  49. metadata +84 -85
  50. data/lib/rltk/cg/old_generated_bindings.rb +0 -6152
@@ -15,31 +15,31 @@ require 'rltk/cg/bindings'
15
15
  #######################
16
16
 
17
17
  module RLTK::CG
18
-
18
+
19
19
  # Bindings for LLVM contexts.
20
20
  class Context
21
21
  include BindingClass
22
-
22
+
23
23
  # The Proc object called by the garbage collector to free resources used by LLVM.
24
24
  CLASS_FINALIZER = Proc.new { |id| Bindings.context_dispose(ptr) if ptr = ObjectSpace._id2ref(id).ptr }
25
-
25
+
26
26
  #################
27
27
  # Class Methods #
28
28
  #################
29
-
29
+
30
30
  # @return [Context] A global context.
31
31
  def self.global
32
32
  self.new(Bindings.get_global_context())
33
33
  end
34
-
34
+
35
35
  ####################
36
36
  # Instance Methods #
37
37
  ####################
38
-
38
+
39
39
  # @param [FFI::Pointer, nil] ptr Pointer representing a context. If nil, a new context is created.
40
40
  def initialize(ptr = nil)
41
41
  @ptr = ptr || Bindings.context_create()
42
-
42
+
43
43
  # Define a finalizer to free the memory used by LLVM for this
44
44
  # context.
45
45
  ObjectSpace.define_finalizer(self, CLASS_FINALIZER)
@@ -19,18 +19,18 @@ require 'rltk/cg/builder'
19
19
  #######################
20
20
 
21
21
  module RLTK::CG
22
-
22
+
23
23
  class Contractor < Builder
24
-
24
+
25
25
  include Filigree::Visitor
26
-
26
+
27
27
  ####################
28
28
  # Instance Methods #
29
29
  ####################
30
-
30
+
31
31
  # Alias out the RLTK::Visitor.visit method.
32
32
  alias :wrapped_visit :visit
33
-
33
+
34
34
  # Visit an object in the context of this builder. See the
35
35
  # Filigree::Visitor's visit method for more details about the basic
36
36
  # behaviour of this method. The special options for this method are:
@@ -42,9 +42,9 @@ module RLTK::CG
42
42
  # @return [Object]
43
43
  def visit(object, at: nil, rcb: false)
44
44
  target at if at
45
-
45
+
46
46
  result = wrapped_visit(object)
47
-
47
+
48
48
  if rcb then [result, current_block] else result end
49
49
  end
50
50
  end
@@ -21,7 +21,7 @@ require 'rltk/cg/target'
21
21
  #######################
22
22
 
23
23
  module RLTK::CG
24
-
24
+
25
25
  # The ExecutionEngine class and its subclasses execute code from the
26
26
  # provided module, as well as providing a {PassManager} and
27
27
  # {FunctionPassManager} for optimizing modules.
@@ -30,13 +30,13 @@ module RLTK::CG
30
30
  class ExecutionEngine
31
31
  include Filigree::AbstractClass
32
32
  include BindingClass
33
-
33
+
34
34
  # The Proc object called by the garbage collector to free resources used by LLVM.
35
35
  CLASS_FINALIZER = Proc.new { |id| Bindings.dispose_execution_engine(ptr) if ptr = ObjectSpace._id2ref(id).ptr }
36
-
36
+
37
37
  # @return [Module]
38
38
  attr_reader :module
39
-
39
+
40
40
  # Create a new execution engine.
41
41
  #
42
42
  # @param [Module] mod Module to be executed.
@@ -45,35 +45,35 @@ module RLTK::CG
45
45
  # @raise [RuntimeError] An error is raised if something went horribly wrong inside LLVM during the creation of this engine.
46
46
  def initialize(mod, &block)
47
47
  check_type(mod, Module, 'mod')
48
-
48
+
49
49
  block = Proc.new { |ptr, error| Bindings.create_execution_engine_for_module(ptr, mod, error) } if block == nil
50
-
50
+
51
51
  ptr = FFI::MemoryPointer.new(:pointer)
52
52
  error = FFI::MemoryPointer.new(:pointer)
53
53
  status = block.call(ptr, error)
54
-
54
+
55
55
  if status.zero?
56
56
  @ptr = ptr.read_pointer
57
57
  @module = mod
58
-
58
+
59
59
  # Associate this engine with the provided module.
60
60
  @module.engine = self
61
-
61
+
62
62
  # Define a finalizer to free the memory used by LLVM for
63
63
  # this execution engine.
64
64
  ObjectSpace.define_finalizer(self, CLASS_FINALIZER)
65
65
  else
66
66
  errorp = error.read_pointer
67
67
  message = errorp.null? ? 'Unknown' : errorp.read_string
68
-
68
+
69
69
  error.autorelease = false
70
-
70
+
71
71
  Bindings.dispose_message(error)
72
-
72
+
73
73
  raise "Error creating execution engine: #{message}"
74
74
  end
75
75
  end
76
-
76
+
77
77
  # Builds a pointer to a global value.
78
78
  #
79
79
  # @param [GlobalValue] global Value you want a pointer to.
@@ -82,7 +82,7 @@ module RLTK::CG
82
82
  def pointer_to_global(global)
83
83
  Bindings.get_pointer_to_global(@ptr, global)
84
84
  end
85
-
85
+
86
86
  # Execute a function in the engine's module with the given arguments.
87
87
  # The arguments may be either GnericValue objects or any object that
88
88
  # can be turned into a GenericValue.
@@ -96,14 +96,14 @@ module RLTK::CG
96
96
  fun.params.zip(args).map do |param, arg|
97
97
  if arg.is_a?(GenericValue) then arg else GenericValue.new(arg) end
98
98
  end
99
-
99
+
100
100
  args_ptr = FFI::MemoryPointer.new(:pointer, args.length)
101
101
  args_ptr.write_array_of_pointer(new_args)
102
-
102
+
103
103
  GenericValue.new(Bindings.run_function(@ptr, fun, args.length, args_ptr))
104
104
  end
105
105
  alias :run :run_function
106
-
106
+
107
107
  # Execute a function in the engine's module with the given arguments
108
108
  # as the main function of a program.
109
109
  #
@@ -115,24 +115,24 @@ module RLTK::CG
115
115
  # Prepare the ARGV parameter.
116
116
  argv = FFI::MemoryPointer.new(:pointer, argc)
117
117
  argv.write_array_of_pointer(args.map { |str| FFI::MemoryPointer.from_string(str) })
118
-
118
+
119
119
  # Prepare the ENV parameter.
120
120
  env = FFI::MemoryPointer.new(:pointer, ENV.size)
121
121
  env.write_array_of_pointer(ENV.to_a.map { |pair| FFI::MemoryPointer.from_string(pair[0] + '=' + pair[1]) })
122
-
122
+
123
123
  GenericValue.new(Bindings.run_function_as_main(@ptr, fun, args.length, argv, env))
124
124
  end
125
125
  alias :run_main :run_function_as_main
126
-
126
+
127
127
  # @return [TargetData] Information about the target architecture for this execution engine.
128
128
  def target_data
129
129
  TargetData.new(Bindings.get_execution_engine_target_data(@ptr))
130
130
  end
131
131
  end
132
-
132
+
133
133
  # An execution engine that interprets the given code.
134
134
  class Interpreter < ExecutionEngine
135
-
135
+
136
136
  # Create a new interpreter.
137
137
  #
138
138
  # @param [Module] mod Module to be executed.
@@ -142,10 +142,10 @@ module RLTK::CG
142
142
  end
143
143
  end
144
144
  end
145
-
145
+
146
146
  # An execution engine that compiles the given code when needed.
147
147
  class JITCompiler < ExecutionEngine
148
-
148
+
149
149
  # Create a new just-in-time compiler.
150
150
  #
151
151
  # @param [Module] mod Module to be executed.
@@ -156,10 +156,10 @@ module RLTK::CG
156
156
  end
157
157
  end
158
158
  end
159
-
159
+
160
160
  # Options for initializing a {MCJITCompiler}.
161
161
  class MCJITCompilerOptions < RLTK::CG::Bindings::MCJITCompilerOptions
162
-
162
+
163
163
  # Create an object representing MCJIT compiler options.
164
164
  #
165
165
  # @param [Integer] opt_level Optimization level
@@ -168,16 +168,16 @@ module RLTK::CG
168
168
  # @param [Boolean] enable_fast_i_sel Turn on fast instruction selection
169
169
  def initialize(opt_level = 0, code_model = :jit_default, no_frame_pointer_elim = false,
170
170
  enable_fast_i_sel = true)
171
-
171
+
172
172
  Bindings.initialize_mcjit_compiler_options(self.to_ptr, self.class.size)
173
-
173
+
174
174
  super(opt_level, code_model, no_frame_pointer_elim.to_i, enable_fast_i_sel.to_i, nil)
175
175
  end
176
176
  end
177
-
177
+
178
178
  # The new LLVM JIT execution engine.
179
179
  class MCJITCompiler < ExecutionEngine
180
-
180
+
181
181
  # Create a new MC just-in-time-compiler.
182
182
  #
183
183
  # @see http://llvm.org/docs/MCJITDesignAndImplementation.html
@@ -17,12 +17,12 @@ require 'rltk/cg/value'
17
17
  #######################
18
18
 
19
19
  module RLTK::CG
20
-
20
+
21
21
  # An LLVM IR function.
22
22
  class Function < GlobalValue
23
23
  # @return [FunctionType] FunctionType object describing this function's type.
24
24
  attr_reader :type
25
-
25
+
26
26
  # Define a new function in a given module. You can also use the
27
27
  # {Module::FunctionCollection#add} method to add functions to
28
28
  # modules.
@@ -38,31 +38,31 @@ module RLTK::CG
38
38
  case overloaded
39
39
  when FFI::Pointer
40
40
  overloaded
41
-
41
+
42
42
  when RLTK::CG::Module
43
43
  @type = if type_info.first.is_a?(FunctionType) then type_info.first else FunctionType.new(*type_info) end
44
-
44
+
45
45
  Bindings.add_function(overloaded, name.to_s, @type)
46
-
46
+
47
47
  else
48
48
  raise 'The first argument to Function.new must be either a pointer or an instance of RLTK::CG::Module.'
49
49
  end
50
-
50
+
51
51
  self.instance_exec(self, &block) if block
52
52
  end
53
-
53
+
54
54
  # @return [FunctionAttrCollection] Proxy object for inspecting function attributes.
55
55
  def attributes
56
56
  @attributes ||= FunctionAttrCollection.new(self)
57
57
  end
58
58
  alias :attrs :attributes
59
-
59
+
60
60
  # @return [BasicBlockCollection] Proxy object for inspecting a function's basic blocks.
61
61
  def basic_blocks
62
62
  @basic_blocks ||= BasicBlockCollection.new(self)
63
63
  end
64
64
  alias :blocks :basic_blocks
65
-
65
+
66
66
  # Get a function's calling convention.
67
67
  #
68
68
  # @see Bindings._enum_call_conv_
@@ -71,7 +71,7 @@ module RLTK::CG
71
71
  def calling_convention
72
72
  Bindings.enum_type(:call_conv)[Bindings.get_function_call_conv(@ptr)]
73
73
  end
74
-
74
+
75
75
  # Set a function's calling convention.
76
76
  #
77
77
  # @see Bindings._enum_call_conv_
@@ -79,45 +79,45 @@ module RLTK::CG
79
79
  # @param [Symbol] conv Calling convention to set.
80
80
  def calling_convention=(conv)
81
81
  Bindings.set_function_call_conv(@ptr, Bindings.enum_type(:call_conv)[conv])
82
-
82
+
83
83
  conv
84
84
  end
85
-
85
+
86
86
  # @return [ParameterCollection] Proxy object for inspecting a function's parameters.
87
87
  def parameters
88
88
  @parameters ||= ParameterCollection.new(self)
89
89
  end
90
90
  alias :params :parameters
91
-
91
+
92
92
  # Verify that the function is valid LLVM IR.
93
93
  #
94
94
  # @return [nil, String] Human-readable description of any invalid constructs if invalid.
95
95
  def verify
96
96
  do_verification(:return_status)
97
97
  end
98
-
98
+
99
99
  # Verify that the function is valid LLVM IR and abort the process if it isn't.
100
100
  #
101
101
  # @return [nil]
102
102
  def verify!
103
103
  do_verification(:abort_process)
104
104
  end
105
-
105
+
106
106
  # Helper function for {#verify} and {#verify!}
107
107
  def do_verification(action)
108
108
  Bindings.verify_function(@ptr, action).to_bool
109
109
  end
110
110
  private :do_verification
111
-
111
+
112
112
  # This class is used to access a function's {BasicBlock BasicBlocks}
113
113
  class BasicBlockCollection
114
114
  include Enumerable
115
-
115
+
116
116
  # @param [Function] fun Function for which this is a proxy.
117
117
  def initialize(fun)
118
118
  @fun = fun
119
119
  end
120
-
120
+
121
121
  # Add a {BasicBlock} to the end of this function.
122
122
  #
123
123
  # @note The first argument to any proc passed to this function
@@ -133,7 +133,7 @@ module RLTK::CG
133
133
  def append(name = '', builder = nil, context = nil, *block_args, &block)
134
134
  BasicBlock.new(@fun, name, builder, context, *block_args, &block)
135
135
  end
136
-
136
+
137
137
  # An iterator for each block inside this collection.
138
138
  #
139
139
  # @yieldparam block [BasicBlock]
@@ -141,41 +141,41 @@ module RLTK::CG
141
141
  # @return [Enumerator] Returns an Enumerator if no block is given.
142
142
  def each
143
143
  return to_enum :each unless block_given?
144
-
144
+
145
145
  ptr = Bindings.get_first_basic_block(@fun)
146
-
146
+
147
147
  self.size.times do |i|
148
148
  yield BasicBlock.new(ptr)
149
149
  ptr = Bindings.get_next_basic_block(ptr)
150
150
  end
151
151
  end
152
-
152
+
153
153
  # @return [BasicBlock, nil] The function's entry block if it has been added.
154
154
  def entry
155
155
  if (ptr = Bindings.get_entry_basic_block(@fun)) then BasicBlock.new(ptr) else nil end
156
156
  end
157
-
157
+
158
158
  # @return [BasicBlock, nil] The function's first block if one has been added.
159
159
  def first
160
160
  if (ptr = Bindings.get_first_basic_block(@fun)) then BasicBlock.new(ptr) else nil end
161
161
  end
162
-
162
+
163
163
  # @return [BasicBlock, nil] The function's last block if one has been added.
164
164
  def last
165
165
  if (ptr = Bindings.get_last_basic_block(@fun)) then BasicBlock.new(ptr) else nil end
166
166
  end
167
-
167
+
168
168
  # @return [Integer] Number of basic blocks that comprise this function.
169
169
  def size
170
170
  Bindings.count_basic_blocks(@fun)
171
171
  end
172
172
  end
173
-
173
+
174
174
  # This class is used to access a function's attributes.
175
175
  class FunctionAttrCollection < AttrCollection
176
176
  @@add_method = :add_function_attr
177
177
  @@del_method = :remove_function_attr
178
-
178
+
179
179
  # Set a target-dependent function attribute.
180
180
  #
181
181
  # @param [String] attribute Attribute name
@@ -186,17 +186,17 @@ module RLTK::CG
186
186
  Bindings.add_target_dependent_function_attr(@value, attribute, value)
187
187
  end
188
188
  end
189
-
190
-
189
+
190
+
191
191
  # This class is used to access a function's parameters.
192
192
  class ParameterCollection
193
193
  include Enumerable
194
-
194
+
195
195
  # @param [Function] fun Function for which this is a proxy.
196
196
  def initialize(fun)
197
197
  @fun = fun
198
198
  end
199
-
199
+
200
200
  # Access the parameter at the given index.
201
201
  #
202
202
  # @param [Integer] index Index of the desired parameter. May be negative.
@@ -204,12 +204,12 @@ module RLTK::CG
204
204
  # @return [Value] Value object representing the parameter.
205
205
  def [](index)
206
206
  index += self.size if index < 0
207
-
207
+
208
208
  if 0 <= index and index < self.size
209
209
  Value.new(Bindings.get_param(@fun, index))
210
210
  end
211
211
  end
212
-
212
+
213
213
  # An iterator for each parameter inside this collection.
214
214
  #
215
215
  # @yieldparam val [Value]
@@ -217,17 +217,17 @@ module RLTK::CG
217
217
  # @return [Enumerator] Returns an Enumerator if no block is given.
218
218
  def each
219
219
  return to_enum :each unless block_given?
220
-
220
+
221
221
  self.size.times { |index| yield self[index] }
222
-
222
+
223
223
  self
224
224
  end
225
-
225
+
226
226
  # @return [Integer] Number of function parameters.
227
227
  def size
228
228
  Bindings.count_params(@fun)
229
229
  end
230
-
230
+
231
231
  # @return [Array<Value>] Array of Value objects representing the function parameters.
232
232
  def to_a
233
233
  self.size.times.to_a.inject([]) { |params, index| params << self[index] }