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.
- checksums.yaml +5 -5
- data/.gitignore +3 -2
- data/.travis.yml +9 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +4 -1
- data/Rakefile +2 -2
- data/bin/rubex +4 -5
- data/lib/rubex.rb +4 -4
- data/lib/rubex/ast.rb +4 -1
- data/lib/rubex/ast/expression.rb +22 -1191
- data/lib/rubex/ast/expression/actual_arg_list.rb +40 -0
- data/lib/rubex/ast/expression/analysed_element_ref.rb +26 -0
- data/lib/rubex/ast/expression/analysed_element_ref/c_var_element_ref.rb +30 -0
- data/lib/rubex/ast/expression/analysed_element_ref/ruby_object_element_ref.rb +42 -0
- data/lib/rubex/ast/expression/arg_declaration.rb +43 -0
- data/lib/rubex/ast/expression/binary.rb +57 -0
- data/lib/rubex/ast/expression/binary/binary_boolean.rb +23 -0
- data/lib/rubex/ast/expression/binary/binary_boolean_special_op.rb +20 -0
- data/lib/rubex/ast/expression/binary/empty_classes.rb +62 -0
- data/lib/rubex/ast/expression/block_given.rb +15 -0
- data/lib/rubex/ast/expression/coerce_object.rb +15 -0
- data/lib/rubex/ast/expression/command_call.rb +74 -0
- data/lib/rubex/ast/expression/command_call/struct_or_union_member_call.rb +38 -0
- data/lib/rubex/ast/expression/element_ref.rb +64 -0
- data/lib/rubex/ast/expression/empty.rb +13 -0
- data/lib/rubex/ast/expression/from_ruby_object.rb +20 -0
- data/lib/rubex/ast/expression/func_ptr_arg_declaration.rb +21 -0
- data/lib/rubex/ast/expression/func_ptr_internal_arg_declaration.rb +13 -0
- data/lib/rubex/ast/expression/literal.rb +30 -0
- data/lib/rubex/ast/expression/literal/array_lit.rb +51 -0
- data/lib/rubex/ast/expression/literal/c_null.rb +15 -0
- data/lib/rubex/ast/expression/literal/char.rb +36 -0
- data/lib/rubex/ast/expression/literal/double.rb +14 -0
- data/lib/rubex/ast/expression/literal/false.rb +33 -0
- data/lib/rubex/ast/expression/literal/hash_lit.rb +45 -0
- data/lib/rubex/ast/expression/literal/int.rb +14 -0
- data/lib/rubex/ast/expression/literal/nil.rb +14 -0
- data/lib/rubex/ast/expression/literal/ruby_symbol.rb +22 -0
- data/lib/rubex/ast/expression/literal/string_lit.rb +45 -0
- data/lib/rubex/ast/expression/literal/true.rb +29 -0
- data/lib/rubex/ast/expression/method_call.rb +52 -0
- data/lib/rubex/ast/expression/method_call/c_function_call.rb +40 -0
- data/lib/rubex/ast/expression/method_call/ruby_method_call.rb +83 -0
- data/lib/rubex/ast/expression/name.rb +127 -0
- data/lib/rubex/ast/expression/ruby_constant.rb +25 -0
- data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_array_element_ref.rb +20 -0
- data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_hash_element_ref.rb +22 -0
- data/lib/rubex/ast/expression/self.rb +15 -0
- data/lib/rubex/ast/expression/size_of.rb +22 -0
- data/lib/rubex/ast/expression/struct_or_union_member_call/element_ref_member_call.rb +23 -0
- data/lib/rubex/ast/expression/to_ruby_object.rb +21 -0
- data/lib/rubex/ast/expression/typecast.rb +20 -0
- data/lib/rubex/ast/expression/typecast_to.rb +10 -0
- data/lib/rubex/ast/expression/unary.rb +37 -0
- data/lib/rubex/ast/expression/unary_base.rb +24 -0
- data/lib/rubex/ast/expression/unary_base/ampersand.rb +16 -0
- data/lib/rubex/ast/expression/unary_base/unary_bit_not.rb +18 -0
- data/lib/rubex/ast/expression/unary_base/unary_not.rb +18 -0
- data/lib/rubex/ast/expression/unary_base/unary_sub.rb +18 -0
- data/lib/rubex/ast/node.rb +111 -111
- data/lib/rubex/ast/statement.rb +9 -1160
- data/lib/rubex/ast/statement/alias.rb +43 -0
- data/lib/rubex/ast/statement/argument_list.rb +59 -0
- data/lib/rubex/ast/statement/assign.rb +35 -0
- data/lib/rubex/ast/statement/begin_block.rb +14 -0
- data/lib/rubex/ast/statement/begin_block/begin.rb +202 -0
- data/lib/rubex/ast/statement/begin_block/else.rb +21 -0
- data/lib/rubex/ast/statement/begin_block/ensure.rb +21 -0
- data/lib/rubex/ast/statement/begin_block/rescue.rb +34 -0
- data/lib/rubex/ast/statement/break.rb +18 -0
- data/lib/rubex/ast/statement/c_array_decl.rb +49 -0
- data/lib/rubex/ast/statement/c_base_type.rb +26 -0
- data/lib/rubex/ast/statement/c_function_decl.rb +30 -0
- data/lib/rubex/ast/statement/c_ptr_decl.rb +52 -0
- data/lib/rubex/ast/statement/c_ptr_decl/c_ptr_func_decl.rb +25 -0
- data/lib/rubex/ast/statement/c_struct_or_union_def.rb +49 -0
- data/lib/rubex/ast/statement/expression.rb +26 -0
- data/lib/rubex/ast/statement/for.rb +73 -0
- data/lib/rubex/ast/statement/forward_decl.rb +31 -0
- data/lib/rubex/ast/statement/if_block.rb +64 -0
- data/lib/rubex/ast/statement/if_block/else.rb +30 -0
- data/lib/rubex/ast/statement/if_block/elsif.rb +22 -0
- data/lib/rubex/ast/statement/if_block/helper.rb +38 -0
- data/lib/rubex/ast/statement/print.rb +49 -0
- data/lib/rubex/ast/statement/raise.rb +66 -0
- data/lib/rubex/ast/statement/return.rb +45 -0
- data/lib/rubex/ast/statement/var_decl.rb +49 -0
- data/lib/rubex/ast/statement/while.rb +34 -0
- data/lib/rubex/ast/statement/yield.rb +41 -0
- data/lib/rubex/ast/top_statement.rb +1 -815
- data/lib/rubex/ast/top_statement/c_bindings.rb +145 -0
- data/lib/rubex/ast/top_statement/klass.rb +125 -0
- data/lib/rubex/ast/top_statement/klass/attached_klass.rb +417 -0
- data/lib/rubex/ast/top_statement/method_def.rb +110 -0
- data/lib/rubex/ast/top_statement/method_def/c_function_def.rb +26 -0
- data/lib/rubex/ast/top_statement/method_def/ruby_method_def.rb +33 -0
- data/lib/rubex/cli.rb +26 -0
- data/lib/rubex/code_writer.rb +1 -1
- data/lib/rubex/compiler.rb +49 -28
- data/lib/rubex/compiler_config.rb +4 -2
- data/lib/rubex/constants.rb +71 -71
- data/lib/rubex/data_type.rb +9 -675
- data/lib/rubex/data_type/c_array.rb +33 -0
- data/lib/rubex/data_type/c_function.rb +23 -0
- data/lib/rubex/data_type/c_ptr.rb +71 -0
- data/lib/rubex/data_type/c_str.rb +23 -0
- data/lib/rubex/data_type/c_struct_or_union.rb +23 -0
- data/lib/rubex/data_type/char.rb +30 -0
- data/lib/rubex/data_type/f_32.rb +38 -0
- data/lib/rubex/data_type/f_64.rb +38 -0
- data/lib/rubex/data_type/int.rb +32 -0
- data/lib/rubex/data_type/int/c_boolean.rb +13 -0
- data/lib/rubex/data_type/int_16.rb +32 -0
- data/lib/rubex/data_type/int_32.rb +32 -0
- data/lib/rubex/data_type/int_64.rb +36 -0
- data/lib/rubex/data_type/int_8.rb +33 -0
- data/lib/rubex/data_type/l_int.rb +38 -0
- data/lib/rubex/data_type/l_l_int.rb +26 -0
- data/lib/rubex/data_type/ruby_method.rb +22 -0
- data/lib/rubex/data_type/ruby_object.rb +19 -0
- data/lib/rubex/data_type/ruby_object/boolean.rb +11 -0
- data/lib/rubex/data_type/ruby_object/boolean/false_type.rb +5 -0
- data/lib/rubex/data_type/ruby_object/boolean/true_type.rb +5 -0
- data/lib/rubex/data_type/ruby_object/nil_type.rb +9 -0
- data/lib/rubex/data_type/ruby_object/ruby_array.rb +10 -0
- data/lib/rubex/data_type/ruby_object/ruby_constant.rb +18 -0
- data/lib/rubex/data_type/ruby_object/ruby_constant/ruby_class.rb +18 -0
- data/lib/rubex/data_type/ruby_object/ruby_hash.rb +9 -0
- data/lib/rubex/data_type/ruby_object/ruby_string.rb +10 -0
- data/lib/rubex/data_type/ruby_object/ruby_symbol.rb +10 -0
- data/lib/rubex/data_type/type_def.rb +34 -0
- data/lib/rubex/data_type/u_char.rb +27 -0
- data/lib/rubex/data_type/u_int.rb +32 -0
- data/lib/rubex/data_type/u_int_16.rb +22 -0
- data/lib/rubex/data_type/u_int_32.rb +22 -0
- data/lib/rubex/data_type/u_int_64.rb +26 -0
- data/lib/rubex/data_type/u_int_8.rb +22 -0
- data/lib/rubex/data_type/u_l_int.rb +36 -0
- data/lib/rubex/data_type/u_l_int/size_t.rb +10 -0
- data/lib/rubex/data_type/u_l_l_int.rb +26 -0
- data/lib/rubex/data_type/void.rb +15 -0
- data/lib/rubex/data_type_helpers/float_helpers.rb +8 -0
- data/lib/rubex/data_type_helpers/helpers.rb +48 -0
- data/lib/rubex/data_type_helpers/int_helpers.rb +10 -0
- data/lib/rubex/data_type_helpers/u_int_helpers.rb +11 -0
- data/lib/rubex/helpers.rb +35 -118
- data/lib/rubex/helpers/node_type_methods.rb +9 -0
- data/lib/rubex/helpers/writers.rb +79 -0
- data/lib/rubex/parser.racc +83 -34
- data/lib/rubex/parser.racc.rb +233 -184
- data/lib/rubex/version.rb +2 -2
- data/rubex.gemspec +2 -0
- data/spec/basic_ruby_method_spec.rb +1 -1
- data/spec/binding_ptr_args_spec.rb +2 -2
- data/spec/bitwise_operators_spec.rb +1 -1
- data/spec/blocks_spec.rb +2 -2
- data/spec/c_bindings_spec.rb +1 -1
- data/spec/c_constants_spec.rb +1 -1
- data/spec/c_function_ptrs_spec.rb +1 -1
- data/spec/c_functions_spec.rb +2 -2
- data/spec/c_struct_interface_spec.rb +1 -1
- data/spec/call_by_reference_spec.rb +2 -2
- data/spec/class_methods_spec.rb +2 -2
- data/spec/class_spec.rb +4 -4
- data/spec/cli_spec.rb +43 -0
- data/spec/comments_spec.rb +2 -2
- data/spec/default_args_spec.rb +21 -23
- data/spec/error_handling_spec.rb +1 -1
- data/spec/examples_spec.rb +4 -4
- data/spec/expressions_spec.rb +1 -1
- data/spec/fixtures/cli/cli.rubex +3 -0
- data/spec/fixtures/examples/array_to_hash.rubex +1 -1
- data/spec/fixtures/examples/rcsv.rubex +10 -6
- data/spec/fixtures/loops/loops.rubex +1 -1
- data/spec/fixtures/ruby_strings/string_blank_bm.rb +7 -5
- data/spec/fixtures/struct/struct.rubex +7 -2
- data/spec/fixtures/temp_allocation/temp_allocation.rubex +8 -0
- data/spec/if_else_spec.rb +3 -7
- data/spec/implicit_lib_include_spec.rb +1 -1
- data/spec/init_ruby_objects_with_literal_syntax_spec.rb +1 -1
- data/spec/loops_spec.rb +1 -1
- data/spec/recursion_spec.rb +18 -21
- data/spec/ruby_constant_method_calls_spec.rb +4 -4
- data/spec/ruby_operators_spec.rb +1 -1
- data/spec/ruby_raise_spec.rb +1 -1
- data/spec/ruby_strings_spec.rb +3 -3
- data/spec/ruby_symbols_spec.rb +1 -1
- data/spec/ruby_types_spec.rb +2 -2
- data/spec/spec_helper.rb +42 -10
- data/spec/statement_expression_spec.rb +3 -3
- data/spec/static_array_spec.rb +3 -3
- data/spec/string_literals_spec.rb +2 -2
- data/spec/struct_spec.rb +4 -4
- data/spec/temp_allocation_spec.rb +35 -0
- data/spec/typecasting_spec.rb +2 -2
- data/spec/var_declarions_spec.rb +2 -2
- metadata +168 -3
@@ -0,0 +1,45 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
module Literal
|
5
|
+
class StringLit < Base
|
6
|
+
def analyse_for_target_type(target_type, local_scope)
|
7
|
+
if target_type.char_ptr?
|
8
|
+
@type = Rubex::DataType::CStr.new
|
9
|
+
elsif target_type.object?
|
10
|
+
@type = Rubex::DataType::RubyString.new
|
11
|
+
analyse_types local_scope
|
12
|
+
else
|
13
|
+
raise Rubex::TypeError, "Cannot assign #{target_type} to string."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def analyse_types(_local_scope)
|
18
|
+
@type ||= Rubex::DataType::RubyString.new
|
19
|
+
@has_temp = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_evaluation_code(code, _local_scope)
|
23
|
+
if @type.cstr?
|
24
|
+
@c_code = "\"#{@name}\""
|
25
|
+
else
|
26
|
+
code << "#{@c_code} = rb_str_new2(\"#{@name}\");"
|
27
|
+
code.nl
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_disposal_code(code)
|
32
|
+
if @type.object?
|
33
|
+
code << "#{@c_code} = 0;"
|
34
|
+
code.nl
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def c_code(_local_scope)
|
39
|
+
@c_code
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
module Literal
|
5
|
+
class True < Base
|
6
|
+
def analyse_for_target_type(target_type, _local_scope)
|
7
|
+
@type = if target_type.object?
|
8
|
+
Rubex::DataType::TrueType.new
|
9
|
+
else
|
10
|
+
Rubex::DataType::CBoolean.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def analyse_types(_local_scope)
|
15
|
+
@type = Rubex::DataType::TrueType.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def c_code(_local_scope)
|
19
|
+
if @type.object?
|
20
|
+
@name
|
21
|
+
else
|
22
|
+
'1'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class MethodCall < Base
|
5
|
+
def initialize(invoker, method_name, arg_list)
|
6
|
+
@method_name = method_name
|
7
|
+
@invoker = invoker
|
8
|
+
@arg_list = arg_list
|
9
|
+
end
|
10
|
+
|
11
|
+
def analyse_types(local_scope)
|
12
|
+
if method_not_within_scope? local_scope
|
13
|
+
raise Rubex::NoMethodError, "Cannot call #{@method_name} from this method."
|
14
|
+
end
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_evaluation_code code, local_scope
|
19
|
+
@arg_list.each { |a| a.generate_evaluation_code(code, local_scope) }
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def type_check_arg_types(entry)
|
25
|
+
@arg_list.map!.with_index do |arg, idx|
|
26
|
+
Helpers.to_lhs_type(entry.type.base_type.arg_list[idx], arg)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Checks if method being called is of the same type of the caller. For
|
31
|
+
# example, only instance methods can call instance methods and only
|
32
|
+
# class methods can call class methods. C functions are accessible from
|
33
|
+
# both instance methods and class methods.
|
34
|
+
#
|
35
|
+
# Since there is no way to determine whether methods outside the scope
|
36
|
+
# of the compiled Rubex file are singletons or not, Rubex will assume
|
37
|
+
# that they belong to the correct scope and will compile a call to those
|
38
|
+
# methods anyway. Error, if any, will be caught only at runtime.
|
39
|
+
def method_not_within_scope?(local_scope)
|
40
|
+
caller_entry = local_scope.find local_scope.name
|
41
|
+
if (caller_entry.singleton? && @entry.singleton?) ||
|
42
|
+
(!caller_entry.singleton? && !@entry.singleton?) ||
|
43
|
+
@entry.c_function?
|
44
|
+
false
|
45
|
+
else
|
46
|
+
true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class CFunctionCall < MethodCall
|
5
|
+
def analyse_types(local_scope)
|
6
|
+
@entry = local_scope.find(@method_name)
|
7
|
+
super
|
8
|
+
append_self_argument unless @entry.extern?
|
9
|
+
@arg_list.analyse_types local_scope
|
10
|
+
@arg_list.allocate_temps local_scope
|
11
|
+
@arg_list.release_temps local_scope
|
12
|
+
@type = @entry.type.base_type
|
13
|
+
type_check_arg_types @entry
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate_evaluation_code code, local_scope
|
17
|
+
super
|
18
|
+
@c_code = code_for_c_method_call local_scope
|
19
|
+
end
|
20
|
+
|
21
|
+
def c_code(local_scope)
|
22
|
+
@c_code
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def append_self_argument
|
28
|
+
@arg_list << Expression::Self.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def code_for_c_method_call(local_scope)
|
32
|
+
str = "#{@entry.c_name}("
|
33
|
+
str << @arg_list.map { |a| a.c_code(local_scope) }.join(',')
|
34
|
+
str << ')'
|
35
|
+
str
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class RubyMethodCall < MethodCall
|
5
|
+
def analyse_types(local_scope)
|
6
|
+
@entry = local_scope.find(@method_name)
|
7
|
+
add_as_ruby_method_to_symtab(local_scope) unless @entry
|
8
|
+
super
|
9
|
+
@arg_list.analyse_types local_scope
|
10
|
+
@type = Rubex::DataType::RubyObject.new
|
11
|
+
@arg_list.map! { |a| a.to_ruby_object }
|
12
|
+
@arg_list.allocate_temps local_scope
|
13
|
+
@arg_list.release_temps local_scope
|
14
|
+
prepare_arg_list(local_scope) if !@entry.extern? && !@arg_list.empty?
|
15
|
+
@has_temp = true
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_evaluation_code code, local_scope
|
19
|
+
super
|
20
|
+
code_for_ruby_method_call code, local_scope
|
21
|
+
end
|
22
|
+
|
23
|
+
def c_code(local_scope)
|
24
|
+
@c_code
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def add_as_ruby_method_to_symtab(local_scope)
|
30
|
+
@entry = local_scope.add_ruby_method(
|
31
|
+
name: @method_name,
|
32
|
+
c_name: @method_name,
|
33
|
+
extern: true,
|
34
|
+
arg_list: @arg_list,
|
35
|
+
scope: nil
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def prepare_arg_list(local_scope)
|
40
|
+
@arg_list_var = @entry.c_name + Rubex::ACTUAL_ARGS_SUFFIX
|
41
|
+
args_size = @entry.type.arg_list&.size || 0
|
42
|
+
local_scope.add_carray(name: @arg_list_var, c_name: @arg_list_var,
|
43
|
+
dimension: Literal::Int.new(args_size.to_s),
|
44
|
+
type: @type)
|
45
|
+
end
|
46
|
+
|
47
|
+
def code_for_ruby_method_call(code, local_scope)
|
48
|
+
str = "#{@c_code} = "
|
49
|
+
if @entry.extern?
|
50
|
+
str << "rb_funcall(#{@invoker.c_code(local_scope)}, "
|
51
|
+
str << "rb_intern(\"#{@method_name}\"), "
|
52
|
+
str << @arg_list.size.to_s
|
53
|
+
@arg_list.each do |arg|
|
54
|
+
str << " ,#{arg.c_code(local_scope)}"
|
55
|
+
end
|
56
|
+
str << ', NULL' if @arg_list.empty?
|
57
|
+
str << ");\n"
|
58
|
+
else
|
59
|
+
str << populate_method_args_into_value_array(local_scope)
|
60
|
+
str << actual_ruby_method_call(local_scope)
|
61
|
+
end
|
62
|
+
code << str
|
63
|
+
end
|
64
|
+
|
65
|
+
def actual_ruby_method_call(local_scope)
|
66
|
+
str = "#{@entry.c_name}(#{@arg_list.size}, #{@arg_list_var || 'NULL'},"
|
67
|
+
str << "#{local_scope.self_name});"
|
68
|
+
end
|
69
|
+
|
70
|
+
def populate_method_args_into_value_array(local_scope)
|
71
|
+
str = ''
|
72
|
+
@arg_list.each_with_index do |arg, idx|
|
73
|
+
str = "#{@arg_list_var}[#{idx}] = "
|
74
|
+
str << arg.c_code(local_scope).to_s
|
75
|
+
str << ";\n"
|
76
|
+
end
|
77
|
+
|
78
|
+
str
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
# Singular name node with no sub expressions.
|
5
|
+
class Name < Base
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
|
10
|
+
# Used when the node is a LHS of an assign statement.
|
11
|
+
def analyse_declaration(_rhs, local_scope)
|
12
|
+
@entry = local_scope.find @name
|
13
|
+
unless @entry
|
14
|
+
local_scope.add_ruby_obj(name: @name, c_name: Rubex::VAR_PREFIX + @name, value: @rhs)
|
15
|
+
@entry = local_scope[@name]
|
16
|
+
end
|
17
|
+
@type = @entry.type
|
18
|
+
end
|
19
|
+
|
20
|
+
def analyse_for_target_type(target_type, local_scope)
|
21
|
+
@entry = local_scope.find @name
|
22
|
+
|
23
|
+
if @entry&.type&.c_function? && target_type.c_function_ptr?
|
24
|
+
@type = @entry.type
|
25
|
+
else
|
26
|
+
analyse_types local_scope
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Analyse a Name node. This can either be a variable name or a method call
|
31
|
+
# without parenthesis. Code in this method that creates a RubyMethodCall
|
32
|
+
# node primarily exists because in Ruby methods without arguments can
|
33
|
+
# be called without parentheses. These names can potentially be Ruby
|
34
|
+
# methods that are not visible to Rubex, but are present in the Ruby
|
35
|
+
# run time. For example, a program like this:
|
36
|
+
#
|
37
|
+
# def foo
|
38
|
+
# bar
|
39
|
+
# #^^^ this is a name node
|
40
|
+
# end
|
41
|
+
def analyse_types(local_scope)
|
42
|
+
@entry = local_scope.find @name
|
43
|
+
unless @entry
|
44
|
+
if ruby_constant?
|
45
|
+
analyse_as_ruby_constant local_scope
|
46
|
+
else
|
47
|
+
add_as_ruby_method_to_scope local_scope
|
48
|
+
end
|
49
|
+
end
|
50
|
+
analyse_as_ruby_method(local_scope) if @entry.type.ruby_method?
|
51
|
+
assign_type_based_on_whether_wrapped_type
|
52
|
+
if @name.is_a?(Expression::Base)
|
53
|
+
@name.allocate_temps local_scope
|
54
|
+
@name.release_temps local_scope
|
55
|
+
end
|
56
|
+
super
|
57
|
+
end
|
58
|
+
|
59
|
+
def generate_evaluation_code(code, local_scope)
|
60
|
+
if @name.respond_to? :generate_evaluation_code
|
61
|
+
@name.generate_evaluation_code code, local_scope
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def generate_disposal_code(code)
|
66
|
+
if @name.respond_to? :generate_disposal_code
|
67
|
+
@name.generate_disposal_code code
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def generate_assignment_code(rhs, code, local_scope)
|
72
|
+
code << "#{c_code(local_scope)} = #{rhs.c_code(local_scope)};"
|
73
|
+
code.nl
|
74
|
+
rhs.generate_disposal_code code
|
75
|
+
end
|
76
|
+
|
77
|
+
def c_code(local_scope)
|
78
|
+
code = super
|
79
|
+
code <<
|
80
|
+
if @name.is_a?(Rubex::AST::Expression::Base)
|
81
|
+
@name.c_code(local_scope)
|
82
|
+
else
|
83
|
+
@entry.c_name
|
84
|
+
end
|
85
|
+
code
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def ruby_constant?
|
91
|
+
@name[0].match(/[A-Z]/)
|
92
|
+
end
|
93
|
+
|
94
|
+
def analyse_as_ruby_constant(local_scope)
|
95
|
+
@name = Expression::RubyConstant.new @name
|
96
|
+
@name.analyse_types local_scope
|
97
|
+
@entry = @name.entry
|
98
|
+
end
|
99
|
+
|
100
|
+
def add_as_ruby_method_to_scope(local_scope)
|
101
|
+
@entry = local_scope.add_ruby_method(
|
102
|
+
name: @name,
|
103
|
+
c_name: @name,
|
104
|
+
extern: true,
|
105
|
+
scope: nil,
|
106
|
+
arg_list: Expression::ActualArgList.new([])
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
def analyse_as_ruby_method(local_scope)
|
111
|
+
@name = Rubex::AST::Expression::RubyMethodCall.new(
|
112
|
+
Expression::Self.new, @name, Expression::ActualArgList.new([])
|
113
|
+
)
|
114
|
+
@name.analyse_types local_scope
|
115
|
+
end
|
116
|
+
|
117
|
+
def assign_type_based_on_whether_wrapped_type
|
118
|
+
if @entry.type.alias_type? || @entry.type.ruby_method? || @entry.type.c_function?
|
119
|
+
@type = @entry.type.type
|
120
|
+
else
|
121
|
+
@type = @entry.type
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class RubyConstant < Base
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
end
|
8
|
+
|
9
|
+
def analyse_types(_local_scope)
|
10
|
+
@type = Rubex::DataType::RubyConstant.new @name
|
11
|
+
c_name = Rubex::DEFAULT_CLASS_MAPPINGS[@name]
|
12
|
+
@entry = Rubex::SymbolTable::Entry.new @name, c_name, @type, nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def c_code(local_scope)
|
16
|
+
if @entry.c_name # built-in constant.
|
17
|
+
@entry.c_name
|
18
|
+
else
|
19
|
+
"rb_const_get(CLASS_OF(#{local_scope.self_name}), rb_intern(\"#{@entry.name}\"))"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class RubyArrayElementRef < RubyObjectElementRef
|
5
|
+
def analyse_types(local_scope)
|
6
|
+
@has_temp = true
|
7
|
+
@pos.analyse_types local_scope
|
8
|
+
@subexprs << @pos
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_evaluation_code(code, local_scope)
|
12
|
+
generate_and_dispose_subexprs(code, local_scope) do
|
13
|
+
code << "#{@c_code} = RARRAY_AREF(#{@entry.c_name}, #{@pos.c_code(local_scope)});"
|
14
|
+
code.nl
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class RubyHashElementRef < RubyObjectElementRef
|
5
|
+
def generate_evaluation_code(code, local_scope)
|
6
|
+
generate_and_dispose_subexprs(code, local_scope) do
|
7
|
+
code << "#{@c_code} = rb_hash_aref(#{@entry.c_name}, #{@pos.c_code(local_scope)});"
|
8
|
+
code.nl
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_assignment_code(rhs, code, local_scope)
|
13
|
+
generate_and_dispose_subexprs(code, local_scope) do
|
14
|
+
code << "rb_hash_aset(#{@entry.c_name}, #{@pos.c_code(local_scope)},"
|
15
|
+
code << "#{rhs.c_code(local_scope)});"
|
16
|
+
code.nl
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|