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,43 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class Alias < Base
|
5
|
+
def initialize(new_name, old_name, location)
|
6
|
+
super(location)
|
7
|
+
@new_name = new_name
|
8
|
+
@old_name = old_name
|
9
|
+
Rubex::CUSTOM_TYPES[@new_name] = @new_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def analyse_statement(local_scope, extern: false)
|
13
|
+
original = @old_name[:dtype].gsub('struct ', '').gsub('union ', '')
|
14
|
+
var = @old_name[:variables][0]
|
15
|
+
ident = var[:ident]
|
16
|
+
ptr_level = var[:ptr_level]
|
17
|
+
|
18
|
+
base_type =
|
19
|
+
if ident.is_a?(Hash) # function pointer
|
20
|
+
cfunc_return_type = Helpers.determine_dtype(original,
|
21
|
+
ident[:return_ptr_level])
|
22
|
+
arg_list = ident[:arg_list].analyse_statement(local_scope)
|
23
|
+
ptr_level = '*' if ptr_level.empty?
|
24
|
+
|
25
|
+
Helpers.determine_dtype(
|
26
|
+
DataType::CFunction.new(nil, nil, arg_list, cfunc_return_type, nil),
|
27
|
+
ptr_level
|
28
|
+
)
|
29
|
+
else
|
30
|
+
Helpers.determine_dtype(original, ptr_level)
|
31
|
+
end
|
32
|
+
|
33
|
+
@type = Rubex::DataType::TypeDef.new(base_type, @new_name, base_type)
|
34
|
+
Rubex::CUSTOM_TYPES[@new_name] = @type
|
35
|
+
local_scope.declare_type(type: @type, extern: extern) if original != @new_name
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_code(code, local_scope); end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
# This node is used for both formal and actual arguments of functions/methods.
|
5
|
+
class ArgumentList < Base
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
# args - [ArgDeclaration]
|
9
|
+
attr_reader :args
|
10
|
+
|
11
|
+
def each(&block)
|
12
|
+
@args.each(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def map!(&block)
|
16
|
+
@args.map!(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def pop
|
20
|
+
@args.pop
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(args)
|
24
|
+
@args = args
|
25
|
+
end
|
26
|
+
|
27
|
+
def analyse_statement(local_scope, extern: false)
|
28
|
+
@args.each do |arg|
|
29
|
+
arg.analyse_types(local_scope, extern: extern)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def push(arg)
|
34
|
+
@args << arg
|
35
|
+
end
|
36
|
+
|
37
|
+
def <<(arg)
|
38
|
+
push arg
|
39
|
+
end
|
40
|
+
|
41
|
+
def ==(other)
|
42
|
+
self.class == other.class && @args == other.args
|
43
|
+
end
|
44
|
+
|
45
|
+
def size
|
46
|
+
@args.size
|
47
|
+
end
|
48
|
+
|
49
|
+
def empty?
|
50
|
+
@args.empty?
|
51
|
+
end
|
52
|
+
|
53
|
+
def [](idx)
|
54
|
+
@args[idx]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class Assign < Base
|
5
|
+
def initialize(lhs, rhs, location)
|
6
|
+
super(location)
|
7
|
+
@lhs = lhs
|
8
|
+
@rhs = rhs
|
9
|
+
end
|
10
|
+
|
11
|
+
def analyse_statement(local_scope)
|
12
|
+
if @lhs.is_a?(Rubex::AST::Expression::Name)
|
13
|
+
@lhs.analyse_declaration @rhs, local_scope
|
14
|
+
else
|
15
|
+
@lhs.analyse_types(local_scope)
|
16
|
+
end
|
17
|
+
@lhs.allocate_temps local_scope
|
18
|
+
@rhs.analyse_for_target_type(@lhs.type, local_scope)
|
19
|
+
@rhs = Helpers.to_lhs_type(@lhs, @rhs)
|
20
|
+
@rhs.allocate_temps local_scope
|
21
|
+
|
22
|
+
@lhs.release_temps local_scope
|
23
|
+
@rhs.release_temps local_scope
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate_code(code, local_scope)
|
27
|
+
super
|
28
|
+
@rhs.generate_evaluation_code code, local_scope
|
29
|
+
@lhs.generate_assignment_code @rhs, code, local_scope
|
30
|
+
@rhs.generate_disposal_code code
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
module BeginBlock
|
5
|
+
class Begin < Base
|
6
|
+
def initialize(statements, tails, location)
|
7
|
+
@tails = tails
|
8
|
+
super(statements, location)
|
9
|
+
end
|
10
|
+
|
11
|
+
def analyse_statement(local_scope)
|
12
|
+
local_scope.found_begin_block
|
13
|
+
declare_error_state_variable local_scope
|
14
|
+
declare_error_klass_variable local_scope
|
15
|
+
declare_unhandled_error_variable local_scope
|
16
|
+
@block_scope = Rubex::SymbolTable::Scope::BeginBlock.new(
|
17
|
+
block_name(local_scope), local_scope
|
18
|
+
)
|
19
|
+
create_c_function_to_house_statements local_scope.outer_scope
|
20
|
+
analyse_tails local_scope
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_code(code, local_scope)
|
24
|
+
code.nl
|
25
|
+
code << '/* begin-rescue-else-ensure-end block begins: */'
|
26
|
+
code.nl
|
27
|
+
super
|
28
|
+
cb_c_name = local_scope.find(@begin_func.name).c_name
|
29
|
+
state_var = local_scope.find(@state_var_name).c_name
|
30
|
+
code << "#{state_var} = 0;\n"
|
31
|
+
code << "rb_protect(#{cb_c_name}, Qnil, &#{state_var});"
|
32
|
+
code.nl
|
33
|
+
generate_rescue_else_ensure code, local_scope
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def generate_rescue_else_ensure(code, local_scope)
|
39
|
+
err_state_var = local_scope.find(@error_var_name).c_name
|
40
|
+
set_error_state_variable err_state_var, code, local_scope
|
41
|
+
set_unhandled_error_variable code, local_scope
|
42
|
+
generate_rescue_blocks err_state_var, code, local_scope
|
43
|
+
generate_else_block code, local_scope
|
44
|
+
generate_ensure_block code, local_scope
|
45
|
+
generate_rb_jump_tag err_state_var, code, local_scope
|
46
|
+
code << "rb_set_errinfo(Qnil);\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
def declare_unhandled_error_variable(local_scope)
|
50
|
+
@unhandled_err_var_name = 'begin_block_' + local_scope.begin_block_counter.to_s + '_unhandled_error'
|
51
|
+
local_scope.declare_var(
|
52
|
+
name: @unhandled_err_var_name,
|
53
|
+
c_name: Rubex::VAR_PREFIX + @unhandled_err_var_name,
|
54
|
+
type: DataType::Int.new
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_unhandled_error_variable(code, local_scope)
|
59
|
+
n = local_scope.find(@unhandled_err_var_name).c_name
|
60
|
+
code << "#{n} = 0;"
|
61
|
+
code.nl
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_rb_jump_tag(_err_state_var, code, local_scope)
|
65
|
+
state_var = local_scope.find(@state_var_name).c_name
|
66
|
+
code << "if (#{local_scope.find(@unhandled_err_var_name).c_name})"
|
67
|
+
code.block do
|
68
|
+
code << "rb_jump_tag(#{state_var});"
|
69
|
+
code.nl
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def generate_ensure_block(code, local_scope)
|
74
|
+
ensure_block = @tails.select { |e| e.is_a?(Ensure) }[0]
|
75
|
+
ensure_block&.generate_code(code, local_scope)
|
76
|
+
end
|
77
|
+
|
78
|
+
# We use a goto statement to jump to the ensure block so that when a
|
79
|
+
# condition arises where no error is raised, the ensure statement will
|
80
|
+
# be executed, after which rb_jump_tag() will be called.
|
81
|
+
def generate_else_block(code, local_scope)
|
82
|
+
else_block = @tails.select { |t| t.is_a?(Else) }[0]
|
83
|
+
|
84
|
+
code << 'else'
|
85
|
+
code.block do
|
86
|
+
state_var = local_scope.find(@state_var_name).c_name
|
87
|
+
code << '/* If exception not among those captured in raise */'
|
88
|
+
code.nl
|
89
|
+
|
90
|
+
code << "if (#{state_var})"
|
91
|
+
code.block do
|
92
|
+
code << "#{local_scope.find(@unhandled_err_var_name).c_name} = 1;"
|
93
|
+
code.nl
|
94
|
+
end
|
95
|
+
|
96
|
+
if else_block
|
97
|
+
code << 'else'
|
98
|
+
code.block do
|
99
|
+
else_block.generate_code code, local_scope
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_error_state_variable(err_state_var, code, _local_scope)
|
106
|
+
code << "#{err_state_var} = rb_errinfo();"
|
107
|
+
code.nl
|
108
|
+
end
|
109
|
+
|
110
|
+
def generate_rescue_blocks(err_state_var, code, local_scope)
|
111
|
+
if @tails[0].is_a?(Rescue)
|
112
|
+
generate_first_rescue_block err_state_var, code, local_scope
|
113
|
+
|
114
|
+
@tails[1..-1].grep(Rescue).each do |resc|
|
115
|
+
else_if_cond = rescue_condition err_state_var, resc, code, local_scope
|
116
|
+
code << "else if (#{else_if_cond})"
|
117
|
+
code.block do
|
118
|
+
resc.generate_code code, local_scope
|
119
|
+
end
|
120
|
+
end
|
121
|
+
else # no rescue blocks present
|
122
|
+
code << "if (0) {}\n"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def generate_first_rescue_block(err_state_var, code, local_scope)
|
127
|
+
code << "if (#{rescue_condition(err_state_var, @tails[0], code, local_scope)})"
|
128
|
+
code.block do
|
129
|
+
@tails[0].generate_code code, local_scope
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def rescue_condition(err_state_var, resc, code, local_scope)
|
134
|
+
resc.error_klass.generate_evaluation_code code, local_scope
|
135
|
+
cond = "RTEST(rb_funcall(#{err_state_var}, rb_intern(\"kind_of?\")"
|
136
|
+
cond << ", 1, #{resc.error_klass.c_code(local_scope)}))"
|
137
|
+
|
138
|
+
cond
|
139
|
+
end
|
140
|
+
|
141
|
+
def declare_error_state_variable(local_scope)
|
142
|
+
@state_var_name = 'begin_block_' + local_scope.begin_block_counter.to_s + '_state'
|
143
|
+
local_scope.declare_var(
|
144
|
+
name: @state_var_name,
|
145
|
+
c_name: Rubex::VAR_PREFIX + @state_var_name,
|
146
|
+
type: DataType::Int.new
|
147
|
+
)
|
148
|
+
end
|
149
|
+
|
150
|
+
def declare_error_klass_variable(local_scope)
|
151
|
+
@error_var_name = 'begin_block_' + local_scope.begin_block_counter.to_s + '_exec'
|
152
|
+
local_scope.declare_var(
|
153
|
+
name: @error_var_name,
|
154
|
+
c_name: Rubex::VAR_PREFIX + @error_var_name,
|
155
|
+
type: DataType::RubyObject.new
|
156
|
+
)
|
157
|
+
end
|
158
|
+
|
159
|
+
def block_name(local_scope)
|
160
|
+
'begin_block_' + local_scope.klass_name + '_' + local_scope.name + '_' +
|
161
|
+
local_scope.begin_block_counter.to_s
|
162
|
+
end
|
163
|
+
|
164
|
+
def create_c_function_to_house_statements(scope)
|
165
|
+
func_name = @block_scope.name
|
166
|
+
arg_list = Statement::ArgumentList.new([
|
167
|
+
AST::Expression::ArgDeclaration.new(
|
168
|
+
{ dtype: 'object', variables: [{ ident: 'dummy' }] }
|
169
|
+
)
|
170
|
+
])
|
171
|
+
@begin_func = TopStatement::CFunctionDef.new(
|
172
|
+
'object', '', func_name, arg_list, @statements
|
173
|
+
)
|
174
|
+
arg_list.analyse_statement @block_scope
|
175
|
+
add_to_symbol_table @begin_func.name, arg_list, scope
|
176
|
+
@begin_func.analyse_statement @block_scope
|
177
|
+
@block_scope.upgrade_symbols_to_global
|
178
|
+
scope.add_begin_block_callback @begin_func
|
179
|
+
end
|
180
|
+
|
181
|
+
def add_to_symbol_table(func_name, arg_list, scope)
|
182
|
+
c_name = Rubex::C_FUNC_PREFIX + func_name
|
183
|
+
scope.add_c_method(
|
184
|
+
name: func_name,
|
185
|
+
c_name: c_name,
|
186
|
+
extern: false,
|
187
|
+
return_type: DataType::RubyObject.new,
|
188
|
+
arg_list: arg_list,
|
189
|
+
scope: @block_scope
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
def analyse_tails(local_scope)
|
194
|
+
@tails.each do |tail|
|
195
|
+
tail.analyse_statement local_scope
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
module BeginBlock
|
5
|
+
class Else < Base
|
6
|
+
def analyse_statement(local_scope)
|
7
|
+
@statements.each do |stmt|
|
8
|
+
stmt.analyse_statement local_scope
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_code(code, local_scope)
|
13
|
+
@statements.each do |stmt|
|
14
|
+
stmt.generate_code code, local_scope
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
module BeginBlock
|
5
|
+
class Ensure < Base
|
6
|
+
def analyse_statement(local_scope)
|
7
|
+
@statements.each do |stmt|
|
8
|
+
stmt.analyse_statement local_scope
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_code(code, local_scope)
|
13
|
+
@statements.each do |stmt|
|
14
|
+
stmt.generate_code code, local_scope
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
module BeginBlock
|
5
|
+
class Rescue < Base
|
6
|
+
attr_reader :error_klass
|
7
|
+
|
8
|
+
def initialize(error_klass, error_obj, statements, location)
|
9
|
+
super(statements, location)
|
10
|
+
@error_klass = error_klass
|
11
|
+
@error_obj = error_obj
|
12
|
+
end
|
13
|
+
|
14
|
+
def analyse_statement(local_scope)
|
15
|
+
@error_klass.analyse_types local_scope
|
16
|
+
unless @error_klass.type.ruby_constant?
|
17
|
+
raise "Must pass an error class to raise. Location #{@location}."
|
18
|
+
end
|
19
|
+
|
20
|
+
@statements.each do |stmt|
|
21
|
+
stmt.analyse_statement local_scope
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_code(code, local_scope)
|
26
|
+
@statements.each do |stmt|
|
27
|
+
stmt.generate_code code, local_scope
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class Break < Base
|
5
|
+
def analyse_statement(local_scope)
|
6
|
+
# TODO: figure whether this is a Ruby break or C break. For now
|
7
|
+
# assuming C break.
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate_code(code, _local_scope)
|
11
|
+
code.write_location @location
|
12
|
+
code << 'break;'
|
13
|
+
code.nl
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|