-
Notifications
You must be signed in to change notification settings - Fork 7
/
tpexpr.h
305 lines (241 loc) · 7.04 KB
/
tpexpr.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
// Type expressions.
#ifndef __TPEXPR_H__
#define __TPEXPR_H__
#include "bring.h"
enum type_tag {
tp_void, tp_any,
tp_real, tp_double, tp_integer, tp_longint,
tp_char, tp_string, tp_varying_string, tp_bool, tp_set,
tp_enum, tp_range, tp_proc, tp_array, tp_dynarray, tp_record, tp_ref,
tp_file, tp_text, tp_fwd_ref, tp_unit, tp_object,
tp_last // Not a type really
};
enum type_flags {
tp_need_init = 1 /* variable of this type should be initilialized by 0 */
/* this flag is set if it is file type or contains file variable */
};
class param_spec : public heap_object {
public:
param_spec *next;
symbol *var;
param_spec(symbol* variable) {
var = variable, next = NULL;
}
};
//---------------------------------------------------------------
class tpd_node;
class tpexpr : public heap_object {
public:
int tag;
int flags;
char *name;
tpd_node *tpd;
bool is_scalar() {
return tag == tp_char || tag == tp_integer
|| tag == tp_real || tag == tp_range || tag == tp_enum;
}
token* insert_before(token *t);
virtual tpexpr* get_typedef();
virtual bool is_reference();
virtual bool is_array();
tpexpr(int tp_tag, tpd_node* tp_tpd = NULL, char* tp_name = NULL) {
tag = tp_tag;
tpd = tp_tpd;
name = tp_name;
flags = 0;
}
};
class simple_tp : public tpexpr {
public:
tpexpr* alias;
virtual tpexpr* get_typedef();
virtual bool is_reference();
virtual bool is_array();
simple_tp(tpexpr* def) : tpexpr(def->tag, def->tpd) { alias = def; }
};
// Node for reference type
class ref_tp : public tpexpr {
public:
tpexpr* base_type;
virtual bool is_reference();
ref_tp(tpexpr* tp = NULL, tpd_node* tpd = NULL);
};
class fwd_ref_tp : public ref_tp {
public:
token* ident;
virtual tpexpr* get_typedef();
fwd_ref_tp(token* t);
};
class enum_tp : public tpexpr {
public:
int n_elems;
char *max;
symbol *first;
symbol *last;
void set_enumeration_name(tpexpr* type);
enum_tp(tpd_node* tpd = NULL) : tpexpr(tp_enum, tpd) { max = NULL; }
void set_bounds(symbol* name);
};
class range_tp : public tpexpr {
public:
char* min;
char* max;
int min_value;
int max_value;
int size; // size of type representing range
range_tp(tpd_node* tpd = NULL) : tpexpr(tp_range, tpd) {
min_value = max_value = 0;
min = max = NULL;
size = 0;
}
void set_bounds(symbol* name);
};
// Node for varying string
// Node for array type
class expr_node;
class proc_tp;
class array_tp : public tpexpr {
public:
tpexpr *elem_type; // type of conmponent
symbol *low_var; // low bound of conformant array
symbol *high_var; // high bound of conformant array
char *low;
char *high;
expr_node *low_expr;
expr_node *high_expr;
int base;
virtual bool is_array();
void set_dim(char *low, char *high,
expr_node *low_expr = NULL,
expr_node *high_expr = NULL);
void set_conformant_dim(symbol* slow,
symbol* shigh);
virtual void insert_dimensions(expr_node* e, array_tp* conf_arr = NULL,
int n = 0);
void insert_length(token* t);
void insert_bound_params(token* before);
void add_proc_param(proc_tp* proc);
// definition of conmformant array variables
void insert_bounds_definition(symbol* array, token* before, int n = 0);
array_tp(tpexpr* tp = NULL, tpd_node* tpd = NULL);
};
class string_tp : public array_tp {
public:
virtual void insert_dimensions(expr_node *e, array_tp*, int);
string_tp();
};
class varying_string_tp : public array_tp {
public:
varying_string_tp();
};
#define MAX_SET_CARD 256
#define SHORT_SET_CARD 32
class set_tp : public tpexpr {
public:
tpexpr* elem_type;
bool is_short_set() { return card() <= SHORT_SET_CARD; }
unsigned card() { return elem_type->tag == tp_enum
? ((enum_tp*)elem_type->get_typedef())->n_elems
: MAX_SET_CARD;
}
set_tp(tpexpr* etype = NULL) : tpexpr(tp_set, NULL, "set") {
elem_type = etype;
}
};
class file_tp : public ref_tp {
public:
file_tp(tpexpr* record_type = NULL, tpd_node* tpd = NULL)
: ref_tp(record_type, tpd)
{ tag = tp_file; flags |= tp_need_init; }
};
class text_tp : public file_tp {
public:
text_tp();
};
// Node for record type
class record_tp : public tpexpr, public b_ring {
public:
void calc_flags();
record_tp(tpd_node *tpd = NULL)
: tpexpr(tp_record, tpd), b_ring(b_ring::record)
{}
};
class unit_tp : public record_tp {
public:
unit_tp(tpd_node *tpd = NULL) : record_tp(tpd) {
tag = tp_unit;
}
};
class object_tp : public record_tp {
public:
symbol* class_name;
object_tp(tpd_node *tpd, object_tp* super = NULL);
};
class proc_tp;
class caller_spec : public heap_object {
public:
caller_spec *next;
proc_tp *caller;
caller_spec(proc_tp *func) { caller = func, next = NULL; }
};
class define_spec : public heap_object {
public:
define_spec *next;
symbol *sym;
define_spec(symbol* defsym, define_spec* chain) {
sym = defsym;
next = chain;
}
};
class proc_fwd_decl_node;
class temp_spec : public heap_object {
public:
tpexpr* type;
temp_spec* next;
temp_spec(tpexpr* tp) { type = tp; next = NULL; }
};
// Node for procedure type
class proc_tp : public tpexpr, public b_ring {
public:
tpexpr *res_type;
param_spec *params;
param_spec *last;
param_spec *extra_params;
char *proc_name;
define_spec *define_list; // list of macros defined in procedure
temp_spec *temp_list; // list of temporary variable
temp_spec *last_temp; // generated for procedure
int n_temp;
int n_subproc;
int make_all_constants_global;
bool is_extern_c;
bool is_constructor;
bool is_destructor;
proc_fwd_decl_node *forward;
caller_spec *callers;
bool is_function_pointer() { return proc_name == NULL; }
void add_define(symbol* v);
void undefine(token* after);
void add_param(symbol *v);
void add_extra_param(symbol *v);
void add_caller(proc_tp* func);
void declare_conformant_array_bounds(token* before);
char* add_temp(tpexpr* type);
void insert_temporaries(token* before);
bool is_function() { return res_type != NULL; }
proc_tp(tpexpr* rtype = NULL, tpd_node *tpd = NULL);
};
extern tpexpr integer_type;
extern tpexpr real_type;
extern tpexpr double_type;
extern tpexpr longint_type;
extern tpexpr char_type;
extern tpexpr void_type;
extern tpexpr any_type;
extern tpexpr bool_type;
extern set_tp set_type;
extern string_tp string_type;
extern text_tp text_type;
extern ref_tp pointer_type;
extern varying_string_tp varying_string_type;
#endif