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