diff options
Diffstat (limited to 'src/openvic-simulation/dataloader')
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.cpp | 10 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.hpp | 2 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.cpp | 135 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.hpp | 24 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/Vic2PathSearch.cpp | 4 |
5 files changed, 125 insertions, 50 deletions
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index dab479f..f42a518 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -204,7 +204,7 @@ template<std::derived_from<detail::BasicParser> Parser, bool (*parse_func)(Parse static Parser _run_ovdl_parser(fs::path const& path) { Parser parser; std::string buffer; - auto error_log_stream = detail::CallbackStream { + auto error_log_stream = detail::make_callback_stream<char>( [](void const* s, std::streamsize n, void* user_data) -> std::streamsize { if (s != nullptr && n > 0 && user_data != nullptr) { static_cast<std::string*>(user_data)->append(static_cast<char const*>(s), n); @@ -215,7 +215,7 @@ static Parser _run_ovdl_parser(fs::path const& path) { } }, &buffer - }; + ); parser.set_error_log_to(error_log_stream); parser.load_from_file(path); if (!buffer.empty()) { @@ -255,12 +255,12 @@ v2script::Parser Dataloader::parse_lua_defines(fs::path const& path) { return _run_ovdl_parser<v2script::Parser, &_lua_parse>(path); } -static bool _csv_parse(csv::Windows1252Parser& parser) { +static bool _csv_parse(csv::Parser& parser) { return parser.parse_csv(); } -csv::Windows1252Parser Dataloader::parse_csv(fs::path const& path) { - return _run_ovdl_parser<csv::Windows1252Parser, &_csv_parse>(path); +csv::Parser Dataloader::parse_csv(fs::path const& path) { + return _run_ovdl_parser<csv::Parser, &_csv_parse>(path); } v2script::Parser& Dataloader::parse_defines_cached(fs::path const& path) { diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index b114eda..3c77cab 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -47,7 +47,7 @@ namespace OpenVic { public: static ovdl::v2script::Parser parse_defines(fs::path const& path); static ovdl::v2script::Parser parse_lua_defines(fs::path const& path); - static ovdl::csv::Windows1252Parser parse_csv(fs::path const& path); + static ovdl::csv::Parser parse_csv(fs::path const& path); /* Cache the Parser so it won't be freed until free_cache is called. This is used to preserve condition and effect * script Nodes until all defines are loaded and the scripts can be parsed. The reference returned by this function diff --git a/src/openvic-simulation/dataloader/NodeTools.cpp b/src/openvic-simulation/dataloader/NodeTools.cpp index 297937a..3843459 100644 --- a/src/openvic-simulation/dataloader/NodeTools.cpp +++ b/src/openvic-simulation/dataloader/NodeTools.cpp @@ -1,34 +1,70 @@ #include "NodeTools.hpp" +#include <type_traits> + +#include <openvic-dataloader/detail/Utility.hpp> +#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> + +#include <dryad/node.hpp> + +#include <range/v3/iterator/operations.hpp> +#include <range/v3/view/enumerate.hpp> + #include "openvic-simulation/types/Colour.hpp" +#include "openvic-simulation/utility/Getters.hpp" using namespace OpenVic; using namespace OpenVic::NodeTools; template<typename T> -static NodeCallback auto _expect_type(Callback<T const&> auto callback) { +static NodeCallback auto _expect_type(Callback<T const*> auto callback) { return [callback](ast::NodeCPtr node) -> bool { if (node != nullptr) { - T const* cast_node = node->cast_to<T>(); + T const* cast_node = dryad::node_try_cast<T>(node); if (cast_node != nullptr) { - return callback(*cast_node); + return callback(cast_node); } - Logger::error("Invalid node type ", node->get_type(), " when expecting ", T::get_type_static()); + Logger::error("Invalid node type ", ast::get_type_name(node->kind()), " when expecting ", utility::type_name<T>()); } else { - Logger::error("Null node when expecting ", T::get_type_static()); + Logger::error("Null node when expecting ", utility::type_name<T>()); } return false; }; } -template<std::derived_from<ast::AbstractStringNode> T> -static Callback<T const&> auto _abstract_string_node_callback(Callback<std::string_view> auto callback, bool allow_empty) { - return [callback, allow_empty](T const& node) -> bool { +using _NodeIterator = typename decltype(std::declval<ast::NodeCPtr>()->children())::iterator; +using _NodeStatementRange = dryad::node_range<_NodeIterator, ast::Statement>; + +static NodeCallback auto _abstract_statement_node_callback(Callback<_NodeStatementRange> auto callback) { + return [callback](ast::NodeCPtr node) -> bool { + if (node != nullptr) { + if (auto const* file_tree = dryad::node_try_cast<ast::FileTree>(node)) { + return callback(file_tree->statements()); + } + if (auto const* list_value = dryad::node_try_cast<ast::ListValue>(node)) { + return callback(list_value->statements()); + } + Logger::error( + "Invalid node type ", ast::get_type_name(node->kind()), " when expecting ", utility::type_name<ast::FileTree>(), " or ", + utility::type_name<ast::ListValue>() + ); + } else { + Logger::error( + "Null node when expecting ", utility::type_name<ast::FileTree>(), " or ", utility::type_name<ast::ListValue>() + ); + } + return false; + }; +} + +template<std::derived_from<ast::FlatValue> T> +static Callback<T const*> auto _abstract_string_node_callback(Callback<std::string_view> auto callback, bool allow_empty) { + return [callback, allow_empty](T const* node) -> bool { if (allow_empty) { - return callback(node._name); + return callback(node->value().view()); } else { - if (!node._name.empty()) { - return callback(node._name); + if (node->value()) { + return callback(node->value().view()); } else { Logger::error("Invalid string value - empty!"); return false; @@ -38,30 +74,27 @@ static Callback<T const&> auto _abstract_string_node_callback(Callback<std::stri } node_callback_t NodeTools::expect_identifier(callback_t<std::string_view> callback) { - return _expect_type<ast::IdentifierNode>(_abstract_string_node_callback<ast::IdentifierNode>(callback, false)); + return _expect_type<ast::IdentifierValue>(_abstract_string_node_callback<ast::IdentifierValue>(callback, false)); } node_callback_t NodeTools::expect_string(callback_t<std::string_view> callback, bool allow_empty) { - return _expect_type<ast::StringNode>(_abstract_string_node_callback<ast::StringNode>(callback, allow_empty)); + return _expect_type<ast::StringValue>(_abstract_string_node_callback<ast::StringValue>(callback, allow_empty)); } node_callback_t NodeTools::expect_identifier_or_string(callback_t<std::string_view> callback, bool allow_empty) { return [callback, allow_empty](ast::NodeCPtr node) -> bool { if (node != nullptr) { - ast::AbstractStringNode const* cast_node = node->cast_to<ast::IdentifierNode>(); - if (cast_node == nullptr) { - cast_node = node->cast_to<ast::StringNode>(); - } + auto const* cast_node = dryad::node_try_cast<ast::FlatValue>(node); if (cast_node != nullptr) { - return _abstract_string_node_callback<ast::AbstractStringNode>(callback, allow_empty)(*cast_node); + return _abstract_string_node_callback<ast::FlatValue>(callback, allow_empty)(cast_node); } Logger::error( - "Invalid node type ", node->get_type(), " when expecting ", ast::IdentifierNode::get_type_static(), " or ", - ast::StringNode::get_type_static() + "Invalid node type ", ast::get_type_name(node->kind()), " when expecting ", utility::type_name<ast::IdentifierValue>(), " or ", + utility::type_name<ast::StringValue>() ); } else { Logger::error( - "Null node when expecting ", ast::IdentifierNode::get_type_static(), " or ", ast::StringNode::get_type_static() + "Null node when expecting ", utility::type_name<ast::IdentifierValue>(), " or ", utility::type_name<ast::StringValue>() ); } return false; @@ -221,28 +254,42 @@ node_callback_t NodeTools::expect_fvec2(callback_t<fvec2_t> callback) { } node_callback_t NodeTools::expect_assign(key_value_callback_t callback) { - return _expect_type<ast::AssignNode>([callback](ast::AssignNode const& assign_node) -> bool { - const bool ret = callback(assign_node._name, assign_node._initializer.get()); - if (!ret) { - Logger::error("Callback failed for assign node with key: ", assign_node._name); + return _expect_type<ast::AssignStatement>([callback](ast::AssignStatement const* assign_node) -> bool { + std::string_view left; + bool ret = expect_identifier(assign_variable_callback(left))(assign_node->left()); + if (ret) { + ret &= callback(left, assign_node->right()); + if (!ret) { + Logger::error("Callback failed for assign node with key: ", left); + } + } else { + Logger::error("Callback key failed for assign node with key: ", left); } return ret; }); } node_callback_t NodeTools::expect_list_and_length(length_callback_t length_callback, node_callback_t callback) { - return _expect_type<ast::AbstractListNode>([length_callback, callback](ast::AbstractListNode const& list_node) -> bool { - std::vector<ast::NodeUPtr> const& list = list_node._statements; + return _abstract_statement_node_callback([length_callback, callback](_NodeStatementRange list) -> bool { bool ret = true; - size_t size = length_callback(list.size()); - if (size > list.size()) { - Logger::error("Trying to read more values than the list contains: ", size, " > ", list.size()); - size = list.size(); + auto dist = ranges::distance(list); + size_t size = length_callback(dist); + + if (size > dist) { + Logger::error("Trying to read more values than the list contains: ", size, " > ", dist); + size = dist; ret = false; } - std::for_each(list.begin(), list.begin() + size, [callback, &ret](ast::NodeUPtr const& sub_node) -> void { - ret &= callback(sub_node.get()); - }); + for (auto [index, sub_node] : list | ranges::views::enumerate) { + if (index >= size) { + break; + } + if (auto const* value = dryad::node_try_cast<ast::ValueStatement>(sub_node)) { + ret &= callback(value->value()); + continue; + } + ret &= callback(sub_node); + } return ret; }); } @@ -286,16 +333,22 @@ node_callback_t NodeTools::expect_length(callback_t<size_t> callback) { } node_callback_t NodeTools::expect_key(std::string_view key, node_callback_t callback, bool* key_found, bool allow_duplicates) { - return _expect_type<ast::AbstractListNode>( - [key, callback, key_found, allow_duplicates](ast::AbstractListNode const& list_node) -> bool { + return _abstract_statement_node_callback( + [key, callback, key_found, allow_duplicates](_NodeStatementRange list) -> bool { bool ret = true; size_t keys_found = 0; - std::vector<ast::NodeUPtr> const& list = list_node._statements; - for (ast::NodeUPtr const& sub_node : list_node._statements) { - ast::AssignNode const* assign_node = sub_node->cast_to<ast::AssignNode>(); - if (assign_node != nullptr && assign_node->_name == key) { + for (auto sub_node : list) { + auto const* assign_node = dryad::node_try_cast<ast::AssignStatement>(sub_node); + if (assign_node == nullptr) { + continue; + } + std::string_view left; + if (!expect_identifier(assign_variable_callback(left))(assign_node->left())) { + continue; + } + if (left == key) { if (keys_found++ == 0) { - ret &= callback(&*assign_node->_initializer); + ret &= callback(assign_node->right()); if (allow_duplicates) { break; } diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index 92682e7..b0bb723 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -14,10 +14,32 @@ #include "openvic-simulation/types/HasIdentifier.hpp" #include "openvic-simulation/types/OrderedContainers.hpp" #include "openvic-simulation/types/Vector.hpp" +#include "openvic-simulation/utility/Getters.hpp" #include "openvic-simulation/utility/TslHelper.hpp" namespace OpenVic { - namespace ast = ovdl::v2script::ast; + namespace ast { + using namespace ovdl::v2script::ast; + using NodeCPtr = const Node*; + + constexpr std::string_view get_type_name(NodeKind kind) { +#define NODE_CASE(Node) \ + case Node: return OpenVic::utility::type_name<ast::Node>(); + switch (kind) { + using enum NodeKind; + NODE_CASE(FileTree); + NODE_CASE(IdentifierValue); + NODE_CASE(StringValue); + NODE_CASE(ListValue); + NODE_CASE(NullValue); + NODE_CASE(EventStatement); + NODE_CASE(AssignStatement); + NODE_CASE(ValueStatement); + default: ovdl::detail::unreachable(); + } + } +#undef NODE_CASE + } using name_list_t = std::vector<std::string>; std::ostream& operator<<(std::ostream& stream, name_list_t const& name_list); diff --git a/src/openvic-simulation/dataloader/Vic2PathSearch.cpp b/src/openvic-simulation/dataloader/Vic2PathSearch.cpp index dd36f28..bc30b6e 100644 --- a/src/openvic-simulation/dataloader/Vic2PathSearch.cpp +++ b/src/openvic-simulation/dataloader/Vic2PathSearch.cpp @@ -182,7 +182,7 @@ static fs::path _search_for_game_path(fs::path hint_path = {}) { lexy_vdf::Parser parser; std::string buffer; - auto error_log_stream = detail::CallbackStream { + auto error_log_stream = detail::make_callback_stream<char>( [](void const* s, std::streamsize n, void* user_data) -> std::streamsize { if (s != nullptr && n > 0 && user_data != nullptr) { static_cast<std::string*>(user_data)->append(static_cast<char const*>(s), n); @@ -193,7 +193,7 @@ static fs::path _search_for_game_path(fs::path hint_path = {}) { } }, &buffer - }; + ); parser.set_error_log_to(error_log_stream); parser.load_from_file(current_path); |