#include #include #include #include #include #include #include #include #include #include namespace hex::pl { bool Validator::validate(const std::vector> &ast) { std::unordered_set identifiers; std::unordered_set types; try { for (const auto &node : ast) { if (node == nullptr) throwValidatorError("nullptr in AST. This is a bug!", 1); if (auto variableDeclNode = dynamic_cast(node.get()); variableDeclNode != nullptr) { if (!identifiers.insert(variableDeclNode->getName().data()).second) throwValidatorError(hex::format("redefinition of identifier '{0}'", variableDeclNode->getName().data()), variableDeclNode->getLineNumber()); this->validate(hex::moveToVector>(variableDeclNode->getType()->clone())); } else if (auto typeDeclNode = dynamic_cast(node.get()); typeDeclNode != nullptr) { if (!types.insert(typeDeclNode->getName().data()).second) throwValidatorError(hex::format("redefinition of type '{0}'", typeDeclNode->getName().data()), typeDeclNode->getLineNumber()); this->validate(hex::moveToVector>(typeDeclNode->getType()->clone())); } else if (auto structNode = dynamic_cast(node.get()); structNode != nullptr) { this->validate(structNode->getMembers()); } else if (auto unionNode = dynamic_cast(node.get()); unionNode != nullptr) { this->validate(unionNode->getMembers()); } else if (auto enumNode = dynamic_cast(node.get()); 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; } }