ArkScript
A small, fast, functional and scripting language for video games
Node.cpp
Go to the documentation of this file.
2 
3 #include <termcolor/termcolor.hpp>
4 
5 #include <Ark/Exceptions.hpp>
6 
7 namespace 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 :
51  Node(value, NodeType::String)
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 
206  case NodeType::Capture:
207  os << "(Capture) " << N.string();
208  break;
209 
210  case NodeType::GetField:
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 
229  case NodeType::Closure:
230  os << "Closure";
231  break;
232 
233  case NodeType::Keyword:
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 
331  case NodeType::GetField:
332  case NodeType::Capture:
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
void swap(Node &other) noexcept
Construct a new Node object.
Definition: Node.cpp:78
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
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