ArkScript
A small, lisp-inspired, functional scripting language
Node.hpp
Go to the documentation of this file.
1/**
2 * @file Node.hpp
3 * @author Lex Plateau (lexplt.dev@gmail.com)
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#include <optional>
19
24
25namespace Ark::internal
26{
27 /**
28 * @brief A node of an Abstract Syntax Tree for ArkScript
29 *
30 */
32 {
33 public:
34 using Value = std::variant<double, std::string, Keyword, std::vector<Node>, Namespace>;
35
36 Node() = default;
37
38 Node(NodeType node_type, const std::string& value);
39
40 explicit Node(NodeType node_type);
41 explicit Node(double value);
42 explicit Node(long value);
43 explicit Node(Keyword value);
44 explicit Node(const Namespace& namespace_);
45
46 /**
47 * @brief Return the string held by the value (if the node type allows it)
48 *
49 * @return const std::string&
50 */
51 [[nodiscard]] const std::string& string() const noexcept;
52
53 /**
54 * @brief Return the number held by the value (if the node type allows it)
55 *
56 * @return double
57 */
58 [[nodiscard]] double number() const noexcept;
59
60 /**
61 * @brief Return the keyword held by the value (if the node type allows it)
62 *
63 * @return Keyword
64 */
65 [[nodiscard]] Keyword keyword() const noexcept;
66
67 /**
68 * @brief Return the namespace held by the value (if the node type allows it)
69 *
70 * @return Namespace&
71 */
72 [[nodiscard]] Namespace& arkNamespace() noexcept;
73
74 /**
75 * @brief Return the namespace held by the value (if the node type allows it)
76 *
77 * @return const Namespace&
78 */
79 [[nodiscard]] const Namespace& constArkNamespace() const noexcept;
80
81 /**
82 * @brief Every node has a list as well as a value so we can push_back on all node no matter their type
83 *
84 * @param node a sub-node to push on the list held by the current node
85 */
86 void push_back(const Node& node) noexcept;
87
88 /**
89 * @brief Return the list of sub-nodes held by the node
90 *
91 * @return std::vector<Node>&
92 */
93 std::vector<Node>& list() noexcept;
94
95 /**
96 * @brief Return the list of sub-nodes held by the node
97 *
98 * @return const std::vector<Node>&
99 */
100 [[nodiscard]] const std::vector<Node>& constList() const noexcept;
101
102 /**
103 * @brief Return the node type
104 *
105 * @return NodeType
106 */
107 [[nodiscard]] NodeType nodeType() const noexcept;
108
109 /**
110 * @brief Check if the node is a list like node
111 * @return true if the node is either a list or a macro
112 * @return false
113 */
114 [[nodiscard]] bool isListLike() const noexcept;
115
116 /**
117 * @brief Check if the node is a function
118 * @return true if the node is a function declaration
119 * @return false
120 */
121 [[nodiscard]] bool isFunction() const noexcept;
122
123 /**
124 * @brief Get the unqualified name, if it has been set
125 *
126 * @return const std::optional<std::string>&
127 */
128 [[nodiscard]] const std::optional<std::string>& getUnqualifiedName() const noexcept;
129
130 /**
131 * @brief Copy a node to the current one, while keeping the filename and position in the file
132 *
133 * @param source node to copy type and value from
134 */
135 void updateValueAndType(const Node& source) noexcept;
136
137 /**
138 * @brief Set the Node Type object
139 *
140 * @param type
141 */
142 void setNodeType(NodeType type) noexcept;
143
144 /**
145 * @brief Set the unqualified name (used by Capture nodes)
146 *
147 * @param name
148 */
149 void setUnqualifiedName(const std::string& name) noexcept;
150
151 /**
152 * @brief Set the String object
153 *
154 * @param value
155 */
156 void setString(const std::string& value) noexcept;
157
158 /**
159 * @brief Position the current node at a given span in a file
160 *
161 * @param source node to copy filename and position from
162 */
163 void setPositionFrom(const Node& source) noexcept;
164
165 /**
166 * @brief Set the comment field with the nearest comment before this node
167 * @param comment
168 * @return Node& reference to this node after updating it
169 */
170 Node& attachNearestCommentBefore(const std::string& comment);
171
172 /**
173 * @brief Set the comment_after field with the nearest comment after this node
174 * @param comment
175 * @return Node& reference to this node after updating it
176 */
177 Node& attachCommentAfter(const std::string& comment);
178
179 /**
180 * @brief Set the m_alt_syntax flag of the node
181 * @param toggle
182 */
183 void setAltSyntax(bool toggle);
184
185 /**
186 * @brief Set the m_is_anonymous_function flag on the node
187 * @param anonymous true to mark the node as an anonymous function
188 */
189 void setFunctionKind(bool anonymous);
190
191 /**
192 * @brief Check if a node is an anonymous function
193 * @return true if the node is of an anonymous function
194 * @return false
195 */
196 [[nodiscard]] bool isAnonymousFunction() const noexcept;
197
198 /**
199 * @brief Get the span of the node (start and end)
200 *
201 * @return const FileSpan
202 */
203 [[nodiscard]] FileSpan position() const noexcept;
204
205 /**
206 * @brief Return the filename in which this node was created
207 *
208 * @return const std::string&
209 */
210 [[nodiscard]] const std::string& filename() const noexcept;
211
212 /**
213 * @brief Return the comment attached to this node, if any
214 * @return const std::string&
215 */
216 [[nodiscard]] const std::string& comment() const noexcept;
217
218 /**
219 * @brief Return the comment attached after this node, if any
220 * @return const std::string&
221 */
222 [[nodiscard]] const std::string& commentAfter() const noexcept;
223
224 /**
225 * @brief Compute a representation of the node without any comments or additional sugar, colors, types
226 * @return String representation of the node
227 */
228 [[nodiscard]] std::string repr() const noexcept;
229
230 /**
231 * @brief Print a node to an output stream with added type annotations
232 * @param os
233 * @return
234 */
235 [[nodiscard]] std::ostream& debugPrint(std::ostream& os) const noexcept;
236
237 friend bool operator==(const Node& A, const Node& B);
238 friend bool operator<(const Node& A, const Node& B);
239 friend class Parser;
240
241 private:
242 NodeType m_type { NodeType::Unused };
244 std::optional<std::string> m_unqualified_name { std::nullopt }; ///< Used by Capture nodes, to have the FQN in the value, and the captured name here
245 // position of the node in the original code, useful when it comes to parser errors
247 std::string m_filename;
248 std::string m_comment;
249 std::string m_after_comment; ///< Comment after node
250 bool m_alt_syntax = false; ///< Used to tell if a node uses the alternative syntax (if available), eg (begin) / {}, (list) / []
251 bool m_is_anonymous_function = true; ///< Function nodes are marked as anonymous/non-anonymous by the ASTLowerer, to enable some optimisations
252 };
253
254 const Node& getTrueNode();
255 const Node& getFalseNode();
256 const Node& getNilNode();
257 const Node& getListNode();
258
259 /**
260 *
261 * @param node
262 * @return std::string a string corresponding to the node type
263 */
264 inline std::string typeToString(const Node& node) noexcept
265 {
266 if (node.nodeType() == NodeType::Symbol)
267 {
268 if (node.string() == "nil")
269 return "Nil";
270 if (node.string() == "true" || node.string() == "false")
271 return "Bool";
272 }
273
274 const auto c = static_cast<std::size_t>(node.nodeType());
275 return (c < nodeTypes.size()) ? std::string(nodeTypes[c]) : "???";
276 }
277}
278
279#endif
Common code for the compiler.
#define ARK_API
Definition Module.hpp:22
ArkScript configuration macros.
Defines position utilities (for text in a file) for the parser, formatter, diagnostics.
A node of an Abstract Syntax Tree for ArkScript.
Definition Node.hpp:32
std::string m_after_comment
Comment after node.
Definition Node.hpp:249
std::string m_comment
Definition Node.hpp:248
std::string m_filename
Definition Node.hpp:247
std::variant< double, std::string, Keyword, std::vector< Node >, Namespace > Value
Definition Node.hpp:34
std::string typeToString(const Node &node) noexcept
Definition Node.hpp:264
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:366
Keyword
The different keywords available.
Definition Common.hpp:75
const Node & getFalseNode()
Definition Node.cpp:360
const Node & getListNode()
Definition Node.cpp:372
const Node & getTrueNode()
Definition Node.cpp:354
STL namespace.
Describes a span for a node/atom in a file, its start position and end position.
Definition Position.hpp:35