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
@@ -16,10 +16,10 @@ require 'rltk/cg/bindings'
16
16
  #######################
17
17
 
18
18
  module RLTK::CG
19
-
19
+
20
20
  # This module contains global operations on the LLVM compiler infrastructure.
21
21
  module LLVM
22
-
22
+
23
23
  # Enable LLVM's built-in stack trace code. This intercepts the OS's
24
24
  # crash signals and prints which component of LLVM you were in at the
25
25
  # time if the crash.
@@ -28,7 +28,7 @@ module RLTK::CG
28
28
  def self.enable_pretty_stack_trace
29
29
  Bindings.enable_pretty_stack_trace
30
30
  end
31
-
31
+
32
32
  # Initialize LLVM to generate code for a given architecture. You may
33
33
  # also specify :all to initialize all targets or :native to
34
34
  # initialize the host target.
@@ -43,22 +43,22 @@ module RLTK::CG
43
43
  def self.init(arch)
44
44
  if arch == :all
45
45
  Bindings.initialize_all_targets
46
-
46
+
47
47
  elsif arch == :native
48
48
  Bindings.initialize_native_target
49
-
49
+
50
50
  elsif Bindings::ARCHS.include?(arch) or Bindings::ARCHS.map { |sym| sym.to_s.downcase.to_sym }.include?(arch)
51
51
  arch = Bindings.get_bname(arch)
52
-
52
+
53
53
  Bindings.send("initialize_#{arch}_target".to_sym)
54
54
  Bindings.send("initialize_#{arch}_target_info".to_sym)
55
55
  Bindings.send("initialize_#{arch}_target_mc".to_sym)
56
-
56
+
57
57
  else
58
58
  raise ArgumentError, "Unsupported architecture specified: #{arch}."
59
59
  end
60
60
  end
61
-
61
+
62
62
  # Initialize access to all available target MC that LLVM is
63
63
  # configured to support.
64
64
  #
@@ -66,7 +66,7 @@ module RLTK::CG
66
66
  def self.initialize_all_target_mcs
67
67
  Bindings.initialize_all_target_mcs
68
68
  end
69
-
69
+
70
70
  # Initialize a given ASM parser inside LLVM. You may also specify
71
71
  # :all to initialize all ASM parsers.
72
72
  #
@@ -80,17 +80,17 @@ module RLTK::CG
80
80
  def self.init_asm_parser(asm)
81
81
  if asm == :all
82
82
  Bindings.initialize_all_asm_parsers
83
-
83
+
84
84
  elsif Bindings::ASM_PARSERS.include?(asm) or Bindings::ASM_PARSERS.map { |sym| sym.to_s.downcase.to_sym }.include?(asm)
85
85
  asm = Bindings.get_bname(asm)
86
-
86
+
87
87
  Bindings.send("initialize_#{asm}_asm_parser".to_sym)
88
-
88
+
89
89
  else
90
90
  raise ArgumentError, "Unsupported assembler type specified: #{asm}"
91
91
  end
92
92
  end
93
-
93
+
94
94
  # Initialize a given ASM printer inside LLVM. You may also specify
95
95
  # :all to initialize all ASM printers or :native to initialize the
96
96
  # printer for the host machine's assembly language.
@@ -105,43 +105,43 @@ module RLTK::CG
105
105
  def self.init_asm_printer(asm)
106
106
  if asm == :all
107
107
  Bindings.initialize_all_asm_printers
108
-
108
+
109
109
  elsif asm == :native
110
110
  Bindings.initialize_native_asm_printer
111
-
111
+
112
112
  elsif Bindings::ASM_PRINTERS.include?(asm) or Bindings::ASM_PRINTERS.map { |sym| sym.to_s.downcase.to_sym }.include?(asm)
113
113
  asm = Bindings.get_bname(asm)
114
-
114
+
115
115
  Bindings.send("initialize_#{asm}_asm_printer".to_sym)
116
-
116
+
117
117
  else
118
118
  raise ArgumentError, "Unsupported assembler type specified: #{asm}"
119
119
  end
120
120
  end
121
-
121
+
122
122
  def self.multithreaded?
123
123
  Bindings.is_multithreaded.to_bool
124
124
  end
125
-
125
+
126
126
  # Deallocate and destroy all ManagedStatic variables.
127
127
  #
128
128
  # @return [void]
129
129
  def self.shutdown
130
130
  Bindings.shutdown
131
131
  end
132
-
132
+
133
133
  # Initialize LLVM's multithreaded infrestructure.
134
134
  #
135
135
  # @return [void]
136
136
  def self.start_multithreaded
137
137
  Bindings.start_multithreaded
138
138
  end
139
-
139
+
140
140
  # Shutdown and cleanup LLVM's multithreaded infrastructure.
141
141
  def self.stop_multithreaded
142
142
  Bindings.stop_multithreaded
143
143
  end
144
-
144
+
145
145
  # @return [String] String representing the version of LLVM targeted by these bindings.
146
146
  def self.version
147
147
  RLTK::LLVM_TARGET_VERSION
@@ -19,10 +19,10 @@ module RLTK::CG
19
19
  # This class is used by the {Module} class to dump and load LLVM bitcode.
20
20
  class MemoryBuffer
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.dispose_memory_buffer(ptr) if ptr = ObjectSpace._id2ref(id).ptr }
25
-
25
+
26
26
  # Create a new memory buffer.
27
27
  #
28
28
  # @param [FFI::Pointer, String, nil] overloaded This parameter may be either a pointer to an existing memory
@@ -36,7 +36,7 @@ module RLTK::CG
36
36
  else
37
37
  buf_ptr = FFI::MemoryPointer.new(:pointer)
38
38
  msg_ptr = FFI::MemoryPointer.new(:pointer)
39
-
39
+
40
40
  status =
41
41
  case overloaded
42
42
  when String
@@ -44,26 +44,26 @@ module RLTK::CG
44
44
  else
45
45
  Bindings.create_memory_buffer_with_stdin(buf_ptr, msg_ptr)
46
46
  end
47
-
47
+
48
48
  if status.zero?
49
49
  buf_ptr.get_pointer(0)
50
50
  else
51
51
  raise msg_ptr.get_pointer(0).get_string(0)
52
52
  end
53
53
  end
54
-
54
+
55
55
  # Define a finalizer to free the memory used by LLVM for this
56
56
  # memory buffer.
57
57
  ObjectSpace.define_finalizer(self, CLASS_FINALIZER)
58
58
  end
59
-
59
+
60
60
  # Get the size of the memory buffer.
61
61
  #
62
62
  # @return [Integer] Size of memory buffer
63
63
  def size
64
64
  Bindings.get_buffer_size(@ptr)
65
65
  end
66
-
66
+
67
67
  # Get a copy of the memory buffer, from the beginning, as a sequence
68
68
  # of characters.
69
69
  #
@@ -16,19 +16,19 @@ require 'rltk/cg/context'
16
16
  #######################
17
17
 
18
18
  module RLTK::CG
19
-
19
+
20
20
  # This class represents a collection of functions, constants, and global
21
21
  # variables.
22
22
  class Module
23
23
  include BindingClass
24
-
24
+
25
25
  # The Proc object called by the garbage collector to free resources used by LLVM.
26
26
  CLASS_FINALIZER = Proc.new { |id| Bindings.dispose_module(ptr) if ptr = ObjectSpace._id2ref(id).ptr }
27
-
27
+
28
28
  # @!attribute [rw] engine
29
29
  # @return [ExecutionEngine, nil] Execution engine associated with this module.
30
30
  attr_accessor :engine
31
-
31
+
32
32
  # Load a module from LLVM bitcode.
33
33
  #
34
34
  # @param [MemoryBuffer, String] overloaded Where to read the bitecode from
@@ -37,24 +37,24 @@ module RLTK::CG
37
37
  # @return [Module]
38
38
  def self.read_bitcode(overloaded, context = nil)
39
39
  buffer = overloaded.is_a?(MemoryBuffer) ? overloaded : MemoryBuffer.new(overloaded)
40
-
40
+
41
41
  mod_ptr = FFI::MemoryPointer.new(:pointer)
42
42
  msg_ptr = FFI::MemoryPointer.new(:pointer)
43
-
43
+
44
44
  status =
45
45
  if context
46
46
  Bindings.parse_bitcode_in_context(context, buffer, mod_ptr, msg_ptr)
47
47
  else
48
48
  Bindings.parse_bitcode(buffer, mod_ptr, msg_ptr)
49
49
  end
50
-
50
+
51
51
  if status.zero?
52
52
  Module.new(mod_ptr.get_pointer(0))
53
53
  else
54
54
  raise msg_ptr.get_pointer(0).get_string(0)
55
55
  end
56
56
  end
57
-
57
+
58
58
  # Load a Module form an LLVM IR.
59
59
  #
60
60
  # @param [MemoryBuffer, String] overloaded Where to read the IR from
@@ -63,22 +63,22 @@ module RLTK::CG
63
63
  # @return [Module]
64
64
  def self.read_ir(overloaded, context = Context.global)
65
65
  buffer = overloaded.is_a?(MemoryBuffer) ? overloaded : MemoryBuffer.new(overloaded)
66
-
66
+
67
67
  mod_ptr = FFI::MemoryPointer.new(:pointer)
68
68
  msg_ptr = FFI::MemoryPointer.new(:pointer)
69
-
69
+
70
70
  status = Bindings.parse_ir_in_context(context, buffer, mod_ptr, msg_ptr)
71
-
71
+
72
72
  if status.zero?
73
73
  Module.new(mod_ptr.get_pointer(0))
74
74
  else
75
75
  raise msg_ptr.get_pointer(0).get_string(0)
76
76
  end
77
77
  end
78
-
78
+
79
79
  # Create a new LLVM module.
80
80
  #
81
- # @param [FFI::Pointer, String] overloaded Pointer to existing module or name of new module.
81
+ # @param [FFI::Pointer, String] overloaded Pointer to existing module or name of new module.
82
82
  # @param [Context, nil] context Optional context in which to create the module.
83
83
  # @param [Proc] block Block to be executed inside the context of the module.
84
84
  def initialize(overloaded, context = nil, &block)
@@ -86,25 +86,25 @@ module RLTK::CG
86
86
  case overloaded
87
87
  when FFI::Pointer
88
88
  overloaded
89
-
89
+
90
90
  when String
91
91
  if context
92
92
  Bindings.module_create_with_name_in_context(overloaded, check_type(context, Context, 'context'))
93
93
  else
94
94
  Bindings.module_create_with_name(overloaded)
95
95
  end
96
-
96
+
97
97
  else
98
98
  raise 'Argument `overloaded` must be a FFI::Pointer of String.'
99
99
  end
100
-
100
+
101
101
  # Define a finalizer to free the memory used by LLVM for this
102
102
  # module.
103
103
  ObjectSpace.define_finalizer(self, CLASS_FINALIZER)
104
-
104
+
105
105
  self.instance_exec(&block) if block
106
106
  end
107
-
107
+
108
108
  # Compile this module to an assembly or object file.
109
109
  #
110
110
  # @param [String] file_name File to emit code to
@@ -117,12 +117,12 @@ module RLTK::CG
117
117
  def compile(file_name, emit_type = :object, machine = TargetMachine.host)
118
118
  machine.emite_module(self, file_name, emit_type)
119
119
  end
120
-
120
+
121
121
  # @return [Context] Context in which this module exists.
122
122
  def context
123
123
  Context.new(Bindings.get_module_context(@ptr))
124
124
  end
125
-
125
+
126
126
  # Print the LLVM IR representation of this value to standard error.
127
127
  # This function is the debugging version of the more general purpose
128
128
  # {#print} method.
@@ -133,13 +133,13 @@ module RLTK::CG
133
133
  def dump
134
134
  Bindings.dump_module(@ptr)
135
135
  end
136
-
136
+
137
137
  # @return [FunctionPassManager] Function pass manager for this module.
138
138
  def function_pass_manager
139
139
  @function_pass_manager ||= FunctionPassManager.new(self)
140
140
  end
141
141
  alias :fpm :function_pass_manager
142
-
142
+
143
143
  # Link another module into this one, taking ownership of it. You may
144
144
  # not access the other module again once linking it.
145
145
  #
@@ -149,25 +149,25 @@ module RLTK::CG
149
149
  def link(other)
150
150
  error = FFI::MemoryPointer.new(:pointer)
151
151
  status = Bindings.link_modules(@ptr, other, :linker_destroy_source, error)
152
-
152
+
153
153
  if not status.zero?
154
154
  errorp = error.read_pointer
155
155
  message = errorp.null? ? 'Unknown' : errorp.read_string
156
-
156
+
157
157
  error.autorelease = false
158
-
158
+
159
159
  Bindings.dispose_message(error)
160
-
160
+
161
161
  raise "Error linking modules: #{message}"
162
162
  end
163
163
  end
164
-
164
+
165
165
  # @return [PassManager] Pass manager for this module.
166
166
  def pass_manager
167
167
  @pass_manager ||= PassManager.new(self)
168
168
  end
169
169
  alias :pm :pass_manager
170
-
170
+
171
171
  # Print the LLVM IR representation of this module to a file.
172
172
  #
173
173
  # @param [String] file_name Name of file to print to
@@ -176,30 +176,30 @@ module RLTK::CG
176
176
  def print(file_name)
177
177
  error = FFI::MemoryPointer.new(:pointer)
178
178
  status = Bindings.print_module_to_file(@ptr, file_name, error)
179
-
179
+
180
180
  if not status.zero?
181
181
  errorp = error.read_pointer
182
182
  message = errorp.null? ? 'Unknown' : errorp.read_string
183
-
183
+
184
184
  error.autorelease = false
185
-
185
+
186
186
  Bindings.dispose_message(error)
187
-
187
+
188
188
  raise "Error printing module: #{message}"
189
189
  end
190
190
  end
191
-
191
+
192
192
  # @return [FunctionCollection] Proxy object for inspecting this module's functions.
193
193
  def functions
194
194
  @functions ||= FunctionCollection.new(self)
195
195
  end
196
196
  alias :funs :functions
197
-
197
+
198
198
  # @return [GlobalCollection] Proxy object for inspecting this module's global values and variables.
199
199
  def globals
200
200
  @globals ||= GlobalCollection.new(self)
201
201
  end
202
-
202
+
203
203
  # Set the module's target triple.
204
204
  #
205
205
  # @param [String] triple Triple value to set.
@@ -208,21 +208,21 @@ module RLTK::CG
208
208
  def target=(triple)
209
209
  Bindings.set_target(@ptr, triple)
210
210
  end
211
-
211
+
212
212
  # Get the module's target triple.
213
213
  #
214
214
  # @return [String]
215
215
  def target
216
216
  Bindings.get_target(@ptr)
217
217
  end
218
-
218
+
219
219
  # Return a LLVM IR representation of this file as a string.
220
220
  #
221
221
  # @return [String]
222
222
  def to_s
223
223
  Bindings.print_module_to_string(@ptr)
224
224
  end
225
-
225
+
226
226
  # Write the module as LLVM bitcode to a file.
227
227
  #
228
228
  # @param [#path, #fileno, Integer, String] overloaded Where to write the bitcode.
@@ -232,50 +232,50 @@ module RLTK::CG
232
232
  0 ==
233
233
  if overloaded.respond_to?(:path)
234
234
  Bindings.write_bitcode_to_file(@ptr, overloaded.path)
235
-
235
+
236
236
  elsif overloaded.respond_to?(:fileno)
237
237
  Bindings.write_bitcode_to_fd(@ptr, overloaded.fileno, 0, 1)
238
-
238
+
239
239
  elsif overloaded.is_a?(Integer)
240
240
  Bindings.write_bitcode_to_fd(@ptr, overloaded, 0, 1)
241
-
241
+
242
242
  elsif overloaded.is_a?(String)
243
243
  Bindings.write_bitcode_to_file(@ptr, overloaded)
244
244
  end
245
245
  end
246
-
246
+
247
247
  # Verify that the module is valid LLVM IR.
248
248
  #
249
249
  # @return [nil, String] Human-readable description of any invalid constructs if invalid.
250
250
  def verify
251
251
  do_verification(:return_status)
252
252
  end
253
-
253
+
254
254
  # Verify that a module is valid LLVM IR and abort the process if it isn't.
255
255
  #
256
256
  # @return [nil]
257
257
  def verify!
258
258
  do_verification(:abort_process)
259
259
  end
260
-
260
+
261
261
  # Helper function for {#verify} and {#verify!}
262
262
  def do_verification(action)
263
263
  str_ptr = FFI::MemoryPointer.new(:pointer)
264
264
  status = Bindings.verify_module(@ptr, action, str_ptr)
265
-
265
+
266
266
  status == 1 ? str_ptr.read_string : nil
267
267
  end
268
268
  private :do_verification
269
-
269
+
270
270
  # This class is used to access a module's {Function Functions}.
271
271
  class FunctionCollection
272
272
  include Enumerable
273
-
273
+
274
274
  # @param [Module] mod Module for which this is a proxy.
275
275
  def initialize(mod)
276
276
  @module = mod
277
277
  end
278
-
278
+
279
279
  # Retreive a Function object.
280
280
  #
281
281
  # @param [String, Symbol, Integer] key Function identifier. Either the name of the function or its index.
@@ -285,12 +285,12 @@ module RLTK::CG
285
285
  case key
286
286
  when String, Symbol
287
287
  self.named(key)
288
-
288
+
289
289
  when Integer
290
290
  (1...key).inject(self.first) { |fun| if fun then self.next(fun) else break end }
291
291
  end
292
292
  end
293
-
293
+
294
294
  # Add a Function to this module.
295
295
  #
296
296
  # @param [String] name Name of the module in LLVM IR.
@@ -301,7 +301,7 @@ module RLTK::CG
301
301
  def add(name, *type_info, &block)
302
302
  Function.new(@module, name, *type_info, &block)
303
303
  end
304
-
304
+
305
305
  # Remove a function from the module.
306
306
  #
307
307
  # @param [Function] fun Function to remove.
@@ -310,7 +310,7 @@ module RLTK::CG
310
310
  def delete(fun)
311
311
  Bindings.delete_function(fun)
312
312
  end
313
-
313
+
314
314
  # An iterator for each function inside this collection.
315
315
  #
316
316
  # @yieldparam fun [Function]
@@ -318,39 +318,39 @@ module RLTK::CG
318
318
  # @return [Enumerator] Returns an Enumerator if no block is given.
319
319
  def each
320
320
  return to_enum(:each) unless block_given?
321
-
321
+
322
322
  fun = self.first
323
-
323
+
324
324
  while fun
325
325
  yield fun
326
326
  fun = self.next(fun)
327
327
  end
328
328
  end
329
-
329
+
330
330
  # @return [Function, nil] The module's first function if one has been added.
331
331
  def first
332
332
  if (ptr = Bindings.get_first_function(@module)).null? then nil else Function.new(ptr) end
333
333
  end
334
-
334
+
335
335
  # @return [Function, nil] The module's last function if one has been added.
336
336
  def last
337
337
  if (ptr = Bindings.get_last_function(@module)).null? then nil else Function.new(ptr) end
338
338
  end
339
-
339
+
340
340
  # @param [String, Symbol] name Name of the desired function.
341
341
  #
342
342
  # @return [Function, nil] The function with the given name.
343
343
  def named(name)
344
344
  if (ptr = Bindings.get_named_function(@module, name)).null? then nil else Function.new(ptr) end
345
345
  end
346
-
346
+
347
347
  # @param [Function] fun Function you want the successor for.
348
348
  #
349
349
  # @return [Function, nil] Next function in the collection.
350
350
  def next(fun)
351
351
  if (ptr = Bindings.get_next_function(fun)).null? then nil else Function.new(ptr) end
352
352
  end
353
-
353
+
354
354
  # @param [Function] fun Function you want the predecessor for.
355
355
  #
356
356
  # @return [Function, nil] Previous function in the collection.
@@ -358,16 +358,16 @@ module RLTK::CG
358
358
  if (ptr = Bindings.get_previous_function(fun)).null? then nil else Function.new(ptr) end
359
359
  end
360
360
  end
361
-
361
+
362
362
  # This class is used to access a module's global variables.
363
363
  class GlobalCollection
364
364
  include Enumerable
365
-
365
+
366
366
  # @param [Module] mod Module for which this is a proxy.
367
367
  def initialize(mod)
368
368
  @module = mod
369
369
  end
370
-
370
+
371
371
  # Retreive a GlobalVariable object.
372
372
  #
373
373
  # @param [String, Symbol, Integer] key Global variable identifier. Either the name of the variable or its index.
@@ -377,12 +377,12 @@ module RLTK::CG
377
377
  case key
378
378
  when String, Symbol
379
379
  self.named(key)
380
-
380
+
381
381
  when Integer
382
382
  (1...key).inject(self.first) { |global| if global then self.next(global) else break end }
383
383
  end
384
384
  end
385
-
385
+
386
386
  # Add a global variable to a module.
387
387
  #
388
388
  # @param [Type] type Type of the global variable.
@@ -390,7 +390,7 @@ module RLTK::CG
390
390
  def add(type, name)
391
391
  GlobalVariable.new(Bindings.add_global(@module, type, name))
392
392
  end
393
-
393
+
394
394
  # Remove a global variable from the module.
395
395
  #
396
396
  # @param [GlobalVariable] global Global variable to remove.
@@ -399,7 +399,7 @@ module RLTK::CG
399
399
  def delete(global)
400
400
  Bindings.delete_global(global)
401
401
  end
402
-
402
+
403
403
  # An iterator for each global variable inside this collection.
404
404
  #
405
405
  # @yieldparam fun [GlobalVariable]
@@ -407,39 +407,39 @@ module RLTK::CG
407
407
  # @return [Enumerator] Returns an Enumerator if no block is given.
408
408
  def each
409
409
  return to_enum(:each) unless block_given?
410
-
410
+
411
411
  global = self.first
412
-
412
+
413
413
  while global
414
414
  yield global
415
415
  global = self.next(global)
416
416
  end
417
417
  end
418
-
418
+
419
419
  # @return [GlobalVariable, nil] The module's first global variable if one has been added.
420
420
  def first
421
421
  if (ptr = Bindings.get_first_global(@module)).null? then nil else GlobalValue.new(ptr) end
422
422
  end
423
-
423
+
424
424
  # @return [GlobalVariable, nil] The module's last global variable if one has been added.
425
425
  def last
426
426
  if (ptr = Bindings.get_last_global(@module)).null? then nil else GlobalValue.new(ptr) end
427
427
  end
428
-
428
+
429
429
  # @param [String, Symbol] name Name of the desired global variable.
430
430
  #
431
431
  # @return [GlobalVariable, nil] The global variable with the given name.
432
432
  def named(name)
433
433
  if (ptr = Bindings.get_named_global(@module, name)).null? then nil else GlobalValue.new(ptr) end
434
434
  end
435
-
435
+
436
436
  # @param [GlobalVariable] global Global variable you want the successor for.
437
437
  #
438
438
  # @return [GlobalVariable, nil] global Next global variable in the collection.
439
439
  def next(global)
440
440
  if (ptr = Bindings.get_next_global(global)).null? then nil else GlobalValue.new(ptr) end
441
441
  end
442
-
442
+
443
443
  # @param [GlobalVariable] global Global variable you want the predecessor for.
444
444
  #
445
445
  # @return [GlobalVariable, nil] Previous global variable in the collection.