rubex 0.1 → 0.1.1

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 (197) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -2
  3. data/.travis.yml +9 -1
  4. data/CONTRIBUTING.md +2 -2
  5. data/README.md +4 -1
  6. data/Rakefile +2 -2
  7. data/bin/rubex +4 -5
  8. data/lib/rubex.rb +4 -4
  9. data/lib/rubex/ast.rb +4 -1
  10. data/lib/rubex/ast/expression.rb +22 -1191
  11. data/lib/rubex/ast/expression/actual_arg_list.rb +40 -0
  12. data/lib/rubex/ast/expression/analysed_element_ref.rb +26 -0
  13. data/lib/rubex/ast/expression/analysed_element_ref/c_var_element_ref.rb +30 -0
  14. data/lib/rubex/ast/expression/analysed_element_ref/ruby_object_element_ref.rb +42 -0
  15. data/lib/rubex/ast/expression/arg_declaration.rb +43 -0
  16. data/lib/rubex/ast/expression/binary.rb +57 -0
  17. data/lib/rubex/ast/expression/binary/binary_boolean.rb +23 -0
  18. data/lib/rubex/ast/expression/binary/binary_boolean_special_op.rb +20 -0
  19. data/lib/rubex/ast/expression/binary/empty_classes.rb +62 -0
  20. data/lib/rubex/ast/expression/block_given.rb +15 -0
  21. data/lib/rubex/ast/expression/coerce_object.rb +15 -0
  22. data/lib/rubex/ast/expression/command_call.rb +74 -0
  23. data/lib/rubex/ast/expression/command_call/struct_or_union_member_call.rb +38 -0
  24. data/lib/rubex/ast/expression/element_ref.rb +64 -0
  25. data/lib/rubex/ast/expression/empty.rb +13 -0
  26. data/lib/rubex/ast/expression/from_ruby_object.rb +20 -0
  27. data/lib/rubex/ast/expression/func_ptr_arg_declaration.rb +21 -0
  28. data/lib/rubex/ast/expression/func_ptr_internal_arg_declaration.rb +13 -0
  29. data/lib/rubex/ast/expression/literal.rb +30 -0
  30. data/lib/rubex/ast/expression/literal/array_lit.rb +51 -0
  31. data/lib/rubex/ast/expression/literal/c_null.rb +15 -0
  32. data/lib/rubex/ast/expression/literal/char.rb +36 -0
  33. data/lib/rubex/ast/expression/literal/double.rb +14 -0
  34. data/lib/rubex/ast/expression/literal/false.rb +33 -0
  35. data/lib/rubex/ast/expression/literal/hash_lit.rb +45 -0
  36. data/lib/rubex/ast/expression/literal/int.rb +14 -0
  37. data/lib/rubex/ast/expression/literal/nil.rb +14 -0
  38. data/lib/rubex/ast/expression/literal/ruby_symbol.rb +22 -0
  39. data/lib/rubex/ast/expression/literal/string_lit.rb +45 -0
  40. data/lib/rubex/ast/expression/literal/true.rb +29 -0
  41. data/lib/rubex/ast/expression/method_call.rb +52 -0
  42. data/lib/rubex/ast/expression/method_call/c_function_call.rb +40 -0
  43. data/lib/rubex/ast/expression/method_call/ruby_method_call.rb +83 -0
  44. data/lib/rubex/ast/expression/name.rb +127 -0
  45. data/lib/rubex/ast/expression/ruby_constant.rb +25 -0
  46. data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_array_element_ref.rb +20 -0
  47. data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_hash_element_ref.rb +22 -0
  48. data/lib/rubex/ast/expression/self.rb +15 -0
  49. data/lib/rubex/ast/expression/size_of.rb +22 -0
  50. data/lib/rubex/ast/expression/struct_or_union_member_call/element_ref_member_call.rb +23 -0
  51. data/lib/rubex/ast/expression/to_ruby_object.rb +21 -0
  52. data/lib/rubex/ast/expression/typecast.rb +20 -0
  53. data/lib/rubex/ast/expression/typecast_to.rb +10 -0
  54. data/lib/rubex/ast/expression/unary.rb +37 -0
  55. data/lib/rubex/ast/expression/unary_base.rb +24 -0
  56. data/lib/rubex/ast/expression/unary_base/ampersand.rb +16 -0
  57. data/lib/rubex/ast/expression/unary_base/unary_bit_not.rb +18 -0
  58. data/lib/rubex/ast/expression/unary_base/unary_not.rb +18 -0
  59. data/lib/rubex/ast/expression/unary_base/unary_sub.rb +18 -0
  60. data/lib/rubex/ast/node.rb +111 -111
  61. data/lib/rubex/ast/statement.rb +9 -1160
  62. data/lib/rubex/ast/statement/alias.rb +43 -0
  63. data/lib/rubex/ast/statement/argument_list.rb +59 -0
  64. data/lib/rubex/ast/statement/assign.rb +35 -0
  65. data/lib/rubex/ast/statement/begin_block.rb +14 -0
  66. data/lib/rubex/ast/statement/begin_block/begin.rb +202 -0
  67. data/lib/rubex/ast/statement/begin_block/else.rb +21 -0
  68. data/lib/rubex/ast/statement/begin_block/ensure.rb +21 -0
  69. data/lib/rubex/ast/statement/begin_block/rescue.rb +34 -0
  70. data/lib/rubex/ast/statement/break.rb +18 -0
  71. data/lib/rubex/ast/statement/c_array_decl.rb +49 -0
  72. data/lib/rubex/ast/statement/c_base_type.rb +26 -0
  73. data/lib/rubex/ast/statement/c_function_decl.rb +30 -0
  74. data/lib/rubex/ast/statement/c_ptr_decl.rb +52 -0
  75. data/lib/rubex/ast/statement/c_ptr_decl/c_ptr_func_decl.rb +25 -0
  76. data/lib/rubex/ast/statement/c_struct_or_union_def.rb +49 -0
  77. data/lib/rubex/ast/statement/expression.rb +26 -0
  78. data/lib/rubex/ast/statement/for.rb +73 -0
  79. data/lib/rubex/ast/statement/forward_decl.rb +31 -0
  80. data/lib/rubex/ast/statement/if_block.rb +64 -0
  81. data/lib/rubex/ast/statement/if_block/else.rb +30 -0
  82. data/lib/rubex/ast/statement/if_block/elsif.rb +22 -0
  83. data/lib/rubex/ast/statement/if_block/helper.rb +38 -0
  84. data/lib/rubex/ast/statement/print.rb +49 -0
  85. data/lib/rubex/ast/statement/raise.rb +66 -0
  86. data/lib/rubex/ast/statement/return.rb +45 -0
  87. data/lib/rubex/ast/statement/var_decl.rb +49 -0
  88. data/lib/rubex/ast/statement/while.rb +34 -0
  89. data/lib/rubex/ast/statement/yield.rb +41 -0
  90. data/lib/rubex/ast/top_statement.rb +1 -815
  91. data/lib/rubex/ast/top_statement/c_bindings.rb +145 -0
  92. data/lib/rubex/ast/top_statement/klass.rb +125 -0
  93. data/lib/rubex/ast/top_statement/klass/attached_klass.rb +417 -0
  94. data/lib/rubex/ast/top_statement/method_def.rb +110 -0
  95. data/lib/rubex/ast/top_statement/method_def/c_function_def.rb +26 -0
  96. data/lib/rubex/ast/top_statement/method_def/ruby_method_def.rb +33 -0
  97. data/lib/rubex/cli.rb +26 -0
  98. data/lib/rubex/code_writer.rb +1 -1
  99. data/lib/rubex/compiler.rb +49 -28
  100. data/lib/rubex/compiler_config.rb +4 -2
  101. data/lib/rubex/constants.rb +71 -71
  102. data/lib/rubex/data_type.rb +9 -675
  103. data/lib/rubex/data_type/c_array.rb +33 -0
  104. data/lib/rubex/data_type/c_function.rb +23 -0
  105. data/lib/rubex/data_type/c_ptr.rb +71 -0
  106. data/lib/rubex/data_type/c_str.rb +23 -0
  107. data/lib/rubex/data_type/c_struct_or_union.rb +23 -0
  108. data/lib/rubex/data_type/char.rb +30 -0
  109. data/lib/rubex/data_type/f_32.rb +38 -0
  110. data/lib/rubex/data_type/f_64.rb +38 -0
  111. data/lib/rubex/data_type/int.rb +32 -0
  112. data/lib/rubex/data_type/int/c_boolean.rb +13 -0
  113. data/lib/rubex/data_type/int_16.rb +32 -0
  114. data/lib/rubex/data_type/int_32.rb +32 -0
  115. data/lib/rubex/data_type/int_64.rb +36 -0
  116. data/lib/rubex/data_type/int_8.rb +33 -0
  117. data/lib/rubex/data_type/l_int.rb +38 -0
  118. data/lib/rubex/data_type/l_l_int.rb +26 -0
  119. data/lib/rubex/data_type/ruby_method.rb +22 -0
  120. data/lib/rubex/data_type/ruby_object.rb +19 -0
  121. data/lib/rubex/data_type/ruby_object/boolean.rb +11 -0
  122. data/lib/rubex/data_type/ruby_object/boolean/false_type.rb +5 -0
  123. data/lib/rubex/data_type/ruby_object/boolean/true_type.rb +5 -0
  124. data/lib/rubex/data_type/ruby_object/nil_type.rb +9 -0
  125. data/lib/rubex/data_type/ruby_object/ruby_array.rb +10 -0
  126. data/lib/rubex/data_type/ruby_object/ruby_constant.rb +18 -0
  127. data/lib/rubex/data_type/ruby_object/ruby_constant/ruby_class.rb +18 -0
  128. data/lib/rubex/data_type/ruby_object/ruby_hash.rb +9 -0
  129. data/lib/rubex/data_type/ruby_object/ruby_string.rb +10 -0
  130. data/lib/rubex/data_type/ruby_object/ruby_symbol.rb +10 -0
  131. data/lib/rubex/data_type/type_def.rb +34 -0
  132. data/lib/rubex/data_type/u_char.rb +27 -0
  133. data/lib/rubex/data_type/u_int.rb +32 -0
  134. data/lib/rubex/data_type/u_int_16.rb +22 -0
  135. data/lib/rubex/data_type/u_int_32.rb +22 -0
  136. data/lib/rubex/data_type/u_int_64.rb +26 -0
  137. data/lib/rubex/data_type/u_int_8.rb +22 -0
  138. data/lib/rubex/data_type/u_l_int.rb +36 -0
  139. data/lib/rubex/data_type/u_l_int/size_t.rb +10 -0
  140. data/lib/rubex/data_type/u_l_l_int.rb +26 -0
  141. data/lib/rubex/data_type/void.rb +15 -0
  142. data/lib/rubex/data_type_helpers/float_helpers.rb +8 -0
  143. data/lib/rubex/data_type_helpers/helpers.rb +48 -0
  144. data/lib/rubex/data_type_helpers/int_helpers.rb +10 -0
  145. data/lib/rubex/data_type_helpers/u_int_helpers.rb +11 -0
  146. data/lib/rubex/helpers.rb +35 -118
  147. data/lib/rubex/helpers/node_type_methods.rb +9 -0
  148. data/lib/rubex/helpers/writers.rb +79 -0
  149. data/lib/rubex/parser.racc +83 -34
  150. data/lib/rubex/parser.racc.rb +233 -184
  151. data/lib/rubex/version.rb +2 -2
  152. data/rubex.gemspec +2 -0
  153. data/spec/basic_ruby_method_spec.rb +1 -1
  154. data/spec/binding_ptr_args_spec.rb +2 -2
  155. data/spec/bitwise_operators_spec.rb +1 -1
  156. data/spec/blocks_spec.rb +2 -2
  157. data/spec/c_bindings_spec.rb +1 -1
  158. data/spec/c_constants_spec.rb +1 -1
  159. data/spec/c_function_ptrs_spec.rb +1 -1
  160. data/spec/c_functions_spec.rb +2 -2
  161. data/spec/c_struct_interface_spec.rb +1 -1
  162. data/spec/call_by_reference_spec.rb +2 -2
  163. data/spec/class_methods_spec.rb +2 -2
  164. data/spec/class_spec.rb +4 -4
  165. data/spec/cli_spec.rb +43 -0
  166. data/spec/comments_spec.rb +2 -2
  167. data/spec/default_args_spec.rb +21 -23
  168. data/spec/error_handling_spec.rb +1 -1
  169. data/spec/examples_spec.rb +4 -4
  170. data/spec/expressions_spec.rb +1 -1
  171. data/spec/fixtures/cli/cli.rubex +3 -0
  172. data/spec/fixtures/examples/array_to_hash.rubex +1 -1
  173. data/spec/fixtures/examples/rcsv.rubex +10 -6
  174. data/spec/fixtures/loops/loops.rubex +1 -1
  175. data/spec/fixtures/ruby_strings/string_blank_bm.rb +7 -5
  176. data/spec/fixtures/struct/struct.rubex +7 -2
  177. data/spec/fixtures/temp_allocation/temp_allocation.rubex +8 -0
  178. data/spec/if_else_spec.rb +3 -7
  179. data/spec/implicit_lib_include_spec.rb +1 -1
  180. data/spec/init_ruby_objects_with_literal_syntax_spec.rb +1 -1
  181. data/spec/loops_spec.rb +1 -1
  182. data/spec/recursion_spec.rb +18 -21
  183. data/spec/ruby_constant_method_calls_spec.rb +4 -4
  184. data/spec/ruby_operators_spec.rb +1 -1
  185. data/spec/ruby_raise_spec.rb +1 -1
  186. data/spec/ruby_strings_spec.rb +3 -3
  187. data/spec/ruby_symbols_spec.rb +1 -1
  188. data/spec/ruby_types_spec.rb +2 -2
  189. data/spec/spec_helper.rb +42 -10
  190. data/spec/statement_expression_spec.rb +3 -3
  191. data/spec/static_array_spec.rb +3 -3
  192. data/spec/string_literals_spec.rb +2 -2
  193. data/spec/struct_spec.rb +4 -4
  194. data/spec/temp_allocation_spec.rb +35 -0
  195. data/spec/typecasting_spec.rb +2 -2
  196. data/spec/var_declarions_spec.rb +2 -2
  197. metadata +168 -3
@@ -0,0 +1,43 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class Alias < Base
5
+ def initialize(new_name, old_name, location)
6
+ super(location)
7
+ @new_name = new_name
8
+ @old_name = old_name
9
+ Rubex::CUSTOM_TYPES[@new_name] = @new_name
10
+ end
11
+
12
+ def analyse_statement(local_scope, extern: false)
13
+ original = @old_name[:dtype].gsub('struct ', '').gsub('union ', '')
14
+ var = @old_name[:variables][0]
15
+ ident = var[:ident]
16
+ ptr_level = var[:ptr_level]
17
+
18
+ base_type =
19
+ if ident.is_a?(Hash) # function pointer
20
+ cfunc_return_type = Helpers.determine_dtype(original,
21
+ ident[:return_ptr_level])
22
+ arg_list = ident[:arg_list].analyse_statement(local_scope)
23
+ ptr_level = '*' if ptr_level.empty?
24
+
25
+ Helpers.determine_dtype(
26
+ DataType::CFunction.new(nil, nil, arg_list, cfunc_return_type, nil),
27
+ ptr_level
28
+ )
29
+ else
30
+ Helpers.determine_dtype(original, ptr_level)
31
+ end
32
+
33
+ @type = Rubex::DataType::TypeDef.new(base_type, @new_name, base_type)
34
+ Rubex::CUSTOM_TYPES[@new_name] = @type
35
+ local_scope.declare_type(type: @type, extern: extern) if original != @new_name
36
+ end
37
+
38
+ def generate_code(code, local_scope); end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,59 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ # This node is used for both formal and actual arguments of functions/methods.
5
+ class ArgumentList < Base
6
+ include Enumerable
7
+
8
+ # args - [ArgDeclaration]
9
+ attr_reader :args
10
+
11
+ def each(&block)
12
+ @args.each(&block)
13
+ end
14
+
15
+ def map!(&block)
16
+ @args.map!(&block)
17
+ end
18
+
19
+ def pop
20
+ @args.pop
21
+ end
22
+
23
+ def initialize(args)
24
+ @args = args
25
+ end
26
+
27
+ def analyse_statement(local_scope, extern: false)
28
+ @args.each do |arg|
29
+ arg.analyse_types(local_scope, extern: extern)
30
+ end
31
+ end
32
+
33
+ def push(arg)
34
+ @args << arg
35
+ end
36
+
37
+ def <<(arg)
38
+ push arg
39
+ end
40
+
41
+ def ==(other)
42
+ self.class == other.class && @args == other.args
43
+ end
44
+
45
+ def size
46
+ @args.size
47
+ end
48
+
49
+ def empty?
50
+ @args.empty?
51
+ end
52
+
53
+ def [](idx)
54
+ @args[idx]
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,35 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class Assign < Base
5
+ def initialize(lhs, rhs, location)
6
+ super(location)
7
+ @lhs = lhs
8
+ @rhs = rhs
9
+ end
10
+
11
+ def analyse_statement(local_scope)
12
+ if @lhs.is_a?(Rubex::AST::Expression::Name)
13
+ @lhs.analyse_declaration @rhs, local_scope
14
+ else
15
+ @lhs.analyse_types(local_scope)
16
+ end
17
+ @lhs.allocate_temps local_scope
18
+ @rhs.analyse_for_target_type(@lhs.type, local_scope)
19
+ @rhs = Helpers.to_lhs_type(@lhs, @rhs)
20
+ @rhs.allocate_temps local_scope
21
+
22
+ @lhs.release_temps local_scope
23
+ @rhs.release_temps local_scope
24
+ end
25
+
26
+ def generate_code(code, local_scope)
27
+ super
28
+ @rhs.generate_evaluation_code code, local_scope
29
+ @lhs.generate_assignment_code @rhs, code, local_scope
30
+ @rhs.generate_disposal_code code
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ module BeginBlock
5
+ class Base < Statement::Base
6
+ def initialize(statements, location)
7
+ @statements = statements
8
+ super(location)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,202 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ module BeginBlock
5
+ class Begin < Base
6
+ def initialize(statements, tails, location)
7
+ @tails = tails
8
+ super(statements, location)
9
+ end
10
+
11
+ def analyse_statement(local_scope)
12
+ local_scope.found_begin_block
13
+ declare_error_state_variable local_scope
14
+ declare_error_klass_variable local_scope
15
+ declare_unhandled_error_variable local_scope
16
+ @block_scope = Rubex::SymbolTable::Scope::BeginBlock.new(
17
+ block_name(local_scope), local_scope
18
+ )
19
+ create_c_function_to_house_statements local_scope.outer_scope
20
+ analyse_tails local_scope
21
+ end
22
+
23
+ def generate_code(code, local_scope)
24
+ code.nl
25
+ code << '/* begin-rescue-else-ensure-end block begins: */'
26
+ code.nl
27
+ super
28
+ cb_c_name = local_scope.find(@begin_func.name).c_name
29
+ state_var = local_scope.find(@state_var_name).c_name
30
+ code << "#{state_var} = 0;\n"
31
+ code << "rb_protect(#{cb_c_name}, Qnil, &#{state_var});"
32
+ code.nl
33
+ generate_rescue_else_ensure code, local_scope
34
+ end
35
+
36
+ private
37
+
38
+ def generate_rescue_else_ensure(code, local_scope)
39
+ err_state_var = local_scope.find(@error_var_name).c_name
40
+ set_error_state_variable err_state_var, code, local_scope
41
+ set_unhandled_error_variable code, local_scope
42
+ generate_rescue_blocks err_state_var, code, local_scope
43
+ generate_else_block code, local_scope
44
+ generate_ensure_block code, local_scope
45
+ generate_rb_jump_tag err_state_var, code, local_scope
46
+ code << "rb_set_errinfo(Qnil);\n"
47
+ end
48
+
49
+ def declare_unhandled_error_variable(local_scope)
50
+ @unhandled_err_var_name = 'begin_block_' + local_scope.begin_block_counter.to_s + '_unhandled_error'
51
+ local_scope.declare_var(
52
+ name: @unhandled_err_var_name,
53
+ c_name: Rubex::VAR_PREFIX + @unhandled_err_var_name,
54
+ type: DataType::Int.new
55
+ )
56
+ end
57
+
58
+ def set_unhandled_error_variable(code, local_scope)
59
+ n = local_scope.find(@unhandled_err_var_name).c_name
60
+ code << "#{n} = 0;"
61
+ code.nl
62
+ end
63
+
64
+ def generate_rb_jump_tag(_err_state_var, code, local_scope)
65
+ state_var = local_scope.find(@state_var_name).c_name
66
+ code << "if (#{local_scope.find(@unhandled_err_var_name).c_name})"
67
+ code.block do
68
+ code << "rb_jump_tag(#{state_var});"
69
+ code.nl
70
+ end
71
+ end
72
+
73
+ def generate_ensure_block(code, local_scope)
74
+ ensure_block = @tails.select { |e| e.is_a?(Ensure) }[0]
75
+ ensure_block&.generate_code(code, local_scope)
76
+ end
77
+
78
+ # We use a goto statement to jump to the ensure block so that when a
79
+ # condition arises where no error is raised, the ensure statement will
80
+ # be executed, after which rb_jump_tag() will be called.
81
+ def generate_else_block(code, local_scope)
82
+ else_block = @tails.select { |t| t.is_a?(Else) }[0]
83
+
84
+ code << 'else'
85
+ code.block do
86
+ state_var = local_scope.find(@state_var_name).c_name
87
+ code << '/* If exception not among those captured in raise */'
88
+ code.nl
89
+
90
+ code << "if (#{state_var})"
91
+ code.block do
92
+ code << "#{local_scope.find(@unhandled_err_var_name).c_name} = 1;"
93
+ code.nl
94
+ end
95
+
96
+ if else_block
97
+ code << 'else'
98
+ code.block do
99
+ else_block.generate_code code, local_scope
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ def set_error_state_variable(err_state_var, code, _local_scope)
106
+ code << "#{err_state_var} = rb_errinfo();"
107
+ code.nl
108
+ end
109
+
110
+ def generate_rescue_blocks(err_state_var, code, local_scope)
111
+ if @tails[0].is_a?(Rescue)
112
+ generate_first_rescue_block err_state_var, code, local_scope
113
+
114
+ @tails[1..-1].grep(Rescue).each do |resc|
115
+ else_if_cond = rescue_condition err_state_var, resc, code, local_scope
116
+ code << "else if (#{else_if_cond})"
117
+ code.block do
118
+ resc.generate_code code, local_scope
119
+ end
120
+ end
121
+ else # no rescue blocks present
122
+ code << "if (0) {}\n"
123
+ end
124
+ end
125
+
126
+ def generate_first_rescue_block(err_state_var, code, local_scope)
127
+ code << "if (#{rescue_condition(err_state_var, @tails[0], code, local_scope)})"
128
+ code.block do
129
+ @tails[0].generate_code code, local_scope
130
+ end
131
+ end
132
+
133
+ def rescue_condition(err_state_var, resc, code, local_scope)
134
+ resc.error_klass.generate_evaluation_code code, local_scope
135
+ cond = "RTEST(rb_funcall(#{err_state_var}, rb_intern(\"kind_of?\")"
136
+ cond << ", 1, #{resc.error_klass.c_code(local_scope)}))"
137
+
138
+ cond
139
+ end
140
+
141
+ def declare_error_state_variable(local_scope)
142
+ @state_var_name = 'begin_block_' + local_scope.begin_block_counter.to_s + '_state'
143
+ local_scope.declare_var(
144
+ name: @state_var_name,
145
+ c_name: Rubex::VAR_PREFIX + @state_var_name,
146
+ type: DataType::Int.new
147
+ )
148
+ end
149
+
150
+ def declare_error_klass_variable(local_scope)
151
+ @error_var_name = 'begin_block_' + local_scope.begin_block_counter.to_s + '_exec'
152
+ local_scope.declare_var(
153
+ name: @error_var_name,
154
+ c_name: Rubex::VAR_PREFIX + @error_var_name,
155
+ type: DataType::RubyObject.new
156
+ )
157
+ end
158
+
159
+ def block_name(local_scope)
160
+ 'begin_block_' + local_scope.klass_name + '_' + local_scope.name + '_' +
161
+ local_scope.begin_block_counter.to_s
162
+ end
163
+
164
+ def create_c_function_to_house_statements(scope)
165
+ func_name = @block_scope.name
166
+ arg_list = Statement::ArgumentList.new([
167
+ AST::Expression::ArgDeclaration.new(
168
+ { dtype: 'object', variables: [{ ident: 'dummy' }] }
169
+ )
170
+ ])
171
+ @begin_func = TopStatement::CFunctionDef.new(
172
+ 'object', '', func_name, arg_list, @statements
173
+ )
174
+ arg_list.analyse_statement @block_scope
175
+ add_to_symbol_table @begin_func.name, arg_list, scope
176
+ @begin_func.analyse_statement @block_scope
177
+ @block_scope.upgrade_symbols_to_global
178
+ scope.add_begin_block_callback @begin_func
179
+ end
180
+
181
+ def add_to_symbol_table(func_name, arg_list, scope)
182
+ c_name = Rubex::C_FUNC_PREFIX + func_name
183
+ scope.add_c_method(
184
+ name: func_name,
185
+ c_name: c_name,
186
+ extern: false,
187
+ return_type: DataType::RubyObject.new,
188
+ arg_list: arg_list,
189
+ scope: @block_scope
190
+ )
191
+ end
192
+
193
+ def analyse_tails(local_scope)
194
+ @tails.each do |tail|
195
+ tail.analyse_statement local_scope
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,21 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ module BeginBlock
5
+ class Else < Base
6
+ def analyse_statement(local_scope)
7
+ @statements.each do |stmt|
8
+ stmt.analyse_statement local_scope
9
+ end
10
+ end
11
+
12
+ def generate_code(code, local_scope)
13
+ @statements.each do |stmt|
14
+ stmt.generate_code code, local_scope
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ module BeginBlock
5
+ class Ensure < Base
6
+ def analyse_statement(local_scope)
7
+ @statements.each do |stmt|
8
+ stmt.analyse_statement local_scope
9
+ end
10
+ end
11
+
12
+ def generate_code(code, local_scope)
13
+ @statements.each do |stmt|
14
+ stmt.generate_code code, local_scope
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ module BeginBlock
5
+ class Rescue < Base
6
+ attr_reader :error_klass
7
+
8
+ def initialize(error_klass, error_obj, statements, location)
9
+ super(statements, location)
10
+ @error_klass = error_klass
11
+ @error_obj = error_obj
12
+ end
13
+
14
+ def analyse_statement(local_scope)
15
+ @error_klass.analyse_types local_scope
16
+ unless @error_klass.type.ruby_constant?
17
+ raise "Must pass an error class to raise. Location #{@location}."
18
+ end
19
+
20
+ @statements.each do |stmt|
21
+ stmt.analyse_statement local_scope
22
+ end
23
+ end
24
+
25
+ def generate_code(code, local_scope)
26
+ @statements.each do |stmt|
27
+ stmt.generate_code code, local_scope
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class Break < Base
5
+ def analyse_statement(local_scope)
6
+ # TODO: figure whether this is a Ruby break or C break. For now
7
+ # assuming C break.
8
+ end
9
+
10
+ def generate_code(code, _local_scope)
11
+ code.write_location @location
12
+ code << 'break;'
13
+ code.nl
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end