Forbid redefenition of builtin types

This commit is contained in:
Eugen Wissner 2025-03-14 11:22:11 +01:00
parent ac084be7f5
commit 5d485f8505
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
5 changed files with 39 additions and 8 deletions

View File

@ -52,7 +52,8 @@ namespace boot
{ {
for (type_definition *const type : program->types) for (type_definition *const type : program->types)
{ {
if (!this->unresolved.insert({ type->identifier, std::make_shared<alias_type>() }).second) if (!this->unresolved.insert({ type->identifier, std::make_shared<alias_type>(type->identifier) }).second
|| this->symbols->contains(type->identifier))
{ {
add_error<already_declared_error>(type->identifier, this->input_file, type->position()); add_error<already_declared_error>(type->identifier, this->input_file, type->position());
} }
@ -61,6 +62,11 @@ namespace boot
{ {
type->accept(this); type->accept(this);
} }
for (auto& unresolved : this->unresolved)
{
auto info = std::make_shared<type_info>(type_info(type(unresolved.second)));
this->symbols->enter(std::move(unresolved.first), info);
}
} }
void declaration_visitor::visit(type_definition *definition) void declaration_visitor::visit(type_definition *definition)
@ -79,7 +85,7 @@ namespace boot
{ {
this->current_type = type(unresolved_alias->second); this->current_type = type(unresolved_alias->second);
} }
else if (auto from_symbol_table = this->symbols.lookup(type_expression->name)) else if (auto from_symbol_table = this->symbols->lookup(type_expression->name))
{ {
this->current_type = from_symbol_table->is_type()->symbol; this->current_type = from_symbol_table->is_type()->symbol;
} }

View File

@ -247,6 +247,11 @@ namespace boot
return tag == type_tag::empty; return tag == type_tag::empty;
} }
alias_type::alias_type(const std::string& name)
: name(name), reference()
{
}
pointer_type::pointer_type(type base) pointer_type::pointer_type(type base)
: base(base) : base(base)
{ {

View File

@ -136,7 +136,7 @@ elna.stagefeedback: stagefeedback-start
-mv elna/*$(objext) stagefeedback/elna -mv elna/*$(objext) stagefeedback/elna
ELNA_INCLUDES = -I $(srcdir)/elna/include -I elna/generated ELNA_INCLUDES = -I $(srcdir)/elna/include -I elna/generated
ELNA_CXXFLAGS = -std=c++14 ELNA_CXXFLAGS = -std=c++17
elna/%.o: elna/boot/%.cc elna/generated/parser.hh elna/generated/location.hh elna/%.o: elna/boot/%.cc elna/generated/parser.hh elna/generated/location.hh
$(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $< $(COMPILE) $(ELNA_CXXFLAGS) $(ELNA_INCLUDES) $<

View File

@ -51,7 +51,7 @@ namespace boot
class declaration_visitor final : public empty_visitor, public error_container class declaration_visitor final : public empty_visitor, public error_container
{ {
type current_type; type current_type;
symbol_table symbols; std::shared_ptr<symbol_table> symbols;
public: public:
std::unordered_map<std::string, std::shared_ptr<alias_type>> unresolved; std::unordered_map<std::string, std::shared_ptr<alias_type>> unresolved;

View File

@ -85,7 +85,10 @@ namespace boot
struct alias_type struct alias_type
{ {
const std::string name;
type reference; type reference;
explicit alias_type(const std::string& name);
}; };
struct pointer_type struct pointer_type
@ -173,22 +176,30 @@ namespace boot
iterator begin() iterator begin()
{ {
return entries.begin(); return this->entries.begin();
} }
iterator end() iterator end()
{ {
return entries.end(); return this->entries.end();
} }
const_iterator cbegin() const const_iterator cbegin() const
{ {
return entries.cbegin(); return this->entries.cbegin();
} }
const_iterator cend() const const_iterator cend() const
{ {
return entries.cend(); return this->entries.cend();
}
/**
* \return Symbol count in the current scope.
*/
std::size_t size() const
{
return this->entries.size();
} }
/** /**
@ -213,6 +224,15 @@ namespace boot
return nothing; return nothing;
} }
/**
* \param name Symbol name.
* \return Whether the table contains a symbol with the given name.
*/
bool contains(const std::string& name)
{
return lookup(name) != nothing;
}
/** /**
* Registers new symbol. * Registers new symbol.
* *