class Ikra::Translator::ASTTranslator
Attributes
expression_translator[R]
statement_translator[R]
Public Class Methods
new()
click to toggle source
# File lib/translator/ast_translator.rb, line 464 def initialize @expression_translator = ExpressionTranslator.new(self) @statement_translator = StatementTranslator.new(self) end
translate_block(block_def_node)
click to toggle source
# File lib/translator/ast_translator.rb, line 520 def self.translate_block(block_def_node) return self.new.translate_block(block_def_node) end
translate_method(method_def_node)
click to toggle source
# File lib/translator/ast_translator.rb, line 528 def self.translate_method(method_def_node) return self.new.translate_method(method_def_node) end
Public Instance Methods
define_assign_variable(name, node)
click to toggle source
Generates code that assigns the value of a node to a newly-defined variable.
# File lib/translator/ast_translator.rb, line 494 def define_assign_variable(name, node) type = node.get_type.to_c_type return "#{type} #{name} = #{node.accept(expression_translator)};" end
generate_method_signature(meth_def_node)
click to toggle source
# File lib/translator/ast_translator.rb, line 532 def generate_method_signature(meth_def_node) method_params = ([ "environment_t * #{Constants::ENV_IDENTIFIER}", "#{meth_def_node.parent.get_type.to_c_type} #{Constants::SELF_IDENTIFIER}"] + meth_def_node.parameters_names_and_types.map do |name, type| "#{type.singleton_type.to_c_type} #{name}" end).join(", ") signature = "__device__ #{meth_def_node.get_type.singleton_type.to_c_type} #{meth_def_node.parent.get_type.mangled_method_name(meth_def_node.name)}(#{method_params})" return signature end
indent_block(str)
click to toggle source
# File lib/translator/ast_translator.rb, line 473 def indent_block(str) return str.split("\n").map do |line| " " + line end.join("\n") end
statements_as_expression(str)
click to toggle source
# File lib/translator/ast_translator.rb, line 469 def statements_as_expression(str) return "[&]#{wrap_in_c_block(str, omit_newl: true)}()" end
temp_identifier_id()
click to toggle source
# File lib/translator/ast_translator.rb, line 488 def temp_identifier_id @@next_temp_identifier_id += 1 @@next_temp_identifier_id end
translate_block(block_def_node)
click to toggle source
# File lib/translator/ast_translator.rb, line 524 def translate_block(block_def_node) return block_def_node.body.accept(statement_translator) end
translate_method(meth_def_node)
click to toggle source
# File lib/translator/ast_translator.rb, line 549 def translate_method(meth_def_node) # TODO: merge with BlockTranslator # TODO: load environment variables # Declare local variables local_variables_def = "" meth_def_node.local_variables_names_and_types.each do |name, type| local_variables_def += "#{type.to_c_type} #{name};\n" end # TODO: There should be a better way to ensure that we don't generate methods # multiple times. mangled_name = meth_def_node.parent.get_type.mangled_method_name(meth_def_node.name) def_label = "def_label_#{mangled_name}" return "#ifndef #{def_label}\n#define #{def_label}\n" + generate_method_signature(meth_def_node) + "\n" + wrap_in_c_block(local_variables_def + meth_def_node.body.accept(statement_translator)) + "#endif" end
translate_method_predecl(meth_def_node)
click to toggle source
# File lib/translator/ast_translator.rb, line 545 def translate_method_predecl(meth_def_node) return generate_method_signature(meth_def_node) + ";" end
wrap_in_c_block(str, omit_newl: false)
click to toggle source
# File lib/translator/ast_translator.rb, line 477 def wrap_in_c_block(str, omit_newl: false) result = "{\n" + indent_block(str) + "\n}" if omit_newl return result else return result + "\n" end end
wrap_in_union_type(str, type)
click to toggle source
# File lib/translator/ast_translator.rb, line 499 def wrap_in_union_type(str, type) if type == Types::PrimitiveType::Int return "union_t(#{type.class_id}, union_v_t::from_int(#{str}))" elsif type == Types::PrimitiveType::Float return "union_t(#{type.class_id}, union_v_t::from_float(#{str}))" elsif type == Types::PrimitiveType::Bool return "union_t(#{type.class_id}, union_v_t::from_bool(#{str}))" elsif type == Types::PrimitiveType::Nil return "union_t(#{type.class_id}, union_v_t::from_int(#{str}))" elsif type.is_a?(Symbolic::ArrayCommand) return "union_t(#{type.class_id}, union_v_t::from_pointer((void *) #{str}))" elsif type.is_a?(Types::LocationAwareArrayType) # TODO: Should not use variable_size_array for fixed size arrays return "union_t(#{type.class_id}, union_v_t::from_variable_size_array_t(#{str}))" elsif !type.is_a?(Types::UnionType) return "union_t(#{type.class_id}, union_v_t::from_object_id(#{str}))" else raise AssertionError.new("UnionType found but singleton type expected") end end