rubex 0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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