#include #include #include #include #include namespace hex::pl { bool Validator::validate(const std::vector &ast) { std::unordered_set identifiers; try { for (const auto &node : ast) { if (node == nullptr) throwValidatorError("nullptr in AST. This is a bug!", 1); if (auto variableDeclNode = dynamic_cast(node); variableDeclNode != nullptr) { if (!identifiers.insert(variableDeclNode->getName().data()).second) throwValidatorError(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) throwValidatorError(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) throwValidatorError(hex::format("redefinition of enum constant '{0}'", name.c_str()), value->getLineNumber()); } } } } catch (PatternLanguageError &e) { this->m_error = e; return false; } return true; } }