1
2
3 /** **********************************************************************
4 ** Module: Type \file type.c
5 This module implements the type abstraction. It is
6 ** rather unpleasant, since this abstraction is quite well suited
7 ** to an object-oriented environment with inheritance.
8 ** Constants:
9 ** TYPE_AGGREGATE - generic general aggregate
10 ** TYPE_BINARY - binary type
11 ** TYPE_BOOLEAN - boolean type
12 ** TYPE_GENERIC - generic type
13 ** TYPE_INTEGER - integer type with default precision
14 ** TYPE_LOGICAL - logical type
15 ** TYPE_NULL - the null type
16 ** TYPE_NUMBER - number type
17 ** TYPE_REAL - real type with default precision
18 ** TYPE_SET_OF_GENERIC - type for unconstrained set of generic items
19 ** TYPE_STRING - string type with default precision
20 **
21 ************************************************************************/
22
23 /*
24 * This code was developed with the support of the United States Government,
25 * and is not subject to copyright.
26 *
27 * $Log: type.c,v $
28 * Revision 1.12 1997/01/21 19:19:51 dar
29 * made C++ compatible
30 *
31 * Revision 1.11 1995/03/09 18:44:45 clark
32 * various fixes for caddetc - before interface clause changes
33 *
34 * Revision 1.10 1994/11/10 19:20:03 clark
35 * Update to IS
36 *
37 * Revision 1.9 1994/05/11 19:51:24 libes
38 * numerous fixes
39 *
40 * Revision 1.8 1993/10/15 18:48:48 libes
41 * CADDETC certified
42 *
43 * Revision 1.6 1993/01/19 22:16:09 libes
44 * *** empty log message ***
45 *
46 * Revision 1.5 1992/09/16 18:23:45 libes
47 * added some functions for easier access to base types
48 *
49 * Revision 1.4 1992/08/18 17:13:43 libes
50 * rm'd extraneous error messages
51 *
52 * Revision 1.3 1992/06/08 18:06:57 libes
53 * prettied up interface to print_objects_when_running
54 *
55 * Revision 1.2 1992/05/31 08:35:51 libes
56 * multiple files
57 *
58 * Revision 1.1 1992/05/28 03:55:04 libes
59 * Initial revision
60 *
61 * Revision 1.9 1992/05/14 10:14:06 libes
62 * don't remember
63 *
64 * Revision 1.8 1992/05/10 06:03:18 libes
65 * cleaned up OBJget_symbol
66 *
67 * Revision 1.7 1992/05/10 01:42:27 libes
68 * does enums and repeat properly
69 *
70 * Revision 1.6 1992/05/05 19:52:11 libes
71 * final alpha
72 *
73 * Revision 1.5 1992/02/19 15:48:46 libes
74 * changed types to enums & flags
75 *
76 * Revision 1.4 1992/02/17 14:33:41 libes
77 * lazy ref/use evaluation now working
78 *
79 * Revision 1.3 1992/02/12 07:05:45 libes
80 * do sub/supertype
81 *
82 * Revision 1.2 1992/02/09 00:50:20 libes
83 * does ref/use correctly
84 *
85 * Revision 1.1 1992/02/05 08:34:24 libes
86 * Initial revision
87 *
88 * Revision 1.0.1.1 1992/01/22 02:47:57 libes
89 * copied from ~pdes
90 *
91 * Revision 4.8 1991/11/14 07:37:50 libes
92 * added TYPEget/put_original_type
93 *
94 * Revision 4.7 1991/09/16 23:13:12 libes
95 * added print functions
96 *
97 * Revision 4.6 1991/06/14 20:48:16 libes
98 * added binary type
99 *
100 * Revision 4.5 1991/01/24 22:20:36 silver
101 * merged changes from NIST and SCRA
102 * SCRA changes are due to DEC ANSI C compiler tests.
103 *
104 * Revision 4.4 91/01/08 18:56:05 pdesadmn
105 * Initial - Beta checkin at SCRA
106 *
107 * Revision 4.3 90/09/14 16:02:28 clark
108 * Initial checkin at SCRA
109 *
110 * Revision 4.3 90/09/14 16:02:28 clark
111 * initial checkin at SCRA
112 *
113 * Revision 4.3 90/09/14 16:02:28 clark
114 * Reintroduce ENT_TYPEget_entity
115 *
116 * Revision 4.2 90/09/14 09:33:20 clark
117 * Add Class_{Boolean,Generic,Logical,Number}_Type
118 * Fix TYPE_equal
119 *
120 * Revision 4.1 90/09/13 15:13:21 clark
121 * BPR 2.1 alpha
122 *
123 */
124
125 #include <assert.h>
126 #include <sc_memmgr.h>
127 #include "express/type.h"
128
129 /* Very commonly-used read-only types */
130 /* non-constant versions probably aren't necessary? */
131 Type Type_Bad;
132 Type Type_Unknown;
133 Type Type_Dont_Care;
134 Type Type_Runtime; /* indicates that this object can't be */
135 /* calculated now but must be deferred */
136 /* til (the mythical) runtime */
137 Type Type_Binary;
138 Type Type_Boolean;
139 Type Type_Enumeration;
140 Type Type_Expression;
141 Type Type_Aggregate;
142 Type Type_Repeat;
143 Type Type_Integer;
144 Type Type_Number;
145 Type Type_Real;
146 Type Type_String;
147 Type Type_String_Encoded;
148 Type Type_Logical;
149 Type Type_Set;
150 Type Type_Attribute;
151 Type Type_Entity;
152 Type Type_Funcall;
153 Type Type_Generic;
154 Type Type_Identifier;
155 Type Type_Oneof;
156 Type Type_Query;
157 Type Type_Self;
158 Type Type_Set_Of_String;
159 Type Type_Set_Of_Generic;
160 Type Type_Bag_Of_Generic;
161
162 struct freelist_head TYPEHEAD_fl;
163 struct freelist_head TYPEBODY_fl;
164
165 Error ERROR_corrupted_type = ERROR_none;
166
167 static Error ERROR_undefined_tag;
168 /**
169 * create a type with no symbol table
170 */
TYPEcreate_nostab(struct Symbol_ * symbol,Scope scope,char objtype)171 Type TYPEcreate_nostab( struct Symbol_ *symbol, Scope scope, char objtype ) {
172 Type t = SCOPEcreate_nostab( OBJ_TYPE );
173 TypeHead th = TYPEHEAD_new();
174
175 t->u.type = th;
176 t->symbol = *symbol;
177 DICTdefine( scope->symbol_table, symbol->name, ( Generic )t, &t->symbol, objtype );
178
179 return t;
180 }
181
182 /**
183 * create a type but this is just a shell, either to be completed later
184 * such as enumerations (which have a symbol table added later)
185 * or to be used as a type reference
186 */
TYPEcreate_name(Symbol * symbol)187 Type TYPEcreate_name( Symbol * symbol ) {
188 Scope s = SCOPEcreate_nostab( OBJ_TYPE );
189 TypeHead t = TYPEHEAD_new();
190
191 s->u.type = t;
192 s->symbol = *symbol;
193 return s;
194 }
195
TYPEcreate_user_defined_tag(Type base,Scope scope,struct Symbol_ * symbol)196 Type TYPEcreate_user_defined_tag( Type base, Scope scope, struct Symbol_ *symbol ) {
197 Type t;
198 extern int tag_count;
199
200 t = ( Type )DICTlookup( scope->symbol_table, symbol->name );
201 if( t ) {
202 if( DICT_type == OBJ_TAG ) {
203 return( t );
204 } else {
205 /* easiest to just generate the error this way!
206 * following call WILL fail intentionally
207 */
208 DICTdefine( scope->symbol_table, symbol->name, 0, symbol, OBJ_TAG );
209 return( 0 );
210 }
211 }
212
213 /* tag is undefined
214 * if we are outside a formal parameter list (hack, hack)
215 * then we can only refer to existing tags, so produce an error
216 */
217 if( tag_count < 0 ) {
218 ERRORreport_with_symbol( ERROR_undefined_tag, symbol,
219 symbol->name );
220 return( 0 );
221 }
222
223 /* otherwise, we're in a formal parameter list,
224 * so it's ok to define it
225 */
226 t = TYPEcreate_nostab( symbol, scope, OBJ_TAG );
227 t->u.type->head = base;
228
229 /* count unique type tags inside PROC and FUNC headers */
230 tag_count++;
231
232 return( t );
233 }
234
TYPEcreate(enum type_enum type)235 Type TYPEcreate( enum type_enum type ) {
236 TypeBody tb = TYPEBODYcreate( type );
237 Type t = TYPEcreate_from_body_anonymously( tb );
238 return( t );
239 }
240
TYPEcreate_from_body_anonymously(TypeBody tb)241 Type TYPEcreate_from_body_anonymously( TypeBody tb ) {
242 Type t = SCOPEcreate_nostab( OBJ_TYPE );
243 TypeHead th = TYPEHEAD_new();
244
245 t->u.type = th;
246 t->u.type->body = tb;
247 t->symbol.name = 0;
248 SYMBOLset( t );
249 return t;
250 }
251
TYPEBODYcreate(enum type_enum type)252 TypeBody TYPEBODYcreate( enum type_enum type ) {
253 TypeBody tb = TYPEBODY_new();
254 tb->type = type;
255 return tb;
256 }
257
258 /**
259 * return true if "type t" inherits from "enum type_enum"
260 * may need to be implemented for more types
261 */
262 #define TYPE_inherits_from(t,e) ((t) && TYPEinherits_from((t),(e)))
263
TYPEinherits_from(Type t,enum type_enum e)264 bool TYPEinherits_from( Type t, enum type_enum e ) {
265 TypeBody tb = t->u.type->body;
266 assert( ( t->type == OBJ_TYPE ) && ( tb ) && "Not a Type!" );
267 switch( e ) {
268 case aggregate_:
269 if( tb->type == aggregate_ ||
270 tb->type == array_ ||
271 tb->type == bag_ ||
272 tb->type == set_ ||
273 tb->type == list_ ) {
274 return true;
275 } else {
276 return( TYPE_inherits_from( tb->base, e ) );
277 }
278 case array_:
279 return( ( tb->type == array_ ) ? true : TYPE_inherits_from( tb->base, e ) );
280 case bag_:
281 return( ( tb->type == bag_ ||
282 tb->type == set_ ) ? true : TYPE_inherits_from( tb->base, e ) );
283 case set_:
284 return( ( tb->type == set_ ) ? true : TYPE_inherits_from( tb->base, e ) );
285 case list_:
286 return( ( tb->type == list_ ) ? true : TYPE_inherits_from( tb->base, e ) );
287 default:
288 break;
289 }
290 return ( tb->type == e );
291 }
292
293 #if 0
294 case binary_:
295 return( ( t->type == binary_ ) ? true : TYPEinherits_from( t->base, e ) );
296 case integer_:
297 return( ( t->type == integer_ ) ? true : TYPEinherits_from( t->base, e ) );
298 case real_:
299 return( ( t->type == real_ ) ? true : TYPEinherits_from( t->base, e ) );
300 case string_:
301 return( ( t->type == string_ ) ? true : TYPEinherits_from( t->base, e ) );
302 case logical_:
303 return( ( t->type == logical_ ) ? true : TYPEinherits_from( t->base, e ) );
304 case boolean_:
305 return( ( t->type == boolean_ ) ? true : TYPEinherits_from( t->base, e ) );
306 default:
307 return( false );
308 }
309 }
310 #endif
311
TYPE_get_symbol(Generic t)312 Symbol * TYPE_get_symbol( Generic t ) {
313 return( &( ( Type )t )->symbol );
314 }
315
316
317 /** Initialize the Type module */
TYPEinitialize()318 void TYPEinitialize() {
319 MEMinitialize( &TYPEHEAD_fl, sizeof( struct TypeHead_ ), 500, 100 );
320 MEMinitialize( &TYPEBODY_fl, sizeof( struct TypeBody_ ), 200, 100 );
321 OBJcreate( OBJ_TYPE, TYPE_get_symbol, "type", OBJ_TYPE_BITS );
322 /* OBJcreate(OBJ_TYPE,TYPE_get_symbol,"(headless) type", OBJ_UNFINDABLE_BITS);*/
323 OBJcreate( OBJ_TAG, TYPE_get_symbol, "tag", OBJ_TYPE_BITS );
324
325 /* Very commonly-used read-only types */
326 Type_Unknown = TYPEcreate( unknown_ );
327 Type_Dont_Care = TYPEcreate( special_ );
328 Type_Bad = TYPEcreate( special_ );
329 Type_Runtime = TYPEcreate( runtime_ );
330
331 Type_Enumeration = TYPEcreate( enumeration_ );
332 Type_Enumeration->u.type->body->flags.shared = 1;
333 resolved_all( Type_Enumeration );
334
335 Type_Expression = TYPEcreate( op_ );
336 Type_Expression->u.type->body->flags.shared = 1;
337
338 Type_Aggregate = TYPEcreate( aggregate_ );
339 Type_Aggregate->u.type->body->flags.shared = 1;
340 Type_Aggregate->u.type->body->base = Type_Runtime;
341
342 Type_Integer = TYPEcreate( integer_ );
343 Type_Integer->u.type->body->flags.shared = 1;
344 resolved_all( Type_Integer );
345
346 Type_Real = TYPEcreate( real_ );
347 Type_Real->u.type->body->flags.shared = 1;
348 resolved_all( Type_Real );
349
350 Type_Number = TYPEcreate( number_ );
351 Type_Number->u.type->body->flags.shared = 1;
352 resolved_all( Type_Number );
353
354 Type_String = TYPEcreate( string_ );
355 Type_String->u.type->body->flags.shared = 1;
356 resolved_all( Type_String );
357
358 Type_String_Encoded = TYPEcreate( string_ );
359 Type_String_Encoded->u.type->body->flags.shared = 1;
360 Type_String_Encoded->u.type->body->flags.encoded = 1;
361 resolved_all( Type_String );
362
363 Type_Logical = TYPEcreate( logical_ );
364 Type_Logical->u.type->body->flags.shared = 1;
365 resolved_all( Type_Logical );
366
367 Type_Binary = TYPEcreate( binary_ );
368 Type_Binary->u.type->body->flags.shared = 1;
369 resolved_all( Type_Binary );
370
371 Type_Number = TYPEcreate( number_ );
372 Type_Number->u.type->body->flags.shared = 1;
373 resolved_all( Type_Number );
374
375 Type_Boolean = TYPEcreate( boolean_ );
376 Type_Boolean->u.type->body->flags.shared = 1;
377 resolved_all( Type_Boolean );
378
379 Type_Generic = TYPEcreate( generic_ );
380 Type_Generic->u.type->body->flags.shared = 1;
381 resolved_all( Type_Generic );
382
383 Type_Set_Of_String = TYPEcreate( set_ );
384 Type_Set_Of_String->u.type->body->flags.shared = 1;
385 Type_Set_Of_String->u.type->body->base = Type_String;
386
387 Type_Set_Of_Generic = TYPEcreate( set_ );
388 Type_Set_Of_Generic->u.type->body->flags.shared = 1;
389 Type_Set_Of_Generic->u.type->body->base = Type_Generic;
390
391 Type_Bag_Of_Generic = TYPEcreate( bag_ );
392 Type_Bag_Of_Generic->u.type->body->flags.shared = 1;
393 Type_Bag_Of_Generic->u.type->body->base = Type_Generic;
394
395 Type_Attribute = TYPEcreate( attribute_ );
396 Type_Attribute->u.type->body->flags.shared = 1;
397
398 Type_Entity = TYPEcreate( entity_ );
399 Type_Entity->u.type->body->flags.shared = 1;
400
401 Type_Funcall = TYPEcreate( funcall_ );
402 Type_Funcall->u.type->body->flags.shared = 1;
403
404 Type_Generic = TYPEcreate( generic_ );
405 Type_Generic->u.type->body->flags.shared = 1;
406
407 Type_Identifier = TYPEcreate( identifier_ );
408 Type_Identifier->u.type->body->flags.shared = 1;
409
410 Type_Repeat = TYPEcreate( integer_ );
411 Type_Repeat->u.type->body->flags.shared = 1;
412 Type_Repeat->u.type->body->flags.repeat = 1;
413
414 Type_Oneof = TYPEcreate( oneof_ );
415 Type_Oneof->u.type->body->flags.shared = 1;
416
417 Type_Query = TYPEcreate( query_ );
418 Type_Query->u.type->body->flags.shared = 1;
419
420 Type_Self = TYPEcreate( self_ );
421 Type_Self->u.type->body->flags.shared = 1;
422
423 ERROR_corrupted_type =
424 ERRORcreate( "Corrupted type in %s", SEVERITY_DUMP );
425
426 ERROR_undefined_tag =
427 ERRORcreate( "Undefined type tag %s", SEVERITY_ERROR );
428 }
429
430 /** Clean up the Type module */
TYPEcleanup(void)431 void TYPEcleanup( void ) {
432 ERRORdestroy( ERROR_corrupted_type );
433 ERRORdestroy( ERROR_undefined_tag );
434 }
435
436 /**
437 * \param t type to examine
438 * \return the base type of the aggregate type
439 * Retrieve the base type of an aggregate.
440 */
TYPEget_nonaggregate_base_type(Type t)441 Type TYPEget_nonaggregate_base_type( Type t ) {
442 while( TYPEis_aggregate( t ) ) {
443 t = t->u.type->body->base;
444 }
445 return t;
446 }
447
448