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,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