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