aboutsummaryrefslogtreecommitdiff
blob: c0d701d721280c411794a9cecb10d26097b13dd7 (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef EXPRESSION_H
#define EXPRESSION_H
/*
 * sparse/expression.h
 *
 * Copyright (C) 2003 Linus Torvalds, all rights reserved
 *
 * Declarations and helper functions for expression parsing.
 */

struct expression_list;

enum expression_type {
	EXPR_CONSTANT,
	EXPR_VALUE,
	EXPR_STRING,
	EXPR_SYMBOL,
	EXPR_BINOP,
	EXPR_ASSIGNMENT,
	EXPR_DEREF,
	EXPR_PREOP,
	EXPR_POSTOP,
	EXPR_CAST,
	EXPR_SIZEOF,
	EXPR_CONDITIONAL,
	EXPR_STATEMENT,
	EXPR_CALL,
	EXPR_COMMA,
	EXPR_COMPARE,
	EXPR_BITFIELD,
	EXPR_INITIALIZER,	// initializer list
	EXPR_IDENTIFIER,	// identifier in initializer
	EXPR_INDEX,		// index in initializer
};

struct expression {
	enum expression_type type;
	int op;
	struct position pos;
	struct symbol *ctype;
	union {
		// EXPR_CONSTANT
		struct token *token;

		// EXPR_VALUE
		unsigned long long value;

		// EXPR_STRING
		struct string *string;

		// EXPR_UNOP, EXPR_PREOP and EXPR_POSTOP
		struct expression *unop;

		// EXPR_SYMBOL
		struct symbol_arg {
			struct symbol *symbol;
			struct ident *symbol_name;
		};

		// EXPR_STATEMENT
		struct statement *statement;

		// EXPR_BINOP, EXPR_COMMA, EXPR_COMPARE and EXPR_ASSIGNMENT
		struct binop_arg {
			struct expression *left, *right;
		};
		// EXPR_DEREF
		struct deref_arg {
			struct expression *deref;
			struct ident *member;
		};
		// EXPR_CAST and EXPR_SIZEOF
		struct cast_arg {
			struct symbol *cast_type;
			struct expression *cast_expression;
		};
		// EXPR_CONDITIONAL
		struct conditional_expr {
			struct expression *conditional, *cond_true, *cond_false;
		};
		// EXPR_CALL
		struct call_expr {
			struct expression *fn;
			struct expression_list *args;
		};
		// EXPR_BITFIELD
		struct bitfield_expr {
			unsigned char bitpos, nrbits;
			struct expression *address;
		};
		// EXPR_INITIALIZER
		struct expression_list *expr_list;
		// EXPR_IDENTIFIER
		struct ident *expr_ident;
		// EXPR_INDEX
		struct index_expr {
			unsigned int idx_from, idx_to;
		};
	};
};

/* Constant expression values */
long long get_expression_value(struct expression *);

/* Expression parsing */
struct token *parse_expression(struct token *token, struct expression **tree);
struct token *conditional_expression(struct token *token, struct expression **tree);
struct token *primary_expression(struct token *token, struct expression **tree);
struct token *parens_expression(struct token *token, struct expression **expr, const char *where);
struct token *assignment_expression(struct token *token, struct expression **tree);

extern int evaluate_expression(struct expression *);

static inline struct expression *alloc_expression(struct position pos, int type)
{
	struct expression *expr = __alloc_expression(0);
	expr->type = type;
	expr->pos = pos;
	return expr;
}

/* Type name parsing */
struct token *typename(struct token *, struct symbol **);

static inline int lookup_type(struct token *token)
{
	if (token->pos.type == TOKEN_IDENT)
		return lookup_symbol(token->ident, NS_TYPEDEF) != NULL;
	return 0;
}

/* Statement parsing */
struct statement *alloc_statement(struct token * token, int type);
struct token *initializer(struct expression **tree, struct token *token);
struct token *compound_statement(struct token *, struct statement *);

/* The preprocessor calls this 'constant_expression()' */
#define constant_expression(token,tree) conditional_expression(token, tree)

#endif