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