1 // Type expressions.
2 
3 #ifndef __TPEXPR_H__
4 #define __TPEXPR_H__
5 
6 #include "bring.h"
7 
8 enum type_tag {
9     tp_void, tp_any,
10     tp_real, tp_double, tp_integer, tp_longint,
11     tp_char, tp_string, tp_varying_string, tp_bool, tp_set,
12     tp_enum, tp_range, tp_proc, tp_array, tp_dynarray, tp_record, tp_ref,
13     tp_file, tp_text, tp_fwd_ref, tp_unit, tp_object,
14     tp_last	// Not a type really
15 };
16 enum type_flags {
17     tp_need_init = 1 /* variable of this type should be initilialized by 0 */
18     /* this flag is set if it is file type or contains file variable       */
19 };
20 
21 class param_spec : public heap_object {
22   public:
23     param_spec *next;
24     symbol     *var;
25 
param_spec(symbol * variable)26     param_spec(symbol* variable) {
27 	var = variable, next = NULL;
28     }
29 };
30 
31 //---------------------------------------------------------------
32 
33 class tpd_node;
34 
35 class tpexpr : public heap_object {
36   public:
37     int      tag;
38     int      flags;
39     char     *name;
40     tpd_node *tpd;
41 
is_scalar()42     bool is_scalar() {
43         return tag == tp_char || tag == tp_integer
44 	    || tag == tp_real || tag == tp_range || tag == tp_enum;
45     }
46 
47     token*  insert_before(token *t);
48     virtual tpexpr* get_typedef();
49     virtual bool is_reference();
50     virtual bool is_array();
51 
52     tpexpr(int tp_tag, tpd_node* tp_tpd = NULL, char* tp_name = NULL) {
53          tag = tp_tag;
54 	 tpd = tp_tpd;
55 	 name = tp_name;
56 	 flags = 0;
57     }
58 };
59 
60 class simple_tp : public tpexpr {
61   public:
62     tpexpr* alias;
63     virtual tpexpr* get_typedef();
64     virtual bool is_reference();
65     virtual bool is_array();
66 
simple_tp(tpexpr * def)67     simple_tp(tpexpr* def) : tpexpr(def->tag, def->tpd) { alias = def; }
68 };
69 
70 
71 // Node for reference type
72 class ref_tp : public tpexpr {
73   public:
74     tpexpr*   base_type;
75 
76     virtual bool is_reference();
77     ref_tp(tpexpr* tp = NULL, tpd_node* tpd = NULL);
78 };
79 
80 class fwd_ref_tp : public ref_tp {
81   public:
82     token* ident;
83 
84     virtual tpexpr* get_typedef();
85     fwd_ref_tp(token* t);
86 };
87 
88 class enum_tp : public tpexpr {
89   public:
90     int     n_elems;
91     char   *max;
92     symbol *first;
93     symbol *last;
94 
95     void   set_enumeration_name(tpexpr* type);
96 
tpexpr(tp_enum,tpd)97     enum_tp(tpd_node* tpd = NULL) : tpexpr(tp_enum, tpd) { max = NULL; }
98     void set_bounds(symbol* name);
99 };
100 
101 
102 class range_tp : public tpexpr {
103   public:
104     char*  min;
105     char*  max;
106     int    min_value;
107     int    max_value;
108     int    size;  // size of type representing range
109 
tpexpr(tp_range,tpd)110     range_tp(tpd_node* tpd = NULL) : tpexpr(tp_range, tpd) {
111 	min_value = max_value = 0;
112         min = max = NULL;
113 	size = 0;
114     }
115     void set_bounds(symbol* name);
116 };
117 
118 // Node for varying string
119 
120 // Node for array type
121 
122 class expr_node;
123 class proc_tp;
124 
125 class array_tp : public tpexpr {
126   public:
127     tpexpr     *elem_type; // type of conmponent
128     symbol     *low_var;   // low bound of conformant array
129     symbol     *high_var;  // high bound of conformant array
130     char       *low;
131     char       *high;
132     expr_node  *low_expr;
133     expr_node  *high_expr;
134     int        base;
135 
136     virtual bool   is_array();
137 
138     void           set_dim(char *low, char *high,
139 			   expr_node *low_expr = NULL,
140 			   expr_node *high_expr = NULL);
141     void           set_conformant_dim(symbol* slow,
142 				      symbol* shigh);
143     virtual void   insert_dimensions(expr_node* e, array_tp* conf_arr = NULL,
144 				    int n = 0);
145     void           insert_length(token* t);
146     void           insert_bound_params(token* before);
147     void           add_proc_param(proc_tp* proc);
148 
149     // definition of conmformant array variables
150     void insert_bounds_definition(symbol* array, token* before, int n = 0);
151 
152     array_tp(tpexpr* tp = NULL, tpd_node* tpd = NULL);
153 };
154 
155 class string_tp : public array_tp {
156   public:
157     virtual void  insert_dimensions(expr_node *e, array_tp*, int);
158     string_tp();
159 };
160 
161 class varying_string_tp : public array_tp {
162   public:
163     varying_string_tp();
164 };
165 
166 #define MAX_SET_CARD   256
167 #define SHORT_SET_CARD 32
168 
169 class set_tp : public tpexpr {
170   public:
171     tpexpr* elem_type;
is_short_set()172     bool is_short_set() { return card() <= SHORT_SET_CARD; }
card()173     unsigned card() { return elem_type->tag == tp_enum
174 			  ? ((enum_tp*)elem_type->get_typedef())->n_elems
175 			  : MAX_SET_CARD;
176     }
177     set_tp(tpexpr* etype = NULL) : tpexpr(tp_set, NULL, "set") {
178 	elem_type = etype;
179     }
180 };
181 
182 class file_tp : public ref_tp {
183   public:
184     file_tp(tpexpr* record_type = NULL, tpd_node* tpd = NULL)
ref_tp(record_type,tpd)185     : ref_tp(record_type, tpd)
186       { tag = tp_file; flags |= tp_need_init; }
187 };
188 
189 class text_tp : public file_tp {
190   public:
191     text_tp();
192 };
193 
194 // Node for record type
195 class record_tp : public tpexpr, public b_ring {
196   public:
197     void calc_flags();
198     record_tp(tpd_node *tpd = NULL)
tpexpr(tp_record,tpd)199 	: tpexpr(tp_record, tpd), b_ring(b_ring::record)
200   {}
201 };
202 
203 class unit_tp : public record_tp {
204   public:
record_tp(tpd)205     unit_tp(tpd_node *tpd = NULL) : record_tp(tpd) {
206 	tag = tp_unit;
207     }
208 };
209 
210 class object_tp : public record_tp {
211   public:
212     symbol* class_name;
213     object_tp(tpd_node *tpd, object_tp* super = NULL);
214 };
215 
216 class proc_tp;
217 
218 class caller_spec : public heap_object {
219   public:
220     caller_spec *next;
221     proc_tp     *caller;
222 
caller_spec(proc_tp * func)223     caller_spec(proc_tp *func) { caller = func, next = NULL; }
224 };
225 
226 
227 class define_spec : public heap_object {
228   public:
229     define_spec *next;
230     symbol      *sym;
231 
define_spec(symbol * defsym,define_spec * chain)232     define_spec(symbol* defsym, define_spec* chain) {
233 	sym = defsym;
234 	next = chain;
235     }
236 };
237 
238 class proc_fwd_decl_node;
239 
240 class temp_spec : public heap_object {
241   public:
242     tpexpr*    type;
243     temp_spec* next;
244 
temp_spec(tpexpr * tp)245     temp_spec(tpexpr* tp) { type = tp; next = NULL; }
246 };
247 
248 
249 // Node for procedure type
250 class proc_tp : public tpexpr, public b_ring {
251   public:
252     tpexpr         *res_type;
253     param_spec     *params;
254     param_spec     *last;
255     param_spec     *extra_params;
256     char           *proc_name;
257 
258     define_spec    *define_list;  // list of macros defined in procedure
259 
260     temp_spec      *temp_list;    // list of temporary variable
261     temp_spec      *last_temp;    // generated for procedure
262     int            n_temp;
263     int            n_subproc;
264     int            make_all_constants_global;
265     bool           is_extern_c;
266     bool           is_constructor;
267     bool           is_destructor;
268 
269     proc_fwd_decl_node *forward;
270 
271     caller_spec    *callers;
272 
is_function_pointer()273     bool is_function_pointer() { return proc_name == NULL; }
274 
275     void add_define(symbol* v);
276     void undefine(token* after);
277 
278     void add_param(symbol *v);
279     void add_extra_param(symbol *v);
280     void add_caller(proc_tp* func);
281     void declare_conformant_array_bounds(token* before);
282 
283     char* add_temp(tpexpr* type);
284     void  insert_temporaries(token* before);
285 
is_function()286     bool is_function() { return res_type != NULL; }
287 
288     proc_tp(tpexpr* rtype = NULL, tpd_node *tpd = NULL);
289 };
290 
291 extern tpexpr    integer_type;
292 extern tpexpr    real_type;
293 extern tpexpr    double_type;
294 extern tpexpr    longint_type;
295 extern tpexpr    char_type;
296 extern tpexpr    void_type;
297 extern tpexpr    any_type;
298 extern tpexpr    bool_type;
299 extern set_tp    set_type;
300 extern string_tp string_type;
301 extern text_tp   text_type;
302 extern ref_tp    pointer_type;
303 extern varying_string_tp varying_string_type;
304 
305 #endif
306