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