ArkScript
A small, fast, functional and scripting language for video games
Node.cpp
Go to the documentation of this file.
3
4#include <Ark/Exceptions.hpp>
5
6#include <fmt/core.h>
7
8namespace Ark::internal
9{
10 Node::Node(const NodeType node_type, const std::string& value) :
11 m_type(node_type), m_value(value)
12 {}
13
14 Node::Node(const NodeType node_type) :
15 m_type(node_type)
16 {
18 m_value = std::vector<Node>();
19 }
20
21 Node::Node(double value) :
22 m_type(NodeType::Number), m_value(value)
23 {}
24
25 Node::Node(const long value) :
26 m_type(NodeType::Number), m_value(static_cast<double>(value))
27 {}
28
30 m_type(NodeType::Keyword), m_value(value)
31 {}
32
33 Node::Node(Namespace namespace_) :
34 m_type(NodeType::Namespace), m_value(namespace_)
35 {}
36
37 const std::string& Node::string() const noexcept
38 {
39 return std::get<std::string>(m_value);
40 }
41
42 double Node::number() const noexcept
43 {
44 return std::get<double>(m_value);
45 }
46
47 Keyword Node::keyword() const noexcept
48 {
49 return std::get<Keyword>(m_value);
50 }
51
53 {
54 return std::get<Namespace>(m_value);
55 }
56
57 const Namespace& Node::constArkNamespace() const noexcept
58 {
59 return std::get<Namespace>(m_value);
60 }
61
62 void Node::push_back(const Node& node) noexcept
63 {
64 list().push_back(node);
65 }
66
67 std::vector<Node>& Node::list() noexcept
68 {
69 return std::get<std::vector<Node>>(m_value);
70 }
71
72 const std::vector<Node>& Node::constList() const noexcept
73 {
74 return std::get<std::vector<Node>>(m_value);
75 }
76
77 NodeType Node::nodeType() const noexcept
78 {
79 return m_type;
80 }
81
82 bool Node::isListLike() const noexcept
83 {
85 }
86
87 bool Node::isStringLike() const noexcept
88 {
90 }
91
92 void Node::updateValueAndType(const Node& source) noexcept
93 {
94 m_type = source.m_type;
95 m_value = source.m_value;
96 }
97
98 void Node::setNodeType(const NodeType type) noexcept
99 {
100 m_type = type;
101 }
102
103 void Node::setString(const std::string& value) noexcept
104 {
105 m_value = value;
106 }
107
108 void Node::setPos(const std::size_t line, const std::size_t col) noexcept
109 {
110 m_line = line;
111 m_col = col;
112 }
113
114 void Node::setFilename(const std::string& filename) noexcept
115 {
116 m_filename = filename;
117 }
118
119 Node& Node::attachNearestCommentBefore(const std::string& comment)
120 {
122 return *this;
123 }
124
125 Node& Node::attachCommentAfter(const std::string& comment)
126 {
127 if (!m_after_comment.empty())
128 m_after_comment += "\n";
130 if (!m_after_comment.empty() && m_after_comment.back() == '\n')
131 m_after_comment.pop_back();
132 return *this;
133 }
134
135 std::size_t Node::line() const noexcept
136 {
137 return m_line;
138 }
139
140 std::size_t Node::col() const noexcept
141 {
142 return m_col;
143 }
144
145 const std::string& Node::filename() const noexcept
146 {
147 return m_filename;
148 }
149
150 const std::string& Node::comment() const noexcept
151 {
152 return m_comment;
153 }
154
155 const std::string& Node::commentAfter() const noexcept
156 {
157 return m_after_comment;
158 }
159
160 std::string Node::repr() const noexcept
161 {
162 std::string data;
163 switch (m_type)
164 {
165 case NodeType::Symbol:
166 data += string();
167 break;
168
170 data += "&" + string();
171 break;
172
174 data += keywords[static_cast<std::size_t>(keyword())];
175 break;
176
177 case NodeType::String:
178 data += "\"" + string() + "\"";
179 break;
180
181 case NodeType::Number:
182 data += fmt::format("{}", number());
183 break;
184
185 case NodeType::List:
186 data += "(";
187 for (std::size_t i = 0, end = constList().size(); i < end; ++i)
188 {
189 data += constList()[i].repr();
190 if (i < end - 1)
191 data += " ";
192 }
193 data += ")";
194 break;
195
196 case NodeType::Field:
197 for (std::size_t i = 0, end = constList().size(); i < end; ++i)
198 {
199 data += constList()[i].repr();
200 if (i < end - 1)
201 data += ".";
202 }
203 break;
204
205 case NodeType::Macro:
206 data += "($ ";
207 for (std::size_t i = 0, end = constList().size(); i < end; ++i)
208 {
209 data += constList()[i].repr();
210 if (i < end - 1)
211 data += " ";
212 }
213 data += ")";
214 break;
215
216 case NodeType::Spread:
217 data += "..." + string();
218 break;
219
220 // namespace node should not have a representation as it is purely internal,
221 // and it can't be exploited by macros (unless you try passing an import node
222 // to a macro, which should not happen?)
224 data += constArkNamespace().ast->repr();
225 break;
226
227 case NodeType::Unused:
228 break;
229 }
230 return data;
231 }
232
233 std::ostream& Node::debugPrint(std::ostream& os) const noexcept
234 {
235 switch (m_type)
236 {
237 case NodeType::Symbol:
238 os << "Symbol:" << string();
239 break;
240
242 os << "Capture:" << string();
243 break;
244
246 os << "Keyword:";
247 switch (keyword())
248 {
249 case Keyword::Fun: os << "Fun"; break;
250 case Keyword::Let: os << "Let"; break;
251 case Keyword::Mut: os << "Mut"; break;
252 case Keyword::Set: os << "Set"; break;
253 case Keyword::If: os << "If"; break;
254 case Keyword::While: os << "While"; break;
255 case Keyword::Begin: os << "Begin"; break;
256 case Keyword::Import: os << "Import"; break;
257 case Keyword::Del: os << "Del"; break;
258 }
259 break;
260
261 case NodeType::String:
262 os << "String:" << string();
263 break;
264
265 case NodeType::Number:
266 os << "Number:" << number();
267 break;
268
269 case NodeType::List:
270 os << "( ";
271 for (const auto& i : constList())
272 i.debugPrint(os) << " ";
273 os << ")";
274 break;
275
276 case NodeType::Field:
277 os << "( Field ";
278 for (const auto& i : constList())
279 i.debugPrint(os) << " ";
280 os << ")";
281 break;
282
283 case NodeType::Macro:
284 os << "( Macro ";
285 for (const auto& i : constList())
286 i.debugPrint(os) << " ";
287 os << ")";
288 break;
289
290 case NodeType::Spread:
291 os << "Spread:" << string();
292 break;
293
295 {
296 const auto details = constArkNamespace();
297 os << "( Namespace:" << details.name << " ";
298 details.ast->debugPrint(os) << " )";
299 break;
300 }
301
302 case NodeType::Unused:
303 break;
304 }
305 return os;
306 }
307
309 {
310 static const Node TrueNode(NodeType::Symbol, "true");
311 return TrueNode;
312 }
313
315 {
316 static const Node FalseNode(NodeType::Symbol, "false");
317 return FalseNode;
318 }
319
321 {
322 static const Node NilNode(NodeType::Symbol, "nil");
323 return NilNode;
324 }
325
327 {
328 static const Node ListNode(NodeType::Symbol, "list");
329 return ListNode;
330 }
331
332 bool operator==(const Node& A, const Node& B)
333 {
334 if (A.m_type != B.m_type) // should have the same types
335 return false;
336
337 if (A.m_type != NodeType::List)
338 return A.m_value == B.m_value;
339 return false;
340 }
341
342 bool operator<(const Node& A, const Node& B)
343 {
344 if (A.nodeType() != B.nodeType())
345 return (static_cast<int>(A.nodeType()) - static_cast<int>(B.nodeType())) < 0;
346
347 switch (A.nodeType())
348 {
349 case NodeType::Number:
350 [[fallthrough]];
351 case NodeType::Symbol:
352 [[fallthrough]];
353 case NodeType::String:
354 return A.m_value < B.m_value;
355
356 default:
357 return false;
358 }
359 }
360}
Common code for the compiler.
ArkScript homemade exceptions.
AST node used by the parser, optimizer and compiler.
A node of an Abstract Syntax Tree for ArkScript.
Definition Node.hpp:31
NodeType nodeType() const noexcept
Return the node type.
Definition Node.cpp:77
std::string m_after_comment
Comment after node.
Definition Node.hpp:228
void setNodeType(NodeType type) noexcept
Set the Node Type object.
Definition Node.cpp:98
bool isListLike() const noexcept
Check if the node is a list like node.
Definition Node.cpp:82
const std::string & filename() const noexcept
Return the filename in which this node was created.
Definition Node.cpp:145
const std::string & string() const noexcept
Return the string held by the value (if the node type allows it)
Definition Node.cpp:37
void setPos(std::size_t line, std::size_t col) noexcept
Set the Position of the node in the text.
Definition Node.cpp:108
const std::vector< Node > & constList() const noexcept
Return the list of sub-nodes held by the node.
Definition Node.cpp:72
Keyword keyword() const noexcept
Return the keyword held by the value (if the node type allows it)
Definition Node.cpp:47
std::string m_comment
Definition Node.hpp:227
NodeType m_type
Definition Node.hpp:222
std::string m_filename
Definition Node.hpp:226
Namespace & arkNamespace() noexcept
Return the namespace held by the value (if the node type allows it)
Definition Node.cpp:52
const std::string & comment() const noexcept
Return the comment attached to this node, if any.
Definition Node.cpp:150
Node & attachNearestCommentBefore(const std::string &comment)
Set the comment field with the nearest comment before this node.
Definition Node.cpp:119
std::string repr() const noexcept
Compute a representation of the node without any comments or additional sugar, colors,...
Definition Node.cpp:160
void setFilename(const std::string &filename) noexcept
Set the original Filename where the node was.
Definition Node.cpp:114
std::size_t m_line
Definition Node.hpp:225
std::ostream & debugPrint(std::ostream &os) const noexcept
Print a node to an output stream with added type annotations.
Definition Node.cpp:233
const Namespace & constArkNamespace() const noexcept
Return the namespace held by the value (if the node type allows it)
Definition Node.cpp:57
const std::string & commentAfter() const noexcept
Return the comment attached after this node, if any.
Definition Node.cpp:155
std::size_t col() const noexcept
Get the column at which this node was created.
Definition Node.cpp:140
void push_back(const Node &node) noexcept
Every node has a list as well as a value so we can push_back on all node no matter their type.
Definition Node.cpp:62
bool isStringLike() const noexcept
Check if the node is a string like node.
Definition Node.cpp:87
void setString(const std::string &value) noexcept
Set the String object.
Definition Node.cpp:103
double number() const noexcept
Return the number held by the value (if the node type allows it)
Definition Node.cpp:42
void updateValueAndType(const Node &source) noexcept
Copy a node to the current one, while keeping the filename and position in the file.
Definition Node.cpp:92
Node & attachCommentAfter(const std::string &comment)
Set the comment_after field with the nearest comment after this node.
Definition Node.cpp:125
std::size_t line() const noexcept
Get the line at which this node was created.
Definition Node.cpp:135
std::size_t m_col
Definition Node.hpp:225
std::vector< Node > & list() noexcept
Return the list of sub-nodes held by the node.
Definition Node.cpp:67
bool operator<(const Namespace &, const Namespace &)
Definition Namespace.hpp:27
bool operator==(const Namespace &A, const Namespace &B)
Definition Namespace.hpp:21
NodeType
The different node types available.
Definition Common.hpp:29
const Node & getNilNode()
Definition Node.cpp:320
Keyword
The different keywords available.
Definition Common.hpp:60
const Node & getFalseNode()
Definition Node.cpp:314
const Node & getListNode()
Definition Node.cpp:326
constexpr std::array< std::string_view, 9 > keywords
List of available keywords in ArkScript.
Definition Common.hpp:73
const Node & getTrueNode()
Definition Node.cpp:308
std::shared_ptr< Node > ast
Definition Namespace.hpp:18