Implement constants
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
#include "elna/gcc/elna-generic.h"
|
||||
#include "elna/gcc/elna-tree.h"
|
||||
#include "elna/gcc/elna-diagnostic.h"
|
||||
|
||||
#include "input.h"
|
||||
@ -97,12 +98,12 @@ namespace gcc
|
||||
|
||||
void generic_visitor::visit(source::integer_literal *literal)
|
||||
{
|
||||
current_expression = build_int_cst_type(integer_type_node, literal->number());
|
||||
this->current_expression = build_int_cst_type(integer_type_node, literal->number());
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::boolean_literal *literal)
|
||||
{
|
||||
current_expression = build_int_cst_type(boolean_type_node, literal->boolean());
|
||||
this->current_expression = build_int_cst_type(boolean_type_node, literal->boolean());
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::binary_expression *expression)
|
||||
@ -179,6 +180,34 @@ namespace gcc
|
||||
operator_code, integer_type_node, left, right);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::constant_definition *definition)
|
||||
{
|
||||
location_t definition_location = get_location(&definition->position());
|
||||
tree definition_tree = build_decl(definition_location, CONST_DECL,
|
||||
get_identifier(definition->identifier().c_str()), integer_type_node);
|
||||
auto result = this->symbol_map.insert({ definition->identifier(), definition_tree });
|
||||
|
||||
if (result.second)
|
||||
{
|
||||
definition->body().accept(this);
|
||||
|
||||
DECL_INITIAL(definition_tree) = build_int_cst_type(integer_type_node, definition->body().number());
|
||||
TREE_CONSTANT(definition_tree) = 1;
|
||||
TREE_READONLY(definition_tree) = 1;
|
||||
|
||||
auto declaration_statement = build1_loc(definition_location, DECL_EXPR,
|
||||
void_type_node, definition_tree);
|
||||
append_to_statement_list(declaration_statement, &this->current_statements);
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(definition_location,
|
||||
"variable '%s' already declared in this scope",
|
||||
definition->identifier().c_str());
|
||||
}
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::declaration *declaration)
|
||||
{
|
||||
if (declaration->type().base() != "Int" && declaration->type().base() != "Bool")
|
||||
@ -236,9 +265,16 @@ namespace gcc
|
||||
}
|
||||
statement->rvalue().accept(this);
|
||||
|
||||
if (TREE_CODE(lvalue->second) == CONST_DECL)
|
||||
{
|
||||
error_at(statement_location, "cannot modify constant '%s'",
|
||||
statement->lvalue().c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
if (TREE_TYPE(this->current_expression) != TREE_TYPE(lvalue->second))
|
||||
{
|
||||
error_at(get_location(&statement->position()),
|
||||
error_at(statement_location,
|
||||
"cannot assign value of type %s to variable '%s' of type %s",
|
||||
print_type(TREE_TYPE(this->current_expression)),
|
||||
statement->lvalue().c_str(),
|
||||
|
Reference in New Issue
Block a user