tan  0.0.1
expr.h
1 #ifndef __TAN_SRC_AST_EXPR_H__
2 #define __TAN_SRC_AST_EXPR_H__
3 #include <utility>
4 #include "base.h"
5 #include "ast_base.h"
6 #include "ast_named.h"
7 #include "typed.h"
8 #include "fwd.h"
9 
10 namespace tanlang {
11 
12 class Expr : public ASTBase, public Typed {
13 protected:
14  Expr(ASTNodeType type, TokenizedSourceFile *src, int bp);
15 
16 public:
17  virtual bool is_comptime_known() { return false; }
18  virtual bool is_lvalue() { return _is_lvalue; }
19  virtual void set_lvalue(bool is_lvalue) { _is_lvalue = is_lvalue; }
20  [[nodiscard]] vector<ASTBase *> get_children() const override;
21 
22  bool is_expr() const override { return true; }
23  bool is_stmt() const override { return false; }
24 
25 protected:
26  bool _is_lvalue = false;
27 };
28 
29 class Literal : public Expr {
30 protected:
31  Literal(ASTNodeType type, TokenizedSourceFile *src, int bp);
32 
33 public:
34  static IntegerLiteral *CreateIntegerLiteral(TokenizedSourceFile *src, uint64_t val, size_t bit_size,
35  bool is_unsigned);
36  static BoolLiteral *CreateBoolLiteral(TokenizedSourceFile *src, bool val);
37  static FloatLiteral *CreateFloatLiteral(TokenizedSourceFile *src, double val, size_t bit_size);
38  static StringLiteral *CreateStringLiteral(TokenizedSourceFile *src, str val);
39  static CharLiteral *CreateCharLiteral(TokenizedSourceFile *src, uint8_t val);
40  static ArrayLiteral *CreateArrayLiteral(TokenizedSourceFile *src, Type *element_type,
41  vector<Literal *> elements = {});
42  static NullPointerLiteral *CreateNullPointerLiteral(TokenizedSourceFile *src, Type *element_type);
43 
44 public:
45  bool is_comptime_known() override { return true; }
46 };
47 
48 class BoolLiteral : public Literal {
49 protected:
50  explicit BoolLiteral(TokenizedSourceFile *src);
51 
52 public:
53  static BoolLiteral *Create(TokenizedSourceFile *src, bool val);
54  [[nodiscard]] bool get_value() const;
55 
56 private:
57  bool _value = false;
58 };
59 
60 class IntegerLiteral : public Literal {
61 protected:
62  explicit IntegerLiteral(TokenizedSourceFile *src);
63 
64 public:
65  static IntegerLiteral *Create(TokenizedSourceFile *src, uint64_t val, bool is_unsigned = false);
66 
67  [[nodiscard]] uint64_t get_value() const { return _value; }
68  [[nodiscard]] bool is_unsigned() const { return _is_unsigned; }
69 
70 private:
71  uint64_t _value = 0;
72  bool _is_unsigned = false;
73 };
74 
75 class FloatLiteral : public Literal {
76 protected:
77  explicit FloatLiteral(TokenizedSourceFile *src);
78 
79 public:
80  static FloatLiteral *Create(TokenizedSourceFile *src, double val);
81  [[nodiscard]] double get_value() const;
82  void set_value(double value);
83 
84 private:
85  double _value = 0;
86 };
87 
88 class StringLiteral : public Literal {
89 protected:
90  explicit StringLiteral(TokenizedSourceFile *src);
91 
92 public:
93  static StringLiteral *Create(TokenizedSourceFile *src, const str &val);
94 
95  [[nodiscard]] str get_value() const;
96  void set_value(str val) { _value = std::move(val); }
97 
98 private:
99  str _value;
100 };
101 
102 class CharLiteral : public Literal {
103 protected:
104  explicit CharLiteral(TokenizedSourceFile *src);
105 
106 public:
107  static CharLiteral *Create(TokenizedSourceFile *src, uint8_t val);
108 
109  void set_value(uint8_t val);
110  [[nodiscard]] uint8_t get_value() const;
111 
112 private:
113  uint8_t _value = 0;
114 };
115 
116 class ArrayLiteral : public Literal {
117 protected:
118  explicit ArrayLiteral(TokenizedSourceFile *src);
119 
120 public:
121  static ArrayLiteral *Create(TokenizedSourceFile *src, vector<Literal *> val);
122  static ArrayLiteral *Create(TokenizedSourceFile *src);
123 
124  void set_elements(const vector<Literal *> &elements);
125  [[nodiscard]] vector<Literal *> get_elements() const;
126 
127 private:
128  vector<Literal *> _elements{};
129 };
130 
131 class NullPointerLiteral : public Literal {
132 protected:
134 
135 public:
136  static NullPointerLiteral *Create(TokenizedSourceFile *src);
137 };
138 
139 class VarRef : public Expr, public ASTNamed {
140 protected:
141  explicit VarRef(TokenizedSourceFile *src);
142 
143 public:
144  static VarRef *Create(TokenizedSourceFile *src, const str &name, Decl *referred);
145  [[nodiscard]] Decl *get_referred() const;
146 
147  [[nodiscard]] Type *get_type() const override;
148  void set_type(Type *) override;
149 
150 private:
151  Decl *_referred = nullptr;
152 };
153 
154 enum class IdentifierType {
155  INVALID,
156  ID_VAR_REF,
157  ID_TYPE_REF,
158 };
159 
160 class Identifier : public Expr, public ASTNamed {
161 protected:
162  explicit Identifier(TokenizedSourceFile *src);
163 
164 public:
165  static Identifier *Create(TokenizedSourceFile *src, const str &name);
166 
167  [[nodiscard]] IdentifierType get_id_type() const;
168  void set_var_ref(VarRef *var_ref);
169  void set_type_ref(Type *type_ref);
170  [[nodiscard]] VarRef *get_var_ref() const;
171  bool is_lvalue() override;
172  void set_lvalue(bool is_lvalue) override;
173 
174 private:
175  IdentifierType _id_type = IdentifierType::INVALID;
176  VarRef *_var_ref = nullptr;
177 };
178 
179 /// make sure to sync this with BinaryOperator::BOPPrecedence
180 enum class BinaryOpKind {
181  SUM, /// +
182  SUBTRACT, /// -
183  MULTIPLY, /// *
184  DIVIDE, /// /
185  MOD, /// %
186  BAND, /// binary and
187  LAND, /// logical and
188  BOR, /// binary or
189  LOR, /// logical or
190  GT, /// >
191  GE, /// >=
192  LT, /// <
193  LE, /// <=
194  EQ, /// ==
195  NE, /// !=
196  XOR, /// ^
197  MEMBER_ACCESS, /// . or []
198 };
199 
200 class BinaryOperator : public Expr {
201 protected:
202  BinaryOperator(BinaryOpKind op, TokenizedSourceFile *src);
203 
204 public:
205  static BinaryOperator *Create(BinaryOpKind op, TokenizedSourceFile *src);
206  static BinaryOperator *Create(BinaryOpKind op, TokenizedSourceFile *src, Expr *lhs, Expr *rhs);
207 
208  /// binary operator precedence
209  static umap<BinaryOpKind, int> BOPPrecedence;
210 
211  void set_lhs(Expr *lhs);
212  void set_rhs(Expr *rhs);
213  [[nodiscard]] Expr *get_lhs() const;
214  [[nodiscard]] Expr *get_rhs() const;
215  [[nodiscard]] BinaryOpKind get_op() const;
216  [[nodiscard]] vector<ASTBase *> get_children() const override;
217 
218 protected:
219  BinaryOpKind _op;
220  Expr *_lhs = nullptr;
221  Expr *_rhs = nullptr;
222 };
223 
224 class MemberAccess : public BinaryOperator {
225 protected:
226  explicit MemberAccess(TokenizedSourceFile *src);
227 
228 public:
230  bool is_lvalue() override;
231  void set_lvalue(bool is_lvalue) override;
232 
233 public:
234  enum {
235  MemberAccessInvalid = 0,
236  MemberAccessBracket,
237  MemberAccessMemberVariable,
238  MemberAccessMemberFunction,
239  } _access_type = MemberAccessInvalid;
240  int _access_idx = -1; /// struct member variable index
241 };
242 
243 /// make sure to sync this with UnaryOperator::UOPPrecedence
244 enum class UnaryOpKind {
245  INVALID, ///
246  BNOT, /// bitwise not
247  LNOT, /// logical not
248  PLUS, /// +
249  MINUS, /// -
250  ADDRESS_OF, /// var v: int; &v
251  PTR_DEREF, /// poitner dereference
252 };
253 
254 class UnaryOperator : public Expr {
255 protected:
256  UnaryOperator(UnaryOpKind op, TokenizedSourceFile *src);
257 
258 public:
259  static UnaryOperator *Create(UnaryOpKind op, TokenizedSourceFile *src);
260  static UnaryOperator *Create(UnaryOpKind op, TokenizedSourceFile *src, Expr *rhs);
261 
262  /// binary operator precedence
263  static umap<UnaryOpKind, int> UOPPrecedence;
264 
265  [[nodiscard]] UnaryOpKind get_op() const;
266  [[nodiscard]] Expr *get_rhs() const;
267  void set_rhs(Expr *rhs);
268 
269  [[nodiscard]] vector<ASTBase *> get_children() const override;
270 
271 protected:
272  UnaryOpKind _op = UnaryOpKind::INVALID;
273  Expr *_rhs = nullptr;
274 };
275 
276 /**
277  * \note Once BinaryOrUnary::set_bop() or BinaryOrUnary::set_uop() is called,
278  * the object is not allowed to change anymore
279  */
280 class BinaryOrUnary : public Expr {
281 protected:
282  BinaryOrUnary(TokenizedSourceFile *src, int bp);
283 
284 public:
285  static BinaryOrUnary *Create(TokenizedSourceFile *src, int bp);
286 
287  enum BinaryOrUnaryKind {
288  UNKNOWN,
289  BINARY,
290  UNARY,
291  };
292 
293  void set_bop(BinaryOperator *bop);
294  void set_uop(UnaryOperator *uop);
295 
296  [[nodiscard]] Expr *get_expr_ptr() const;
297  [[nodiscard]] ASTBase *get() const override;
298  [[nodiscard]] Type *get_type() const override;
299  void set_type(Type *type) override;
300 
301  [[nodiscard]] vector<ASTBase *> get_children() const override;
302 
303  bool is_lvalue() override;
304  void set_lvalue(bool is_lvalue) override;
305 
306 private:
307  BinaryOrUnaryKind _kind = UNKNOWN;
308  union {
309  BinaryOperator *_bop = nullptr;
310  UnaryOperator *_uop;
311  };
312 };
313 
314 class Parenthesis : public Expr {
315 protected:
316  explicit Parenthesis(TokenizedSourceFile *src);
317 
318 public:
319  static Parenthesis *Create(TokenizedSourceFile *src);
320 
321  void set_sub(Expr *sub);
322  [[nodiscard]] Expr *get_sub() const;
323  [[nodiscard]] vector<ASTBase *> get_children() const override;
324 
325  bool is_lvalue() override;
326  void set_lvalue(bool is_lvalue) override;
327 
328 private:
329  Expr *_sub = nullptr;
330 };
331 
332 class FunctionCall : public Expr, public ASTNamed {
333 protected:
334  explicit FunctionCall(TokenizedSourceFile *src);
335 
336 public:
338  [[nodiscard]] size_t get_n_args() const;
339  [[nodiscard]] Expr *get_arg(size_t i) const;
340 
341  [[nodiscard]] vector<ASTBase *> get_children() const override;
342 
343 public:
344  vector<Expr *> _args{};
345  FunctionDecl *_callee = nullptr;
346 };
347 
348 class Assignment : public Expr {
349 protected:
350  explicit Assignment(TokenizedSourceFile *src);
351 
352 public:
353  static Assignment *Create(TokenizedSourceFile *src);
354 
355  [[nodiscard]] ASTBase *get_lhs() const;
356  void set_lhs(ASTBase *lhs);
357  [[nodiscard]] Expr *get_rhs() const;
358  void set_rhs(Expr *rhs);
359 
360  [[nodiscard]] vector<ASTBase *> get_children() const override;
361 
362 protected:
363  ASTBase *_lhs = nullptr; /// lhs can be decl or expr (identifier)
364  Expr *_rhs = nullptr;
365 };
366 
367 class Cast : public Expr {
368 protected:
369  explicit Cast(TokenizedSourceFile *src);
370 
371 public:
372  static Cast *Create(TokenizedSourceFile *src);
373  [[nodiscard]] Expr *get_lhs() const;
374  void set_lhs(Expr *lhs);
375 
376  [[nodiscard]] vector<ASTBase *> get_children() const override;
377 
378  bool is_lvalue() override;
379  void set_lvalue(bool is_lvalue) override;
380  bool is_comptime_known() override;
381 
382 protected:
383  Expr *_lhs = nullptr;
384 };
385 
386 } // namespace tanlang
387 
388 #endif //__TAN_SRC_AST_EXPR_H__
All named AST nodes should inherit this class.
Definition: ast_named.h:10
Expr * _rhs
lhs can be decl or expr (identifier)
Definition: expr.h:364
vector< ASTBase * > get_children() const override
Get a ordered list of child nodes.
Definition: expr.cpp:285
Expr * get_rhs() const
Definition: expr.cpp:272
BinaryOperator(BinaryOpKind op, TokenizedSourceFile *src)
Definition: expr.cpp:145
vector< ASTBase * > get_children() const override
Get a ordered list of child nodes.
Definition: expr.cpp:189
static umap< BinaryOpKind, int > BOPPrecedence
binary operator precedence
Definition: expr.h:209
ASTBase * get() const override
Get the "actual" this. Used for implementing proxy classes.
Definition: expr.cpp:332
vector< ASTBase * > get_children() const override
Get a ordered list of child nodes.
Definition: expr.cpp:338
vector< ASTBase * > get_children() const override
Get a ordered list of child nodes.
Definition: expr.cpp:301
Expr * get_lhs() const
Definition: expr.cpp:289
vector< ASTBase * > get_children() const override
Get a ordered list of child nodes.
Definition: expr.cpp:11
vector< ASTBase * > get_children() const override
Get a ordered list of child nodes.
Definition: expr.cpp:264
static FunctionCall * Create(TokenizedSourceFile *src)
Definition: expr.cpp:253
Literal(ASTNodeType type, TokenizedSourceFile *src, int bp)
Definition: expr.cpp:15
static MemberAccess * Create(TokenizedSourceFile *src)
Definition: expr.cpp:240
static Parenthesis * Create(TokenizedSourceFile *src)
Definition: expr.cpp:223
vector< ASTBase * > get_children() const override
Get a ordered list of child nodes.
Definition: expr.cpp:232
Different from SourceFile, TokenizedSourceFile manages the tokenized text of a source file.
Type is immutable once created. The exception is StructType. Its information is updated in multiple s...
Definition: type.h:22
All typed AST nodes should inherit this class.
Definition: typed.h:11
static umap< UnaryOpKind, int > UOPPrecedence
binary operator precedence
Definition: expr.h:263
vector< ASTBase * > get_children() const override
Get a ordered list of child nodes.
Definition: expr.cpp:219
static VarRef * Create(TokenizedSourceFile *src, const str &name, Decl *referred)
Definition: expr.cpp:90