Save procedure info in the symbol table

This commit is contained in:
Eugen Wissner 2025-03-31 12:48:30 +02:00
parent f2e2da4a34
commit 013bf91fbd
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 96 additions and 77 deletions

View File

@ -46,6 +46,33 @@ namespace elna::boot
{
}
procedure_type declaration_visitor::build_procedure(procedure_type_expression& type_expression)
{
procedure_type::return_t result_return;
if (type_expression.return_type.no_return)
{
result_return = procedure_type::return_t(std::monostate{});
}
else if (type_expression.return_type.proper_type != nullptr)
{
type_expression.return_type.proper_type->accept(this);
result_return = procedure_type::return_t(this->current_type);
}
else
{
result_return = procedure_type::return_t();
}
procedure_type result_type = procedure_type(result_return);
for (std::shared_ptr<struct type_expression> parameter : type_expression.parameters)
{
parameter->accept(this);
result_type.parameters.push_back(this->current_type);
}
return result_type;
}
void declaration_visitor::visit(program *program)
{
for (type_definition *const type : program->types)
@ -134,7 +161,7 @@ namespace elna::boot
{
auto result_type = std::make_shared<union_type>();
for (auto& field : type_expression->fields)
for (const field_declaration& field : type_expression->fields)
{
field.second->accept(this);
result_type->fields.push_back(std::make_pair(field.first, this->current_type));
@ -144,26 +171,10 @@ namespace elna::boot
void declaration_visitor::visit(procedure_type_expression *type_expression)
{
std::shared_ptr<procedure_type> result_type;
std::shared_ptr<procedure_type> result_type =
std::make_shared<procedure_type>(std::move(build_procedure(*type_expression)));
if (type_expression->return_type.no_return)
{
result_type = std::make_shared<procedure_type>(procedure_type::return_t(std::monostate{}));
}
else if (type_expression->return_type.proper_type != nullptr)
{
type_expression->return_type.proper_type->accept(this);
result_type = std::make_shared<procedure_type>(procedure_type::return_t(this->current_type));
}
else
{
result_type = std::make_shared<procedure_type>(procedure_type::return_t());
}
for (auto& parameter : type_expression->parameters)
{
parameter->accept(this);
result_type->parameters.push_back(this->current_type);
}
this->current_type = type(result_type);
}
void declaration_visitor::visit(variable_declaration *declaration)
@ -177,14 +188,10 @@ namespace elna::boot
void declaration_visitor::visit(procedure_definition *definition)
{
for (auto heading_parameter : definition->heading().parameters)
{
heading_parameter->accept(this);
}
if (definition->heading().return_type.proper_type != nullptr)
{
definition->heading().return_type.proper_type->accept(this);
}
std::shared_ptr<procedure_info> info = std::make_shared<procedure_info>(
build_procedure(definition->heading()), definition->parameter_names);
this->symbols->enter(definition->identifier, info);
if (definition->body != nullptr)
{
definition->body->accept(this);

View File

@ -53,6 +53,11 @@ namespace elna::boot
{
}
type::type(std::shared_ptr<procedure_type> procedure)
: tag(type_tag::procedure), procedure(procedure)
{
}
void type::copy(const type& other)
{
switch (other.tag)
@ -77,6 +82,9 @@ namespace elna::boot
case type_tag::array:
new (&array) std::shared_ptr<array_type>(other.array);
break;
case type_tag::procedure:
new (&procedure) std::shared_ptr<procedure_type>(other.procedure);
break;
}
}
@ -110,6 +118,9 @@ namespace elna::boot
case type_tag::array:
new (&array) std::shared_ptr<array_type>(std::move(other.array));
break;
case type_tag::procedure:
new (&procedure) std::shared_ptr<procedure_type>(std::move(other.procedure));
break;
}
}
@ -164,85 +175,52 @@ namespace elna::boot
case type_tag::array:
this->array.~shared_ptr<array_type>();
break;
case type_tag::procedure:
this->procedure.~shared_ptr<procedure_type>();
break;
}
}
template<>
std::shared_ptr<alias_type> type::get<alias_type>() const
{
if (tag == type_tag::alias)
{
return this->alias.lock();
}
else
{
return nullptr;
}
return tag == type_tag::alias ? this->alias.lock() : nullptr;
}
template<>
std::shared_ptr<primitive_type> type::get<primitive_type>() const
{
if (tag == type_tag::primitive)
{
return this->primitive;
}
else
{
return nullptr;
}
return tag == type_tag::primitive ? this->primitive : nullptr;
}
template<>
std::shared_ptr<record_type> type::get<record_type>() const
{
if (tag == type_tag::record)
{
return this->record;
}
else
{
return nullptr;
}
return tag == type_tag::record ? this->record : nullptr;
}
template<>
std::shared_ptr<union_type> type::get<union_type>() const
{
if (tag == type_tag::_union)
{
return this->_union;
}
else
{
return nullptr;
}
return tag == type_tag::_union ? this->_union : nullptr;
}
template<>
std::shared_ptr<pointer_type> type::get<pointer_type>() const
{
if (tag == type_tag::pointer)
{
return this->pointer;
}
else
{
return nullptr;
}
return tag == type_tag::pointer ? this->pointer : nullptr;
}
template<>
std::shared_ptr<array_type> type::get<array_type>() const
{
if (tag == type_tag::array)
{
return this->array;
}
else
{
return nullptr;
}
return tag == type_tag::array ? this->array : nullptr;
}
template<>
std::shared_ptr<procedure_type> type::get<procedure_type>() const
{
return tag == type_tag::procedure ? this->procedure : nullptr;
}
bool type::empty() const
@ -284,6 +262,11 @@ namespace elna::boot
return nullptr;
}
std::shared_ptr<procedure_info> info::is_procedure()
{
return nullptr;
}
type_info::type_info(const type symbol)
: symbol(symbol)
{
@ -294,6 +277,16 @@ namespace elna::boot
return std::static_pointer_cast<type_info>(shared_from_this());
}
procedure_info::procedure_info(const procedure_type symbol, const std::vector<std::string> names)
: symbol(symbol), names(names)
{
}
std::shared_ptr<procedure_info> procedure_info::is_procedure()
{
return std::static_pointer_cast<procedure_info>(shared_from_this());
}
std::shared_ptr<symbol_table> builtin_symbol_table()
{
auto result = std::make_shared<symbol_table>();

View File

@ -51,6 +51,8 @@ namespace elna::boot
type current_type;
std::shared_ptr<symbol_table> symbols;
procedure_type build_procedure(procedure_type_expression& type_expression);
public:
std::unordered_map<std::string, std::shared_ptr<alias_type>> unresolved;

View File

@ -33,6 +33,7 @@ namespace elna::boot
class union_type;
class pointer_type;
class array_type;
class procedure_type;
class type
{
@ -44,7 +45,8 @@ namespace elna::boot
record,
_union,
pointer,
array
array,
procedure
};
type_tag tag{ type_tag::empty };
union
@ -55,6 +57,7 @@ namespace elna::boot
std::shared_ptr<union_type> _union;
std::shared_ptr<pointer_type> pointer;
std::shared_ptr<array_type> array;
std::shared_ptr<procedure_type> procedure;
};
void copy(const type& other);
@ -68,6 +71,7 @@ namespace elna::boot
explicit type(std::shared_ptr<union_type> _union);
explicit type(std::shared_ptr<pointer_type> pointer);
explicit type(std::shared_ptr<array_type> array);
explicit type(std::shared_ptr<procedure_type> procedure);
type(const type& other);
type& operator=(const type& other);
@ -138,6 +142,7 @@ namespace elna::boot
};
class type_info;
class procedure_info;
class info : public std::enable_shared_from_this<info>
{
@ -145,6 +150,7 @@ namespace elna::boot
virtual ~info() = 0;
virtual std::shared_ptr<type_info> is_type();
virtual std::shared_ptr<procedure_info> is_procedure();
};
class type_info : public info
@ -157,6 +163,17 @@ namespace elna::boot
std::shared_ptr<type_info> is_type() override;
};
class procedure_info : public info
{
public:
const procedure_type symbol;
const std::vector<std::string> names;
procedure_info(const procedure_type symbol, const std::vector<std::string> names);
std::shared_ptr<procedure_info> is_procedure() override;
};
/**
* Symbol table.
*/