#include #include #include #include namespace hex::lang { Validator::Validator() { } bool Validator::validate(const std::vector& ast) { std::unordered_set identifiers; try { for (const auto &node : ast) { if (node == nullptr) throwValidateError("nullptr in AST. This is a bug!", 1); if (auto variableDeclNode = dynamic_cast(node); variableDeclNode != nullptr) { if (!identifiers.insert(variableDeclNode->getName().data()).second) throwValidateError(hex::format("redefinition of identifier '{0}'", variableDeclNode->getName().data()), variableDeclNode->getLineNumber()); this->validate({ variableDeclNode->getType() }); } else if (auto typeDeclNode = dynamic_cast(node); typeDeclNode != nullptr) { if (!identifiers.insert(typeDeclNode->getName().data()).second) throwValidateError(hex::format("redefinition of identifier '{0}'", typeDeclNode->getName().data()), typeDeclNode->getLineNumber()); this->validate({ typeDeclNode->getType() }); } else if (auto structNode = dynamic_cast(node); structNode != nullptr) { this->validate(structNode->getMembers()); } else if (auto unionNode = dynamic_cast(node); unionNode != nullptr) { this->validate(unionNode->getMembers()); } else if (auto enumNode = dynamic_cast(node); enumNode != nullptr) { std::unordered_set enumIdentifiers; for (auto &[name, value] : enumNode->getEntries()) { if (!enumIdentifiers.insert(name).second) throwValidateError(hex::format("redefinition of enum constant '{0}'", name.c_str()), value->getLineNumber()); } } } } catch (ValidatorError &e) { this->m_error = e; return false; } return true; } }