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