diff --git a/include/plasp/pddl/expressions/PrimitiveType.h b/include/plasp/pddl/expressions/PrimitiveType.h index 0001f0e..1c1fdd7 100644 --- a/include/plasp/pddl/expressions/PrimitiveType.h +++ b/include/plasp/pddl/expressions/PrimitiveType.h @@ -1,6 +1,7 @@ #ifndef __PLASP__PDDL__EXPRESSION__PRIMITIVE_TYPE_H #define __PLASP__PDDL__EXPRESSION__PRIMITIVE_TYPE_H +#include #include #include #include @@ -25,8 +26,7 @@ class PrimitiveType: public Expression static PrimitiveType *parseDeclaration(utils::Parser &parser, Context &context); static void parseTypedDeclaration(utils::Parser &parser, Context &context); - template - static PrimitiveType *parseExisting(utils::Parser &parser, Container &primitiveTypes); + static PrimitiveType *parseExisting(utils::Parser &parser, Context &context); // TODO: method for lazy creation if not existing @@ -38,6 +38,9 @@ class PrimitiveType: public Expression bool isDeclared() const; + private: + static PrimitiveType *create(std::string name, Context &context); + private: PrimitiveType(); @@ -56,50 +59,6 @@ class PrimitiveType: public Expression //////////////////////////////////////////////////////////////////////////////////////////////////// -template -PrimitiveType *PrimitiveType::parseExisting(utils::Parser &parser, - Container &primitiveTypes) -{ - parser.skipWhiteSpace(); - - const auto typeName = parser.parseIdentifier(isIdentifier); - - BOOST_ASSERT(!typeName.empty()); - - // TODO: use hash map - const auto match = std::find_if(primitiveTypes.cbegin(), primitiveTypes.cend(), - [&](const auto &primitiveType) - { - return primitiveType->name() == typeName; - }); - - if (match == primitiveTypes.cend()) - { - // Allow implicit type "object" - if (typeName == "object") - { - auto objectType = std::make_unique(PrimitiveType()); - objectType->m_name = typeName; - objectType->setDirty(false); - objectType->setDeclared(); - - // TODO: make std::vector-independent - primitiveTypes.emplace_back(std::move(objectType)); - - return primitiveTypes.back().get(); - } - else - throw utils::ParserException(parser.row(), parser.column(), "Primitive type \"" + typeName + "\" used but never declared"); - } - - auto *type = match->get(); - type->setDirty(); - - return type; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - } } } diff --git a/src/plasp/pddl/expressions/Constant.cpp b/src/plasp/pddl/expressions/Constant.cpp index ec7f621..843bd28 100644 --- a/src/plasp/pddl/expressions/Constant.cpp +++ b/src/plasp/pddl/expressions/Constant.cpp @@ -65,7 +65,7 @@ void Constant::parseTypedDeclaration(utils::Parser &parser, Context &context) return; // If existing, parse and store parent type - auto *type = PrimitiveType::parseExisting(parser, context.primitiveTypes); + auto *type = PrimitiveType::parseExisting(parser, context); // Assign parent type to all types that were previously flagged std::for_each(context.constants.begin(), context.constants.end(), diff --git a/src/plasp/pddl/expressions/PrimitiveType.cpp b/src/plasp/pddl/expressions/PrimitiveType.cpp index cac8d8d..ad5f82f 100644 --- a/src/plasp/pddl/expressions/PrimitiveType.cpp +++ b/src/plasp/pddl/expressions/PrimitiveType.cpp @@ -26,6 +26,26 @@ PrimitiveType::PrimitiveType() //////////////////////////////////////////////////////////////////////////////////////////////////// +PrimitiveType *PrimitiveType::create(std::string name, Context &context) +{ + // Create new primitive type if not already existing + auto type = std::make_unique(PrimitiveType()); + + type->m_name = name; + + BOOST_ASSERT(!type->m_name.empty()); + + // Flag type for potentially upcoming parent type declaration + type->setDirty(); + + // TODO: Store constant in hash map + context.primitiveTypes.emplace_back(std::move(type)); + + return context.primitiveTypes.back().get(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + PrimitiveType *PrimitiveType::parseDeclaration(utils::Parser &parser, Context &context) { parser.skipWhiteSpace(); @@ -49,20 +69,7 @@ PrimitiveType *PrimitiveType::parseDeclaration(utils::Parser &parser, Context &c return type; } - // Create new primitive type if not already existing - auto type = std::make_unique(PrimitiveType()); - - type->m_name = typeName; - - BOOST_ASSERT(!type->m_name.empty()); - - // Flag type for potentially upcoming parent type declaration - type->setDirty(); - - // TODO: Store constant in hash map - context.primitiveTypes.emplace_back(std::move(type)); - - return context.primitiveTypes.back().get(); + return create(typeName, context); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -82,7 +89,7 @@ void PrimitiveType::parseTypedDeclaration(utils::Parser &parser, Context &contex return; // If existing, parse and store parent type - auto *parentType = parseExisting(parser, context.primitiveTypes); + auto *parentType = parseExisting(parser, context); parentType->setDirty(false); @@ -103,6 +110,38 @@ void PrimitiveType::parseTypedDeclaration(utils::Parser &parser, Context &contex //////////////////////////////////////////////////////////////////////////////////////////////////// +PrimitiveType *PrimitiveType::parseExisting(utils::Parser &parser, Context &context) +{ + parser.skipWhiteSpace(); + + const auto typeName = parser.parseIdentifier(isIdentifier); + + BOOST_ASSERT(!typeName.empty()); + + // TODO: use hash map + const auto match = std::find_if(context.primitiveTypes.cbegin(), context.primitiveTypes.cend(), + [&](const auto &primitiveType) + { + return primitiveType->name() == typeName; + }); + + if (match == context.primitiveTypes.cend()) + { + // Primitive type "object" is implicitly declared + if (typeName != "object") + throw ConsistencyException("Primitive type \"" + typeName + "\" used but never declared"); + + return create(typeName, context); + } + + auto *type = match->get(); + type->setDirty(); + + return type; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void PrimitiveType::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const { expressionVisitor.visit(*this); diff --git a/src/plasp/pddl/expressions/Type.cpp b/src/plasp/pddl/expressions/Type.cpp index 2aed578..4490828 100644 --- a/src/plasp/pddl/expressions/Type.cpp +++ b/src/plasp/pddl/expressions/Type.cpp @@ -18,7 +18,7 @@ namespace expressions ExpressionPointer parseExistingPrimitiveType(utils::Parser &parser, Context &context, const Variables ¶meters) { - auto reference = std::make_unique>(PrimitiveType::parseExisting(parser, context.primitiveTypes)); + auto reference = std::make_unique>(PrimitiveType::parseExisting(parser, context)); return reference; } diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index 384e943..e3bfd4e 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -94,7 +94,7 @@ void Variable::parseTypedDeclaration(utils::Parser &parser, Context &context, Va } // Parse primitive type - const auto *type = PrimitiveType::parseExisting(parser, context.primitiveTypes); + const auto *type = PrimitiveType::parseExisting(parser, context); setType(type); }