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,49 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class CArrayDecl < Base
5
+ attr_reader :type, :array_list, :name, :dimension
6
+
7
+ def initialize(type, array_ref, array_list, location)
8
+ super(location)
9
+ @name = array_ref.name
10
+ @array_list = array_list
11
+ @dimension = array_ref.pos
12
+ @type = Rubex::TYPE_MAPPINGS[type].new
13
+ end
14
+
15
+ def analyse_statement(local_scope, extern: false)
16
+ @dimension.analyse_types local_scope
17
+ create_symbol_table_entry local_scope
18
+ return if @array_list.nil?
19
+ analyse_array_list local_scope
20
+ verify_array_list_types local_scope
21
+ end
22
+
23
+ def generate_code(code, local_scope); end
24
+
25
+ def rescan_declarations(local_scope); end
26
+
27
+ private
28
+
29
+ def analyse_array_list(local_scope)
30
+ @array_list.each do |expr|
31
+ expr.analyse_types(local_scope)
32
+ end
33
+ end
34
+
35
+ def verify_array_list_types(_local_scope)
36
+ @array_list.all? do |expr|
37
+ return true if @type >= expr.type
38
+ raise "Specified type #{@type} but list contains #{expr.type}."
39
+ end
40
+ end
41
+
42
+ def create_symbol_table_entry(local_scope)
43
+ local_scope.add_carray(name: @name, c_name: Rubex::ARRAY_PREFIX + @name,
44
+ dimension: @dimension, type: @type, value: @array_list)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,26 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class CBaseType < Base
5
+ attr_reader :type, :name, :value
6
+
7
+ def initialize(type, name, value = nil)
8
+ @type = type
9
+ @name = name
10
+ @value = value
11
+ end
12
+
13
+ def ==(other)
14
+ self.class == other.class &&
15
+ type == other.class &&
16
+ name == other.name &&
17
+ value == other.value
18
+ end
19
+
20
+ def analyse_statement(_local_scope)
21
+ @type = Rubex::Helpers.determine_dtype @type
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class CFunctionDecl < Base
5
+ def initialize(type, return_ptr_level, name, arg_list)
6
+ @type, @return_ptr_level, @name, @arg_list = type, return_ptr_level,
7
+ name, arg_list
8
+ end
9
+
10
+ def analyse_statement(local_scope, extern: false)
11
+ @arg_list&.analyse_statement(local_scope, extern: extern)
12
+ c_name = extern ? @name : (Rubex::C_FUNC_PREFIX + @name)
13
+ @entry = local_scope.add_c_method(
14
+ name: @name,
15
+ c_name: c_name,
16
+ return_type: Helpers.determine_dtype(@type, @return_ptr_level),
17
+ arg_list: @arg_list,
18
+ scope: nil,
19
+ extern: extern
20
+ )
21
+ end
22
+
23
+ def generate_code(code, local_scope)
24
+ super
25
+ code << "/* C function #{@name} declared.*/" if @entry.extern?
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,52 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class CPtrDecl < Base
5
+ attr_reader :entry, :type
6
+
7
+ def initialize(type, name, value, ptr_level, location)
8
+ super(location)
9
+ @name = name
10
+ @type = type
11
+ @value = value
12
+ @ptr_level = ptr_level
13
+ end
14
+
15
+ def analyse_statement(local_scope, extern: false)
16
+ cptr_cname extern
17
+ @type = Helpers.determine_dtype @type, @ptr_level
18
+ if @value
19
+ @value.analyse_for_target_type(@type, local_scope)
20
+ @value = Helpers.to_lhs_type(self, @value)
21
+ end
22
+
23
+ @entry = local_scope.declare_var name: @name, c_name: @c_name,
24
+ type: @type, value: @value, extern: extern
25
+ end
26
+
27
+ def rescan_declarations(local_scope)
28
+ base_type = @entry.type.base_type
29
+ if base_type.is_a? String
30
+ type = Helpers.determine_dtype base_type, @ptr_level
31
+ local_scope[@name].type = type
32
+ end
33
+ end
34
+
35
+ def generate_code(code, local_scope)
36
+ if @value
37
+ @value.generate_evaluation_code code, local_scope
38
+ code << "#{local_scope.find(@name).c_name} = #{@value.c_code(local_scope)};"
39
+ code.nl
40
+ @value.generate_disposal_code code
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def cptr_cname(extern)
47
+ @c_name = extern ? @name : Rubex::POINTER_PREFIX + @name
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,25 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class CPtrFuncDecl < CPtrDecl
5
+ def initialize(type, name, value, ptr_level, location)
6
+ super
7
+ end
8
+
9
+ def analyse_statement(local_scope, extern: false)
10
+ cptr_cname extern
11
+ ident = @type[:ident]
12
+ ident[:arg_list].analyse_statement(local_scope)
13
+ @type = DataType::CFunction.new(
14
+ @name,
15
+ @c_name,
16
+ ident[:arg_list],
17
+ Helpers.determine_dtype(@type[:dtype], ident[:return_ptr_level]),
18
+ nil
19
+ )
20
+ super
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,49 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class CStructOrUnionDef < Base
5
+ attr_reader :name, :declarations, :type, :kind, :entry, :scope
6
+
7
+ def initialize(kind, name, declarations, location)
8
+ super(location)
9
+ @declarations = declarations
10
+ if /struct/.match kind
11
+ @kind = :struct
12
+ elsif /union/.match kind
13
+ @kind = :union
14
+ end
15
+ @name = name
16
+ end
17
+
18
+ def analyse_statement(outer_scope, extern: false)
19
+ @scope = Rubex::SymbolTable::Scope::StructOrUnion.new(
20
+ @name, outer_scope
21
+ )
22
+ c_name = if extern
23
+ @kind.to_s + " " + @name
24
+ else
25
+ Rubex::TYPE_PREFIX + @scope.klass_name + "_" + @name
26
+ end
27
+ @type = Rubex::DataType::CStructOrUnion.new(@kind, @name, c_name,
28
+ @scope)
29
+
30
+ @declarations.each do |decl|
31
+ decl.analyse_statement @scope, extern: extern
32
+ end
33
+ Rubex::CUSTOM_TYPES[@name] = @type
34
+ @entry = outer_scope.declare_sue(name: @name, c_name: c_name,
35
+ type: @type, extern: extern)
36
+ end
37
+
38
+ def generate_code(code, local_scope = nil); end
39
+
40
+ def rescan_declarations(_local_scope)
41
+ @declarations.each do |decl|
42
+ decl.respond_to?(:rescan_declarations) &&
43
+ decl.rescan_declarations(@scope)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,26 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class Expression < Base
5
+ def initialize(expr, location)
6
+ super(location)
7
+ @expr = expr
8
+ end
9
+
10
+ def analyse_statement(local_scope)
11
+ @expr.analyse_types local_scope
12
+ @expr.allocate_temps local_scope
13
+ @expr.release_temps local_scope
14
+ end
15
+
16
+ def generate_code(code, local_scope)
17
+ super
18
+ @expr.generate_evaluation_code code, local_scope
19
+ code << @expr.c_code(local_scope) + ';'
20
+ code.nl
21
+ @expr.generate_disposal_code code
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,73 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class For < Base
5
+ def initialize(left_expr, left_op, middle, right_op, right_expr, statements, location)
6
+ super(location)
7
+ @left_expr = left_expr
8
+ @left_op = left_op
9
+ @middle = middle
10
+ @right_op = right_op
11
+ @right_expr = right_expr
12
+ @statements = statements
13
+ end
14
+
15
+ def analyse_statement(local_scope)
16
+ @left_expr.analyse_types local_scope
17
+ @right_expr.analyse_types local_scope
18
+
19
+ [@left_expr, @right_expr].each do |e|
20
+ e.allocate_temps local_scope
21
+ end
22
+ [@left_expr, @right_expr].each do |e|
23
+ e.release_temps local_scope
24
+ end
25
+
26
+ @middle = local_scope[@middle] # middle will not be an expr.
27
+ @statements.each do |stat|
28
+ stat.analyse_statement local_scope
29
+ end
30
+ end
31
+
32
+ def generate_code(code, local_scope)
33
+ code << for_loop_header(code, local_scope)
34
+ code.block do
35
+ @statements.each do |stat|
36
+ stat.generate_code code, local_scope
37
+ end
38
+ end
39
+ @left_expr.generate_disposal_code code
40
+ @right_expr.generate_disposal_code code
41
+ end
42
+
43
+ private
44
+
45
+ def for_loop_header(code, local_scope)
46
+ @left_expr.generate_evaluation_code code, local_scope
47
+ @right_expr.generate_evaluation_code code, local_scope
48
+ for_stmt = ''
49
+ for_stmt << "for (#{@middle.c_name} = #{@left_expr.c_code(local_scope)}"
50
+
51
+ if @left_op == '<'
52
+ for_stmt << ' + 1'
53
+ elsif @left_op == '>'
54
+ for_stmt << ' - 1'
55
+ end
56
+
57
+ for_stmt << "; #{@middle.c_name} #{@right_op} #{@right_expr.c_code(local_scope)}; "
58
+ for_stmt << (@middle.c_name).to_s
59
+
60
+ if ['>', '>='].include? @right_op
61
+ for_stmt << '--'
62
+ elsif ['<', '<='].include? @right_op
63
+ for_stmt << '++'
64
+ end
65
+
66
+ for_stmt << ')'
67
+
68
+ for_stmt
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,31 @@
1
+ module Rubex
2
+ module AST
3
+ module Statement
4
+ class ForwardDecl < Base
5
+ def initialize(kind, name, location)
6
+ super(location)
7
+ @name = name
8
+ if /struct/.match kind
9
+ @kind = :struct
10
+ elsif /union/.match kind
11
+ @kind = :union
12
+ end
13
+ Rubex::CUSTOM_TYPES[@name] = @name
14
+ end
15
+
16
+ def analyse_statement(local_scope, extern: false)
17
+ @c_name = Rubex::TYPE_PREFIX + local_scope.klass_name + '_' + @name
18
+ @type = Rubex::DataType::TypeDef.new("#{@kind} #{@name}", @c_name, @type)
19
+ local_scope.declare_type type: @type, extern: extern
20
+ end
21
+
22
+ def rescan_declarations(_local_scope)
23
+ @type = Rubex::DataType::TypeDef.new("#{@kind} #{@name}", @c_name,
24
+ Rubex::CUSTOM_TYPES[@name])
25
+ end
26
+
27
+ def generate_code(code, local_scope); end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,64 @@
1
+ require_relative 'if_block/helper'
2
+ module Rubex
3
+ module AST
4
+ module Statement
5
+ class IfBlock < Base
6
+ attr_reader :expr, :statements, :if_tail
7
+ include Rubex::AST::Statement::IfBlock::Helper
8
+
9
+ def initialize(expr, statements, if_tail, location)
10
+ super(location)
11
+ @expr = expr
12
+ @statements = statements
13
+ @if_tail = if_tail
14
+ end
15
+
16
+ def analyse_statement(local_scope)
17
+ @tail_exprs = if_tail_exprs # FIME: gets current expr too. make descriptive.
18
+ @tail_exprs.each do |tail|
19
+ tail.analyse_types local_scope
20
+ tail.allocate_temps local_scope
21
+ end
22
+
23
+ @tail_exprs.each do |tail|
24
+ tail.release_temps local_scope
25
+ end
26
+ super
27
+ end
28
+
29
+ def if_tail_exprs
30
+ tail_exprs = []
31
+ temp = self
32
+ while temp.respond_to?(:if_tail) &&
33
+ !temp.is_a?(Rubex::AST::Statement::IfBlock::Else)
34
+ tail_exprs << temp.expr
35
+ temp = temp.if_tail
36
+ end
37
+
38
+ tail_exprs
39
+ end
40
+
41
+ def generate_code(code, local_scope)
42
+ @tail_exprs.each do |tail|
43
+ tail.generate_evaluation_code(code, local_scope)
44
+ end
45
+ generate_code_for_statement 'if', code, local_scope, self
46
+
47
+ tail = @if_tail
48
+ while tail
49
+ if tail.is_a?(Elsif)
50
+ generate_code_for_statement 'else if', code, local_scope, tail
51
+ elsif tail.is_a?(Else)
52
+ generate_code_for_statement 'else', code, local_scope, tail
53
+ end
54
+ tail = tail.if_tail
55
+ end
56
+
57
+ @tail_exprs.each do |tail|
58
+ tail.generate_disposal_code code
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'helper'
2
+ module Rubex
3
+ module AST
4
+ module Statement
5
+ class IfBlock < Base
6
+ class Else < Base
7
+ attr_reader :statements
8
+ include Rubex::AST::Statement::IfBlock::Helper
9
+
10
+ def initialize(statements, location)
11
+ super(location)
12
+ @statements = statements
13
+ end
14
+
15
+ def analyse_statement(local_scope)
16
+ @statements.each do |stat|
17
+ stat.analyse_statement local_scope
18
+ end
19
+ end
20
+
21
+ def generate_code(code, local_scope); end
22
+
23
+ def if_tail
24
+ nil
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end