rubex 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/CONTRIBUTING.md +73 -9
  4. data/HISTORY.md +19 -0
  5. data/README.md +53 -8
  6. data/REFERENCE.md +112 -44
  7. data/benchmarks/no_gil/no_gil.rb +24 -0
  8. data/benchmarks/no_gil/no_gil.rubex +22 -0
  9. data/bin/rubex +1 -1
  10. data/examples/c_struct_interface/c_struct_interface.rubex +1 -0
  11. data/lib/rubex.rb +1 -0
  12. data/lib/rubex/ast.rb +11 -7
  13. data/lib/rubex/ast/expression.rb +1 -1
  14. data/lib/rubex/ast/expression/actual_arg_list.rb +7 -0
  15. data/lib/rubex/ast/expression/analysed_element_ref/c_var_element_ref.rb +5 -2
  16. data/lib/rubex/ast/expression/analysed_element_ref/ruby_object_element_ref.rb +26 -9
  17. data/lib/rubex/ast/expression/binary/binary_boolean.rb +1 -1
  18. data/lib/rubex/ast/expression/binary/binary_expo.rb +34 -0
  19. data/lib/rubex/ast/expression/binary/colon2.rb +34 -0
  20. data/lib/rubex/ast/expression/binary/empty_classes.rb +0 -3
  21. data/lib/rubex/ast/expression/command_call.rb +24 -0
  22. data/lib/rubex/ast/{statement → expression/command_call}/print.rb +4 -5
  23. data/lib/rubex/ast/{statement → expression/command_call}/raise.rb +29 -24
  24. data/lib/rubex/ast/expression/command_call/require.rb +27 -0
  25. data/lib/rubex/ast/expression/command_call/yield.rb +36 -0
  26. data/lib/rubex/ast/expression/element_ref.rb +10 -5
  27. data/lib/rubex/ast/expression/instance_var.rb +33 -0
  28. data/lib/rubex/ast/expression/method_call.rb +4 -2
  29. data/lib/rubex/ast/expression/method_call/c_function_call.rb +4 -3
  30. data/lib/rubex/ast/expression/method_call/ruby_method_call.rb +7 -5
  31. data/lib/rubex/ast/expression/name.rb +10 -1
  32. data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_array_element_ref.rb +5 -2
  33. data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_hash_element_ref.rb +10 -2
  34. data/lib/rubex/ast/expression/to_ruby_object.rb +1 -0
  35. data/lib/rubex/ast/expression/unary.rb +7 -3
  36. data/lib/rubex/ast/expression/unary_base/ampersand.rb +5 -0
  37. data/lib/rubex/ast/node.rb +213 -185
  38. data/lib/rubex/ast/node/file_node.rb +25 -0
  39. data/lib/rubex/ast/node/main_node.rb +56 -0
  40. data/lib/rubex/ast/statement/begin_block/begin.rb +4 -3
  41. data/lib/rubex/ast/statement/c_array_decl.rb +1 -1
  42. data/lib/rubex/ast/statement/c_ptr_decl.rb +2 -0
  43. data/lib/rubex/ast/statement/no_gil_block.rb +70 -0
  44. data/lib/rubex/ast/statement/return.rb +1 -0
  45. data/lib/rubex/ast/top_statement.rb +1 -1
  46. data/lib/rubex/ast/top_statement/klass.rb +4 -0
  47. data/lib/rubex/ast/top_statement/klass/attached_klass.rb +88 -10
  48. data/lib/rubex/ast/top_statement/method_def.rb +2 -3
  49. data/lib/rubex/ast/top_statement/method_def/c_function_def.rb +10 -4
  50. data/lib/rubex/cli.rb +11 -6
  51. data/lib/rubex/code_supervisor.rb +49 -0
  52. data/lib/rubex/code_writer.rb +22 -1
  53. data/lib/rubex/compiler.rb +109 -30
  54. data/lib/rubex/compiler_config.rb +14 -1
  55. data/lib/rubex/constants.rb +3 -0
  56. data/lib/rubex/data_type.rb +2 -3
  57. data/lib/rubex/data_type/ruby_object/ruby_symbol.rb +0 -1
  58. data/lib/rubex/error.rb +4 -0
  59. data/lib/rubex/helpers/writers.rb +33 -4
  60. data/lib/rubex/lexer.rex +9 -1
  61. data/lib/rubex/lexer.rex.rb +15 -2
  62. data/lib/rubex/parser.racc +125 -49
  63. data/lib/rubex/parser.racc.rb +1526 -1376
  64. data/lib/rubex/rake_task.rb +42 -6
  65. data/lib/rubex/symbol_table/entry.rb +6 -0
  66. data/lib/rubex/symbol_table/scope.rb +28 -3
  67. data/lib/rubex/version.rb +1 -1
  68. data/rubex.gemspec +1 -0
  69. data/spec/basic_ruby_method_spec.rb +2 -2
  70. data/spec/blocks_spec.rb +2 -2
  71. data/spec/box_op_multi_args_spec.rb +34 -0
  72. data/spec/c_function_ptrs_spec.rb +2 -2
  73. data/spec/c_functions_spec.rb +2 -0
  74. data/spec/c_struct_interface_spec.rb +8 -3
  75. data/spec/default_args_spec.rb +2 -2
  76. data/spec/external_c_struct_spec.rb +33 -0
  77. data/spec/fixtures/api/consumer.rubex +0 -0
  78. data/spec/fixtures/api/implementation.rubex +0 -0
  79. data/spec/fixtures/api/implementation.rubexd +0 -0
  80. data/spec/fixtures/box_op_multi_args/box_op_multi_args.rubex +3 -0
  81. data/spec/fixtures/c_functions/c_functions.rubex +13 -0
  82. data/spec/fixtures/c_struct_interface/c_struct_interface.rubex +28 -0
  83. data/spec/fixtures/class_methods/class_methods.rubex +1 -1
  84. data/spec/fixtures/error_handling/error_handling.rubex +2 -2
  85. data/spec/fixtures/external_c_struct/external_c_struct.rubex +16 -0
  86. data/spec/fixtures/if_else/if_else.rubex +1 -1
  87. data/spec/fixtures/init_ruby_objects_with_literal_syntax/init_ruby_objects_with_literal_syntax.rubex +1 -1
  88. data/spec/fixtures/instance_variables/instance_variables.rubex +25 -0
  89. data/spec/fixtures/loops/loops.rubex +2 -2
  90. data/spec/fixtures/module/module.rubex +28 -0
  91. data/spec/fixtures/multi_file_programs/Rakefile +8 -0
  92. data/spec/fixtures/multi_file_programs/a.rubex +5 -0
  93. data/spec/fixtures/multi_file_programs/b.rubex +5 -0
  94. data/spec/fixtures/multi_file_programs/multi_file_programs.rubex +14 -0
  95. data/spec/fixtures/no_gil/no_gil.rubex +24 -0
  96. data/spec/fixtures/no_gil_attach_class/no_gil_attach_class.rubex +23 -0
  97. data/spec/fixtures/no_gil_compile_check/no_gil_compile_check.rubex +4 -0
  98. data/spec/fixtures/outside_stmts/outside_stmts.rubex +6 -0
  99. data/spec/fixtures/pow/pow.rubex +4 -0
  100. data/spec/fixtures/rake_task/single_file/test.rubex +3 -0
  101. data/spec/fixtures/recursion/recursion.rubex +1 -1
  102. data/spec/fixtures/ruby_constant_scoping/ruby_constant_scoping.rubex +7 -0
  103. data/spec/fixtures/ruby_operators/ruby_operators.rubex +1 -1
  104. data/spec/fixtures/ruby_raise/ruby_raise.rubex +2 -2
  105. data/spec/fixtures/ruby_types/ruby_types.rubex +4 -4
  106. data/spec/fixtures/statement_expression/statement_expression.rubex +2 -2
  107. data/spec/fixtures/static_array/static_array.rubex +3 -3
  108. data/spec/fixtures/string_literals/string_literals.rubex +12 -2
  109. data/spec/fixtures/struct/struct.rubex +1 -1
  110. data/spec/fixtures/var_declarations/var_declarations.rubex +1 -1
  111. data/spec/implicit_lib_include_spec.rb +2 -2
  112. data/spec/init_ruby_objects_with_literal_syntax_spec.rb +2 -2
  113. data/spec/instance_variables_spec.rb +33 -0
  114. data/spec/loops_spec.rb +2 -2
  115. data/spec/module_spec.rb +39 -0
  116. data/spec/multi_file_programs_spec.rb +41 -0
  117. data/spec/no_gil_attach_class_spec.rb +33 -0
  118. data/spec/no_gil_compile_check_spec.rb +25 -0
  119. data/spec/no_gil_spec.rb +36 -0
  120. data/spec/outside_stmts_spec.rb +34 -0
  121. data/spec/pow_spec.rb +33 -0
  122. data/spec/rake_task_spec.rb +142 -0
  123. data/spec/recursion_spec.rb +4 -4
  124. data/spec/ruby_constant_scoping_spec.rb +42 -0
  125. data/spec/ruby_raise_spec.rb +2 -2
  126. data/spec/ruby_symbols_spec.rb +2 -2
  127. data/spec/ruby_types_spec.rb +2 -2
  128. data/spec/spec_helper.rb +17 -3
  129. data/spec/string_literals_spec.rb +1 -0
  130. metadata +90 -6
  131. data/lib/rubex/ast/statement/yield.rb +0 -41
@@ -0,0 +1,25 @@
1
+ module Rubex
2
+ module AST
3
+ module Node
4
+ # Class for denoting a rubex file that is required from another rubex file.
5
+ # Takes the Object scope from the MainNode or other FileNode objects and
6
+ # uses that for storing any symbols that it encounters.
7
+ class FileNode < Base
8
+ def analyse_statement(_local_scope)
9
+ add_top_statements_to_object_scope
10
+ super()
11
+ rescan_declarations @scope
12
+ end
13
+
14
+ def generate_code(supervisor)
15
+ supervisor.init_file(@file_name)
16
+ code_writer = supervisor.code(@file_name)
17
+ code_writer.write_include @file_name
18
+ generate_header_file @file_name, supervisor.header(@file_name)
19
+ super
20
+ generate_init_method code_writer
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,56 @@
1
+ module Rubex
2
+ module AST
3
+ module Node
4
+ # Main class that acts as the apex node of the Rubex AST.
5
+ class MainNode < Base
6
+
7
+ # Central method that starts that processing of the AST. Called by Compiler.
8
+ #
9
+ # @param target_name [String] Target file name of the extension. The Init_
10
+ # method is named after this.
11
+ # @param supervisor [Rubex::CodeSupervisor] Object for holding output code
12
+ # for header and implementation code of each rubex file.
13
+ def process_statements(target_name, supervisor)
14
+ if target_name != @file_name
15
+ raise Rubex::TargetFileMismatchError,
16
+ "target_name #{target_name} does not match @file_name #{@file_name}"
17
+ end
18
+ @scope = Rubex::SymbolTable::Scope::Klass.new('Object', nil)
19
+ add_top_statements_to_object_scope
20
+ create_symtab_entries_for_top_statements(@scope)
21
+ analyse_statement
22
+ rescan_declarations @scope
23
+ generate_common_utils_files supervisor
24
+ generate_header_and_implementation supervisor
25
+ end
26
+
27
+ def generate_common_utils_files supervisor
28
+ supervisor.init_file(Rubex::COMMON_UTILS_FILE)
29
+ header = supervisor.header(Rubex::COMMON_UTILS_FILE)
30
+ header.in_header_guard(Rubex::COMMON_UTILS_CONST) do
31
+ header << "#include <ruby.h>\n"
32
+ header << "#include <stdint.h>\n"
33
+ header << "#include <stdbool.h>\n"
34
+ header << "#include <math.h>\n"
35
+ write_usability_functions_header header
36
+ write_usability_macros header
37
+ end
38
+
39
+ code = supervisor.code(Rubex::COMMON_UTILS_FILE)
40
+ code.write_include(Rubex::COMMON_UTILS_FILE)
41
+ write_usability_functions_code code
42
+
43
+ Rubex::Compiler::CONFIG.add_dep(Rubex::COMMON_UTILS_FILE)
44
+ end
45
+
46
+ def generate_header_and_implementation(supervisor)
47
+ generate_header_file @file_name, supervisor.header(@file_name)
48
+ code_writer = supervisor.code(@file_name)
49
+ code_writer.write_include @file_name
50
+ generate_code supervisor
51
+ generate_init_method code_writer
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -160,16 +160,17 @@ module Rubex
160
160
  'begin_block_' + local_scope.klass_name + '_' + local_scope.name + '_' +
161
161
  local_scope.begin_block_counter.to_s
162
162
  end
163
-
163
+
164
164
  def create_c_function_to_house_statements(scope)
165
165
  func_name = @block_scope.name
166
166
  arg_list = Statement::ArgumentList.new([
167
167
  AST::Expression::ArgDeclaration.new(
168
- { dtype: 'object', variables: [{ ident: 'dummy' }] }
168
+ { dtype: 'object',
169
+ variables: [{ ident: 'dummy' }] }
169
170
  )
170
171
  ])
171
172
  @begin_func = TopStatement::CFunctionDef.new(
172
- 'object', '', func_name, arg_list, @statements
173
+ 'object', '', func_name, arg_list, nil, @statements
173
174
  )
174
175
  arg_list.analyse_statement @block_scope
175
176
  add_to_symbol_table @begin_func.name, arg_list, scope
@@ -8,7 +8,7 @@ module Rubex
8
8
  super(location)
9
9
  @name = array_ref.name
10
10
  @array_list = array_list
11
- @dimension = array_ref.pos
11
+ @dimension = array_ref.pos[0]
12
12
  @type = Rubex::TYPE_MAPPINGS[type].new
13
13
  end
14
14
 
@@ -17,7 +17,9 @@ module Rubex
17
17
  @type = Helpers.determine_dtype @type, @ptr_level
18
18
  if @value
19
19
  @value.analyse_for_target_type(@type, local_scope)
20
+ @value.allocate_temps(local_scope)
20
21
  @value = Helpers.to_lhs_type(self, @value)
22
+ @value.release_temps(local_scope)
21
23
  end
22
24
 
23
25
  @entry = local_scope.declare_var name: @name, c_name: @c_name,
@@ -0,0 +1,70 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class NoGilBlock < Base
5
+ def initialize statements
6
+ @statements = statements
7
+ end
8
+
9
+ def analyse_statement(local_scope)
10
+ local_scope.found_no_gil_block
11
+ @block_scope = Rubex::SymbolTable::Scope::NoGilBlock.new(
12
+ block_name(local_scope), local_scope)
13
+ create_c_function_to_house_statements local_scope.outer_scope
14
+ # TODO: check if ruby objects exist in the block. Raise error if yes.
15
+ end
16
+
17
+ def generate_code(code, local_scope)
18
+ code.nl
19
+ code << "/* no_gil block: */"
20
+ code.nl
21
+ super
22
+ cb_c_name = local_scope.find(@no_gil_func.name).c_name
23
+ code << "rb_thread_call_without_gvl(#{cb_c_name}, NULL, RUBY_UBF_PROCESS, NULL);"
24
+ code.nl
25
+ end
26
+
27
+ private
28
+
29
+ def block_name(local_scope)
30
+ "no_gil_block_" + local_scope.klass_name + "_" + local_scope.name + "_" +
31
+ local_scope.no_gil_block_counter.to_s
32
+ end
33
+
34
+ def create_c_function_to_house_statements(outer_scope)
35
+ func_name = @block_scope.name
36
+ arg_list = Statement::ArgumentList.new([
37
+ AST::Expression::ArgDeclaration.new(
38
+ {
39
+ dtype: 'void',
40
+ variables:
41
+ [{
42
+ ptr_level: "*",
43
+ ident: 'dummy'
44
+ }]
45
+ })
46
+ ])
47
+ @no_gil_func = TopStatement::CFunctionDef.new(
48
+ 'void', '*', func_name, arg_list, nil, @statements)
49
+ arg_list.analyse_statement @block_scope
50
+ add_to_symbol_table @no_gil_func.name, arg_list, outer_scope
51
+ @no_gil_func.analyse_statement @block_scope
52
+ @block_scope.upgrade_symbols_to_global
53
+ outer_scope.add_no_gil_block_callback @no_gil_func
54
+ end
55
+
56
+ def add_to_symbol_table(func_name, arg_list, outer_scope)
57
+ c_name = Rubex::C_FUNC_PREFIX + func_name
58
+ outer_scope.add_c_method(
59
+ name: func_name,
60
+ c_name: c_name,
61
+ extern: false,
62
+ return_type: DataType::RubyObject.new,
63
+ arg_list: arg_list,
64
+ scope: @block_scope
65
+ )
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -27,6 +27,7 @@ module Rubex
27
27
  else
28
28
  t
29
29
  end
30
+
30
31
  @expression = @expression.to_ruby_object if local_scope.type.type.object?
31
32
 
32
33
  # TODO: Raise error if type as inferred from the
@@ -1 +1 @@
1
- Dir['./lib/rubex/ast/top_statement/**/*.rb'].sort.each { |f| require f }
1
+ Dir[File.join(File.dirname(File.dirname(__FILE__)), "ast", "top_statement", "**", "*.rb" )].sort.each { |f| require f }
@@ -47,6 +47,10 @@ module Rubex
47
47
  cb.generate_code code
48
48
  end
49
49
 
50
+ @scope.no_gil_block_callbacks.each do |cb|
51
+ cb.generate_code code
52
+ end
53
+
50
54
  @statements.each do |stat|
51
55
  stat.generate_code code
52
56
  end
@@ -17,13 +17,13 @@ module Rubex
17
17
 
18
18
  def analyse_statement(outer_scope)
19
19
  super(outer_scope, attach_klass: true)
20
- prepare_data_holding_struct
20
+ prepare_data_holding_struct!
21
21
  prepare_rb_data_type_t_struct
22
22
  detach_and_modify_auxillary_c_functions_from_statements
23
23
  add_auxillary_functions_to_klass_scope
24
24
  prepare_auxillary_c_functions
25
25
  @statements[1..-1].each do |stmt| # 0th stmt is the data struct
26
- if ruby_method_or_c_func?(stmt)
26
+ if ruby_method_or_c_func_without_gil_lock?(stmt)
27
27
  rewrite_method_with_data_fetching stmt
28
28
  end
29
29
  stmt.analyse_statement @scope
@@ -72,6 +72,7 @@ module Rubex
72
72
  if stmt.name == ALLOC_FUNC_NAME
73
73
  @auxillary_c_functions[ALLOC_FUNC_NAME] = stmt
74
74
  @user_defined_alloc = true
75
+ modify_alloc_func stmt
75
76
  indexes << idx
76
77
  elsif stmt.name == DEALLOC_FUNC_NAME
77
78
  @auxillary_c_functions[DEALLOC_FUNC_NAME] = stmt
@@ -90,8 +91,8 @@ module Rubex
90
91
  end
91
92
  end
92
93
 
93
- indexes.each do |idx|
94
- @statements.delete_at idx
94
+ @statements.delete_if.with_index do |s, i|
95
+ indexes.include? i
95
96
  end
96
97
  end
97
98
 
@@ -100,10 +101,22 @@ module Rubex
100
101
  write_memcount_c_function code
101
102
  end
102
103
 
104
+ # FIXME : change this. its too ugly.
105
+ def ugly_code_mod_hack code
106
+ ret = ""
107
+ ret << 'return TypedData_Wrap_Struct('
108
+ ret << "#{@alloc_c_func.type.arg_list[0].entry.c_name},"
109
+ ret << "&#{@data_type_t}, #{Rubex::POINTER_PREFIX}data);\n"
110
+
111
+ c = code.instance_variable_get(:@code)
112
+ c.insert -4, ret
113
+ end
114
+
103
115
  # Actually write the alloc function into C code.
104
- def write_alloc_c_function(code)
116
+ def write_alloc_c_function(code)
105
117
  if user_defined_alloc?
106
118
  @auxillary_c_functions[ALLOC_FUNC_NAME].generate_code code
119
+ ugly_code_mod_hack code
107
120
  else
108
121
  code.write_c_method_header(
109
122
  type: @alloc_c_func.type.type.to_s,
@@ -122,7 +135,7 @@ module Rubex
122
135
  lines << 'return TypedData_Wrap_Struct('
123
136
  lines << "#{@alloc_c_func.type.arg_list[0].entry.c_name},"
124
137
  lines << "&#{@data_type_t}, data);\n"
125
-
138
+
126
139
  code << lines
127
140
  end
128
141
  end
@@ -131,7 +144,7 @@ module Rubex
131
144
  # TODO: modify for supporting inheritance
132
145
  def member_struct_allocations
133
146
  c_name = @scope.find(@attached_type).c_name
134
- "data->#{Rubex::POINTER_PREFIX + @attached_type} = (#{c_name}*)xmalloc(sizeof(#{c_name}));\n"
147
+ "data->#{Rubex::POINTER_PREFIX + @attached_type} = (#{c_name}*)xmalloc(sizeof(#{c_name}));\n"
135
148
  end
136
149
 
137
150
  # Actually write the dealloc function into C code.
@@ -198,7 +211,7 @@ module Rubex
198
211
 
199
212
  # Prepare the data holding struct 'data' that will hold a pointer to the
200
213
  # struct that is attached to this class.
201
- def prepare_data_holding_struct
214
+ def prepare_data_holding_struct!
202
215
  struct_name = @name + '_data_struct'
203
216
  declarations = declarations_for_data_struct
204
217
  @data_struct = Statement::CStructOrUnionDef.new(
@@ -230,8 +243,8 @@ module Rubex
230
243
  prepare_get_struct_c_function
231
244
  end
232
245
 
233
- def ruby_method_or_c_func?(stmt)
234
- stmt.is_a?(RubyMethodDef) || stmt.is_a?(CFunctionDef)
246
+ def ruby_method_or_c_func_without_gil_lock?(stmt)
247
+ stmt.is_a?(RubyMethodDef) || (stmt.is_a?(CFunctionDef) && !stmt.no_gil)
235
248
  end
236
249
 
237
250
  # Rewrite method `stmt` so that the `data` variable becomes available
@@ -368,6 +381,71 @@ module Rubex
368
381
  end
369
382
  end
370
383
 
384
+ # In case of user supplied allocate function, add a statement at the
385
+ # beginning to declare and obtain the data variable and also add a
386
+ # return statement involving TypedDataStruct at the end so that the
387
+ # user is freed from needing to write these.
388
+ def modify_alloc_func(func)
389
+ stmts = []
390
+ stmts << data_var_cptr_decl(nil)
391
+ stmts.concat data_struct_allocations
392
+ stmts.reverse.each do |s|
393
+ func.statements.unshift s
394
+ end
395
+ end
396
+
397
+ # declare a pointer to a data struct.
398
+ def data_var_cptr_decl(value = nil)
399
+ Statement::CPtrDecl.new(
400
+ @data_struct.entry.name, 'data', value, '*', @location)
401
+ end
402
+
403
+ def data_struct_allocations
404
+ stmts = []
405
+ # assign malloc for top level data struct
406
+ rhs = Expression::CommandCall.new(
407
+ nil, 'xmalloc',
408
+ Expression::ActualArgList.new(
409
+ [
410
+ Expression::SizeOf.new(@data_struct.entry.name, '')
411
+ ])
412
+ )
413
+ rhs.typecast = Expression::Typecast.new(@data_struct.entry.name, '*')
414
+ assign_data_struct = Statement::Assign.new(
415
+ Expression::Name.new('data'), rhs, @location
416
+ )
417
+
418
+ stmts << assign_data_struct
419
+ stmts << xmalloc_inner_struct_member
420
+ stmts
421
+ end
422
+
423
+ def xmalloc_inner_struct_member
424
+ t = @scope.find(@attached_type).name
425
+ lhs = Expression::CommandCall.new(
426
+ Expression::ElementRef.new(
427
+ 'data',
428
+ Expression::ActualArgList.new(
429
+ [
430
+ Expression::Literal::Int.new('0')
431
+ ]
432
+ )
433
+ ),
434
+ t,
435
+ nil
436
+ )
437
+ rhs = Expression::CommandCall.new(
438
+ nil, 'xmalloc',
439
+ Expression::ActualArgList.new(
440
+ [
441
+ Expression::SizeOf.new(t, '')
442
+ ]
443
+ )
444
+ )
445
+ rhs.typecast = Expression::Typecast.new(t, '*')
446
+ Statement::Assign.new(lhs, rhs, @location)
447
+ end
448
+
371
449
  # Modify the dealloc function by adding an argument of type void* so
372
450
  # that it is compatible with what Ruby expects. This is done so that
373
451
  # the user is not burdened with additional knowledge of knowing the
@@ -6,7 +6,7 @@ module Rubex
6
6
  # Ruby name of the method.
7
7
  attr_reader :name
8
8
  # Method arguments. Accessor because arguments need to be modified in
9
- # case of auxillary C functions of attach classes.
9
+ # case of auxillary C functions of attach classes.
10
10
  attr_accessor :arg_list
11
11
  # The statments/expressions contained within the method.
12
12
  attr_reader :statements
@@ -53,7 +53,7 @@ module Rubex
53
53
  private
54
54
 
55
55
  def generate_function_definition(code, c_function:)
56
- declare_types code, @scope
56
+ declare_types code, @scope.type_entries
57
57
  declare_args code unless c_function
58
58
  declare_vars code, @scope
59
59
  declare_carrays code, @scope
@@ -104,7 +104,6 @@ module Rubex
104
104
  end
105
105
  end
106
106
  end
107
-
108
107
  end
109
108
  end
110
109
  end
@@ -2,25 +2,31 @@ module Rubex
2
2
  module AST
3
3
  module TopStatement
4
4
  class CFunctionDef < MethodDef
5
- attr_reader :type, :return_ptr_level
5
+ attr_reader :type, :return_ptr_level, :no_gil
6
6
 
7
- def initialize(type, return_ptr_level, name, arg_list, statements)
7
+ def initialize(type, return_ptr_level, name, arg_list, function_tags, statements)
8
8
  super(name, arg_list, statements)
9
9
  @type = type
10
10
  @return_ptr_level = return_ptr_level
11
+ @function_tags = function_tags
12
+ @no_gil = false
13
+ if @function_tags == "no_gil"
14
+ @no_gil = true
15
+ end
11
16
  end
12
17
 
13
18
  def analyse_statement(outer_scope, extern: false)
14
19
  super(outer_scope)
20
+ @entry.no_gil = @no_gil
15
21
  end
16
22
 
17
23
  def generate_code(code)
18
24
  code.write_c_method_header(type: @entry.type.type.to_s,
19
- c_name: @entry.c_name, args: Helpers.create_arg_arrays(@arg_list))
25
+ c_name: @entry.c_name,
26
+ args: Helpers.create_arg_arrays(@arg_list))
20
27
  super code, c_function: true
21
28
  end
22
29
  end
23
-
24
30
  end
25
31
  end
26
32
  end