rubex 0.1.1 → 0.1.2

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.
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