OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4AulAST.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 // C4Aul abstract syntax tree nodes
17 
18 #ifndef INC_C4AulAST
19 #define INC_C4AulAST
20 
21 #include "script/C4Value.h"
22 
23 namespace aul { namespace ast {
24  class Noop;
25  class StringLit;
26  class IntLit;
27  class BoolLit;
28  class ArrayLit;
29  class ProplistLit;
30  class NilLit;
31  class ThisLit;
32  class VarExpr;
33  class UnOpExpr;
34  class BinOpExpr;
35  class AssignmentExpr;
36  class SubscriptExpr;
37  class SliceExpr;
38  class CallExpr;
39  class ParExpr;
40  class FunctionExpr;
41  class Block;
42  class Return;
43  class ForLoop;
44  class RangeLoop;
45  class DoLoop;
46  class WhileLoop;
47  class Break;
48  class Continue;
49  class If;
50  class VarDecl;
51  class FunctionDecl;
52  class IncludePragma;
53  class AppendtoPragma;
54  class Script;
55 }}
56 
57 namespace aul {
59 {
60 public:
61  virtual ~AstVisitor() = default;
62 
63  virtual void visit(const ::aul::ast::Noop *) {}
64  virtual void visit(const ::aul::ast::StringLit *) {}
65  virtual void visit(const ::aul::ast::IntLit *) {}
66  virtual void visit(const ::aul::ast::BoolLit *) {}
67  virtual void visit(const ::aul::ast::ArrayLit *) {}
68  virtual void visit(const ::aul::ast::ProplistLit *) {}
69  virtual void visit(const ::aul::ast::NilLit *) {}
70  virtual void visit(const ::aul::ast::ThisLit *) {}
71  virtual void visit(const ::aul::ast::VarExpr *n) {}
72  virtual void visit(const ::aul::ast::UnOpExpr *) {}
73  virtual void visit(const ::aul::ast::BinOpExpr *) {}
74  virtual void visit(const ::aul::ast::AssignmentExpr *) {}
75  virtual void visit(const ::aul::ast::SubscriptExpr *) {}
76  virtual void visit(const ::aul::ast::SliceExpr *) {}
77  virtual void visit(const ::aul::ast::CallExpr *) {}
78  virtual void visit(const ::aul::ast::ParExpr *) {}
79  virtual void visit(const ::aul::ast::Block *) {}
80  virtual void visit(const ::aul::ast::Return *) {}
81  virtual void visit(const ::aul::ast::ForLoop *) {}
82  virtual void visit(const ::aul::ast::RangeLoop *) {}
83  virtual void visit(const ::aul::ast::DoLoop *) {}
84  virtual void visit(const ::aul::ast::WhileLoop *) {}
85  virtual void visit(const ::aul::ast::Break *) {}
86  virtual void visit(const ::aul::ast::Continue *) {}
87  virtual void visit(const ::aul::ast::If *) {}
88  virtual void visit(const ::aul::ast::VarDecl *) {}
89  virtual void visit(const ::aul::ast::FunctionDecl *) {}
90  virtual void visit(const ::aul::ast::FunctionExpr *) {}
91  virtual void visit(const ::aul::ast::IncludePragma *) {}
92  virtual void visit(const ::aul::ast::AppendtoPragma *) {}
93  virtual void visit(const ::aul::ast::Script *) {}
94 
95  // This template will catch any type missing from the list above
96  // to ensure that the nodes don't accidentally get visited via a
97  // base class instead
98  template<class T>
99  void visit(const T *) = delete;
100 };
101 }
102 
103 namespace aul { namespace ast {
104 
105 #define AST_NODE(cls) \
106  public: \
107  virtual void accept(::aul::AstVisitor *v) const override { v->visit(this); } \
108  template<class... T> static std::unique_ptr<cls> New(const char *loc, T &&...t) { auto n = std::make_unique<cls>(std::forward<T>(t)...); n->loc = loc; return n; } \
109  private:
110 
111 class Node
112 {
113 public:
114  virtual ~Node() = default;
115 
116  struct Location
117  {
118  std::string file;
119  size_t line = 0;
120  size_t column = 0;
121  };
122 
123  const char *loc = nullptr;
124 
125  virtual void accept(::aul::AstVisitor *) const = 0;
126 };
127 
128 class Stmt : public Node
129 {
130 public:
131  // Does executing this statement generate a return value?
132  virtual bool has_value() const { return false; }
133 };
134 
135 typedef std::unique_ptr<Stmt> StmtPtr;
136 
137 class Noop : public Stmt
138 {
139  AST_NODE(Noop);
140 };
141 
142 class Expr : public Stmt
143 {
144 public:
145  bool has_value() const override { return true; }
146 };
147 typedef std::unique_ptr<Expr> ExprPtr;
148 
149 class Literal : public Expr
150 {};
151 
152 class StringLit : public Literal
153 {
154  AST_NODE(StringLit);
155 public:
156  explicit StringLit(const std::string &value) : value(value) {}
157  std::string value;
158 };
159 
160 class IntLit : public Literal
161 {
162  AST_NODE(IntLit);
163 public:
164  explicit IntLit(int32_t value) : value(value) {}
165  uint32_t value;
166 };
167 
168 class BoolLit : public Literal
169 {
170  AST_NODE(BoolLit);
171 public:
172  explicit BoolLit(bool value) : value(value) {}
173  bool value;
174 };
175 
176 class ArrayLit : public Literal
177 {
178  AST_NODE(ArrayLit);
179 public:
180  std::vector<ExprPtr> values;
181 };
182 
183 class ProplistLit : public Literal
184 {
185  AST_NODE(ProplistLit);
186 public:
187  std::vector<std::pair<std::string, ExprPtr>> values;
188 };
189 
190 class NilLit : public Literal
191 {
192  AST_NODE(NilLit);
193 };
194 
195 class ThisLit : public Literal
196 {
197  AST_NODE(ThisLit);
198 };
199 
200 class VarExpr : public Expr
201 {
202  AST_NODE(VarExpr);
203 public:
204  explicit VarExpr(const std::string &identifier) : identifier(identifier) {}
205  std::string identifier;
206 };
207 
208 class UnOpExpr : public Expr
209 {
210  AST_NODE(UnOpExpr);
211 public:
212  UnOpExpr(int op, ExprPtr &&operand) : op(op), operand(std::move(operand)) {}
213  ExprPtr operand;
214  int op; // TODO: Make this a proper operator type
215 };
216 
217 class BinOpExpr : public Expr
218 {
219  AST_NODE(BinOpExpr);
220 public:
221  BinOpExpr(int op, ExprPtr &&lhs, ExprPtr &&rhs) : op(op), lhs(std::move(lhs)), rhs(std::move(rhs)) {}
222  ExprPtr lhs, rhs;
223  int op; // TODO: Make this a proper operator type
224 };
225 
226 class AssignmentExpr : public Expr
227 {
228  AST_NODE(AssignmentExpr);
229 public:
230  AssignmentExpr(ExprPtr &&lhs, ExprPtr &&rhs) : lhs(std::move(lhs)), rhs(std::move(rhs)) {}
231  ExprPtr lhs, rhs;
232 };
233 
234 class SubscriptExpr : public Expr
235 {
236  AST_NODE(SubscriptExpr);
237 public:
238  SubscriptExpr(ExprPtr &&object, ExprPtr &&index) : object(std::move(object)), index(std::move(index)) {}
239  ExprPtr object, index;
240 };
241 
242 class SliceExpr : public Expr
243 {
244  AST_NODE(SliceExpr);
245 public:
246  SliceExpr(ExprPtr &&object, ExprPtr &&start, ExprPtr &&end) : object(std::move(object)), start(std::move(start)), end(std::move(end)) {}
247  ExprPtr object, start, end;
248 };
249 
250 class CallExpr : public Expr
251 {
252  AST_NODE(CallExpr);
253 public:
254  bool safe_call = false; // Will this call fail gracefully when the function doesn't exist?
255  bool append_unnamed_pars = false; // Will this call append all unnamed parameters of the current function?
256  ExprPtr context;
257  std::vector<ExprPtr> args;
258  std::string callee;
259 };
260 
261 class ParExpr : public Expr
262 {
263  AST_NODE(ParExpr);
264 public:
265  explicit ParExpr(ExprPtr &&arg) : arg(std::move(arg)) {}
266  ExprPtr arg;
267 };
268 
269 class Block : public Stmt
270 {
271  AST_NODE(Block);
272 public:
273  std::vector<StmtPtr> children;
274 };
275 
276 class ControlFlow : public Stmt
277 {};
278 
279 class Return : public ControlFlow
280 {
281  AST_NODE(Return);
282 public:
283  explicit Return(ExprPtr &&value) : value(std::move(value)) {}
284  ExprPtr value;
285 };
286 
287 class Loop : public ControlFlow
288 {
289 public:
290  ExprPtr cond;
291  StmtPtr body;
292 };
293 typedef std::unique_ptr<Loop> LoopPtr;
294 
295 class ForLoop : public Loop
296 {
297  AST_NODE(ForLoop);
298 public:
299  StmtPtr init;
300  ExprPtr incr;
301 };
302 
303 class RangeLoop : public Loop
304 {
305  AST_NODE(RangeLoop);
306 public:
307  std::string var;
308  bool scoped_var = false;
309 };
310 
311 class DoLoop : public Loop
312 {
313  AST_NODE(DoLoop);
314 };
315 
316 class WhileLoop : public Loop
317 {
318  AST_NODE(WhileLoop);
319 };
320 
321 class LoopControl : public ControlFlow
322 {};
323 
324 class Break : public LoopControl
325 {
326  AST_NODE(Break);
327 };
328 
329 class Continue : public LoopControl
330 {
331  AST_NODE(Continue);
332 };
333 
334 class If : public ControlFlow
335 {
336  AST_NODE(If);
337 public:
338  ExprPtr cond;
339  StmtPtr iftrue, iffalse;
340 };
341 
342 class Decl : public Stmt
343 {};
344 typedef std::unique_ptr<Decl> DeclPtr;
345 
346 class VarDecl : public Decl
347 {
348  AST_NODE(VarDecl);
349 public:
350  enum class Scope
351  {
352  Func,
353  Object,
354  Global
355  };
356 
358  bool constant;
359 
360  struct Var
361  {
362  std::string name;
363  ExprPtr init;
364  };
365  std::vector<Var> decls;
366 };
367 
368 class Function
369 {
370 public:
371  struct Parameter
372  {
373  std::string name;
375  explicit Parameter(const std::string &name, C4V_Type type = C4V_Any) : name(name), type(type) {}
376  };
377  std::vector<Parameter> params;
378  bool has_unnamed_params = false;
379  std::unique_ptr<Block> body;
380 
381  virtual ~Function() = default;
382  virtual void accept(::aul::AstVisitor *v) const = 0;
383 };
384 
385 class FunctionDecl : public Decl, public Function
386 {
387  AST_NODE(FunctionDecl);
388 public:
389  explicit FunctionDecl(const std::string &name) : name(name) {}
390  std::string name;
391  bool is_global = false;
392 };
393 
394 class FunctionExpr : public Expr, public Function
395 {
396  // This node is used for constant proplists
397  AST_NODE(FunctionExpr);
398 public:
399 };
400 
401 class Pragma : public Decl
402 {};
403 
404 class IncludePragma : public Pragma
405 {
406  AST_NODE(IncludePragma);
407 public:
408  explicit IncludePragma(const std::string &what) : what(what) {}
409  std::string what;
410 };
411 
412 class AppendtoPragma : public Pragma
413 {
414  AST_NODE(AppendtoPragma);
415 public:
416  AppendtoPragma() = default;
417  explicit AppendtoPragma(const std::string &what) : what(what) {}
418  std::string what;
419 };
420 
421 class Script : public Node
422 {
423  AST_NODE(Script);
424 public:
425  std::vector<DeclPtr> declarations;
426 };
427 
428 #undef AST_NODE
429 
430 }}
431 
432 namespace aul {
433 // A recursive visitor that visits the children of all nodes. Override the visit() functions you're interested in in child classes.
435 {
436 public:
437  ~DefaultRecursiveVisitor() override = default;
438 
439  using AstVisitor::visit;
440 
441  void visit(const ::aul::ast::ArrayLit *n) override
442  {
443  for (const auto &c : n->values)
444  c->accept(this);
445  }
446  void visit(const ::aul::ast::ProplistLit *n) override
447  {
448  for (const auto &c : n->values)
449  c.second->accept(this);
450  }
451  void visit(const ::aul::ast::UnOpExpr *n) override
452  {
453  n->operand->accept(this);
454  }
455  void visit(const ::aul::ast::BinOpExpr *n) override
456  {
457  n->lhs->accept(this);
458  n->rhs->accept(this);
459  }
460  void visit(const ::aul::ast::AssignmentExpr *n) override
461  {
462  n->lhs->accept(this);
463  n->rhs->accept(this);
464  }
465  void visit(const ::aul::ast::SubscriptExpr *n) override
466  {
467  n->object->accept(this);
468  n->index->accept(this);
469  }
470  void visit(const ::aul::ast::SliceExpr *n) override
471  {
472  n->object->accept(this);
473  n->start->accept(this);
474  n->end->accept(this);
475  }
476  void visit(const ::aul::ast::CallExpr *n) override
477  {
478  if (n->context)
479  n->context->accept(this);
480  for (const auto &a : n->args)
481  a->accept(this);
482  }
483  void visit(const ::aul::ast::ParExpr *n) override
484  {
485  n->arg->accept(this);
486  }
487  void visit(const ::aul::ast::Block *n) override
488  {
489  for (const auto &s : n->children)
490  s->accept(this);
491  }
492  void visit(const ::aul::ast::Return *n) override
493  {
494  n->value->accept(this);
495  }
496  void visit(const ::aul::ast::ForLoop *n) override
497  {
498  if (n->init)
499  n->init->accept(this);
500  if (n->cond)
501  n->cond->accept(this);
502  if (n->incr)
503  n->incr->accept(this);
504  n->body->accept(this);
505  }
506  void visit(const ::aul::ast::RangeLoop *n) override
507  {
508  n->cond->accept(this);
509  n->body->accept(this);
510  }
511  void visit(const ::aul::ast::DoLoop *n) override
512  {
513  n->body->accept(this);
514  n->cond->accept(this);
515  }
516  void visit(const ::aul::ast::WhileLoop *n) override
517  {
518  n->cond->accept(this);
519  n->body->accept(this);
520  }
521  void visit(const ::aul::ast::If *n) override
522  {
523  n->cond->accept(this);
524  n->iftrue->accept(this);
525  if (n->iffalse)
526  n->iffalse->accept(this);
527  }
528  void visit(const ::aul::ast::VarDecl *n) override
529  {
530  for (const auto &d : n->decls)
531  if (d.init)
532  d.init->accept(this);
533  }
534  void visit(const ::aul::ast::FunctionDecl *n) override
535  {
536  n->body->accept(this);
537  }
538  void visit(const ::aul::ast::FunctionExpr *n) override
539  {
540  n->body->accept(this);
541  }
542  void visit(const ::aul::ast::Script *n) override
543  {
544  for (const auto &d : n->declarations)
545  d->accept(this);
546  }
547 };
548 }
549 
550 #endif
virtual void visit(const ::aul::ast::ForLoop *)
Definition: C4AulAST.h:81
virtual void accept(::aul::AstVisitor *v) const =0
void visit(const ::aul::ast::AssignmentExpr *n) override
Definition: C4AulAST.h:460
virtual void visit(const ::aul::ast::IncludePragma *)
Definition: C4AulAST.h:91
virtual void visit(const ::aul::ast::Continue *)
Definition: C4AulAST.h:86
void visit(const ::aul::ast::CallExpr *n) override
Definition: C4AulAST.h:476
std::string var
Definition: C4AulAST.h:307
VarExpr(const std::string &identifier)
Definition: C4AulAST.h:204
void visit(const ::aul::ast::DoLoop *n) override
Definition: C4AulAST.h:511
C4V_Type
Definition: C4Value.h:23
virtual ~Function()=default
ExprPtr cond
Definition: C4AulAST.h:338
virtual void visit(const ::aul::ast::WhileLoop *)
Definition: C4AulAST.h:84
bool has_value() const override
Definition: C4AulAST.h:145
virtual void visit(const ::aul::ast::SliceExpr *)
Definition: C4AulAST.h:76
virtual void visit(const ::aul::ast::Noop *)
Definition: C4AulAST.h:63
virtual void visit(const ::aul::ast::CallExpr *)
Definition: C4AulAST.h:77
SubscriptExpr(ExprPtr &&object, ExprPtr &&index)
Definition: C4AulAST.h:238
virtual void visit(const ::aul::ast::ThisLit *)
Definition: C4AulAST.h:70
virtual ~AstVisitor()=default
void visit(const ::aul::ast::BinOpExpr *n) override
Definition: C4AulAST.h:455
void visit(const ::aul::ast::ArrayLit *n) override
Definition: C4AulAST.h:441
void visit(const ::aul::ast::UnOpExpr *n) override
Definition: C4AulAST.h:451
void visit(const ::aul::ast::FunctionDecl *n) override
Definition: C4AulAST.h:534
bool append_unnamed_pars
Definition: C4AulAST.h:255
SliceExpr(ExprPtr &&object, ExprPtr &&start, ExprPtr &&end)
Definition: C4AulAST.h:246
void visit(const ::aul::ast::SliceExpr *n) override
Definition: C4AulAST.h:470
virtual void visit(const ::aul::ast::BinOpExpr *)
Definition: C4AulAST.h:73
std::string callee
Definition: C4AulAST.h:258
virtual void visit(const ::aul::ast::StringLit *)
Definition: C4AulAST.h:64
virtual void visit(const ::aul::ast::AssignmentExpr *)
Definition: C4AulAST.h:74
void visit(const ::aul::ast::Return *n) override
Definition: C4AulAST.h:492
std::vector< StmtPtr > children
Definition: C4AulAST.h:273
#define a
void visit(const ::aul::ast::VarDecl *n) override
Definition: C4AulAST.h:528
void visit(const ::aul::ast::ProplistLit *n) override
Definition: C4AulAST.h:446
virtual void visit(const ::aul::ast::DoLoop *)
Definition: C4AulAST.h:83
std::unique_ptr< Decl > DeclPtr
Definition: C4AulAST.h:344
std::vector< ExprPtr > args
Definition: C4AulAST.h:257
virtual void visit(const ::aul::ast::Block *)
Definition: C4AulAST.h:79
virtual void visit(const ::aul::ast::FunctionDecl *)
Definition: C4AulAST.h:89
std::vector< Parameter > params
Definition: C4AulAST.h:377
Parameter(const std::string &name, C4V_Type type=C4V_Any)
Definition: C4AulAST.h:375
virtual void visit(const ::aul::ast::BoolLit *)
Definition: C4AulAST.h:66
AppendtoPragma(const std::string &what)
Definition: C4AulAST.h:417
ExprPtr value
Definition: C4AulAST.h:284
std::unique_ptr< Block > body
Definition: C4AulAST.h:379
IncludePragma(const std::string &what)
Definition: C4AulAST.h:408
std::vector< ExprPtr > values
Definition: C4AulAST.h:180
StmtPtr iftrue
Definition: C4AulAST.h:339
std::unique_ptr< Expr > ExprPtr
Definition: C4AulAST.h:147
std::vector< DeclPtr > declarations
Definition: C4AulAST.h:425
AssignmentExpr(ExprPtr &&lhs, ExprPtr &&rhs)
Definition: C4AulAST.h:230
StmtPtr body
Definition: C4AulAST.h:291
virtual void visit(const ::aul::ast::ParExpr *)
Definition: C4AulAST.h:78
virtual void visit(const ::aul::ast::IntLit *)
Definition: C4AulAST.h:65
uint32_t value
Definition: C4AulAST.h:165
virtual void visit(const ::aul::ast::SubscriptExpr *)
Definition: C4AulAST.h:75
ExprPtr cond
Definition: C4AulAST.h:290
bool has_unnamed_params
Definition: C4AulAST.h:378
virtual void visit(const ::aul::ast::ProplistLit *)
Definition: C4AulAST.h:68
virtual void visit(const ::aul::ast::Script *)
Definition: C4AulAST.h:93
BinOpExpr(int op, ExprPtr &&lhs, ExprPtr &&rhs)
Definition: C4AulAST.h:221
virtual void visit(const ::aul::ast::Return *)
Definition: C4AulAST.h:80
StmtPtr iffalse
Definition: C4AulAST.h:339
void visit(const ::aul::ast::WhileLoop *n) override
Definition: C4AulAST.h:516
void visit(const ::aul::ast::Block *n) override
Definition: C4AulAST.h:487
~DefaultRecursiveVisitor() override=default
void visit(const ::aul::ast::Script *n) override
Definition: C4AulAST.h:542
UnOpExpr(int op, ExprPtr &&operand)
Definition: C4AulAST.h:212
std::vector< Var > decls
Definition: C4AulAST.h:365
void visit(const ::aul::ast::FunctionExpr *n) override
Definition: C4AulAST.h:538
virtual void visit(const ::aul::ast::If *)
Definition: C4AulAST.h:87
std::string value
Definition: C4AulAST.h:157
void visit(const ::aul::ast::ParExpr *n) override
Definition: C4AulAST.h:483
const char * loc
Definition: C4AulAST.h:123
FunctionDecl(const std::string &name)
Definition: C4AulAST.h:389
virtual void visit(const ::aul::ast::NilLit *)
Definition: C4AulAST.h:69
std::unique_ptr< Stmt > StmtPtr
Definition: C4AulAST.h:135
virtual void visit(const ::aul::ast::RangeLoop *)
Definition: C4AulAST.h:82
virtual void visit(const ::aul::ast::VarDecl *)
Definition: C4AulAST.h:88
BoolLit(bool value)
Definition: C4AulAST.h:172
virtual void accept(::aul::AstVisitor *) const =0
IntLit(int32_t value)
Definition: C4AulAST.h:164
std::string name
Definition: C4AulAST.h:390
std::string identifier
Definition: C4AulAST.h:205
std::string name
Definition: C4AulAST.h:362
void visit(const ::aul::ast::RangeLoop *n) override
Definition: C4AulAST.h:506
Return(ExprPtr &&value)
Definition: C4AulAST.h:283
virtual ~Node()=default
virtual void visit(const ::aul::ast::AppendtoPragma *)
Definition: C4AulAST.h:92
virtual void visit(const ::aul::ast::VarExpr *n)
Definition: C4AulAST.h:71
std::unique_ptr< Loop > LoopPtr
Definition: C4AulAST.h:293
virtual void visit(const ::aul::ast::UnOpExpr *)
Definition: C4AulAST.h:72
virtual void visit(const ::aul::ast::ArrayLit *)
Definition: C4AulAST.h:67
void visit(const ::aul::ast::SubscriptExpr *n) override
Definition: C4AulAST.h:465
virtual void visit(const ::aul::ast::Break *)
Definition: C4AulAST.h:85
#define s
std::vector< std::pair< std::string, ExprPtr > > values
Definition: C4AulAST.h:187
void visit(const ::aul::ast::If *n) override
Definition: C4AulAST.h:521
void visit(const ::aul::ast::ForLoop *n) override
Definition: C4AulAST.h:496
virtual bool has_value() const
Definition: C4AulAST.h:132
ParExpr(ExprPtr &&arg)
Definition: C4AulAST.h:265
virtual void visit(const ::aul::ast::FunctionExpr *)
Definition: C4AulAST.h:90
StringLit(const std::string &value)
Definition: C4AulAST.h:156
Definition: C4AulAST.h:23