Exemplo n.º 1
0
std::pair<std::shared_ptr<Node>, boost::optional<Status>>
createNode(const Status& originalStatus, Point p, Point d,
        const std::shared_ptr<Node>& base, NodeFactory& nodeFactory,
        const HeurCalculator& heurCalculator, const Checker& checker,
        Dumper* dumper)
{
    Point pd = p+d, pmd = p-d;
    if (originalStatus.value(pd) != FieldType::floor ||
            !originalStatus.reachable(pmd)) {
        return {};
    }

    Status status(originalStatus);
    status.currentPos(p);
    if (heurCalculator.calculateStone(status, pd) < 0 ||
            !status.moveStone(p, pd)) {
        return {};
    }

    auto doCreateNode =
            [&]() {
                return nodeFactory.createNode(
                        status, MoveDescriptor(p, d), base);
            };
    if (pd != status.table().destination()) {
        if (!checker.check(status, pd)) {
            if (dumper) {
                dumper->reject(doCreateNode(), checker.errorMessage());
            }
            return {};
        }
    }

    return {doCreateNode(), std::move(status)};
}
Exemplo n.º 2
0
NodePointer Demangle::stripGenericArgsFromContextNode(NodePointer node,
                                                      NodeFactory &factory) {
  switch (node->getKind()) {
  case Demangle::Node::Kind::BoundGenericClass:
  case Demangle::Node::Kind::BoundGenericEnum:
  case Demangle::Node::Kind::BoundGenericStructure:
  case Demangle::Node::Kind::BoundGenericOtherNominalType:
    // Bound generic types have a 'Type' node under them, whose child is
    // the non-generic reference. If we don't see that structure, do nothing.
    if (node->getNumChildren() < 2 ||
        node->getChild(0)->getKind() != Demangle::Node::Kind::Type ||
        node->getChild(0)->getNumChildren() < 1)
      return node;

    // Strip generic arguments from that child, then return it.
    return stripGenericArgsFromContextNode(node->getChild(0)->getChild(0),
                                          factory);

  case Demangle::Node::Kind::Class:
  case Demangle::Node::Kind::Enum:
  case Demangle::Node::Kind::Structure:
  case Demangle::Node::Kind::OtherNominalType: {
    if (node->getNumChildren() < 2)
      return node;

    auto newContext = stripGenericArgsFromContextNode(node->getChild(0),
                                                      factory);
    if (newContext == node->getChild(0)) return node;

    auto newNode = factory.createNode(node->getKind());
    newNode->addChild(newContext, factory);
    for (unsigned i = 1, n = node->getNumChildren(); i != n; ++i)
      newNode->addChild(node->getChild(i), factory);
    return newNode;
  }
      
  case Demangle::Node::Kind::Extension: {
    // Strip generic arguments from the extended type.
    if (node->getNumChildren() < 2)
      return node;
    
    auto newExtended = stripGenericArgsFromContextNode(node->getChild(1),
                                                       factory);
    if (newExtended == node->getChild(1)) return node;
    
    auto newNode = factory.createNode(Node::Kind::Extension);
    newNode->addChild(node->getChild(0), factory);
    newNode->addChild(newExtended, factory);
    if (node->getNumChildren() == 3)
      newNode->addChild(node->getChild(2), factory);
    return newNode;
  }

  case Demangle::Node::Kind::Module:
    // Modules terminate the recursion.
    return node;

  default:
    // FIXME: Handle local contexts.
    return node;
  }
}