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,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
|