aboutsummaryrefslogtreecommitdiff
path: root/expr.h
blob: a6cac6d4cdf479878b98f3d7fc81e2048f155675 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
enum expressionkind {
	/* primary expression */
	EXPRIDENT,
	EXPRCONST,
	EXPRSTRING,

	/* postfix expression */
	EXPRCALL,
	/* member E.M gets transformed to *(typeof(E.M) *)((char *)E + offsetof(typeof(E), M)) */
	EXPRINCDEC,
	EXPRCOMPOUND,
	/* subscript E1[E2] gets transformed to *((E1)+(E2)) */

	EXPRUNARY,
	EXPRCAST,
	EXPRBINARY,
	EXPRCOND,
	EXPRASSIGN,
	EXPRCOMMA,

	EXPRBUILTIN,
	EXPRTEMP,
};

enum expressionflags {
	EXPRFLAG_LVAL    = 1<<0,
	EXPRFLAG_DECAYED = 1<<1,
};

struct expression {
	enum expressionkind kind;
	enum expressionflags flags;
	struct type *type;
	struct expression *next;
	union {
		struct {
			struct declaration *decl;
		} ident;
		union {
			uint64_t i;
			double f;
		} constant;
		struct {
			char *data;
			size_t size;
		} string;
		struct {
			struct expression *func, *args;
			size_t nargs;
		} call;
		struct {
			struct initializer *init;
		} compound;
		struct {
			int op;
			_Bool post;
			struct expression *base;
		} incdec;
		struct {
			int op;
			struct expression *base;
		} unary;
		struct {
			struct expression *e;
		} cast;
		struct {
			int op;
			struct expression *l, *r;
		} binary;
		struct {
			struct expression *e, *t, *f;
		} cond;
		struct {
			struct expression *l, *r;
		} assign;
		struct {
			struct expression *exprs;
		} comma;
		struct {
			enum {
				BUILTINVASTART,
				BUILTINVAARG,
				BUILTINVAEND,
			} kind;
			struct expression *arg;
		} builtin;
		struct value *temp;
	};
};

struct scope;

struct expression *expr(struct scope *);
struct expression *assignexpr(struct scope *);
uint64_t intconstexpr(struct scope *);
void delexpr(struct expression *);

void exprpromote(struct expression **);  // XXX: move to type
struct expression *exprconvert(struct expression *, struct type *);