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,49 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class CArrayDecl < Base
|
5
|
+
attr_reader :type, :array_list, :name, :dimension
|
6
|
+
|
7
|
+
def initialize(type, array_ref, array_list, location)
|
8
|
+
super(location)
|
9
|
+
@name = array_ref.name
|
10
|
+
@array_list = array_list
|
11
|
+
@dimension = array_ref.pos
|
12
|
+
@type = Rubex::TYPE_MAPPINGS[type].new
|
13
|
+
end
|
14
|
+
|
15
|
+
def analyse_statement(local_scope, extern: false)
|
16
|
+
@dimension.analyse_types local_scope
|
17
|
+
create_symbol_table_entry local_scope
|
18
|
+
return if @array_list.nil?
|
19
|
+
analyse_array_list local_scope
|
20
|
+
verify_array_list_types local_scope
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_code(code, local_scope); end
|
24
|
+
|
25
|
+
def rescan_declarations(local_scope); end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def analyse_array_list(local_scope)
|
30
|
+
@array_list.each do |expr|
|
31
|
+
expr.analyse_types(local_scope)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def verify_array_list_types(_local_scope)
|
36
|
+
@array_list.all? do |expr|
|
37
|
+
return true if @type >= expr.type
|
38
|
+
raise "Specified type #{@type} but list contains #{expr.type}."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_symbol_table_entry(local_scope)
|
43
|
+
local_scope.add_carray(name: @name, c_name: Rubex::ARRAY_PREFIX + @name,
|
44
|
+
dimension: @dimension, type: @type, value: @array_list)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class CBaseType < Base
|
5
|
+
attr_reader :type, :name, :value
|
6
|
+
|
7
|
+
def initialize(type, name, value = nil)
|
8
|
+
@type = type
|
9
|
+
@name = name
|
10
|
+
@value = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
self.class == other.class &&
|
15
|
+
type == other.class &&
|
16
|
+
name == other.name &&
|
17
|
+
value == other.value
|
18
|
+
end
|
19
|
+
|
20
|
+
def analyse_statement(_local_scope)
|
21
|
+
@type = Rubex::Helpers.determine_dtype @type
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class CFunctionDecl < Base
|
5
|
+
def initialize(type, return_ptr_level, name, arg_list)
|
6
|
+
@type, @return_ptr_level, @name, @arg_list = type, return_ptr_level,
|
7
|
+
name, arg_list
|
8
|
+
end
|
9
|
+
|
10
|
+
def analyse_statement(local_scope, extern: false)
|
11
|
+
@arg_list&.analyse_statement(local_scope, extern: extern)
|
12
|
+
c_name = extern ? @name : (Rubex::C_FUNC_PREFIX + @name)
|
13
|
+
@entry = local_scope.add_c_method(
|
14
|
+
name: @name,
|
15
|
+
c_name: c_name,
|
16
|
+
return_type: Helpers.determine_dtype(@type, @return_ptr_level),
|
17
|
+
arg_list: @arg_list,
|
18
|
+
scope: nil,
|
19
|
+
extern: extern
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_code(code, local_scope)
|
24
|
+
super
|
25
|
+
code << "/* C function #{@name} declared.*/" if @entry.extern?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class CPtrDecl < Base
|
5
|
+
attr_reader :entry, :type
|
6
|
+
|
7
|
+
def initialize(type, name, value, ptr_level, location)
|
8
|
+
super(location)
|
9
|
+
@name = name
|
10
|
+
@type = type
|
11
|
+
@value = value
|
12
|
+
@ptr_level = ptr_level
|
13
|
+
end
|
14
|
+
|
15
|
+
def analyse_statement(local_scope, extern: false)
|
16
|
+
cptr_cname extern
|
17
|
+
@type = Helpers.determine_dtype @type, @ptr_level
|
18
|
+
if @value
|
19
|
+
@value.analyse_for_target_type(@type, local_scope)
|
20
|
+
@value = Helpers.to_lhs_type(self, @value)
|
21
|
+
end
|
22
|
+
|
23
|
+
@entry = local_scope.declare_var name: @name, c_name: @c_name,
|
24
|
+
type: @type, value: @value, extern: extern
|
25
|
+
end
|
26
|
+
|
27
|
+
def rescan_declarations(local_scope)
|
28
|
+
base_type = @entry.type.base_type
|
29
|
+
if base_type.is_a? String
|
30
|
+
type = Helpers.determine_dtype base_type, @ptr_level
|
31
|
+
local_scope[@name].type = type
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_code(code, local_scope)
|
36
|
+
if @value
|
37
|
+
@value.generate_evaluation_code code, local_scope
|
38
|
+
code << "#{local_scope.find(@name).c_name} = #{@value.c_code(local_scope)};"
|
39
|
+
code.nl
|
40
|
+
@value.generate_disposal_code code
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def cptr_cname(extern)
|
47
|
+
@c_name = extern ? @name : Rubex::POINTER_PREFIX + @name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class CPtrFuncDecl < CPtrDecl
|
5
|
+
def initialize(type, name, value, ptr_level, location)
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
def analyse_statement(local_scope, extern: false)
|
10
|
+
cptr_cname extern
|
11
|
+
ident = @type[:ident]
|
12
|
+
ident[:arg_list].analyse_statement(local_scope)
|
13
|
+
@type = DataType::CFunction.new(
|
14
|
+
@name,
|
15
|
+
@c_name,
|
16
|
+
ident[:arg_list],
|
17
|
+
Helpers.determine_dtype(@type[:dtype], ident[:return_ptr_level]),
|
18
|
+
nil
|
19
|
+
)
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class CStructOrUnionDef < Base
|
5
|
+
attr_reader :name, :declarations, :type, :kind, :entry, :scope
|
6
|
+
|
7
|
+
def initialize(kind, name, declarations, location)
|
8
|
+
super(location)
|
9
|
+
@declarations = declarations
|
10
|
+
if /struct/.match kind
|
11
|
+
@kind = :struct
|
12
|
+
elsif /union/.match kind
|
13
|
+
@kind = :union
|
14
|
+
end
|
15
|
+
@name = name
|
16
|
+
end
|
17
|
+
|
18
|
+
def analyse_statement(outer_scope, extern: false)
|
19
|
+
@scope = Rubex::SymbolTable::Scope::StructOrUnion.new(
|
20
|
+
@name, outer_scope
|
21
|
+
)
|
22
|
+
c_name = if extern
|
23
|
+
@kind.to_s + " " + @name
|
24
|
+
else
|
25
|
+
Rubex::TYPE_PREFIX + @scope.klass_name + "_" + @name
|
26
|
+
end
|
27
|
+
@type = Rubex::DataType::CStructOrUnion.new(@kind, @name, c_name,
|
28
|
+
@scope)
|
29
|
+
|
30
|
+
@declarations.each do |decl|
|
31
|
+
decl.analyse_statement @scope, extern: extern
|
32
|
+
end
|
33
|
+
Rubex::CUSTOM_TYPES[@name] = @type
|
34
|
+
@entry = outer_scope.declare_sue(name: @name, c_name: c_name,
|
35
|
+
type: @type, extern: extern)
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_code(code, local_scope = nil); end
|
39
|
+
|
40
|
+
def rescan_declarations(_local_scope)
|
41
|
+
@declarations.each do |decl|
|
42
|
+
decl.respond_to?(:rescan_declarations) &&
|
43
|
+
decl.rescan_declarations(@scope)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class Expression < Base
|
5
|
+
def initialize(expr, location)
|
6
|
+
super(location)
|
7
|
+
@expr = expr
|
8
|
+
end
|
9
|
+
|
10
|
+
def analyse_statement(local_scope)
|
11
|
+
@expr.analyse_types local_scope
|
12
|
+
@expr.allocate_temps local_scope
|
13
|
+
@expr.release_temps local_scope
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate_code(code, local_scope)
|
17
|
+
super
|
18
|
+
@expr.generate_evaluation_code code, local_scope
|
19
|
+
code << @expr.c_code(local_scope) + ';'
|
20
|
+
code.nl
|
21
|
+
@expr.generate_disposal_code code
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class For < Base
|
5
|
+
def initialize(left_expr, left_op, middle, right_op, right_expr, statements, location)
|
6
|
+
super(location)
|
7
|
+
@left_expr = left_expr
|
8
|
+
@left_op = left_op
|
9
|
+
@middle = middle
|
10
|
+
@right_op = right_op
|
11
|
+
@right_expr = right_expr
|
12
|
+
@statements = statements
|
13
|
+
end
|
14
|
+
|
15
|
+
def analyse_statement(local_scope)
|
16
|
+
@left_expr.analyse_types local_scope
|
17
|
+
@right_expr.analyse_types local_scope
|
18
|
+
|
19
|
+
[@left_expr, @right_expr].each do |e|
|
20
|
+
e.allocate_temps local_scope
|
21
|
+
end
|
22
|
+
[@left_expr, @right_expr].each do |e|
|
23
|
+
e.release_temps local_scope
|
24
|
+
end
|
25
|
+
|
26
|
+
@middle = local_scope[@middle] # middle will not be an expr.
|
27
|
+
@statements.each do |stat|
|
28
|
+
stat.analyse_statement local_scope
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_code(code, local_scope)
|
33
|
+
code << for_loop_header(code, local_scope)
|
34
|
+
code.block do
|
35
|
+
@statements.each do |stat|
|
36
|
+
stat.generate_code code, local_scope
|
37
|
+
end
|
38
|
+
end
|
39
|
+
@left_expr.generate_disposal_code code
|
40
|
+
@right_expr.generate_disposal_code code
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def for_loop_header(code, local_scope)
|
46
|
+
@left_expr.generate_evaluation_code code, local_scope
|
47
|
+
@right_expr.generate_evaluation_code code, local_scope
|
48
|
+
for_stmt = ''
|
49
|
+
for_stmt << "for (#{@middle.c_name} = #{@left_expr.c_code(local_scope)}"
|
50
|
+
|
51
|
+
if @left_op == '<'
|
52
|
+
for_stmt << ' + 1'
|
53
|
+
elsif @left_op == '>'
|
54
|
+
for_stmt << ' - 1'
|
55
|
+
end
|
56
|
+
|
57
|
+
for_stmt << "; #{@middle.c_name} #{@right_op} #{@right_expr.c_code(local_scope)}; "
|
58
|
+
for_stmt << (@middle.c_name).to_s
|
59
|
+
|
60
|
+
if ['>', '>='].include? @right_op
|
61
|
+
for_stmt << '--'
|
62
|
+
elsif ['<', '<='].include? @right_op
|
63
|
+
for_stmt << '++'
|
64
|
+
end
|
65
|
+
|
66
|
+
for_stmt << ')'
|
67
|
+
|
68
|
+
for_stmt
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Statement
|
4
|
+
class ForwardDecl < Base
|
5
|
+
def initialize(kind, name, location)
|
6
|
+
super(location)
|
7
|
+
@name = name
|
8
|
+
if /struct/.match kind
|
9
|
+
@kind = :struct
|
10
|
+
elsif /union/.match kind
|
11
|
+
@kind = :union
|
12
|
+
end
|
13
|
+
Rubex::CUSTOM_TYPES[@name] = @name
|
14
|
+
end
|
15
|
+
|
16
|
+
def analyse_statement(local_scope, extern: false)
|
17
|
+
@c_name = Rubex::TYPE_PREFIX + local_scope.klass_name + '_' + @name
|
18
|
+
@type = Rubex::DataType::TypeDef.new("#{@kind} #{@name}", @c_name, @type)
|
19
|
+
local_scope.declare_type type: @type, extern: extern
|
20
|
+
end
|
21
|
+
|
22
|
+
def rescan_declarations(_local_scope)
|
23
|
+
@type = Rubex::DataType::TypeDef.new("#{@kind} #{@name}", @c_name,
|
24
|
+
Rubex::CUSTOM_TYPES[@name])
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate_code(code, local_scope); end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative 'if_block/helper'
|
2
|
+
module Rubex
|
3
|
+
module AST
|
4
|
+
module Statement
|
5
|
+
class IfBlock < Base
|
6
|
+
attr_reader :expr, :statements, :if_tail
|
7
|
+
include Rubex::AST::Statement::IfBlock::Helper
|
8
|
+
|
9
|
+
def initialize(expr, statements, if_tail, location)
|
10
|
+
super(location)
|
11
|
+
@expr = expr
|
12
|
+
@statements = statements
|
13
|
+
@if_tail = if_tail
|
14
|
+
end
|
15
|
+
|
16
|
+
def analyse_statement(local_scope)
|
17
|
+
@tail_exprs = if_tail_exprs # FIME: gets current expr too. make descriptive.
|
18
|
+
@tail_exprs.each do |tail|
|
19
|
+
tail.analyse_types local_scope
|
20
|
+
tail.allocate_temps local_scope
|
21
|
+
end
|
22
|
+
|
23
|
+
@tail_exprs.each do |tail|
|
24
|
+
tail.release_temps local_scope
|
25
|
+
end
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
def if_tail_exprs
|
30
|
+
tail_exprs = []
|
31
|
+
temp = self
|
32
|
+
while temp.respond_to?(:if_tail) &&
|
33
|
+
!temp.is_a?(Rubex::AST::Statement::IfBlock::Else)
|
34
|
+
tail_exprs << temp.expr
|
35
|
+
temp = temp.if_tail
|
36
|
+
end
|
37
|
+
|
38
|
+
tail_exprs
|
39
|
+
end
|
40
|
+
|
41
|
+
def generate_code(code, local_scope)
|
42
|
+
@tail_exprs.each do |tail|
|
43
|
+
tail.generate_evaluation_code(code, local_scope)
|
44
|
+
end
|
45
|
+
generate_code_for_statement 'if', code, local_scope, self
|
46
|
+
|
47
|
+
tail = @if_tail
|
48
|
+
while tail
|
49
|
+
if tail.is_a?(Elsif)
|
50
|
+
generate_code_for_statement 'else if', code, local_scope, tail
|
51
|
+
elsif tail.is_a?(Else)
|
52
|
+
generate_code_for_statement 'else', code, local_scope, tail
|
53
|
+
end
|
54
|
+
tail = tail.if_tail
|
55
|
+
end
|
56
|
+
|
57
|
+
@tail_exprs.each do |tail|
|
58
|
+
tail.generate_disposal_code code
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
module Rubex
|
3
|
+
module AST
|
4
|
+
module Statement
|
5
|
+
class IfBlock < Base
|
6
|
+
class Else < Base
|
7
|
+
attr_reader :statements
|
8
|
+
include Rubex::AST::Statement::IfBlock::Helper
|
9
|
+
|
10
|
+
def initialize(statements, location)
|
11
|
+
super(location)
|
12
|
+
@statements = statements
|
13
|
+
end
|
14
|
+
|
15
|
+
def analyse_statement(local_scope)
|
16
|
+
@statements.each do |stat|
|
17
|
+
stat.analyse_statement local_scope
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_code(code, local_scope); end
|
22
|
+
|
23
|
+
def if_tail
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|