Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/spider/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ set(SPIDER_TDL_SHARED_SOURCES
tdl/parser/ast/node_impl/NamedVar.cpp
tdl/parser/ast/node_impl/type_impl/container_impl/List.cpp
tdl/parser/ast/node_impl/type_impl/container_impl/Map.cpp
tdl/parser/ast/node_impl/type_impl/container_impl/Tuple.cpp
tdl/parser/ast/node_impl/type_impl/primitive_impl/Bool.cpp
tdl/parser/ast/node_impl/type_impl/primitive_impl/Float.cpp
tdl/parser/ast/node_impl/type_impl/primitive_impl/Int.cpp
Expand All @@ -219,6 +220,7 @@ set(SPIDER_TDL_SHARED_HEADERS
tdl/parser/ast/node_impl/type_impl/Container.hpp
tdl/parser/ast/node_impl/type_impl/container_impl/List.hpp
tdl/parser/ast/node_impl/type_impl/container_impl/Map.hpp
tdl/parser/ast/node_impl/type_impl/container_impl/Tuple.hpp
tdl/parser/ast/node_impl/type_impl/Primitive.hpp
tdl/parser/ast/node_impl/type_impl/primitive_impl/Bool.hpp
tdl/parser/ast/node_impl/type_impl/primitive_impl/Float.hpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "Tuple.hpp"

#include <cstddef>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include <fmt/format.h>
#include <fmt/ranges.h>
#include <ystdlib/error_handling/Result.hpp>

#include <spider/tdl/parser/ast/Node.hpp>
#include <spider/tdl/parser/ast/node_impl/Type.hpp>
#include <spider/tdl/parser/ast/utils.hpp>

namespace spider::tdl::parser::ast::node_impl::type_impl::container_impl {
auto Tuple::create(std::vector<std::unique_ptr<Node>> elements)
-> ystdlib::error_handling::Result<std::unique_ptr<Node>> {
for (auto const& type : elements) {
YSTDLIB_ERROR_HANDLING_TRYV(validate_child_node_type<Type>(type.get()));
}

auto tuple{std::make_unique<Tuple>(Tuple{})};
for (auto& type : elements) {
YSTDLIB_ERROR_HANDLING_TRYV(tuple->add_child(std::move(type)));
}
return tuple;
}

auto Tuple::serialize_to_str(size_t indentation_level) const
-> ystdlib::error_handling::Result<std::string> {
constexpr std::string_view cTypeTag{"[Type[Container[Tuple]]]"};

if (is_empty()) {
return fmt::format("{}{}:Empty", create_indentation(indentation_level), cTypeTag);
}

std::vector<std::string> serialized_children;
YSTDLIB_ERROR_HANDLING_TRYV(
visit_children([&](Node const& child) -> ystdlib::error_handling::Result<void> {
serialized_children.emplace_back(
fmt::format(
"{}Element[{}]:\n{}",
create_indentation(indentation_level + 1),
serialized_children.size(),
YSTDLIB_ERROR_HANDLING_TRYX(
child.serialize_to_str(indentation_level + 2)
)
)
);
return ystdlib::error_handling::success();
})
);
return fmt::format(
"{}{}:\n{}",
create_indentation(indentation_level),
cTypeTag,
fmt::join(serialized_children, "\n")
);
}
} // namespace spider::tdl::parser::ast::node_impl::type_impl::container_impl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef SPIDER_TDL_PARSER_AST_NODE_IMPL_TYPE_IMPL_CONTAINER_IMPL_TUPLE_HPP
#define SPIDER_TDL_PARSER_AST_NODE_IMPL_TYPE_IMPL_CONTAINER_IMPL_TUPLE_HPP

#include <cstddef>
#include <memory>
#include <string>
#include <vector>

#include <ystdlib/error_handling/Result.hpp>

#include <spider/tdl/parser/ast/Node.hpp>
#include <spider/tdl/parser/ast/node_impl/type_impl/Container.hpp>

namespace spider::tdl::parser::ast::node_impl::type_impl::container_impl {
class Tuple : public Container {
public:
// Factory function
/**
* @param elements
* @return A result containing a unique pointer to a new `Tuple` instance as a collection of the
* given element types, or an error code indicating the failure:
* - Forwards `validate_child_node_type`'s return values.
*/
[[nodiscard]] static auto create(std::vector<std::unique_ptr<Node>> elements)
-> ystdlib::error_handling::Result<std::unique_ptr<Node>>;

// Methods implementing `Node`
[[nodiscard]] auto serialize_to_str(size_t indentation_level) const
-> ystdlib::error_handling::Result<std::string> override;

// Methods
[[nodiscard]] auto is_empty() const -> bool { return 0 == get_num_children(); }

private:
// Constructor
Tuple() = default;
};
} // namespace spider::tdl::parser::ast::node_impl::type_impl::container_impl

#endif // SPIDER_TDL_PARSER_AST_NODE_IMPL_TYPE_IMPL_CONTAINER_IMPL_TUPLE_HPP
56 changes: 56 additions & 0 deletions tests/tdl/test-parser-ast.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// NOLINTBEGIN(cert-err58-cpp,cppcoreguidelines-avoid-do-while,readability-function-cognitive-complexity,cppcoreguidelines-avoid-non-const-global-variables,cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays)

#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include <catch2/catch_test_macros.hpp>
#include <catch2/generators/catch_generators.hpp>
Expand All @@ -15,6 +17,7 @@
#include <spider/tdl/parser/ast/node_impl/NamedVar.hpp>
#include <spider/tdl/parser/ast/node_impl/type_impl/container_impl/List.hpp>
#include <spider/tdl/parser/ast/node_impl/type_impl/container_impl/Map.hpp>
#include <spider/tdl/parser/ast/node_impl/type_impl/container_impl/Tuple.hpp>
#include <spider/tdl/parser/ast/node_impl/type_impl/primitive_impl/Bool.hpp>
#include <spider/tdl/parser/ast/node_impl/type_impl/primitive_impl/Float.hpp>
#include <spider/tdl/parser/ast/node_impl/type_impl/primitive_impl/Int.hpp>
Expand All @@ -28,6 +31,7 @@ TEST_CASE("test-ast-node", "[tdl][ast][Node]") {
using spider::tdl::parser::ast::node_impl::NamedVar;
using spider::tdl::parser::ast::node_impl::type_impl::container_impl::List;
using spider::tdl::parser::ast::node_impl::type_impl::container_impl::Map;
using spider::tdl::parser::ast::node_impl::type_impl::container_impl::Tuple;
using spider::tdl::parser::ast::node_impl::type_impl::primitive_impl::Bool;
using spider::tdl::parser::ast::node_impl::type_impl::primitive_impl::Float;
using spider::tdl::parser::ast::node_impl::type_impl::primitive_impl::Int;
Expand Down Expand Up @@ -231,6 +235,58 @@ TEST_CASE("test-ast-node", "[tdl][ast][Node]") {
REQUIRE_FALSE(serialized_result.has_error());
REQUIRE(serialized_result.value() == cExpectedSerializedResult);
}

SECTION("Tuple") {
SECTION("Empty") {
auto empty_tuple_result{Tuple::create({})};
REQUIRE_FALSE(empty_tuple_result.has_error());
auto const* tuple_node{dynamic_cast<Tuple const*>(empty_tuple_result.value().get())};
REQUIRE(nullptr != tuple_node);

REQUIRE(tuple_node->get_num_children() == 0);

constexpr std::string_view cExpectedSerializedResult{"[Type[Container[Tuple]]]:Empty"};
auto const serialized_result{tuple_node->serialize_to_str(0)};
REQUIRE_FALSE(serialized_result.has_error());
REQUIRE(serialized_result.value() == cExpectedSerializedResult);
}

SECTION("Tuple with elements") {
auto int_node{Int::create(IntSpec::Int64)};
auto float_node{Float::create(FloatSpec::Double)};
auto map_result{
Map::create(Int::create(IntSpec::Int64), Float::create(FloatSpec::Double))
};
REQUIRE_FALSE(map_result.has_error());
std::vector<std::unique_ptr<Node>> elements;
elements.emplace_back(std::move(int_node));
elements.emplace_back(std::move(float_node));
elements.emplace_back(std::move(map_result.value()));
auto tuple_result{Tuple::create(std::move(elements))};
REQUIRE_FALSE(tuple_result.has_error());
auto const* tuple_node{dynamic_cast<Tuple const*>(tuple_result.value().get())};
REQUIRE(nullptr != tuple_node);

REQUIRE(tuple_node->get_num_children() == 3);

constexpr std::string_view cExpectedSerializedResult{
"[Type[Container[Tuple]]]:\n"
" Element[0]:\n"
" [Type[Primitive[Int]]]:int64\n"
" Element[1]:\n"
" [Type[Primitive[Float]]]:double\n"
" Element[2]:\n"
" [Type[Container[Map]]]:\n"
" KeyType:\n"
" [Type[Primitive[Int]]]:int64\n"
" ValueType:\n"
" [Type[Primitive[Float]]]:double"
};
auto const serialized_result{tuple_node->serialize_to_str(0)};
REQUIRE_FALSE(serialized_result.has_error());
REQUIRE(serialized_result.value() == cExpectedSerializedResult);
}
}
}
} // namespace

Expand Down