aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/dataloader/NodeTools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/dataloader/NodeTools.cpp')
-rw-r--r--src/openvic-simulation/dataloader/NodeTools.cpp135
1 files changed, 94 insertions, 41 deletions
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;
}