ArkScript
A small, fast, functional and scripting language for video games
Node.cpp
Go to the documentation of this file.
2
3#include <termcolor/proxy.hpp>
4
5#include <Ark/Exceptions.hpp>
6
7namespace Ark::internal
8{
9 // Static methods.
11 {
12 static const Node TrueNode { "true", NodeType::Symbol };
13 return TrueNode;
14 }
15
17 {
18 static const Node FalseNode { "false", NodeType::Symbol };
19 return FalseNode;
20 }
21
23 {
24 static const Node NilNode { "nil", NodeType::Symbol };
25 return NilNode;
26 }
27
29 {
30 static const Node ListNode { "list", NodeType::Symbol };
31 return ListNode;
32 }
33
34 // Normal Methods
35 Node::Node(long value) noexcept :
36 m_type(NodeType::Number),
37 m_value(static_cast<double>(value))
38 {}
39
40 Node::Node(double value) noexcept :
41 m_type(NodeType::Number),
42 m_value(value)
43 {}
44
45 Node::Node(const std::string& value, NodeType const& type) noexcept :
46 m_type(type),
47 m_value(value)
48 {}
49
50 Node::Node(const std::string& value) noexcept :
52 {}
53
54 Node::Node(Keyword value) noexcept :
55 m_type(NodeType::Keyword),
56 m_value(value)
57 {}
58
59 Node::Node(NodeType type) noexcept :
60 m_type(type)
61 {}
62
63 Node::Node(const Node& other) noexcept :
64 m_type(other.m_type),
65 m_value(other.m_value),
66 m_list(other.m_list),
67 m_line(other.m_line),
68 m_col(other.m_col),
69 m_filename(other.m_filename)
70 {}
71
72 Node& Node::operator=(Node other) noexcept
73 {
74 swap(other);
75 return *this;
76 }
77
78 void Node::swap(Node& other) noexcept
79 {
80 using std::swap;
81
82 swap(m_type, other.m_type);
83 swap(m_value, other.m_value);
84 swap(m_list, other.m_list);
85 swap(m_line, other.m_line);
86 swap(m_col, other.m_col);
87 swap(m_filename, other.m_filename);
88 }
89
90 // -------------------------
91
92 const std::string& Node::string() const noexcept
93 {
94 return std::get<std::string>(m_value);
95 }
96
97 double Node::number() const noexcept
98 {
99 return std::get<double>(m_value);
100 }
101
102 Keyword Node::keyword() const noexcept
103 {
104 return std::get<Keyword>(m_value);
105 }
106
107 // -------------------------
108
109 void Node::push_back(const Node& node) noexcept
110 {
111 m_list.push_back(node);
112 }
113
114 std::vector<Node>& Node::list() noexcept
115 {
116 return m_list;
117 }
118
119 const std::vector<Node>& Node::constList() const noexcept
120 {
121 return m_list;
122 }
123
124 // -------------------------
125
126 NodeType Node::nodeType() const noexcept
127 {
128 return m_type;
129 }
130
131 void Node::setNodeType(NodeType type) noexcept
132 {
133 m_type = type;
134 }
135
136 void Node::setString(const std::string& value) noexcept
137 {
138 m_value = value;
139 }
140
141 void Node::setNumber(double value) noexcept
142 {
143 m_value = value;
144 }
145
146 void Node::setKeyword(Keyword kw) noexcept
147 {
148 m_value = kw;
149 }
150
151 // -------------------------
152
153 void Node::setPos(std::size_t line, std::size_t col) noexcept
154 {
155 m_line = line;
156 m_col = col;
157 }
158
159 void Node::setFilename(const std::string& filename) noexcept
160 {
161 m_filename = filename;
162 }
163
164 std::size_t Node::line() const noexcept
165 {
166 return m_line;
167 }
168
169 std::size_t Node::col() const noexcept
170 {
171 return m_col;
172 }
173
174 const std::string& Node::filename() const noexcept
175 {
176 return m_filename;
177 }
178
179 // -------------------------
180
181 auto colors = std::vector(
182 { termcolor::blue,
183 termcolor::red,
184 termcolor::green,
185 termcolor::cyan,
186 termcolor::magenta });
187
188 void swap(Node& lhs, Node& rhs) noexcept
189 {
190 lhs.swap(rhs);
191 }
192 std::ostream& operator<<(std::ostream& os, const Node& N) noexcept
193 {
194 static int index = 0;
195
196 switch (N.m_type)
197 {
198 case NodeType::String:
199 os << '"' << N.string() << '"';
200 break;
201
202 case NodeType::Symbol:
203 os << "(Symbol) " << N.string();
204 break;
205
207 os << "(Capture) " << N.string();
208 break;
209
211 os << "(GetField) " << N.string();
212 break;
213
214 case NodeType::Number:
215 os << N.number();
216 break;
217
218 case NodeType::List:
219 {
220 os << colors[index % colors.size()] << "( " << termcolor::reset;
221 index++;
222 for (auto& t : N.m_list)
223 os << t << " ";
224 index--;
225 os << colors[index % colors.size()] << ")" << termcolor::reset;
226 break;
227 }
228
230 os << "Closure";
231 break;
232
234 switch (N.keyword())
235 {
236 case Keyword::Fun: os << "Fun"; break;
237 case Keyword::Let: os << "Let"; break;
238 case Keyword::Mut: os << "Mut"; break;
239 case Keyword::Set: os << "Set"; break;
240 case Keyword::If: os << "If"; break;
241 case Keyword::While: os << "While"; break;
242 case Keyword::Begin: os << "Begin"; break;
243 case Keyword::Import: os << "Import"; break;
244 case Keyword::Quote: os << "Quote"; break;
245 case Keyword::Del: os << "Del"; break;
246 }
247 break;
248
249 case NodeType::Macro:
250 {
251 os << colors[index % colors.size()] << "( " << termcolor::reset << "Macro ";
252 index++;
253 for (auto& t : N.m_list)
254 os << t << " ";
255 index--;
256 os << colors[index % colors.size()] << ")" << termcolor::reset;
257 break;
258 }
259
260 case NodeType::Spread:
261 os << "(Spread) " << N.string();
262 break;
263
264 case NodeType::Unused:
265 os << "(Unused)";
266 break;
267
268 default:
269 os << "~\\._./~";
270 break;
271 }
272 return os;
273 }
274
275 std::ostream& operator<<(std::ostream& os, const std::vector<Node>& N) noexcept
276 {
277 os << "( ";
278 for (auto& t : N)
279 os << t << " ";
280 os << ")";
281
282 return os;
283 }
284
285 bool operator==(const Node& A, const Node& B)
286 {
287 if (A.m_type != B.m_type) // should have the same types
288 return false;
289
290 if (A.m_type != NodeType::List &&
292 return A.m_value == B.m_value;
293
294 if (A.m_type == NodeType::List)
295 throw TypeError("Can not compare lists");
296
297 // any other type => false (here, Closure)
298 return false;
299 }
300
301 bool operator<(const Node& A, const Node& B)
302 {
303 if (A.nodeType() != B.nodeType())
304 return (static_cast<int>(A.nodeType()) - static_cast<int>(B.nodeType())) < 0;
305
306 switch (A.nodeType())
307 {
308 case NodeType::Number:
309 case NodeType::Symbol:
310 case NodeType::String:
311 return A.m_value < B.m_value;
312
313 case NodeType::List:
314 return A.m_list < B.m_list;
315
316 default:
317 return false;
318 }
319 }
320
321 bool operator!(const Node& A)
322 {
323 switch (A.nodeType())
324 {
325 case NodeType::List:
326 return A.constList().empty();
327
328 case NodeType::Number:
329 return !A.number();
330
333 case NodeType::String:
334 return A.string().size() == 0;
335
336 case NodeType::Symbol:
337 if (A.string() == "true")
338 return false;
339 else if (A.string() == "false" || A.string() == "nil")
340 return true;
341 return false;
342
343 default:
344 return false;
345 }
346 }
347}
ArkScript homemade exceptions.
AST node used by the parser, optimizer and compiler.
A type error triggered when types don't match.
Definition: Exceptions.hpp:29
A node of an Abstract Syntax Tree for ArkScript.
Definition: Node.hpp:29
NodeType nodeType() const noexcept
Return the node type.
Definition: Node.cpp:126
Node & operator=(Node other) noexcept
Construct a new Node object.
Definition: Node.cpp:72
static const Node & getListNode()
Provide a statically initialized / correct and guaranteed to be initialized Node representing "Empty ...
Definition: Node.cpp:28
void setNodeType(NodeType type) noexcept
Set the Node Type object.
Definition: Node.cpp:131
const std::string & filename() const noexcept
Return the filename in which this node was created.
Definition: Node.cpp:174
const std::string & string() const noexcept
Return the string held by the value (if the node type allows it)
Definition: Node.cpp:92
void setPos(std::size_t line, std::size_t col) noexcept
Set the Position of the node in the text.
Definition: Node.cpp:153
const std::vector< Node > & constList() const noexcept
Return the list of sub-nodes held by the node.
Definition: Node.cpp:119
std::vector< Node > m_list
Definition: Node.hpp:242
void setKeyword(Keyword kw) noexcept
Set the Keyword object.
Definition: Node.cpp:146
Keyword keyword() const noexcept
Return the keyword held by the value (if the node type allows it)
Definition: Node.cpp:102
NodeType m_type
Definition: Node.hpp:240
std::string m_filename
Definition: Node.hpp:245
void setFilename(const std::string &filename) noexcept
Set the original Filename where the node was.
Definition: Node.cpp:159
std::size_t m_line
Definition: Node.hpp:244
void setNumber(double value) noexcept
Set the Number object.
Definition: Node.cpp:141
static const Node & getNilNode()
Provide a statically initialized / correct and guaranteed to be initialized Node representing "Nil".
Definition: Node.cpp:22
std::size_t col() const noexcept
Get the column at which this node was created.
Definition: Node.cpp:169
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:109
void setString(const std::string &value) noexcept
Set the String object.
Definition: Node.cpp:136
static const Node & getTrueNode()
Provide a statically initialized / correct and guaranteed to be initialized Node representing "true".
Definition: Node.cpp:10
double number() const noexcept
Return the number held by the value (if the node type allows it)
Definition: Node.cpp:97
static const Node & getFalseNode()
Provide a statically initialized / correct and guaranteed to be initialized Node representing "false"...
Definition: Node.cpp:16
std::size_t line() const noexcept
Get the line at which this node was created.
Definition: Node.cpp:164
std::size_t m_col
Definition: Node.hpp:244
friend void swap(Node &lhs, Node &rhs) noexcept
Definition: Node.cpp:188
std::vector< Node > & list() noexcept
Return the list of sub-nodes held by the node.
Definition: Node.cpp:114
std::ostream & operator<<(std::ostream &os, const std::vector< Node > &N) noexcept
Definition: Node.cpp:275
bool operator!(const Node &A)
Definition: Node.cpp:321
void swap(Node &lhs, Node &rhs) noexcept
Definition: Node.cpp:188
NodeType
The different node types available.
Definition: Common.hpp:29
auto colors
Definition: Node.cpp:181
Keyword
The different keywords available.
Definition: Common.hpp:59
bool operator<(const Closure &A, const Closure &B) noexcept
Definition: Closure.hpp:112
bool operator==(const Closure &A, const Closure &B) noexcept
Definition: Closure.hpp:107