Save procedure info in the symbol table
This commit is contained in:
parent
f2e2da4a34
commit
013bf91fbd
@ -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);
|
||||
|
@ -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>();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user