ArkScript
A small, fast, functional and scripting language for video games
Node.hpp
Go to the documentation of this file.
1/**
2 * @file Node.hpp
3 * @author Alexandre Plateau ([email protected])
4 * @brief AST node used by the parser, optimizer and compiler
5 * @date 2020-10-27
6 *
7 * @copyright Copyright (c) 2020-2025
8 *
9 */
10
11#ifndef COMPILER_AST_NODE_HPP
12#define COMPILER_AST_NODE_HPP
13
14#include <variant>
15#include <ostream>
16#include <string>
17#include <vector>
18
21#include <Ark/Platform.hpp>
22
23namespace Ark::internal
24{
25 /**
26 * @brief A node of an Abstract Syntax Tree for ArkScript
27 *
28 */
30 {
31 public:
32 using Value = std::variant<double, std::string, Keyword, std::vector<Node>, Namespace>;
33
34 Node() = default;
35
36 Node(NodeType node_type, const std::string& value);
37
38 explicit Node(NodeType node_type);
39 explicit Node(double value);
40 explicit Node(long value);
41 explicit Node(Keyword value);
42 explicit Node(const Namespace& namespace_);
43
44 /**
45 * @brief Return the string held by the value (if the node type allows it)
46 *
47 * @return const std::string&
48 */
49 [[nodiscard]] const std::string& string() const noexcept;
50
51 /**
52 * @brief Return the number held by the value (if the node type allows it)
53 *
54 * @return double
55 */
56 [[nodiscard]] double number() const noexcept;
57
58 /**
59 * @brief Return the keyword held by the value (if the node type allows it)
60 *
61 * @return Keyword
62 */
63 [[nodiscard]] Keyword keyword() const noexcept;
64
65 /**
66 * @brief Return the namespace held by the value (if the node type allows it)
67 *
68 * @return Namespace&
69 */
70 [[nodiscard]] Namespace& arkNamespace() noexcept;
71
72 /**
73 * @brief Return the namespace held by the value (if the node type allows it)
74 *
75 * @return const Namespace&
76 */
77 [[nodiscard]] const Namespace& constArkNamespace() const noexcept;
78
79 /**
80 * @brief Every node has a list as well as a value so we can push_back on all node no matter their type
81 *
82 * @param node a sub-node to push on the list held by the current node
83 */
84 void push_back(const Node& node) noexcept;
85
86 /**
87 * @brief Return the list of sub-nodes held by the node
88 *
89 * @return std::vector<Node>&
90 */
91 std::vector<Node>& list() noexcept;
92
93 /**
94 * @brief Return the list of sub-nodes held by the node
95 *
96 * @return const std::vector<Node>&
97 */
98 [[nodiscard]] const std::vector<Node>& constList() const noexcept;
99
100 /**
101 * @brief Return the node type
102 *
103 * @return NodeType
104 */
105 [[nodiscard]] NodeType nodeType() const noexcept;
106
107 /**
108 * @brief Check if the node is a list like node
109 * @return true if the node is either a list or a macro
110 * @return false
111 */
112 [[nodiscard]] bool isListLike() const noexcept;
113
114 /**
115 * @brief Check if the node is a string like node
116 * @return true if the node is either a symbol, a string or a spread
117 * @return false
118 */
119 [[nodiscard]] bool isStringLike() const noexcept;
120
121 /**
122 * @brief Copy a node to the current one, while keeping the filename and position in the file
123 *
124 * @param source node to copy type and value from
125 */
126 void updateValueAndType(const Node& source) noexcept;
127
128 /**
129 * @brief Set the Node Type object
130 *
131 * @param type
132 */
133 void setNodeType(NodeType type) noexcept;
134
135 /**
136 * @brief Set the String object
137 *
138 * @param value
139 */
140 void setString(const std::string& value) noexcept;
141
142 /**
143 * @brief Set the Position of the node in the text
144 *
145 * @param line
146 * @param col
147 */
148 void setPos(std::size_t line, std::size_t col) noexcept;
149
150 /**
151 * @brief Set the original Filename where the node was
152 *
153 * @param filename
154 */
155 void setFilename(const std::string& filename) noexcept;
156
157 /**
158 * @brief Set the comment field with the nearest comment before this node
159 * @param comment
160 * @return Node& reference to this node after updating it
161 */
162 Node& attachNearestCommentBefore(const std::string& comment);
163
164 /**
165 * @brief Set the comment_after field with the nearest comment after this node
166 * @param comment
167 * @return Node& reference to this node after updating it
168 */
169 Node& attachCommentAfter(const std::string& comment);
170
171 /**
172 * @brief Get the line at which this node was created
173 *
174 * @return std::size_t
175 */
176 [[nodiscard]] std::size_t line() const noexcept;
177
178 /**
179 * @brief Get the column at which this node was created
180 *
181 * @return std::size_t
182 */
183 [[nodiscard]] std::size_t col() const noexcept;
184
185 /**
186 * @brief Return the filename in which this node was created
187 *
188 * @return const std::string&
189 */
190 [[nodiscard]] const std::string& filename() const noexcept;
191
192 /**
193 * @brief Return the comment attached to this node, if any
194 * @return const std::string&
195 */
196 [[nodiscard]] const std::string& comment() const noexcept;
197
198 /**
199 * @brief Return the comment attached after this node, if any
200 * @return const std::string&
201 */
202 [[nodiscard]] const std::string& commentAfter() const noexcept;
203
204 /**
205 * @brief Compute a representation of the node without any comments or additional sugar, colors, types
206 * @return String representation of the node
207 */
208 [[nodiscard]] std::string repr() const noexcept;
209
210 /**
211 * @brief Print a node to an output stream with added type annotations
212 * @param os
213 * @return
214 */
215 [[nodiscard]] std::ostream& debugPrint(std::ostream& os) const noexcept;
216
217 friend bool operator==(const Node& A, const Node& B);
218 friend bool operator<(const Node& A, const Node& B);
219
220 private:
221 NodeType m_type { NodeType::Unused };
223 // position of the node in the original code, useful when it comes to parser errors
224 std::size_t m_line = 0, m_col = 0;
225 std::string m_filename;
226 std::string m_comment;
227 std::string m_after_comment; ///< Comment after node
228 };
229
230 const Node& getTrueNode();
231 const Node& getFalseNode();
232 const Node& getNilNode();
233 const Node& getListNode();
234
235 /**
236 *
237 * @param node
238 * @return std::string a string corresponding to the node type
239 */
240 inline std::string typeToString(const Node& node) noexcept
241 {
242 if (node.nodeType() == NodeType::Symbol)
243 {
244 if (node.string() == "nil")
245 return "Nil";
246 if (node.string() == "true" || node.string() == "false")
247 return "Bool";
248 }
249
250 const auto c = static_cast<std::size_t>(node.nodeType());
251 return (c < nodeTypes.size()) ? std::string(nodeTypes[c]) : "???";
252 }
253}
254
255#endif
Common code for the compiler.
#define ARK_API
Definition Module.hpp:28
ArkScript configuration macros.
A node of an Abstract Syntax Tree for ArkScript.
Definition Node.hpp:30
std::string m_after_comment
Comment after node.
Definition Node.hpp:227
std::string m_comment
Definition Node.hpp:226
std::string m_filename
Definition Node.hpp:225
std::variant< double, std::string, Keyword, std::vector< Node >, Namespace > Value
Definition Node.hpp:32
std::string typeToString(const Node &node) noexcept
Definition Node.hpp:240
constexpr std::array< std::string_view, 11 > nodeTypes
Node types as string, in the same order as the enum NodeType.
Definition Common.hpp:59
NodeType
The different node types available.
Definition Common.hpp:44
const Node & getNilNode()
Definition Node.cpp:320
Keyword
The different keywords available.
Definition Common.hpp:75
const Node & getFalseNode()
Definition Node.cpp:314
const Node & getListNode()
Definition Node.cpp:326
const Node & getTrueNode()
Definition Node.cpp:308