aboutsummaryrefslogtreecommitdiff
path: root/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp')
-rw-r--r--include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp131
1 files changed, 104 insertions, 27 deletions
diff --git a/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp b/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp
index 7b382fd..8e39bd9 100644
--- a/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp
+++ b/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp
@@ -1,18 +1,24 @@
#pragma once
+#include <cstddef>
+#include <cstdint>
#include <iostream>
#include <memory>
-#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>
+#include <openvic-dataloader/detail/OptionalConstexpr.hpp>
#include <openvic-dataloader/detail/SelfType.hpp>
#include <openvic-dataloader/detail/TypeName.hpp>
-#define OVDL_PRINT_FUNC_DEF std::ostream& print(std::ostream& stream, size_t indent) const override
+namespace ovdl::v2script {
+ class Parser;
+}
+
+#define OVDL_PRINT_FUNC_DEF std::ostream& print(std::ostream& stream, std::size_t indent) const override
// defines get_type_static and get_type for string type naming
#define OVDL_RT_TYPE_DEF \
@@ -32,31 +38,86 @@ namespace ovdl::v2script::ast {
using NodeCPtr = const Node*;
using NodeUPtr = std::unique_ptr<Node>;
+ struct NodeLocation {
+ const char* _begin = nullptr;
+ const char* _end = nullptr;
+
+ NodeLocation() = default;
+ NodeLocation(const char* pos) : _begin(pos),
+ _end(pos) {}
+ NodeLocation(const char* begin, const char* end) : _begin(begin),
+ _end(end) {}
+
+ NodeLocation(const NodeLocation&) = default;
+ NodeLocation& operator=(const NodeLocation&) = default;
+
+ NodeLocation(NodeLocation&&) = default;
+ NodeLocation& operator=(NodeLocation&&) = default;
+
+ const char* begin() const { return _begin; }
+ const char* end() const { return _end; }
+
+ static inline NodeLocation make_from(const char* begin, const char* end) {
+ end++;
+ if (begin >= end) return NodeLocation(begin);
+ return NodeLocation(begin, end);
+ }
+ };
+
struct Node {
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
- Node() = default;
+ Node(NodeLocation location) : _location(location) {}
Node(Node&&) = default;
Node& operator=(Node&&) = default;
virtual ~Node() = default;
- virtual std::ostream& print(std::ostream& stream, size_t indent) const = 0;
- static std::ostream& print_ptr(std::ostream& stream, NodeCPtr node, size_t indent);
+ virtual std::ostream& print(std::ostream& stream, std::size_t indent) const = 0;
+ static std::ostream& print_ptr(std::ostream& stream, NodeCPtr node, std::size_t indent);
explicit operator std::string() const;
static constexpr std::string_view get_type_static() { return detail::type_name<Node>(); }
constexpr virtual std::string_view get_type() const = 0;
+ static constexpr std::string_view get_base_type_static() { return detail::type_name<Node>(); }
+ constexpr virtual std::string_view get_base_type() const { return get_base_type_static(); }
+
template<typename T>
constexpr bool is_type() const {
return get_type().compare(detail::type_name<T>()) == 0;
}
template<typename T>
- constexpr std::optional<T&> cast_to() {
- if (is_type<T>()) return static_cast<T>(*this);
- return std::nullopt;
+ constexpr bool is_derived_from() const {
+ return is_type<T>() || get_base_type().compare(detail::type_name<T>()) == 0;
}
+
+ template<typename T>
+ constexpr T* cast_to() {
+ if (is_derived_from<T>() || is_type<Node>()) return (static_cast<T*>(this));
+ return nullptr;
+ }
+
+ template<typename T>
+ constexpr const T* const cast_to() const {
+ if (is_derived_from<T>() || is_type<Node>()) return (static_cast<const T*>(this));
+ return nullptr;
+ }
+
+ const NodeLocation location() const { return _location; }
+
+ struct line_col {
+ uint32_t line;
+ uint32_t column;
+ };
+
+ private:
+ friend class ::ovdl::v2script::Parser;
+ const line_col get_begin_line_col(const Parser& parser) const;
+ const line_col get_end_line_col(const Parser& parser) const;
+
+ private:
+ NodeLocation _location;
};
inline std::ostream& operator<<(std::ostream& stream, Node const& node) {
@@ -65,6 +126,9 @@ namespace ovdl::v2script::ast {
inline std::ostream& operator<<(std::ostream& stream, NodeCPtr node) {
return Node::print_ptr(stream, node, 0);
}
+ inline std::ostream& operator<<(std::ostream& stream, Node::line_col const& val) {
+ return stream << '(' << val.line << ':' << val.column << ')';
+ }
template<class T, class... Args>
NodePtr make_node_ptr(Args&&... args) {
@@ -97,18 +161,22 @@ namespace ovdl::v2script::ast {
struct AbstractStringNode : public Node {
std::string _name;
- explicit AbstractStringNode(std::string&& name);
+ AbstractStringNode(std::string&& name);
+ AbstractStringNode(NodeLocation location, std::string&& name);
OVDL_TYPE_DEFINE_SELF;
OVDL_RT_TYPE_DEF;
OVDL_PRINT_FUNC_DEF;
+ static constexpr std::string_view get_base_type_static() { return detail::type_name<AbstractStringNode>(); }
+ constexpr std::string_view get_base_type() const override { return ::ovdl::detail::type_name<std::decay_t<decltype(*this)>>(); }
};
-#define OVDL_AST_STRING_NODE(NAME) \
- struct NAME final : public AbstractStringNode { \
- explicit NAME(std::string&& name); \
- OVDL_TYPE_DEFINE_SELF; \
- OVDL_RT_TYPE_DEF; \
- OVDL_PRINT_FUNC_DEF; \
+#define OVDL_AST_STRING_NODE(NAME) \
+ struct NAME final : public AbstractStringNode { \
+ NAME(std::string&& name); \
+ NAME(NodeLocation location, std::string&& name); \
+ OVDL_TYPE_DEFINE_SELF; \
+ OVDL_RT_TYPE_DEF; \
+ OVDL_PRINT_FUNC_DEF; \
}
// Value Expression Nodes
@@ -131,7 +199,7 @@ namespace ovdl::v2script::ast {
struct AssignNode final : public Node {
std::string _name;
NodeUPtr _initializer;
- explicit AssignNode(NodeCPtr name, NodePtr init);
+ AssignNode(NodeLocation location, NodeCPtr name, NodePtr init);
OVDL_TYPE_DEFINE_SELF;
OVDL_RT_TYPE_DEF;
OVDL_PRINT_FUNC_DEF;
@@ -140,17 +208,21 @@ namespace ovdl::v2script::ast {
struct AbstractListNode : public Node {
std::vector<NodeUPtr> _statements;
AbstractListNode(const std::vector<NodePtr>& statements = std::vector<NodePtr> {});
+ AbstractListNode(NodeLocation location, const std::vector<NodePtr>& statements = std::vector<NodePtr> {});
OVDL_TYPE_DEFINE_SELF;
OVDL_RT_TYPE_DEF;
OVDL_PRINT_FUNC_DEF;
+ static constexpr std::string_view get_base_type_static() { return detail::type_name<AbstractListNode>(); }
+ constexpr std::string_view get_base_type() const override { return ::ovdl::detail::type_name<std::decay_t<decltype(*this)>>(); }
};
-#define OVDL_AST_LIST_NODE(NAME) \
- struct NAME final : public AbstractListNode { \
- explicit NAME(const std::vector<NodePtr>& statements = std::vector<NodePtr> {}); \
- OVDL_TYPE_DEFINE_SELF; \
- OVDL_RT_TYPE_DEF; \
- OVDL_PRINT_FUNC_DEF; \
+#define OVDL_AST_LIST_NODE(NAME) \
+ struct NAME final : public AbstractListNode { \
+ NAME(const std::vector<NodePtr>& statements = std::vector<NodePtr> {}); \
+ NAME(NodeLocation location, const std::vector<NodePtr>& statements = std::vector<NodePtr> {}); \
+ OVDL_TYPE_DEFINE_SELF; \
+ OVDL_RT_TYPE_DEF; \
+ OVDL_PRINT_FUNC_DEF; \
}
OVDL_AST_LIST_NODE(FileNode);
@@ -170,7 +242,8 @@ namespace ovdl::v2script::ast {
Province
} _type;
std::vector<NodeUPtr> _statements;
- explicit EventNode(Type type, const std::vector<NodePtr>& statements = {});
+ EventNode(Type type, const std::vector<NodePtr>& statements = {});
+ EventNode(NodeLocation location, Type type, const std::vector<NodePtr>& statements = {});
OVDL_TYPE_DEFINE_SELF;
OVDL_RT_TYPE_DEF;
OVDL_PRINT_FUNC_DEF;
@@ -179,7 +252,8 @@ namespace ovdl::v2script::ast {
struct DecisionNode final : public Node {
NodeUPtr _name;
std::vector<NodeUPtr> _statements;
- explicit DecisionNode(NodePtr name, const std::vector<NodePtr>& statements = {});
+ DecisionNode(NodePtr name, const std::vector<NodePtr>& statements = {});
+ DecisionNode(NodeLocation location, NodePtr name, const std::vector<NodePtr>& statements = {});
OVDL_TYPE_DEFINE_SELF;
OVDL_RT_TYPE_DEF;
OVDL_PRINT_FUNC_DEF;
@@ -188,7 +262,8 @@ namespace ovdl::v2script::ast {
struct EventMtthModifierNode final : public Node {
NodeUPtr _factor_value;
std::vector<NodeUPtr> _statements;
- EventMtthModifierNode() {}
+ EventMtthModifierNode() : Node({}) {}
+ EventMtthModifierNode(NodeLocation location) : Node(location) {}
OVDL_TYPE_DEFINE_SELF;
OVDL_RT_TYPE_DEF;
OVDL_PRINT_FUNC_DEF;
@@ -202,7 +277,8 @@ namespace ovdl::v2script::ast {
} _type;
NodeUPtr _name;
NodeUPtr _initializer;
- explicit ExecutionNode(Type type, NodePtr name, NodePtr init);
+ ExecutionNode(Type type, NodePtr name, NodePtr init);
+ ExecutionNode(NodeLocation location, Type type, NodePtr name, NodePtr init);
OVDL_TYPE_DEFINE_SELF;
OVDL_RT_TYPE_DEF;
OVDL_PRINT_FUNC_DEF;
@@ -211,7 +287,8 @@ namespace ovdl::v2script::ast {
struct ExecutionListNode final : public Node {
ExecutionNode::Type _type;
std::vector<NodeUPtr> _statements;
- explicit ExecutionListNode(ExecutionNode::Type type, const std::vector<NodePtr>& statements);
+ ExecutionListNode(ExecutionNode::Type type, const std::vector<NodePtr>& statements);
+ ExecutionListNode(NodeLocation location, ExecutionNode::Type type, const std::vector<NodePtr>& statements);
OVDL_TYPE_DEFINE_SELF;
OVDL_RT_TYPE_DEF;
OVDL_PRINT_FUNC_DEF;