|
|
|
@ -16,12 +16,12 @@ namespace elna
|
|
|
|
|
{
|
|
|
|
|
namespace gcc
|
|
|
|
|
{
|
|
|
|
|
generic_visitor::generic_visitor(std::shared_ptr<source::symbol_table<tree>> symbol_table)
|
|
|
|
|
generic_visitor::generic_visitor(std::shared_ptr<boot::symbol_table<tree>> symbol_table)
|
|
|
|
|
{
|
|
|
|
|
this->symbol_map = symbol_table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::call_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::call_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
if (auto symbol = this->symbol_map->lookup(expression->name()))
|
|
|
|
|
{
|
|
|
|
@ -57,7 +57,7 @@ namespace gcc
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::cast_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::cast_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
tree cast_target = build_type(expression->target());
|
|
|
|
|
gcc_assert(cast_target != NULL_TREE);
|
|
|
|
@ -68,14 +68,23 @@ namespace gcc
|
|
|
|
|
cast_target, this->current_expression);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::size_of_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::size_of_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
auto body_type = build_type(expression->body());
|
|
|
|
|
|
|
|
|
|
this->current_expression = build1(CONVERT_EXPR, integer_type_node, TYPE_SIZE_UNIT(body_type));
|
|
|
|
|
this->current_expression = build1(CONVERT_EXPR,
|
|
|
|
|
this->symbol_map->lookup("Word")->payload, TYPE_SIZE_UNIT(body_type));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::program *program)
|
|
|
|
|
bool generic_visitor::is_integral_type(tree type)
|
|
|
|
|
{
|
|
|
|
|
gcc_assert(TYPE_P(type));
|
|
|
|
|
|
|
|
|
|
return type == this->symbol_map->lookup("Int")->payload
|
|
|
|
|
|| type == this->symbol_map->lookup("Word")->payload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(boot::program *program)
|
|
|
|
|
{
|
|
|
|
|
for (const auto definition : program->value_definitions)
|
|
|
|
|
{
|
|
|
|
@ -119,7 +128,7 @@ namespace gcc
|
|
|
|
|
cgraph_node::finalize_function(this->main_fndecl, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::procedure_definition *definition)
|
|
|
|
|
void generic_visitor::visit(boot::procedure_definition *definition)
|
|
|
|
|
{
|
|
|
|
|
std::vector<tree> parameter_types(definition->parameters.size());
|
|
|
|
|
|
|
|
|
@ -133,7 +142,7 @@ namespace gcc
|
|
|
|
|
tree declaration_type = build_function_type_array(return_type,
|
|
|
|
|
definition->parameters.size(), parameter_types.data());
|
|
|
|
|
this->main_fndecl = build_fn_decl(definition->identifier().c_str(), declaration_type);
|
|
|
|
|
this->symbol_map->enter(definition->identifier(), source::make_info(this->main_fndecl));
|
|
|
|
|
this->symbol_map->enter(definition->identifier(), boot::make_info(this->main_fndecl));
|
|
|
|
|
|
|
|
|
|
if (definition->body() != nullptr)
|
|
|
|
|
{
|
|
|
|
@ -155,7 +164,7 @@ namespace gcc
|
|
|
|
|
|
|
|
|
|
if (definition->body() != nullptr)
|
|
|
|
|
{
|
|
|
|
|
this->symbol_map->enter(parameter->identifier(), source::make_info(declaration_tree));
|
|
|
|
|
this->symbol_map->enter(parameter->identifier(), boot::make_info(declaration_tree));
|
|
|
|
|
}
|
|
|
|
|
argument_chain.append(declaration_tree);
|
|
|
|
|
}
|
|
|
|
@ -187,7 +196,7 @@ namespace gcc
|
|
|
|
|
{
|
|
|
|
|
this->current_statements = alloc_stmt_list();
|
|
|
|
|
this->variable_chain = tree_chain();
|
|
|
|
|
this->symbol_map = std::make_shared<source::symbol_table<tree>>(this->symbol_map);
|
|
|
|
|
this->symbol_map = std::make_shared<boot::symbol_table<tree>>(this->symbol_map);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tree_symbol_mapping generic_visitor::leave_scope()
|
|
|
|
@ -201,17 +210,21 @@ namespace gcc
|
|
|
|
|
return tree_symbol_mapping{ bind_expr, new_block };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::number_literal<std::int32_t> *literal)
|
|
|
|
|
void generic_visitor::visit(boot::number_literal<std::int32_t> *literal)
|
|
|
|
|
{
|
|
|
|
|
this->current_expression = build_int_cst(integer_type_node, literal->number());
|
|
|
|
|
auto symbol = this->symbol_map->lookup("Int");
|
|
|
|
|
|
|
|
|
|
this->current_expression = build_int_cst(symbol->payload, literal->number());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::number_literal<std::uint32_t> *literal)
|
|
|
|
|
void generic_visitor::visit(boot::number_literal<std::uint32_t> *literal)
|
|
|
|
|
{
|
|
|
|
|
this->current_expression = build_int_cstu(unsigned_type_node, literal->number());
|
|
|
|
|
auto symbol = this->symbol_map->lookup("Word");
|
|
|
|
|
|
|
|
|
|
this->current_expression = build_int_cstu(symbol->payload, literal->number());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::number_literal<double> *literal)
|
|
|
|
|
void generic_visitor::visit(boot::number_literal<double> *literal)
|
|
|
|
|
{
|
|
|
|
|
REAL_VALUE_TYPE real_value1;
|
|
|
|
|
|
|
|
|
@ -226,27 +239,27 @@ namespace gcc
|
|
|
|
|
mpfr_clear(number);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::number_literal<bool> *boolean)
|
|
|
|
|
void generic_visitor::visit(boot::number_literal<bool> *boolean)
|
|
|
|
|
{
|
|
|
|
|
this->current_expression = build_int_cst_type(boolean_type_node, boolean->number());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::number_literal<unsigned char> *character)
|
|
|
|
|
void generic_visitor::visit(boot::number_literal<unsigned char> *character)
|
|
|
|
|
{
|
|
|
|
|
this->current_expression = build_int_cstu(elna_char_type_node, character->number());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::number_literal<nullptr_t> *)
|
|
|
|
|
void generic_visitor::visit(boot::number_literal<nullptr_t> *)
|
|
|
|
|
{
|
|
|
|
|
this->current_expression = null_pointer_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::string_literal *string)
|
|
|
|
|
void generic_visitor::visit(boot::string_literal *string)
|
|
|
|
|
{
|
|
|
|
|
this->current_expression = build_string_literal(string->string().size() + 1, string->string().c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::build_binary_operation(bool condition, source::binary_expression *expression,
|
|
|
|
|
void generic_visitor::build_binary_operation(bool condition, boot::binary_expression *expression,
|
|
|
|
|
tree_code operator_code, tree left, tree right, tree target_type)
|
|
|
|
|
{
|
|
|
|
|
auto expression_location = get_location(&expression->position());
|
|
|
|
@ -263,12 +276,12 @@ namespace gcc
|
|
|
|
|
error_at(expression_location,
|
|
|
|
|
"invalid operands of type %s and %s for operator %s",
|
|
|
|
|
print_type(left_type), print_type(right_type),
|
|
|
|
|
elna::source::print_binary_operator(expression->operation()));
|
|
|
|
|
elna::boot::print_binary_operator(expression->operation()));
|
|
|
|
|
this->current_expression = error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::binary_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::binary_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
expression->lhs().accept(this);
|
|
|
|
|
auto left = this->current_expression;
|
|
|
|
@ -282,9 +295,8 @@ namespace gcc
|
|
|
|
|
tree_code operator_code = ERROR_MARK;
|
|
|
|
|
tree target_type = error_mark_node;
|
|
|
|
|
|
|
|
|
|
if (is_pointer_type(left_type)
|
|
|
|
|
&& (right_type == integer_type_node || right_type == unsigned_type_node)
|
|
|
|
|
&& expression->operation() == source::binary_operator::sum)
|
|
|
|
|
if (is_pointer_type(left_type) && is_integral_type(right_type)
|
|
|
|
|
&& expression->operation() == boot::binary_operator::sum)
|
|
|
|
|
{
|
|
|
|
|
tree convert_expression = build1_loc(expression_location, CONVERT_EXPR,
|
|
|
|
|
sizetype, right);
|
|
|
|
@ -297,45 +309,45 @@ namespace gcc
|
|
|
|
|
error_at(expression_location,
|
|
|
|
|
"invalid operands of type %s and %s for operator %s",
|
|
|
|
|
print_type(left_type), print_type(right_type),
|
|
|
|
|
elna::source::print_binary_operator(expression->operation()));
|
|
|
|
|
boot::print_binary_operator(expression->operation()));
|
|
|
|
|
this->current_expression = error_mark_node;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
switch (expression->operation())
|
|
|
|
|
{
|
|
|
|
|
case source::binary_operator::sum:
|
|
|
|
|
case boot::binary_operator::sum:
|
|
|
|
|
operator_code = PLUS_EXPR;
|
|
|
|
|
target_type = left_type;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::subtraction:
|
|
|
|
|
case boot::binary_operator::subtraction:
|
|
|
|
|
operator_code = MINUS_EXPR;
|
|
|
|
|
target_type = left_type;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::division:
|
|
|
|
|
case boot::binary_operator::division:
|
|
|
|
|
operator_code = TRUNC_DIV_EXPR;
|
|
|
|
|
target_type = left_type;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::remainder:
|
|
|
|
|
case boot::binary_operator::remainder:
|
|
|
|
|
operator_code = TRUNC_MOD_EXPR;
|
|
|
|
|
target_type = left_type;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::multiplication:
|
|
|
|
|
case boot::binary_operator::multiplication:
|
|
|
|
|
operator_code = MULT_EXPR;
|
|
|
|
|
target_type = left_type;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::less:
|
|
|
|
|
case boot::binary_operator::less:
|
|
|
|
|
operator_code = LT_EXPR;
|
|
|
|
|
target_type = boolean_type_node;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::greater:
|
|
|
|
|
case boot::binary_operator::greater:
|
|
|
|
|
operator_code = GT_EXPR;
|
|
|
|
|
target_type = boolean_type_node;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::less_equal:
|
|
|
|
|
case boot::binary_operator::less_equal:
|
|
|
|
|
operator_code = LE_EXPR;
|
|
|
|
|
target_type = boolean_type_node;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::greater_equal:
|
|
|
|
|
case boot::binary_operator::greater_equal:
|
|
|
|
|
operator_code = GE_EXPR;
|
|
|
|
|
target_type = boolean_type_node;
|
|
|
|
|
break;
|
|
|
|
@ -344,17 +356,17 @@ namespace gcc
|
|
|
|
|
}
|
|
|
|
|
if (operator_code != ERROR_MARK) // An arithmetic operation.
|
|
|
|
|
{
|
|
|
|
|
build_binary_operation(left_type == integer_type_node || left_type == double_type_node,
|
|
|
|
|
build_binary_operation(is_integral_type(left_type) || left_type == double_type_node,
|
|
|
|
|
expression, operator_code, left, right, target_type);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
switch (expression->operation())
|
|
|
|
|
{
|
|
|
|
|
case source::binary_operator::conjunction:
|
|
|
|
|
case boot::binary_operator::conjunction:
|
|
|
|
|
operator_code = TRUTH_ANDIF_EXPR;
|
|
|
|
|
target_type = boolean_type_node;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::disjunction:
|
|
|
|
|
case boot::binary_operator::disjunction:
|
|
|
|
|
operator_code = TRUTH_ORIF_EXPR;
|
|
|
|
|
target_type = boolean_type_node;
|
|
|
|
|
break;
|
|
|
|
@ -369,11 +381,11 @@ namespace gcc
|
|
|
|
|
}
|
|
|
|
|
switch (expression->operation())
|
|
|
|
|
{
|
|
|
|
|
case source::binary_operator::equals:
|
|
|
|
|
case boot::binary_operator::equals:
|
|
|
|
|
operator_code = EQ_EXPR;
|
|
|
|
|
target_type = boolean_type_node;
|
|
|
|
|
break;
|
|
|
|
|
case source::binary_operator::not_equals:
|
|
|
|
|
case boot::binary_operator::not_equals:
|
|
|
|
|
operator_code = NE_EXPR;
|
|
|
|
|
target_type = boolean_type_node;
|
|
|
|
|
break;
|
|
|
|
@ -387,34 +399,34 @@ namespace gcc
|
|
|
|
|
operator_code, target_type, left, right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::unary_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::unary_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
expression->operand().accept(this);
|
|
|
|
|
|
|
|
|
|
switch (expression->operation())
|
|
|
|
|
{
|
|
|
|
|
case source::unary_operator::reference:
|
|
|
|
|
case boot::unary_operator::reference:
|
|
|
|
|
TREE_ADDRESSABLE(this->current_expression) = 1;
|
|
|
|
|
this->current_expression = build_fold_addr_expr_with_type_loc(get_location(&expression->position()),
|
|
|
|
|
this->current_expression,
|
|
|
|
|
build_pointer_type_for_mode(TREE_TYPE(this->current_expression), VOIDmode, true));
|
|
|
|
|
TREE_NO_TRAMPOLINE(this->current_expression) = 1;
|
|
|
|
|
break;
|
|
|
|
|
case source::unary_operator::negation:
|
|
|
|
|
case boot::unary_operator::negation:
|
|
|
|
|
this->current_expression = build1_loc(get_location(&expression->position()), TRUTH_NOT_EXPR,
|
|
|
|
|
boolean_type_node, this->current_expression);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::constant_definition *definition)
|
|
|
|
|
void generic_visitor::visit(boot::constant_definition *definition)
|
|
|
|
|
{
|
|
|
|
|
location_t definition_location = get_location(&definition->position());
|
|
|
|
|
definition->body().accept(this);
|
|
|
|
|
|
|
|
|
|
tree definition_tree = build_decl(definition_location, CONST_DECL,
|
|
|
|
|
get_identifier(definition->identifier().c_str()), TREE_TYPE(this->current_expression));
|
|
|
|
|
auto result = this->symbol_map->enter(definition->identifier(), source::make_info(definition_tree));
|
|
|
|
|
auto result = this->symbol_map->enter(definition->identifier(), boot::make_info(definition_tree));
|
|
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
|
{
|
|
|
|
@ -435,7 +447,7 @@ namespace gcc
|
|
|
|
|
this->current_expression = NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::type_definition *definition)
|
|
|
|
|
void generic_visitor::visit(boot::type_definition *definition)
|
|
|
|
|
{
|
|
|
|
|
tree tree_type = build_type(definition->body());
|
|
|
|
|
|
|
|
|
@ -446,7 +458,7 @@ namespace gcc
|
|
|
|
|
location_t definition_location = get_location(&definition->position());
|
|
|
|
|
tree definition_tree = build_decl(definition_location, TYPE_DECL,
|
|
|
|
|
get_identifier(definition->identifier().c_str()), tree_type);
|
|
|
|
|
auto result = this->symbol_map->enter(definition->identifier(), source::make_info(tree_type));
|
|
|
|
|
auto result = this->symbol_map->enter(definition->identifier(), boot::make_info(tree_type));
|
|
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
|
{
|
|
|
|
@ -465,9 +477,9 @@ namespace gcc
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tree generic_visitor::build_type(source::type_expression& type)
|
|
|
|
|
tree generic_visitor::build_type(boot::type_expression& type)
|
|
|
|
|
{
|
|
|
|
|
if (source::basic_type_expression *basic_type = type.is_basic())
|
|
|
|
|
if (boot::basic_type_expression *basic_type = type.is_basic())
|
|
|
|
|
{
|
|
|
|
|
auto symbol = this->symbol_map->lookup(basic_type->base_name());
|
|
|
|
|
|
|
|
|
@ -480,7 +492,7 @@ namespace gcc
|
|
|
|
|
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
else if (source::array_type_expression *array_type = type.is_array())
|
|
|
|
|
else if (boot::array_type_expression *array_type = type.is_array())
|
|
|
|
|
{
|
|
|
|
|
tree lower_bound = build_int_cst_type(integer_type_node, 0);
|
|
|
|
|
tree upper_bound = build_int_cst_type(integer_type_node, array_type->size);
|
|
|
|
@ -494,7 +506,7 @@ namespace gcc
|
|
|
|
|
|
|
|
|
|
return build_array_type(base_type, range_type);
|
|
|
|
|
}
|
|
|
|
|
else if (source::pointer_type_expression *pointer_type = type.is_pointer())
|
|
|
|
|
else if (boot::pointer_type_expression *pointer_type = type.is_pointer())
|
|
|
|
|
{
|
|
|
|
|
tree base_type = build_type(pointer_type->base());
|
|
|
|
|
|
|
|
|
@ -504,7 +516,7 @@ namespace gcc
|
|
|
|
|
}
|
|
|
|
|
return build_pointer_type_for_mode(base_type, VOIDmode, true);
|
|
|
|
|
}
|
|
|
|
|
else if (source::record_type_expression *record_type = type.is_record())
|
|
|
|
|
else if (boot::record_type_expression *record_type = type.is_record())
|
|
|
|
|
{
|
|
|
|
|
std::set<std::string> field_names;
|
|
|
|
|
tree record_type_node = make_node(RECORD_TYPE);
|
|
|
|
@ -536,7 +548,7 @@ namespace gcc
|
|
|
|
|
|
|
|
|
|
return record_type_node;
|
|
|
|
|
}
|
|
|
|
|
else if (source::union_type_expression *union_type = type.is_union())
|
|
|
|
|
else if (boot::union_type_expression *union_type = type.is_union())
|
|
|
|
|
{
|
|
|
|
|
std::set<std::string> field_names;
|
|
|
|
|
tree union_type_node = make_node(UNION_TYPE);
|
|
|
|
@ -571,7 +583,7 @@ namespace gcc
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::variable_declaration *declaration)
|
|
|
|
|
void generic_visitor::visit(boot::variable_declaration *declaration)
|
|
|
|
|
{
|
|
|
|
|
tree declaration_type = build_type(declaration->type());
|
|
|
|
|
gcc_assert(declaration_type != NULL_TREE);
|
|
|
|
@ -579,7 +591,7 @@ namespace gcc
|
|
|
|
|
auto declaration_location = get_location(&declaration->position());
|
|
|
|
|
tree declaration_tree = build_decl(declaration_location, VAR_DECL,
|
|
|
|
|
get_identifier(declaration->identifier().c_str()), declaration_type);
|
|
|
|
|
auto result = this->symbol_map->enter(declaration->identifier(), source::make_info(declaration_tree));
|
|
|
|
|
auto result = this->symbol_map->enter(declaration->identifier(), boot::make_info(declaration_tree));
|
|
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
|
{
|
|
|
|
@ -598,7 +610,7 @@ namespace gcc
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::variable_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::variable_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
auto symbol = this->symbol_map->lookup(expression->name());
|
|
|
|
|
|
|
|
|
@ -613,7 +625,7 @@ namespace gcc
|
|
|
|
|
this->current_expression = symbol->payload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::array_access_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::array_access_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
expression->base().accept(this);
|
|
|
|
|
tree designator = this->current_expression;
|
|
|
|
@ -627,7 +639,7 @@ namespace gcc
|
|
|
|
|
ARRAY_REF, element_type, designator, index, NULL_TREE, NULL_TREE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::field_access_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::field_access_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
expression->base().accept(this);
|
|
|
|
|
tree field_declaration = TYPE_FIELDS(TREE_TYPE(this->current_expression));
|
|
|
|
@ -659,7 +671,7 @@ namespace gcc
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::dereference_expression *expression)
|
|
|
|
|
void generic_visitor::visit(boot::dereference_expression *expression)
|
|
|
|
|
{
|
|
|
|
|
expression->base().accept(this);
|
|
|
|
|
|
|
|
|
@ -667,7 +679,7 @@ namespace gcc
|
|
|
|
|
TREE_TYPE(TREE_TYPE(this->current_expression)), this->current_expression);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::assign_statement *statement)
|
|
|
|
|
void generic_visitor::visit(boot::assign_statement *statement)
|
|
|
|
|
{
|
|
|
|
|
statement->lvalue().accept(this);
|
|
|
|
|
|
|
|
|
@ -699,7 +711,7 @@ namespace gcc
|
|
|
|
|
this->current_expression = NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::if_statement *statement)
|
|
|
|
|
void generic_visitor::visit(boot::if_statement *statement)
|
|
|
|
|
{
|
|
|
|
|
tree endif_label_decl = build_label_decl("endif", UNKNOWN_LOCATION);
|
|
|
|
|
tree goto_endif = build1(GOTO_EXPR, void_type_node, endif_label_decl);
|
|
|
|
@ -723,7 +735,7 @@ namespace gcc
|
|
|
|
|
this->current_expression = NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::make_if_branch(source::conditional_statements& branch, tree goto_endif)
|
|
|
|
|
void generic_visitor::make_if_branch(boot::conditional_statements& branch, tree goto_endif)
|
|
|
|
|
{
|
|
|
|
|
branch.prerequisite().accept(this);
|
|
|
|
|
|
|
|
|
@ -767,7 +779,7 @@ namespace gcc
|
|
|
|
|
return label_decl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::while_statement *statement)
|
|
|
|
|
void generic_visitor::visit(boot::while_statement *statement)
|
|
|
|
|
{
|
|
|
|
|
statement->body().prerequisite().accept(this);
|
|
|
|
|
|
|
|
|
@ -816,15 +828,15 @@ namespace gcc
|
|
|
|
|
this->current_expression = NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::expression_statement *statement)
|
|
|
|
|
void generic_visitor::visit(boot::call_statement *statement)
|
|
|
|
|
{
|
|
|
|
|
statement->body().accept(this);
|
|
|
|
|
append_to_statement_list(this->current_expression, &this->current_statements);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void generic_visitor::visit(source::return_statement *statement)
|
|
|
|
|
void generic_visitor::visit(boot::return_statement *statement)
|
|
|
|
|
{
|
|
|
|
|
source::expression *return_expression = statement->return_expression();
|
|
|
|
|
boot::expression *return_expression = statement->return_expression();
|
|
|
|
|
|
|
|
|
|
if (return_expression == nullptr)
|
|
|
|
|
{
|
|
|
|
|