patrick
/
plasp
Archived
1
0
Fork 0
This repository has been archived on 2023-07-19. You can view files and clone it, but cannot push or open issues or pull requests.
plasp/src/plasp/pddl/expressions/PrimitiveType.cpp

184 lines
4.4 KiB
C++

#include <plasp/pddl/expressions/PrimitiveType.h>
#include <algorithm>
#include <boost/assert.hpp>
#include <plasp/input/ParserException.h>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h>
namespace plasp
{
namespace pddl
{
namespace expressions
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// PrimitiveType
//
////////////////////////////////////////////////////////////////////////////////////////////////////
PrimitiveType::PrimitiveType()
: m_isDirty{true}
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
PrimitiveType::PrimitiveType(std::string name)
: m_isDirty{true},
m_name{name}
{
BOOST_ASSERT(!m_name.empty());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
{
auto &types = domain.types();
context.parser.skipWhiteSpace();
const auto typeName = context.parser.parseIdentifier();
const auto match = std::find_if(types.cbegin(), types.cend(),
[&](const auto &primitiveType)
{
return primitiveType->name() == typeName;
});
// Return existing primitive type
if (match != types.cend())
{
auto *type = match->get();
type->setDirty();
return;
}
types.emplace_back(PrimitiveTypePointer(new PrimitiveType(typeName)));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
{
auto &types = domain.types();
// Parse and store type
parseDeclaration(context, domain);
context.parser.skipWhiteSpace();
// Check for type inheritance
if (!context.parser.testAndSkip<char>('-'))
return;
domain.checkRequirement(Requirement::Type::Typing);
// If existing, parse and store parent type
auto parentType = parseAndFind(context, domain);
parentType->setDirty(false);
// Assign parent type to all types that were previously flagged
std::for_each(types.begin(), types.end(),
[&](auto &childType)
{
if (!childType->isDirty())
return;
childType->m_parentTypes.push_back(parentType);
childType->setDirty(false);
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////
PrimitiveTypePointer PrimitiveType::parseAndFind(Context &context, Domain &domain)
{
auto &parser = context.parser;
auto &types = domain.types();
parser.skipWhiteSpace();
const auto typeName = parser.parseIdentifier();
if (typeName.empty())
throw input::ParserException(parser.location(), "no type supplied");
const auto match = std::find_if(types.cbegin(), types.cend(),
[&](const auto &primitiveType)
{
return primitiveType->name() == typeName;
});
if (match == types.cend())
{
// Only "object" is allowed as an implicit type
if (typeName == "object" || typeName == "objects")
{
context.logger.log(output::Priority::Warning, parser.location(), "primitive type “" + typeName + "” should be declared");
types.emplace_back(PrimitiveTypePointer(new PrimitiveType(typeName)));
}
else
throw input::ParserException(parser.location(), "type “" + typeName + "” used but never declared");
return types.back().get();
}
auto *type = match->get();
type->setDirty();
return type;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void PrimitiveType::setDirty(bool isDirty)
{
m_isDirty = isDirty;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
bool PrimitiveType::isDirty() const
{
return m_isDirty;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string &PrimitiveType::name() const
{
return m_name;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const PrimitiveTypes &PrimitiveType::parentTypes() const
{
return m_parentTypes;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void PrimitiveType::print(std::ostream &ostream) const
{
// TODO: implement correctly
ostream << "(<primitive type" << m_name << ">)";
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}