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,10 @@
1
+ module Rubex
2
+ module DataType
3
+ class Size_t < ULInt
4
+ def to_s
5
+ 'size_t'
6
+ end
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,26 @@
1
+ module Rubex
2
+ module DataType
3
+ class ULLInt
4
+ include UIntHelpers
5
+ def to_s
6
+ 'unsigned long long int'
7
+ end
8
+
9
+ def to_ruby_object(arg)
10
+ "ULL2NUM(#{arg})"
11
+ end
12
+
13
+ def from_ruby_object(arg)
14
+ "NUM2ULL(#{arg})"
15
+ end
16
+
17
+ def ullint?
18
+ true
19
+ end
20
+
21
+ def p_formatter
22
+ '%llu'
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module Rubex
2
+ module DataType
3
+ class Void
4
+ include Helpers
5
+
6
+ def void?
7
+ true
8
+ end
9
+
10
+ def to_s
11
+ 'void'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ module Rubex
2
+ module DataType
3
+ module FloatHelpers
4
+ include Helpers
5
+ end
6
+
7
+ end
8
+ end
@@ -0,0 +1,48 @@
1
+ module Rubex
2
+ module DataType
3
+ # Citations
4
+ # Printf arguments:
5
+ # http://www.thinkage.ca/english/gcos/expl/c/lib/printf.html
6
+ module Helpers
7
+ include ::Comparable
8
+ %i[
9
+ float? float32? float64?
10
+ int? int8? int16? int32? int64?
11
+ uint? uint8? uint16? uint32? uint64?
12
+ lint? ulint? llint? ullint?
13
+ char? object? bool? carray? cbool?
14
+ cptr? nil_type? struct_or_union?
15
+ alias_type? string? cstr? ruby_class?
16
+ ruby_method? c_function? ruby_constant? void?
17
+ ruby_string? uchar? ruby_array? ruby_hash?
18
+ ].each do |dtype|
19
+ define_method(dtype) { return false }
20
+ end
21
+
22
+ def ==(other)
23
+ self.class == other.class
24
+ end
25
+
26
+ def to_ruby_object(arg)
27
+ arg
28
+ end
29
+
30
+ def from_ruby_object(arg)
31
+ arg
32
+ end
33
+
34
+ def base_type
35
+ self
36
+ end
37
+
38
+ # Helper function to know if a dtype is a char pointer.
39
+ def char_ptr?
40
+ cptr? && base_type.char?
41
+ end
42
+
43
+ def c_function_ptr?
44
+ cptr? && base_type.c_function?
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,10 @@
1
+ module Rubex
2
+ module DataType
3
+ module IntHelpers
4
+ include Helpers
5
+ def to_ruby_object(arg)
6
+ "INT2NUM(#{arg})"
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module Rubex
2
+ module DataType
3
+ module UIntHelpers
4
+ include Helpers
5
+ def to_ruby_object(arg)
6
+ "UINT2NUM(#{arg})"
7
+ end
8
+ end
9
+
10
+ end
11
+ end
@@ -1,154 +1,71 @@
1
+ require 'rubex/ast'
2
+ require_relative 'helpers/writers'
3
+ require_relative 'helpers/node_type_methods'
4
+
1
5
  module Rubex
2
6
  module Helpers
3
7
  class << self
4
- def to_lhs_type lhs, rhs
8
+ def construct_function_argument(data)
9
+ if data[:variables][0][:ident].is_a?(Hash)
10
+ Rubex::AST::Expression::FuncPtrArgDeclaration.new(data)
11
+ else
12
+ Rubex::AST::Expression::ArgDeclaration.new(data)
13
+ end
14
+ end
15
+
16
+ def to_lhs_type(lhs, rhs)
5
17
  if lhs.type.object?
6
- return rhs.to_ruby_object
18
+ rhs.to_ruby_object
7
19
  elsif !lhs.type.object? && rhs.type.object?
8
- return rhs.from_ruby_object(lhs)
20
+ rhs.from_ruby_object(lhs)
9
21
  else
10
- return rhs
11
- end
22
+ rhs
23
+ end
12
24
  end
13
25
 
14
- def result_type_for left, right
15
- begin
16
- return left.dup if left == right
17
- return (left < right ? right.dup : left.dup)
18
- rescue ArgumentError => e
19
- raise Rubex::TypeError, e.to_s
20
- end
26
+ def result_type_for(left, right)
27
+ return left.dup if left == right
28
+
29
+ (left < right ? right.dup : left.dup)
30
+ rescue ArgumentError => e
31
+ raise Rubex::TypeError, e.to_s
21
32
  end
22
33
 
23
- def determine_dtype data, ptr_level
24
- if ptr_level && ptr_level[-1] == "*"
34
+ def determine_dtype(data, ptr_level)
35
+ if ptr_level && ptr_level[-1] == '*'
25
36
  ptr_level = ptr_level.dup
26
37
  base_type = Rubex::DataType::CPtr.new simple_dtype(data)
27
38
  ptr_level.chop!
28
39
 
29
- ptr_level.each_char do |star|
40
+ ptr_level.each_char do |_star|
30
41
  base_type = Rubex::DataType::CPtr.new base_type
31
42
  end
32
43
 
33
- return base_type
44
+ base_type
34
45
  else
35
- return simple_dtype(data)
46
+ simple_dtype(data)
36
47
  end
37
48
  end
38
49
 
39
- def simple_dtype dtype
50
+ def simple_dtype(dtype)
40
51
  if dtype.is_a?(Rubex::DataType::CFunction)
41
52
  dtype
42
53
  else
43
54
  begin
44
- Rubex::CUSTOM_TYPES[dtype] || Rubex::TYPE_MAPPINGS[dtype].new
45
- rescue
55
+ Rubex::CUSTOM_TYPES[dtype] || Rubex::TYPE_MAPPINGS[dtype].new
56
+ rescue StandardError
46
57
  raise Rubex::TypeError, "Type #{dtype} not previously declared."
47
- end
58
+ end
48
59
  end
49
60
  end
50
61
 
51
- def create_arg_arrays arg_list
52
- arg_list.inject([]) do |array, arg|
62
+ def create_arg_arrays(arg_list)
63
+ arg_list.each_with_object([]) do |arg, array|
53
64
  entry = arg.entry
54
- c_name = entry.type.base_type.c_function? ? "" : entry.c_name
65
+ c_name = entry.type.base_type.c_function? ? '' : entry.c_name
55
66
  array << [entry.type.to_s, c_name]
56
- array
57
- end
58
- end
59
- end
60
-
61
- module Writers
62
- def declare_temps code, scope
63
- scope.temp_entries.each do |var|
64
- code.declare_variable type: var.type.to_s, c_name: var.c_name
65
- end
66
- end
67
-
68
- def declare_vars code, scope
69
- scope.var_entries.each do |var|
70
- if var.type.base_type.c_function?
71
- code.declare_func_ptr var: var
72
- else
73
- code.declare_variable type: var.type.to_s, c_name: var.c_name
74
- end
75
- end
76
- end
77
-
78
- def declare_carrays code, scope
79
- scope.carray_entries.select { |s|
80
- s.type.dimension.is_a? Rubex::AST::Expression::Literal::Base
81
- }. each do |arr|
82
- type = arr.type.type.to_s
83
- c_name = arr.c_name
84
- dimension = arr.type.dimension.c_code(@scope)
85
- value = arr.value.map { |a| a.c_code(@scope) } if arr.value
86
- code.declare_carray(type: type, c_name: c_name, dimension: dimension,
87
- value: value)
88
67
  end
89
68
  end
90
-
91
- def declare_types code, scope
92
- scope.type_entries.each do |entry|
93
- # if !entry.extern
94
- type = entry.type
95
-
96
- if type.alias_type?
97
- base = type.old_type
98
- if base.respond_to?(:base_type) && base.base_type.c_function?
99
- func = base.base_type
100
- str = "typedef #{func.type} (#{type.old_type.ptr_level} #{type.new_type})"
101
- str << "(" + func.arg_list.map { |e| e.type.to_s }.join(',') + ")"
102
- str << ";"
103
- code << str
104
- else
105
- code << "typedef #{type.old_type} #{type.new_type};"
106
- end
107
- elsif type.struct_or_union? && !entry.extern?
108
- code << sue_header(entry)
109
- code.block(sue_footer(entry)) do
110
- declare_vars code, type.scope
111
- declare_carrays code, type.scope
112
- declare_ruby_objects code, type.scope
113
- end
114
- end
115
- code.nl
116
- # end
117
- end
118
- end
119
-
120
- def sue_header entry
121
- type = entry.type
122
- str = "#{type.kind} #{type.name}"
123
- if !entry.extern
124
- str.prepend "typedef "
125
- end
126
-
127
- str
128
- end
129
-
130
- def sue_footer entry
131
- str =
132
- if entry.extern
133
- ";"
134
- else
135
- " #{entry.type.c_name};"
136
- end
137
-
138
- str
139
- end
140
-
141
- def declare_ruby_objects code, scope
142
- scope.ruby_obj_entries.each do |var|
143
- code.declare_variable type: var.type.to_s, c_name: var.c_name
144
- end
145
- end
146
- end
147
-
148
- module NodeTypeMethods
149
- [:expression?, :statement?, :literal?, :ruby_method?].each do |meth|
150
- define_method(meth) { false }
151
- end
152
69
  end
153
70
  end
154
71
  end
@@ -0,0 +1,9 @@
1
+ module Rubex
2
+ module Helpers
3
+ module NodeTypeMethods
4
+ [:expression?, :statement?, :literal?, :ruby_method?].each do |meth|
5
+ define_method(meth) { false }
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,79 @@
1
+ module Rubex
2
+ module Helpers
3
+ module Writers
4
+ def declare_temps(code, scope)
5
+ scope.temp_entries.each do |var|
6
+ code.declare_variable type: var.type.to_s, c_name: var.c_name
7
+ end
8
+ end
9
+
10
+ def declare_vars(code, scope)
11
+ scope.var_entries.each do |var|
12
+ if var.type.base_type.c_function?
13
+ code.declare_func_ptr var: var
14
+ else
15
+ code.declare_variable type: var.type.to_s, c_name: var.c_name
16
+ end
17
+ end
18
+ end
19
+
20
+ def declare_carrays(code, scope)
21
+ scope.carray_entries.select do |s|
22
+ s.type.dimension.is_a? Rubex::AST::Expression::Literal::Base
23
+ end.each do |arr|
24
+ type = arr.type.type.to_s
25
+ c_name = arr.c_name
26
+ dimension = arr.type.dimension.c_code(@scope)
27
+ value = arr.value.map { |a| a.c_code(@scope) } if arr.value
28
+ code.declare_carray(type: type, c_name: c_name, dimension: dimension, value: value)
29
+ end
30
+ end
31
+
32
+ def declare_types(code, scope)
33
+ scope.type_entries.each do |entry|
34
+ # if !entry.extern
35
+ type = entry.type
36
+
37
+ if type.alias_type?
38
+ base = type.old_type
39
+ if base.respond_to?(:base_type) && base.base_type.c_function?
40
+ func = base.base_type
41
+ str = "typedef #{func.type} (#{type.old_type.ptr_level} #{type.new_type})"
42
+ str << '(' + func.arg_list.map { |e| e.type.to_s }.join(',') + ')'
43
+ str << ';'
44
+ code << str
45
+ else
46
+ code << "typedef #{type.old_type} #{type.new_type};"
47
+ end
48
+ elsif type.struct_or_union? && !entry.extern?
49
+ code << sue_header(entry)
50
+ code.block(sue_footer(entry)) do
51
+ declare_vars code, type.scope
52
+ declare_carrays code, type.scope
53
+ declare_ruby_objects code, type.scope
54
+ end
55
+ end
56
+ code.nl
57
+ # end
58
+ end
59
+ end
60
+
61
+ def sue_header(entry)
62
+ type = entry.type
63
+ str = "#{type.kind} #{type.name}"
64
+ str.prepend 'typedef ' unless entry.extern
65
+ str
66
+ end
67
+
68
+ def sue_footer(entry)
69
+ entry.extern ? ';' : " #{entry.type.c_name};"
70
+ end
71
+
72
+ def declare_ruby_objects(code, scope)
73
+ scope.ruby_obj_entries.each do |var|
74
+ code.declare_variable type: var.type.to_s, c_name: var.c_name
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -133,10 +133,10 @@ rule
133
133
 
134
134
  c_func_args:
135
135
  { result = [] }
136
- | c_func_normal_arg { result = [Expression::ArgDeclaration.new(val[0])] }
136
+ | c_func_normal_arg { result = [construct_function_argument(val[0])] }
137
137
  | c_func_args tCOMMA c_func_normal_arg
138
138
  {
139
- result = [*val[0], Expression::ArgDeclaration.new(val[2])]
139
+ result = [*val[0], construct_function_argument(val[2])]
140
140
  }
141
141
 
142
142
  opt_c_func_arg_list:
@@ -144,7 +144,7 @@ rule
144
144
  | tLPAREN c_func_args tRPAREN
145
145
  {
146
146
  # self is a compulsory implicit argument for C methods.
147
- val[1] << Expression::ArgDeclaration.new(
147
+ val[1] << construct_function_argument(
148
148
  { dtype: 'object', variables: [ {ident: 'self' }] })
149
149
  result = Statement::ArgumentList.new(val[1])
150
150
  }
@@ -209,6 +209,8 @@ rule
209
209
  }
210
210
  | dtype opt_star tLPAREN opt_star opt_identifier tRPAREN opt_c_func_arg_list
211
211
  {
212
+ force_into_func_ptr_internal_args(val[6])
213
+
212
214
  result = {
213
215
  dtype: val[0],
214
216
  variables: [
@@ -245,7 +247,7 @@ rule
245
247
  if val[4].empty? # since last arg of cfunc must be self.
246
248
  val[4] = Statement::ArgumentList.new(
247
249
  [
248
- Expression::ArgDeclaration.new(
250
+ construct_function_argument(
249
251
  { dtype: 'object', variables: [ { ident: 'self' }] }
250
252
  )
251
253
  ]
@@ -311,19 +313,19 @@ rule
311
313
  {
312
314
  result = Statement::While.new val[1], val[3], location
313
315
  }
314
- | op_assign {}
316
+ | op_assign {result = val[0]}
315
317
  | struct_or_union_def
316
318
  | forward_declaration
317
319
  | alias_stmt
318
320
  | expr { result = Statement::Expression.new(val[0], location) }
319
321
  | kRAISE opt_lparen command_arg_list opt_rparen
320
322
  {
321
- result = Statement::Raise.new(Statement::ActualArgList.new(val[2]))
323
+ result = Statement::Raise.new(Expression::ActualArgList.new(val[2]))
322
324
  }
323
325
  | kBREAK { result = Statement::Break.new(location) }
324
326
  | kYIELD opt_lparen command_arg_list opt_rparen
325
327
  {
326
- result = Statement::Yield.new(Statement::ActualArgList.new(val[2]))
328
+ result = Statement::Yield.new(Expression::ActualArgList.new(val[2]))
327
329
  }
328
330
  | begin_block
329
331
 
@@ -431,6 +433,7 @@ rule
431
433
  result = {}
432
434
 
433
435
  if val[5] # function (pointer) decl
436
+ force_into_func_ptr_internal_args(val[5])
434
437
  result[:ptr_level] = val[2]
435
438
  result[:ident] = {
436
439
  :return_ptr_level => val[0],
@@ -446,7 +449,8 @@ rule
446
449
  {
447
450
  result = {}
448
451
 
449
- if !val[2].empty?
452
+ if !val[2].empty? # function pointer
453
+ force_into_func_ptr_internal_args(val[5])
450
454
  result[:ptr_level] = val[0]
451
455
  result[:ident] = {
452
456
  :name => val[1],
@@ -491,7 +495,7 @@ rule
491
495
  | method_or_attr tASSIGN expr
492
496
  {
493
497
  result = {
494
- name: Expression::CommandCall.new(val[0][0], val[0][1], []),
498
+ name: Expression::CommandCall.new(val[0][0], val[0][1], Expression::ActualArgList.new([])),
495
499
  value: val[2]
496
500
  }
497
501
  }
@@ -535,11 +539,11 @@ rule
535
539
  f_args:
536
540
  f_normal_arg
537
541
  {
538
- result = [Expression::ArgDeclaration.new(val[0])]
542
+ result = [construct_function_argument(val[0])]
539
543
  }
540
544
  | f_args tCOMMA f_normal_arg
541
545
  {
542
- result = [*val[0], Expression::ArgDeclaration.new(val[2])]
546
+ result = [*val[0], construct_function_argument(val[2])]
543
547
  }
544
548
 
545
549
  f_normal_arg:
@@ -579,8 +583,8 @@ rule
579
583
  val[1].typecast = val[0]
580
584
  result = val[1]
581
585
  }
582
- | expr tANDOP expr { result = binary_op val }
583
- | expr tOROP expr { result = binary_op val }
586
+ | expr tANDOP expr { result = Expression::BinaryBoolAnd.new(val[0], val[1], val[2]) }
587
+ | expr tOROP expr { result = Expression::BinaryBoolOr.new(val[0], val[1], val[2]) }
584
588
 
585
589
  typecast:
586
590
  tLT dtype opt_star tGT { result = Expression::Typecast.new(val[1], val[2]) }
@@ -592,17 +596,17 @@ rule
592
596
  | tLPAREN expr tRPAREN { result = val[1] }
593
597
 
594
598
  expr_value:
595
- expr_value tPLUS expr_value { result = binary_op val }
596
- | expr_value tMINUS expr_value { result = binary_op val }
597
- | expr_value tSTAR expr_value { result = binary_op val }
598
- | expr_value tDIVIDE expr_value { result = binary_op val }
599
- | expr_value tEXPO expr_value { result = binary_op val }
600
- | expr_value tMODULUS expr_value { result = binary_op val }
601
- | expr_value tBIT_AND expr_value { result = binary_op val }
602
- | expr_value tBIT_OR expr_value { result = binary_op val }
603
- | expr_value tBIT_XOR expr_value { result = binary_op val }
604
- | expr_value tBIT_LSHIFT expr_value { result = binary_op val }
605
- | expr_value tBIT_RSHIFT expr_value { result = binary_op val }
599
+ expr_value tPLUS expr_value { result = Expression::BinaryAdd.new(val[0], val[1], val[2]) }
600
+ | expr_value tMINUS expr_value { result = Expression::BinaryMinus.new(val[0], val[1], val[2]) }
601
+ | expr_value tSTAR expr_value { result = Expression::BinaryMultiply.new(val[0], val[1], val[2]) }
602
+ | expr_value tDIVIDE expr_value { result = Expression::BinaryDivide.new(val[0], val[1], val[2]) }
603
+ | expr_value tEXPO expr_value { result = Expression::BinaryExpo.new(val[0], val[1], val[2]) }
604
+ | expr_value tMODULUS expr_value { result = Expression::BinaryMod.new(val[0], val[1], val[2]) }
605
+ | expr_value tBIT_AND expr_value { result = Expression::BinaryAnd.new(val[0], val[1], val[2]) }
606
+ | expr_value tBIT_OR expr_value { result = Expression::BinaryOr.new(val[0], val[1], val[2]) }
607
+ | expr_value tBIT_XOR expr_value { result = Expression::BinaryXor.new(val[0], val[1], val[2]) }
608
+ | expr_value tBIT_LSHIFT expr_value { result = Expression::BinaryLShift.new(val[0], val[1], val[2]) }
609
+ | expr_value tBIT_RSHIFT expr_value { result = Expression::BinaryRShift.new(val[0], val[1], val[2]) }
606
610
  | tMINUS expr_value =UMINUS { result = unary_op val }
607
611
  | tBIT_AND expr_value =ADDRESS_OF{ result = unary_op val }
608
612
  | tBIT_NOT expr_value { result = unary_op val }
@@ -610,12 +614,12 @@ rule
610
614
  | atomic_value {}
611
615
 
612
616
  expr_cmp:
613
- expr_value tEQ expr_value { result = binary_op val }
614
- | expr_value tNEQ expr_value { result = binary_op val }
615
- | expr_value tLT expr_value { result = binary_op val }
616
- | expr_value tLTEQ expr_value { result = binary_op val }
617
- | expr_value tGT expr_value { result = binary_op val }
618
- | expr_value tGTEQ expr_value { result = binary_op val }
617
+ expr_value tEQ expr_value { result = Expression::BinaryBoolEq.new(val[0], val[1], val[2]) }
618
+ | expr_value tNEQ expr_value { result = Expression::BinaryBoolNEq.new(val[0], val[1], val[2]) }
619
+ | expr_value tLT expr_value { result = Expression::BinaryBoolLt.new(val[0], val[1], val[2]) }
620
+ | expr_value tLTEQ expr_value { result = Expression::BinaryBoolLtEq.new(val[0], val[1], val[2]) }
621
+ | expr_value tGT expr_value { result = Expression::BinaryBoolGt.new(val[0], val[1], val[2]) }
622
+ | expr_value tGTEQ expr_value { result = Expression::BinaryBoolGtEq.new(val[0], val[1], val[2]) }
619
623
  | tLPAREN expr_cmp tRPAREN { result = val[1] }
620
624
 
621
625
  atomic_value:
@@ -660,8 +664,8 @@ rule
660
664
  }
661
665
 
662
666
  command_opt_args:
663
- { result = [] }
664
- | tLPAREN command_arg_list tRPAREN { result = val[1] }
667
+ { result = Expression::ActualArgList.new([]) }
668
+ | tLPAREN command_arg_list tRPAREN { result = Expression::ActualArgList.new(val[1]) }
665
669
 
666
670
  command_arg_list:
667
671
  { result = [] }
@@ -724,8 +728,10 @@ end
724
728
  ---- header
725
729
  require_relative 'lexer.rex.rb'
726
730
  require_relative 'ast.rb'
731
+ require_relative 'helpers.rb'
727
732
 
728
733
  include Rubex::AST
734
+ include Rubex::Helpers
729
735
 
730
736
  ---- inner
731
737
 
@@ -867,6 +873,10 @@ def check_for_primitive_dtype token
867
873
  token
868
874
  end
869
875
 
876
+ def construct_function_argument data
877
+ Rubex::Helpers.construct_function_argument data
878
+ end
879
+
870
880
  def binary_op val
871
881
  Expression::Binary.new val[0], val[1], val[2]
872
882
  end
@@ -877,7 +887,40 @@ end
877
887
 
878
888
  # expr, op_assign, expr => expr = expr op expr
879
889
  def op_assign val
880
- Statement::Assign.new(val[0], binary_op([val[0], val[1][0], val[2]]), location)
890
+ left = val[0]
891
+ right = val[2]
892
+ operator = val[1][0]
893
+
894
+ expression =
895
+ case operator
896
+ when '+'
897
+ Expression::BinaryAdd.new(left, operator, right)
898
+ when '-'
899
+ Expression::BinaryMinus.new(left, operator, right)
900
+ when '*'
901
+ Expression::BinaryMultiply.new(left, operator, right)
902
+ when '/'
903
+ Expression::BinaryDivide.new(left, operator, right)
904
+ when '**'
905
+ Expression::BinaryExpo.new(left, operator, right)
906
+ when '%'
907
+ Expression::BinaryMod.new(left, operator, right)
908
+ when '&'
909
+ Expression::BinaryAnd.new(left, operator, right)
910
+ when '|'
911
+ Expression::BinaryOr.new(left, operator, right)
912
+ when '<<'
913
+ Expression::BinaryLShift.new(left, operator, right)
914
+ when '>>'
915
+ Expression::BinaryRShift.new(left, operator, right)
916
+ when '^'
917
+ Expression::BinaryXor.new(left, operator, right)
918
+ else
919
+ raise "Cannot identify operator #{operator}"
920
+ end
921
+
922
+
923
+ Statement::Assign.new(left.dup, expression, location)
881
924
  end
882
925
 
883
926
  def variable_decl_nodes val
@@ -891,7 +934,7 @@ def variable_decl_nodes val
891
934
  statement =
892
935
  if ident.is_a?(Hash) # only if function pointer
893
936
  dtype = { dtype: type, ident: ident }
894
- Statement::CPtrDecl.new(dtype, ident[:name], var[:value], ptr_level,
937
+ Statement::CPtrFuncDecl.new(dtype, ident[:name], var[:value], ptr_level,
895
938
  location)
896
939
  else
897
940
  if ptr_level
@@ -913,3 +956,9 @@ end
913
956
  def add_dtype_to_lexer dtype
914
957
  @custom_dtypes[dtype] = true
915
958
  end
959
+
960
+ def force_into_func_ptr_internal_args data
961
+ data.map! do |arg|
962
+ Expression::FuncPtrInternalArgDeclaration.new(arg.data_hash)
963
+ end
964
+ end