aboutsummaryrefslogtreecommitdiff
path: root/boot/semantic.cc
diff options
context:
space:
mode:
Diffstat (limited to 'boot/semantic.cc')
-rw-r--r--boot/semantic.cc57
1 files changed, 47 insertions, 10 deletions
diff --git a/boot/semantic.cc b/boot/semantic.cc
index bc7c2d2..a48226b 100644
--- a/boot/semantic.cc
+++ b/boot/semantic.cc
@@ -78,7 +78,17 @@ namespace elna::boot
std::string return_error::what() const
{
- return "Procedure '" + identifier + "' is expected to return, but does not have a return statement";
+ return "Procedure '" + this->identifier + "' is expected to return, but does not have a return statement";
+ }
+
+ base_type_error::base_type_error(const std::string& base, const struct position position)
+ : error(position), base(base)
+ {
+ }
+
+ std::string base_type_error::what() const
+ {
+ return "Record base type '" + this->base + "' is not a record.";
}
type_analysis_visitor::type_analysis_visitor(symbol_bag bag)
@@ -291,8 +301,37 @@ namespace elna::boot
void name_analysis_visitor::visit(record_type_expression *type_expression)
{
- auto result_type = std::make_shared<record_type>();
-
+ std::shared_ptr<record_type> result_type;
+ if (type_expression->base.has_value())
+ {
+ if (auto unresolved_alias = this->bag.declared(type_expression->base.value()))
+ {
+ result_type = std::make_shared<record_type>(type(unresolved_alias));
+ }
+ else if (auto base_symbol = this->bag.lookup(type_expression->base.value()))
+ {
+ if (auto base_type_info = base_symbol->is_type())
+ {
+ result_type = std::make_shared<record_type>(base_type_info->symbol);
+ }
+ else
+ {
+ add_error<base_type_error>(type_expression->base.value(), type_expression->position());
+ this->current_type = type();
+ return;
+ }
+ }
+ else
+ {
+ add_error<undeclared_error>(type_expression->base.value(), type_expression->position());
+ this->current_type = type();
+ return;
+ }
+ }
+ else
+ {
+ result_type = std::make_shared<record_type>();
+ }
result_type->fields = build_composite_type(type_expression->fields);
this->current_type = type(result_type);
@@ -498,7 +537,7 @@ namespace elna::boot
{
call->callable().accept(this);
}
- for (expression *const argument: call->arguments)
+ for (expression *const argument : call->arguments)
{
argument->accept(this);
}
@@ -551,15 +590,13 @@ namespace elna::boot
expression->operand().accept(this);
}
- void name_analysis_visitor::visit(named_expression *type_expression)
+ void name_analysis_visitor::visit(named_expression *expression)
{
- auto unresolved_alias = this->bag.declared(type_expression->name);
-
- if (unresolved_alias != nullptr)
+ if (auto unresolved_alias = this->bag.declared(expression->name))
{
this->current_type = type(unresolved_alias);
}
- else if (auto from_symbol_table = this->bag.lookup(type_expression->name))
+ else if (auto from_symbol_table = this->bag.lookup(expression->name))
{
if (auto type_symbol = from_symbol_table->is_type())
{
@@ -568,7 +605,7 @@ namespace elna::boot
}
else
{
- add_error<undeclared_error>(type_expression->name, type_expression->position());
+ add_error<undeclared_error>(expression->name, expression->position());
this->current_type = type();
}
}