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