Support the remainder operator
This commit is contained in:
@ -50,14 +50,6 @@ namespace gcc
|
||||
{
|
||||
format_number = "%f\n";
|
||||
}
|
||||
else if (argument_type == elna_char_type_node)
|
||||
{
|
||||
format_number = "%c\n";
|
||||
}
|
||||
else if (is_string_type(argument_type))
|
||||
{
|
||||
format_number = "%s\n";
|
||||
}
|
||||
else if (is_pointer_type(argument_type))
|
||||
{
|
||||
format_number = "%p\n";
|
||||
@ -357,6 +349,10 @@ namespace gcc
|
||||
operator_code = TRUNC_DIV_EXPR;
|
||||
target_type = left_type;
|
||||
break;
|
||||
case source::binary_operator::remainder:
|
||||
operator_code = TRUNC_MOD_EXPR;
|
||||
target_type = left_type;
|
||||
break;
|
||||
case source::binary_operator::multiplication:
|
||||
operator_code = MULT_EXPR;
|
||||
target_type = left_type;
|
||||
@ -737,18 +733,18 @@ namespace gcc
|
||||
|
||||
void generic_visitor::visit(source::if_statement *statement)
|
||||
{
|
||||
statement->prerequisite().accept(this);
|
||||
statement->body().prerequisite().accept(this);
|
||||
|
||||
if (TREE_TYPE(this->current_expression) != boolean_type_node)
|
||||
{
|
||||
error_at(get_location(&statement->prerequisite().position()),
|
||||
error_at(get_location(&statement->body().prerequisite().position()),
|
||||
"expected expression of boolean type but its type is %s",
|
||||
print_type(TREE_TYPE(this->current_expression)));
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
auto then_location = get_location(&statement->body().position());
|
||||
auto prerequisite_location = get_location(&statement->prerequisite().position());
|
||||
auto then_location = get_location(&statement->position());
|
||||
auto prerequisite_location = get_location(&statement->body().prerequisite().position());
|
||||
|
||||
auto then_label_decl = build_label_decl("then", then_location);
|
||||
auto endif_label_decl = build_label_decl("end_if", then_location);
|
||||
@ -762,7 +758,7 @@ namespace gcc
|
||||
tree goto_else_or_endif = NULL_TREE;
|
||||
if (statement->alternative() != nullptr)
|
||||
{
|
||||
auto else_location = get_location(&statement->alternative()->position());
|
||||
auto else_location = get_location(&statement->position());
|
||||
else_label_decl = build_label_decl("else", else_location);
|
||||
goto_else_or_endif = build1_loc(else_location, GOTO_EXPR, void_type_node, else_label_decl);
|
||||
}
|
||||
@ -779,8 +775,10 @@ namespace gcc
|
||||
void_type_node, then_label_decl);
|
||||
append_to_statement_list(then_label_expr, &this->current_statements);
|
||||
|
||||
statement->body().accept(this);
|
||||
|
||||
for (const auto body_statement : statement->body().statements)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
if (statement->alternative() != nullptr)
|
||||
{
|
||||
append_to_statement_list(goto_endif, &this->current_statements);
|
||||
@ -788,7 +786,10 @@ namespace gcc
|
||||
auto else_label_expr = build1(LABEL_EXPR, void_type_node, else_label_decl);
|
||||
append_to_statement_list(else_label_expr, &this->current_statements);
|
||||
|
||||
statement->alternative()->accept(this);
|
||||
for (const auto body_statement : *statement->alternative())
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
}
|
||||
auto endif_label_expr = build1(LABEL_EXPR, void_type_node, endif_label_decl);
|
||||
append_to_statement_list(endif_label_expr, &this->current_statements);
|
||||
@ -808,18 +809,18 @@ namespace gcc
|
||||
|
||||
void generic_visitor::visit(source::while_statement *statement)
|
||||
{
|
||||
statement->prerequisite().accept(this);
|
||||
statement->body().prerequisite().accept(this);
|
||||
|
||||
if (TREE_TYPE(this->current_expression) != boolean_type_node)
|
||||
{
|
||||
error_at(get_location(&statement->prerequisite().position()),
|
||||
error_at(get_location(&statement->body().prerequisite().position()),
|
||||
"expected expression of boolean type but its type is %s",
|
||||
print_type(TREE_TYPE(this->current_expression)));
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
auto prerequisite_location = get_location(&statement->prerequisite().position());
|
||||
auto body_location = get_location(&statement->body().position());
|
||||
auto prerequisite_location = get_location(&statement->body().prerequisite().position());
|
||||
auto body_location = get_location(&statement->position());
|
||||
|
||||
auto prerequisite_label_decl = build_label_decl("while_check", prerequisite_location);
|
||||
auto prerequisite_label_expr = build1_loc(prerequisite_location, LABEL_EXPR,
|
||||
@ -842,8 +843,10 @@ namespace gcc
|
||||
void_type_node, body_label_decl);
|
||||
append_to_statement_list(body_label_expr, &this->current_statements);
|
||||
|
||||
statement->body().accept(this);
|
||||
|
||||
for (const auto body_statement : statement->body().statements)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
auto goto_check = build1(GOTO_EXPR, void_type_node, prerequisite_label_decl);
|
||||
append_to_statement_list(goto_check, &this->current_statements);
|
||||
|
||||
|
Reference in New Issue
Block a user