/
tree.h
341 lines (285 loc) · 8.87 KB
/
tree.h
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
//
// Copyright (C) 2011-2012 Nick Gasson
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef _TREE_H
#define _TREE_H
#include "lib.h"
#include "ident.h"
#include "type.h"
#include "loc.h"
#include <stdint.h>
typedef enum port_mode {
PORT_INVALID,
PORT_IN,
PORT_OUT,
PORT_INOUT,
PORT_BUFFER
} port_mode_t;
typedef enum class {
C_DEFAULT,
C_SIGNAL,
C_VARIABLE,
C_CONSTANT,
C_FILE
} class_t;
typedef enum tree_kind {
T_ENTITY,
T_ARCH,
T_PORT_DECL,
T_FCALL,
T_LITERAL,
T_SIGNAL_DECL,
T_VAR_DECL,
T_PROCESS,
T_REF,
T_WAIT,
T_TYPE_DECL,
T_VAR_ASSIGN,
T_PACKAGE,
T_SIGNAL_ASSIGN,
T_QUALIFIED,
T_ENUM_LIT,
T_CONST_DECL,
T_FUNC_DECL,
T_ELAB,
T_AGGREGATE,
T_ASSERT,
T_ATTR_REF,
T_ARRAY_REF,
T_ARRAY_SLICE,
T_INSTANCE,
T_IF,
T_NULL,
T_PACK_BODY,
T_FUNC_BODY,
T_RETURN,
T_CASSIGN,
T_WHILE,
T_WAVEFORM,
T_ALIAS,
T_FOR,
T_ATTR_DECL,
T_ATTR_SPEC,
T_PROC_DECL,
T_PROC_BODY,
T_EXIT,
T_PCALL,
T_CASE,
T_BLOCK,
T_COND,
T_CONCAT,
T_TYPE_CONV,
T_SELECT,
T_COMPONENT,
T_IF_GENERATE,
T_FOR_GENERATE,
T_FILE_DECL,
T_LAST_TREE_KIND
} tree_kind_t;
typedef struct tree *tree_t;
typedef struct literal {
union {
int64_t i;
double r;
};
enum { L_INT, L_REAL } kind;
} literal_t;
typedef struct assoc {
union {
unsigned pos;
tree_t name;
range_t range;
};
tree_t value;
enum { A_POS, A_NAMED, A_RANGE, A_OTHERS } kind;
} assoc_t;
typedef struct param {
tree_t value;
union {
range_t range; // P_RANGE
ident_t name; // P_NAME
unsigned pos; // P_POS
};
enum { P_POS, P_NAMED, P_RANGE } kind;
} param_t;
typedef struct context {
ident_t name;
loc_t loc;
} context_t;
typedef struct tree_wr_ctx *tree_wr_ctx_t;
typedef struct tree_rd_ctx *tree_rd_ctx_t;
tree_t tree_new(tree_kind_t kind);
tree_kind_t tree_kind(tree_t t);
void tree_change_kind(tree_t t, tree_kind_t kind);
const loc_t *tree_loc(tree_t t);
void tree_set_loc(tree_t t, const loc_t *loc);
// T_PORT_DECL, T_SIGNAL_DECL, T_VAR_DECL, T_REF, T_TYPE_DECL,
// T_CONST_DECL, T_FUNC_DECL, T_ALIAS, T_ATTR_DECL, T_TYPE_CONV,
// T_FILE_DECL
type_t tree_type(tree_t t);
void tree_set_type(tree_t t, type_t ty);
bool tree_has_type(tree_t t);
// T_ENTITY, T_PORT_DECL, T_FCALL, T_ARCH, T_SIGNAL_DECL, T_PROCESS,
// T_VAR_DECL, T_REF, T_TYPE_DECL, T_PACKAGE, T_QUALIFIED, T_ENUM_LIT,
// T_CONST_DECL, T_FUNC_DECL, T_ATTR_REF, T_INSTANCE, T_WHILE,
// T_ATTR_DECL, T_PCALL, T_TYPE_CONV, T_COMPONENT, T_IF_GENERATE,
// T_FOR_GENERATE, T_FILE_DECL
ident_t tree_ident(tree_t t);
void tree_set_ident(tree_t t, ident_t i);
bool tree_has_ident(tree_t t);
// T_ARCH, T_ATTR_REF, T_INSTANCE, T_FOR, T_ATTR_SPEC, T_PCALL,
// T_IF_GENERATE, T_FOR_GENERATE
ident_t tree_ident2(tree_t t);
void tree_set_ident2(tree_t t, ident_t i);
// T_ENTITY, T_FUNC_DECL, T_COMPONENT
unsigned tree_ports(tree_t t);
tree_t tree_port(tree_t t, unsigned n);
void tree_add_port(tree_t t, tree_t d);
// T_PORT_DECL
port_mode_t tree_port_mode(tree_t t);
void tree_set_port_mode(tree_t t, port_mode_t mode);
// T_FILE_DECL
tree_t tree_file_mode(tree_t t);
void tree_set_file_mode(tree_t t, tree_t m);
// T_ENTITY, T_COMPONENT
unsigned tree_generics(tree_t t);
tree_t tree_generic(tree_t t, unsigned n);
void tree_add_generic(tree_t t, tree_t d);
// T_INSTANCE
unsigned tree_genmaps(tree_t t);
param_t tree_genmap(tree_t t, unsigned n);
void tree_add_genmap(tree_t t, param_t e);
// T_FCALL, T_ARRAY_REF, T_INSTANCE, T_PCALL, T_CONCAT, T_TYPE_CONV
unsigned tree_params(tree_t t);
param_t tree_param(tree_t t, unsigned n);
void tree_add_param(tree_t t, param_t e);
// T_LITERAL
literal_t tree_literal(tree_t t);
void tree_set_literal(tree_t t, literal_t lit);
// T_PORT_DECL, T_SIGNAL_DECL, T_VAR_DECL, T_VAR_ASSIGN,
// T_QUALIFIED, T_CONST_DECL, T_ASSERT, T_ATTR_SPEC
// T_ARRAY_REF, T_IF, T_WHILE, T_REF, T_ALIAS, T_WAVEFORM
// T_COND, T_SELECT, T_IF_GENERATE, T_FILE_DECL
bool tree_has_value(tree_t t);
tree_t tree_value(tree_t t);
void tree_set_value(tree_t t, tree_t v);
// T_SIGNAL_ASSIGN, T_COND
unsigned tree_waveforms(tree_t t);
tree_t tree_waveform(tree_t t, unsigned n);
void tree_add_waveform(tree_t t, tree_t w);
// T_ARCH, T_PROCESS, T_PACKAGE, T_FUNC_BODY, T_PROC_BODY, T_BLOCK,
// T_IF_GENERATE, T_FOR_GENERATE
unsigned tree_decls(tree_t t);
tree_t tree_decl(tree_t t, unsigned n);
void tree_add_decl(tree_t t, tree_t d);
// T_ARCH, T_PROCESS, T_IF, T_WHILE, T_FOR, T_FUNC_BODY, T_BLOCK
// T_PROC_BODY, T_IF_GENERATE, T_FOR_GENERATE
unsigned tree_stmts(tree_t t);
tree_t tree_stmt(tree_t t, unsigned n);
void tree_add_stmt(tree_t t, tree_t d);
// T_IF
unsigned tree_else_stmts(tree_t t);
tree_t tree_else_stmt(tree_t t, unsigned n);
void tree_add_else_stmt(tree_t t, tree_t d);
// T_CASSIGN
unsigned tree_conds(tree_t t);
tree_t tree_cond(tree_t t, unsigned n);
void tree_add_cond(tree_t t, tree_t d);
// T_WAIT
bool tree_has_delay(tree_t t);
tree_t tree_delay(tree_t t);
void tree_set_delay(tree_t t, tree_t d);
// T_WAIT, T_PROCESS
unsigned tree_triggers(tree_t t);
tree_t tree_trigger(tree_t t, unsigned n);
void tree_add_trigger(tree_t t, tree_t s);
// T_VAR_ASSIGN, T_SIGNAL_ASSIGN, T_CASSIGN
tree_t tree_target(tree_t t);
void tree_set_target(tree_t t, tree_t lhs);
// T_REF, T_FCALL, T_INSTANCE, T_PCALL, T_TYPE_CONV
tree_t tree_ref(tree_t t);
void tree_set_ref(tree_t t, tree_t decl);
// T_ENTITY, T_ARCH, T_PACKAGE
unsigned tree_contexts(tree_t t);
context_t tree_context(tree_t t, unsigned n);
void tree_add_context(tree_t t, context_t ctx);
// T_AGGREGATE, T_CASE, T_SELECT
unsigned tree_assocs(tree_t t);
assoc_t tree_assoc(tree_t t, unsigned n);
void tree_add_assoc(tree_t t, assoc_t a);
void tree_change_assoc(tree_t t, unsigned i, assoc_t a);
// T_ASSERT
tree_t tree_severity(tree_t t);
void tree_set_severity(tree_t t, tree_t s);
// T_ASSERT
tree_t tree_message(tree_t t);
void tree_set_message(tree_t t, tree_t m);
// T_ENUM_LIT
unsigned tree_pos(tree_t t);
void tree_set_pos(tree_t t, unsigned pos);
// T_SIGNAL_DECL
unsigned tree_drivers(tree_t t);
tree_t tree_driver(tree_t t, unsigned n);
void tree_add_driver(tree_t t, tree_t d);
// T_SIGNAL_DECL
unsigned tree_sub_drivers(tree_t t, unsigned elem);
tree_t tree_sub_driver(tree_t t, unsigned elem, unsigned n);
void tree_add_sub_driver(tree_t t, unsigned elem, tree_t p);
// T_ARRAY_SLICE, T_FOR
range_t tree_range(tree_t t);
void tree_set_range(tree_t t, range_t r);
// T_PORT_DECL
class_t tree_class(tree_t t);
void tree_set_class(tree_t t, class_t c);
// T_CASSIGN, T_SIGNAL_ASSIGN
tree_t tree_reject(tree_t t);
void tree_set_reject(tree_t t, tree_t r);
uint32_t tree_index(tree_t t);
void tree_add_attr_str(tree_t t, ident_t name, ident_t str);
ident_t tree_attr_str(tree_t t, ident_t name);
void tree_add_attr_int(tree_t t, ident_t name, int n);
int tree_attr_int(tree_t t, ident_t name, int def);
void tree_add_attr_ptr(tree_t t, ident_t name, void *ptr);
void *tree_attr_ptr(tree_t t, ident_t name);
tree_t tree_attr_tree(tree_t t, ident_t name);
void tree_add_attr_tree(tree_t t, ident_t name, tree_t val);
// Utility functions
int64_t assume_int(tree_t t);
void range_bounds(range_t r, int64_t *low, int64_t *high);
tree_t call_builtin(const char *builtin, type_t type, ...);
typedef void (*tree_visit_fn_t)(tree_t t, void *context);
unsigned tree_visit(tree_t t, tree_visit_fn_t fn, void *context);
unsigned tree_visit_only(tree_t t, tree_visit_fn_t fn,
void *context, tree_kind_t kind);
typedef tree_t (*tree_rewrite_fn_t)(tree_t t, void *context);
tree_t tree_rewrite(tree_t t, tree_rewrite_fn_t fn, void *context);
tree_t tree_copy(tree_t t);
void tree_gc(void);
tree_wr_ctx_t tree_write_begin(FILE *f);
void tree_write(tree_t t, tree_wr_ctx_t ctx);
void tree_write_end(tree_wr_ctx_t ctx);
FILE *tree_write_file(tree_wr_ctx_t ctx);
tree_rd_ctx_t tree_read_begin(FILE *f, const char *name);
tree_t tree_read(tree_rd_ctx_t ctx);
void tree_read_end(tree_rd_ctx_t ctx);
FILE *tree_read_file(tree_rd_ctx_t ctx);
tree_t tree_read_recall(tree_rd_ctx_t ctx, uint32_t index);
// Utility typedefs
typedef unsigned (*tree_formals_t)(tree_t t);
typedef tree_t (*tree_formal_t)(tree_t t, unsigned n);
typedef unsigned (*tree_actuals_t)(tree_t t);
typedef param_t (*tree_actual_t)(tree_t t, unsigned n);
#endif // _TREE_H