Type check the return statement
This commit is contained in:
179
boot/semantic.cc
179
boot/semantic.cc
@ -65,6 +65,18 @@ namespace elna::boot
|
||||
auto info = std::make_shared<type_info>(type_info(type(unresolved.second)));
|
||||
this->symbols->enter(std::move(unresolved.first), info);
|
||||
}
|
||||
for (variable_declaration *const variable : program->variables)
|
||||
{
|
||||
variable->accept(this);
|
||||
}
|
||||
for (procedure_definition *const procedure : program->procedures)
|
||||
{
|
||||
procedure->accept(this);
|
||||
}
|
||||
for (statement *const statement : program->body)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(type_definition *definition)
|
||||
@ -106,142 +118,219 @@ namespace elna::boot
|
||||
this->current_type = type(std::make_shared<array_type>(this->current_type, type_expression->size));
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(record_type_expression *)
|
||||
void declaration_visitor::visit(record_type_expression *type_expression)
|
||||
{
|
||||
this->current_type = type(std::make_shared<record_type>());
|
||||
auto result_type = std::make_shared<record_type>();
|
||||
|
||||
for (auto& field : type_expression->fields)
|
||||
{
|
||||
field.second->accept(this);
|
||||
result_type->fields.push_back(std::make_pair(field.first, this->current_type));
|
||||
}
|
||||
this->current_type = type(result_type);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(union_type_expression *)
|
||||
void declaration_visitor::visit(union_type_expression *type_expression)
|
||||
{
|
||||
this->current_type = type(std::make_shared<union_type>());
|
||||
auto result_type = std::make_shared<union_type>();
|
||||
|
||||
for (auto& field : type_expression->fields)
|
||||
{
|
||||
field.second->accept(this);
|
||||
result_type->fields.push_back(std::make_pair(field.first, this->current_type));
|
||||
}
|
||||
this->current_type = type(result_type);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(procedure_type_expression *)
|
||||
{
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(variable_declaration *)
|
||||
void declaration_visitor::visit(variable_declaration *declaration)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
declaration->variable_type().accept(this);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(constant_definition *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(procedure_definition *)
|
||||
void declaration_visitor::visit(procedure_definition *definition)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
for (auto heading_parameter : definition->heading().parameters)
|
||||
{
|
||||
heading_parameter->accept(this);
|
||||
}
|
||||
if (definition->heading().return_type.type != nullptr)
|
||||
{
|
||||
definition->heading().return_type.type->accept(this);
|
||||
}
|
||||
if (definition->body != nullptr)
|
||||
{
|
||||
definition->body->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(assign_statement *)
|
||||
void declaration_visitor::visit(assign_statement *statement)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
statement->lvalue().accept(this);
|
||||
statement->rvalue().accept(this);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(if_statement *)
|
||||
void declaration_visitor::visit(if_statement *statement)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
statement->body().prerequisite().accept(this);
|
||||
for (struct statement *const statement : statement->body().statements)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
for (const auto branch : statement->branches)
|
||||
{
|
||||
branch->prerequisite().accept(this);
|
||||
|
||||
for (struct statement *const statement : branch->statements)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
}
|
||||
if (statement->alternative() != nullptr)
|
||||
{
|
||||
for (struct statement *const statement : *statement->alternative())
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(while_statement *)
|
||||
void declaration_visitor::visit(while_statement *statement)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
statement->body().prerequisite().accept(this);
|
||||
for (struct statement *const statement : statement->body().statements)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
for (const auto branch : statement->branches)
|
||||
{
|
||||
branch->prerequisite().accept(this);
|
||||
|
||||
for (struct statement *const statement : branch->statements)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(return_statement *)
|
||||
void declaration_visitor::visit(return_statement *statement)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
if (statement->return_expression() != nullptr)
|
||||
{
|
||||
statement->return_expression()->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(defer_statement *)
|
||||
void declaration_visitor::visit(defer_statement *statement)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
for (struct statement *const statement : statement->statements)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(procedure_call *)
|
||||
void declaration_visitor::visit(procedure_call *call)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
call->callable().accept(this);
|
||||
for (expression *const argument: call->arguments)
|
||||
{
|
||||
argument->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(block *)
|
||||
void declaration_visitor::visit(block *block)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
for (constant_definition *const constant : block->constants)
|
||||
{
|
||||
constant->accept(this);
|
||||
}
|
||||
for (variable_declaration *const variable : block->variables)
|
||||
{
|
||||
variable->accept(this);
|
||||
}
|
||||
for (statement *const statement : block->body)
|
||||
{
|
||||
statement->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(traits_expression *)
|
||||
void declaration_visitor::visit(traits_expression *trait)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
if (!trait->parameters.empty())
|
||||
{
|
||||
trait->parameters.front()->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(cast_expression *)
|
||||
void declaration_visitor::visit(cast_expression *expression)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
expression->value().accept(this);
|
||||
expression->target().accept(this);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(binary_expression *)
|
||||
void declaration_visitor::visit(binary_expression *expression)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
expression->lhs().accept(this);
|
||||
expression->rhs().accept(this);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(unary_expression *)
|
||||
void declaration_visitor::visit(unary_expression *expression)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
expression->operand().accept(this);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(variable_expression *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(array_access_expression *)
|
||||
void declaration_visitor::visit(array_access_expression *expression)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
expression->base().accept(this);
|
||||
expression->index().accept(this);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(field_access_expression *)
|
||||
void declaration_visitor::visit(field_access_expression *expression)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
expression->base().accept(this);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(dereference_expression *)
|
||||
void declaration_visitor::visit(dereference_expression *expression)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
expression->base().accept(this);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(literal<std::int32_t> *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(literal<std::uint32_t> *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(literal<double> *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(literal<bool> *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(literal<unsigned char> *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(literal<std::nullptr_t> *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(literal<std::string> *)
|
||||
{
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user