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,15 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ class Self < Base
5
+ def c_code(local_scope)
6
+ local_scope.self_name
7
+ end
8
+
9
+ def type
10
+ Rubex::DataType::RubyObject.new
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ # C sizeof operator.
5
+ class SizeOf < Base
6
+ def initialize(type, ptr_level)
7
+ @type, @ptr_level = type, ptr_level
8
+ end
9
+
10
+ def analyse_types(local_scope)
11
+ @size_of_type = Helpers.determine_dtype @type, @ptr_level
12
+ @type = DataType::ULInt.new
13
+ super
14
+ end
15
+
16
+ def c_code(_local_scope)
17
+ "sizeof(#{@size_of_type})"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ class ElementRefMemberCall < StructOrUnionMemberCall
5
+ def analyse_types(local_scope, struct_scope)
6
+ @command.analyse_types local_scope, struct_scope
7
+ @type = @command.type
8
+ @has_temp = @command.has_temp
9
+ @subexprs = [@command]
10
+ end
11
+
12
+ def generate_evaluation_code(code, local_scope)
13
+ @command.generate_element_ref_code @expr, code, local_scope
14
+ @c_code = @command.c_code(local_scope)
15
+ end
16
+
17
+ def c_code(local_scope)
18
+ @c_code
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ # internal node for converting to ruby object.
5
+ class ToRubyObject < CoerceObject
6
+ attr_reader :type
7
+
8
+ def initialize(expr)
9
+ @expr = expr
10
+ @type = Rubex::DataType::RubyObject.new
11
+ end
12
+
13
+ def c_code(local_scope)
14
+ t = @expr.type
15
+ t = t.c_function? || t.alias_type? ? t.type : t
16
+ t.to_ruby_object(@expr.c_code(local_scope)).to_s
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ class Typecast < Base
5
+ def initialize(dtype, ptr_level)
6
+ @dtype = dtype
7
+ @ptr_level = ptr_level
8
+ end
9
+
10
+ def analyse_types(_local_scope)
11
+ @type = Rubex::Helpers.determine_dtype @dtype, @ptr_level
12
+ end
13
+
14
+ def c_code(_local_scope)
15
+ "(#{@type})"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ # Internal class to typecast from a C type to another C type.
5
+ class TypecastTo < CoerceObject
6
+ def initialize(dtype); end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ require_relative 'unary_base'
2
+ Dir['./lib/rubex/ast/expression/unary_base/*.rb'].each { |f| require f }
3
+ module Rubex
4
+ module AST
5
+ module Expression
6
+ class Unary < Base
7
+ OP_CLASS_MAP = {
8
+ '&' => Rubex::AST::Expression::Ampersand,
9
+ '-' => Rubex::AST::Expression::UnarySub,
10
+ '!' => Rubex::AST::Expression::UnaryNot,
11
+ '~' => Rubex::AST::Expression::UnaryBitNot
12
+ }.freeze
13
+
14
+ def initialize(operator, expr)
15
+ @operator = operator
16
+ @expr = expr
17
+ end
18
+
19
+ def analyse_types(local_scope)
20
+ @expr = OP_CLASS_MAP[@operator].new(@expr)
21
+ @expr.analyse_types local_scope
22
+ @type = @expr.type
23
+ super
24
+ end
25
+
26
+ def generate_evaluation_code(code, local_scope)
27
+ @expr.generate_evaluation_code code, local_scope
28
+ end
29
+
30
+ def c_code(local_scope)
31
+ code = super
32
+ code << @expr.c_code(local_scope)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+
5
+ class UnaryBase < Base
6
+ def initialize expr
7
+ @expr = expr
8
+ end
9
+
10
+ def analyse_types local_scope
11
+ @expr.analyse_types local_scope
12
+ @expr = @expr.to_ruby_object if @expr.type.object?
13
+ @type = @expr.type
14
+ @expr.allocate_temps local_scope
15
+ @expr.release_temps local_scope
16
+ end
17
+
18
+ def generate_evaluation_code code, local_scope
19
+ @expr.generate_evaluation_code code, local_scope
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ class Ampersand < UnaryBase
5
+ def analyse_types(local_scope)
6
+ @expr.analyse_types local_scope
7
+ @type = DataType::CPtr.new @expr.type
8
+ end
9
+
10
+ def c_code(local_scope)
11
+ "&#{@expr.c_code(local_scope)}"
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ class UnaryBitNot < UnaryBase
5
+ attr_reader :type
6
+
7
+ def c_code(local_scope)
8
+ code = @expr.c_code(local_scope)
9
+ if @type.object?
10
+ "rb_funcall(#{code}, rb_intern(\"~\"), 0)"
11
+ else
12
+ "~#{code}"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ class UnaryNot < UnaryBase
5
+ attr_reader :type
6
+
7
+ def c_code(local_scope)
8
+ code = @expr.c_code(local_scope)
9
+ if @type.object?
10
+ "rb_funcall(#{code}, rb_intern(\"!\"), 0)"
11
+ else
12
+ "!#{code}"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Rubex
2
+ module AST
3
+ module Expression
4
+ class UnarySub < UnaryBase
5
+ attr_reader :type
6
+
7
+ def c_code(local_scope)
8
+ code = @expr.c_code(local_scope)
9
+ if @type.object?
10
+ "rb_funcall(#{code}, rb_intern(\"-\"), 0)"
11
+ else
12
+ "-#{code}"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,15 +1,16 @@
1
+ require 'rubex/helpers'
1
2
  module Rubex
2
3
  module AST
3
4
  class Node
4
5
  include Rubex::Helpers::Writers
5
6
  attr_reader :statements
6
7
 
7
- def initialize statements
8
+ def initialize(statements)
8
9
  @statements = statements.flatten
9
10
  end
10
11
 
11
- def process_statements target_name, code
12
- @scope = Rubex::SymbolTable::Scope::Klass.new 'Object', nil
12
+ def process_statements(target_name, code)
13
+ @scope = Rubex::SymbolTable::Scope::Klass.new('Object', nil)
13
14
  add_top_statements_to_object_scope
14
15
  analyse_statement
15
16
  rescan_declarations @scope
@@ -18,11 +19,11 @@ module Rubex
18
19
  generate_init_method target_name, code
19
20
  end
20
21
 
21
- def == other
22
+ def ==(other)
22
23
  self.class == other.class
23
24
  end
24
25
 
25
- private
26
+ private
26
27
 
27
28
  # Scan all the statements that do not belong to any particular class
28
29
  # (meaning that they belong to Object) and add them to the Object class,
@@ -32,7 +33,7 @@ module Rubex
32
33
  combined_statements = []
33
34
  @statements.each do |stmt|
34
35
  if stmt.is_a?(TopStatement::Klass) || stmt.is_a?(TopStatement::CBindings)
35
- if !temp.empty?
36
+ unless temp.empty?
36
37
  object_klass = TopStatement::Klass.new('Object', @scope, temp)
37
38
  combined_statements << object_klass
38
39
  end
@@ -44,23 +45,24 @@ module Rubex
44
45
  end
45
46
  end
46
47
 
47
- if !temp.empty?
48
+ unless temp.empty?
48
49
  combined_statements << TopStatement::Klass.new('Object', @scope, temp)
49
50
  end
50
51
 
51
52
  @statements = combined_statements
52
53
  end
53
54
 
54
- def generate_preamble code
55
+ def generate_preamble(code)
55
56
  code << "#include <ruby.h>\n"
56
57
  code << "#include <stdint.h>\n"
57
58
  code << "#include <stdbool.h>\n"
58
59
  @scope.include_files.each do |name|
59
- if name[0] == '<' && name[-1] == '>'
60
- code << "#include #{name}\n"
61
- else
62
- code << "#include \"#{name}\"\n"
63
- end
60
+ code <<
61
+ if name[0] == '<' && name[-1] == '>'
62
+ "#include #{name}\n"
63
+ else
64
+ "#include \"#{name}\"\n"
65
+ end
64
66
  end
65
67
  write_usability_macros code
66
68
  @statements.grep(Rubex::AST::TopStatement::Klass).each do |klass|
@@ -73,41 +75,41 @@ module Rubex
73
75
  code.nl
74
76
  end
75
77
 
76
- def write_global_variable_declarations code
78
+ def write_global_variable_declarations(code)
77
79
  @statements.each do |stmt|
78
- if stmt.is_a?(TopStatement::Klass)
79
- stmt.statements.each do |s|
80
- if s.is_a?(TopStatement::MethodDef)
81
- s.scope.global_entries.each do |g|
82
- code << "static #{g.type} #{g.c_name};"
83
- code.nl
84
- end # .each
85
- end # if
86
- end # .each
87
- end # if
88
- end # .each
80
+ next unless stmt.is_a?(TopStatement::Klass)
81
+ stmt.statements.each do |s|
82
+ next unless s.is_a?(TopStatement::MethodDef)
83
+ s.scope.global_entries.each do |g|
84
+ code << "static #{g.type} #{g.c_name};"
85
+ code.nl
86
+ end
87
+ end
88
+ end
89
89
  end
90
90
 
91
- def write_user_klasses code
91
+ def write_user_klasses(code)
92
92
  code.nl
93
93
  @scope.ruby_class_entries.each do |klass|
94
- code << "VALUE #{klass.c_name};"
95
- code.nl
94
+ unless Rubex::DEFAULT_CLASS_MAPPINGS.has_key?(klass.name)
95
+ code << "VALUE #{klass.c_name};"
96
+ code.nl
97
+ end
96
98
  end
97
99
  end
98
100
 
99
- def write_usability_macros code
101
+ def write_usability_macros(code)
100
102
  code.nl
101
- code.c_macro Rubex::RUBEX_PREFIX + "INT2BOOL(arg) (arg ? Qtrue : Qfalse)"
103
+ code.c_macro Rubex::RUBEX_PREFIX + 'INT2BOOL(arg) (arg ? Qtrue : Qfalse)'
102
104
  code.nl
103
105
  end
104
106
 
105
- def write_usability_functions code
107
+ def write_usability_functions(code)
106
108
  code.nl
107
109
  write_char_2_ruby_str code
108
110
  end
109
111
 
110
- def write_char_2_ruby_str code
112
+ def write_char_2_ruby_str(code)
111
113
  code << "VALUE #{Rubex::C_FUNC_CHAR2RUBYSTR}(char ch);"
112
114
  code.nl
113
115
  code << "VALUE #{Rubex::C_FUNC_CHAR2RUBYSTR}(char ch)"
@@ -116,27 +118,27 @@ module Rubex
116
118
  code << "s[0] = ch;\n"
117
119
  code << "s[1] = '\\0';\n"
118
120
  code << "return rb_str_new2(s);\n"
119
- end
121
+ end
120
122
  end
121
123
 
122
- def write_function_declarations code
124
+ def write_function_declarations(code)
123
125
  @statements.each do |stmt|
124
- if stmt.is_a?(Rubex::AST::TopStatement::Klass)
125
- stmt.scope.ruby_method_entries.each do |entry|
126
- code.write_ruby_method_header(
127
- type: entry.type.type.to_s, c_name: entry.c_name)
128
- code.colon
129
- end
126
+ next unless stmt.is_a?(Rubex::AST::TopStatement::Klass)
127
+ stmt.scope.ruby_method_entries.each do |entry|
128
+ code.write_ruby_method_header(
129
+ type: entry.type.type.to_s, c_name: entry.c_name
130
+ )
131
+ code.colon
132
+ end
130
133
 
131
- stmt.scope.c_method_entries.each do |entry|
132
- if !entry.extern?
133
- code.write_c_method_header(
134
- type: entry.type.type.to_s,
135
- c_name: entry.c_name,
136
- args: Helpers.create_arg_arrays(entry.type.arg_list))
137
- code.colon
138
- end
139
- end
134
+ stmt.scope.c_method_entries.each do |entry|
135
+ next if entry.extern?
136
+ code.write_c_method_header(
137
+ type: entry.type.type.to_s,
138
+ c_name: entry.c_name,
139
+ args: Helpers.create_arg_arrays(entry.type.arg_list)
140
+ )
141
+ code.colon
140
142
  end
141
143
  end
142
144
  end
@@ -150,76 +152,76 @@ module Rubex
150
152
 
151
153
  def create_symtab_entries_for_top_statements
152
154
  @statements.each do |stat|
153
- if stat.is_a? Rubex::AST::TopStatement::Klass
154
- name = stat.name
155
- # The top level scope in Ruby is Object. The Object class's immediate
156
- # ancestor is also Object. Hence, it is important to set the class
157
- # scope and ancestor scope of Object as Object, and make sure that
158
- # the same scope object is used for 'Object' class every single time
159
- # throughout the compilation process.
160
- if name != 'Object'
161
- ancestor_entry = @scope.find(stat.ancestor)
162
- if !ancestor_entry && Rubex::DEFAULT_CLASS_MAPPINGS[stat.ancestor]
163
- ancestor_c_name = Rubex::DEFAULT_CLASS_MAPPINGS[stat.ancestor]
164
- ancestor_scope = object_or_stdlib_klass_scope stat.ancestor
165
- @scope.add_ruby_class(name: stat.ancestor, c_name: ancestor_c_name,
166
- scope: @scope, ancestor: nil, extern: true)
167
- else
168
- ancestor_scope = ancestor_entry&.type&.scope || @scope
169
- end
170
- klass_scope = Rubex::SymbolTable::Scope::Klass.new(
171
- name, ancestor_scope)
155
+ next unless stat.is_a? Rubex::AST::TopStatement::Klass
156
+ name = stat.name
157
+ # The top level scope in Ruby is Object. The Object class's immediate
158
+ # ancestor is also Object. Hence, it is important to set the class
159
+ # scope and ancestor scope of Object as Object, and make sure that
160
+ # the same scope object is used for 'Object' class every single time
161
+ # throughout the compilation process.
162
+ if name != 'Object'
163
+ ancestor_entry = @scope.find(stat.ancestor)
164
+ if !ancestor_entry && Rubex::DEFAULT_CLASS_MAPPINGS[stat.ancestor]
165
+ ancestor_c_name = Rubex::DEFAULT_CLASS_MAPPINGS[stat.ancestor]
166
+ ancestor_scope = object_or_stdlib_klass_scope stat.ancestor
167
+ @scope.add_ruby_class(name: stat.ancestor, c_name: ancestor_c_name,
168
+ scope: @scope, ancestor: nil, extern: true)
172
169
  else
173
- ancestor_scope = @scope
174
- klass_scope = @scope
170
+ ancestor_scope = ancestor_entry&.type&.scope || @scope
175
171
  end
176
- c_name = c_name_for_class name
177
-
178
- @scope.add_ruby_class(name: name, c_name: c_name, scope: klass_scope,
179
- ancestor: ancestor_scope, extern: false)
172
+ klass_scope = Rubex::SymbolTable::Scope::Klass.new(
173
+ name, ancestor_scope
174
+ )
175
+ else
176
+ ancestor_scope = @scope
177
+ klass_scope = @scope
180
178
  end
179
+ c_name = c_name_for_class name
180
+
181
+ @scope.add_ruby_class(name: name, c_name: c_name, scope: klass_scope,
182
+ ancestor: ancestor_scope, extern: false)
181
183
  end
182
184
  end
183
185
 
184
- def object_or_stdlib_klass_scope name
185
- name != 'Object' ? Rubex::SymbolTable::Scope::Klass.new(name, nil) :
186
+ def object_or_stdlib_klass_scope(name)
187
+ name != 'Object' ? Rubex::SymbolTable::Scope::Klass.new(name, nil) :
186
188
  @scope
187
189
  end
188
190
 
189
- def c_name_for_class name
191
+ def c_name_for_class(name)
190
192
  c_name =
191
- if Rubex::DEFAULT_CLASS_MAPPINGS.has_key? name
192
- Rubex::DEFAULT_CLASS_MAPPINGS[name]
193
- else
194
- Rubex::RUBY_CLASS_PREFIX + name
195
- end
193
+ if Rubex::DEFAULT_CLASS_MAPPINGS.key? name
194
+ Rubex::DEFAULT_CLASS_MAPPINGS[name]
195
+ else
196
+ Rubex::RUBY_CLASS_PREFIX + name
197
+ end
196
198
 
197
199
  c_name
198
200
  end
199
201
 
200
- def rescan_declarations scope
202
+ def rescan_declarations(_scope)
201
203
  @statements.each do |stat|
202
- stat.respond_to?(:rescan_declarations) and
204
+ stat.respond_to?(:rescan_declarations) &&
203
205
  stat.rescan_declarations(@scope)
204
206
  end
205
207
  end
206
208
 
207
- def generate_code code
209
+ def generate_code(code)
208
210
  @statements.each do |stat|
209
211
  stat.generate_code code
210
212
  end
211
213
  end
212
214
 
213
- def generate_init_method target_name, code
215
+ def generate_init_method(target_name, code)
214
216
  name = "Init_#{target_name}"
215
217
  code.new_line
216
- code.write_func_declaration type: "void", c_name: name, args: [], static: false
217
- code.write_c_method_header type: "void", c_name: name, args: [], static: false
218
+ code.write_func_declaration type: 'void', c_name: name, args: [], static: false
219
+ code.write_c_method_header type: 'void', c_name: name, args: [], static: false
218
220
  code.block do
219
221
  @statements.each do |top_stmt|
220
222
  if top_stmt.is_a?(TopStatement::Klass) && top_stmt.name != 'Object'
221
223
  entry = @scope.find top_stmt.name
222
- code.declare_variable type: "VALUE", c_name: entry.c_name
224
+ code.declare_variable type: 'VALUE', c_name: entry.c_name
223
225
  end
224
226
  end
225
227
  code.nl
@@ -235,35 +237,33 @@ module Rubex
235
237
  end
236
238
 
237
239
  # specify allocation method in case of attached class
238
- if top_stmt.is_a?(TopStatement::AttachedKlass)
239
- entry = top_stmt.entry
240
- scope = top_stmt.scope
241
- alloc = ""
242
- alloc << "rb_define_alloc_func(#{entry.c_name}, "
243
- alloc << "#{scope.find(TopStatement::AttachedKlass::ALLOC_FUNC_NAME).c_name});\n"
240
+ next unless top_stmt.is_a?(TopStatement::AttachedKlass)
241
+ entry = top_stmt.entry
242
+ scope = top_stmt.scope
243
+ alloc = ''
244
+ alloc << "rb_define_alloc_func(#{entry.c_name}, "
245
+ alloc << "#{scope.find(TopStatement::AttachedKlass::ALLOC_FUNC_NAME).c_name});\n"
244
246
 
245
- code << alloc
246
- end
247
+ code << alloc
247
248
  end
248
249
  code.nl
249
250
 
250
251
  @statements.each do |top_stmt|
251
- if top_stmt.is_a? TopStatement::Klass
252
- entry = @scope.find top_stmt.name
253
- klass_scope = entry.type.scope
254
- klass_scope.ruby_method_entries.each do |meth|
255
- if meth.singleton?
256
- code.write_singleton_method klass: entry.c_name,
257
- method_name: meth.name, method_c_name: meth.c_name
258
- else
259
- code.write_instance_method klass: entry.c_name,
260
- method_name: meth.name, method_c_name: meth.c_name
261
- end
252
+ next unless top_stmt.is_a? TopStatement::Klass
253
+ entry = @scope.find top_stmt.name
254
+ klass_scope = entry.type.scope
255
+ klass_scope.ruby_method_entries.each do |meth|
256
+ if meth.singleton?
257
+ code.write_singleton_method klass: entry.c_name,
258
+ method_name: meth.name, method_c_name: meth.c_name
259
+ else
260
+ code.write_instance_method klass: entry.c_name,
261
+ method_name: meth.name, method_c_name: meth.c_name
262
262
  end
263
263
  end
264
264
  end
265
265
  end
266
266
  end
267
- end # class Node
268
- end # module AST
269
- end # module Rubex
267
+ end
268
+ end
269
+ end