Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "calculus.h"
63
#include "error.h"
64
#include "common.h"
65
#include "type_ops.h"
66
#include "xalloc.h"
67
 
68
 
69
/*
7 7u83 70
 * TYPE REPRESENTING A LIST OF ALGEBRAS
71
 *
72
 * This type is used to represent the list of all algebras.
73
 */
2 7u83 74
 
75
typedef struct ALGEBRA_LIST_tag {
7 7u83 76
    ALGEBRA_DEFN alg;
77
    struct ALGEBRA_LIST_tag *next;
78
} ALGEBRA_LIST;
2 7u83 79
 
80
 
81
/*
7 7u83 82
 * CURRENT ALGEBRA
83
 *
84
 * The variable algebra holds all the information on the algebra read
85
 * from the input file.  The list all_algebras contains a list of all
86
 * the algebras defined.
87
 */
2 7u83 88
 
7 7u83 89
ALGEBRA_DEFN *algebra = NULL;
90
static ALGEBRA_LIST *all_algebras = NULL;
2 7u83 91
 
92
 
93
/*
7 7u83 94
 * CREATE A NEW ALGEBRA
95
 *
96
 * This routine allocates and initialises a new algebra structure.
97
 */
2 7u83 98
 
7 7u83 99
void
100
new_algebra(void)
2 7u83 101
{
7 7u83 102
    ALGEBRA_LIST *p = xmalloc_nof(ALGEBRA_LIST, 1);
103
    p->alg.name = "ALGEBRA";
104
    p->alg.major_no = 1;
105
    p->alg.minor_no = 0;
106
    p->alg.primitives = NULL_list(PRIMITIVE_P);
107
    p->alg.identities = NULL_list(IDENTITY_P);
108
    p->alg.enumerations = NULL_list(ENUM_P);
109
    p->alg.structures = NULL_list(STRUCTURE_P);
110
    p->alg.unions = NULL_list(UNION_P);
111
    p->alg.types = NULL_list(TYPE_P);
112
    p->next = all_algebras;
113
    all_algebras = p;
114
    algebra = &(p->alg);
115
    return;
2 7u83 116
}
117
 
118
 
119
/*
7 7u83 120
 * LOOK UP AN ALGEBRA
121
 *
122
 * This routine looks up the algebra named nm.  It returns null if the
123
 * algebra has not been defined.
124
 */
2 7u83 125
 
7 7u83 126
ALGEBRA_DEFN *
127
find_algebra(char *nm)
2 7u83 128
{
7 7u83 129
    ALGEBRA_LIST *p;
130
    for (p = all_algebras; p != NULL; p = p->next) {
131
	if (streq(p->alg.name, nm)) {
132
		return(&(p->alg));
133
	}
2 7u83 134
    }
7 7u83 135
    return(NULL);
2 7u83 136
}
137
 
138
 
139
/*
7 7u83 140
 * LAST IDENTIFIER
141
 *
142
 * This variable is set by name_type and name_aux_type to the identifier
143
 * of the last non-composite type looked up.
144
 */
2 7u83 145
 
7 7u83 146
static CLASS_ID_P last_id = NULL_ptr(CLASS_ID);
2 7u83 147
 
148
 
149
/*
7 7u83 150
 * REGISTER A TYPE
151
 *
152
 * This routine adds the type t to the list of all types.
153
 */
2 7u83 154
 
7 7u83 155
TYPE_P
156
register_type(TYPE_P t)
2 7u83 157
{
7 7u83 158
    char *nm = name_type(t);
159
    CLASS_ID_P id = last_id;
160
    LIST(TYPE_P)r = algebra->types;
161
    while (!IS_NULL_list(r)) {
162
	TYPE_P s = DEREF_ptr(HEAD_list(r));
163
	if (streq(name_type(s), nm)) {
2 7u83 164
 
165
	    /* Check for multiple definition */
7 7u83 166
	    if (!IS_type_undef(DEREF_type(s))) {
167
		char *fn1 = DEREF_string(cid_file(id));
168
		int ln1 = DEREF_int(cid_line(id));
169
		char *fn2 = DEREF_string(cid_file(last_id));
170
		int ln2 = DEREF_int(cid_line(last_id));
171
		if (fn2 == crt_file_name) {
172
		    char *fn = fn1;
173
		    int ln = ln1;
174
		    fn1 = fn2;
175
		    ln1 = ln2;
176
		    fn2 = fn;
177
		    ln2 = ln;
2 7u83 178
		}
7 7u83 179
		error_posn(ERROR_SERIOUS, fn1, ln1,
180
			   "Type %s already defined (at %s, line %d)", nm, fn2,
181
			   ln2);
2 7u83 182
	    }
183
 
7 7u83 184
	    COPY_type(s, DEREF_type(t));
185
	    return(s);
2 7u83 186
	}
7 7u83 187
	r = TAIL_list(r);
2 7u83 188
    }
7 7u83 189
    CONS_ptr(t, algebra->types, algebra->types);
190
    return(t);
2 7u83 191
}
192
 
193
 
194
/*
7 7u83 195
 * LOOK UP A NAMED TYPE
196
 *
197
 * This routine looks up the type named nm in the list of all types
198
 * associated with the algebra alg.  The type is created if necessary,
199
 * and the result is returned.
200
 */
2 7u83 201
 
7 7u83 202
TYPE_P
203
find_type(ALGEBRA_DEFN *alg, char *nm)
2 7u83 204
{
7 7u83 205
    TYPE s0;
206
    TYPE_P s;
207
    LIST(TYPE_P)t = alg->types;
208
    while (!IS_NULL_list(t)) {
209
	s = DEREF_ptr(HEAD_list(t));
210
	if (streq(name_type(s), nm)) {
211
		return(s);
212
	}
213
	t = TAIL_list(t);
2 7u83 214
    }
7 7u83 215
    s = MAKE_ptr(SIZE_type);
216
    MAKE_type_undef(0, nm, s0);
217
    COPY_type(s, s0);
218
    s = register_type(s);
219
    return(s);
2 7u83 220
}
221
 
222
 
223
/*
7 7u83 224
 * DOES A TYPE INVOLVE AN IDENTITY
225
 *
226
 * This routine checks whether the type t is an identity or a compound
227
 * type derived from an identity.
228
 */
2 7u83 229
 
7 7u83 230
int
231
is_identity_type(TYPE_P t)
2 7u83 232
{
7 7u83 233
    TYPE t0 = DEREF_type(t);
234
    while (IS_type_ptr_etc(t0)) {
235
	t0 = DEREF_type(DEREF_ptr(type_ptr_etc_sub(t0)));
2 7u83 236
    }
7 7u83 237
    return(IS_type_ident(t0));
2 7u83 238
}
239
 
240
 
241
/*
7 7u83 242
 * DEAL WITH COMPOUND TYPES INVOLVING IDENTITIES
243
 *
244
 * From the point of view of the list of all types, identity types are
245
 * distinct from their definitions.  This routine is called after creating
246
 * a compound type, r, to ensure that the corresponding type with any
247
 * identities replaced by their definition is also created.
248
 */
2 7u83 249
 
7 7u83 250
static TYPE_P
251
compound_identity(TYPE_P r, int depth)
2 7u83 252
{
7 7u83 253
    TYPE r0 = DEREF_type(r);
254
    if (depth > MAX_TYPE_DEPTH) {
255
	error(ERROR_SERIOUS, "Cyclic type definition involving %s",
256
		name_type(r));
257
	return(NULL_ptr(TYPE));
2 7u83 258
    }
7 7u83 259
    if (IS_type_ident(r0)) {
260
	IDENTITY_P a = DEREF_ptr(type_ident_id(DEREF_type(r)));
261
	TYPE_P s = DEREF_ptr(ident_defn(a));
262
	return(s);
2 7u83 263
    }
7 7u83 264
    if (IS_type_ptr_etc(r0)) {
265
	unsigned tag = TAG_type(r0);
266
	TYPE_P s = DEREF_ptr(type_ptr_etc_sub(r0));
267
	s = compound_identity(s, depth);
268
	if (!IS_NULL_ptr(s)) {
269
	    return(compound_type(tag, s, depth + 1));
2 7u83 270
	}
271
    }
7 7u83 272
    return(NULL_ptr(TYPE));
2 7u83 273
}
274
 
275
 
276
/*
7 7u83 277
 * CREATE A COMPOUND TYPE
278
 *
279
 * This routine creates a compound type from the type operation indicated
280
 * by tag and the sub-type r.  The routine is designed to ensure that
281
 * only one copy of each type is created.
282
 */
2 7u83 283
 
7 7u83 284
TYPE_P
285
compound_type(unsigned tag, TYPE_P r, int depth)
2 7u83 286
{
7 7u83 287
    TYPE s0;
288
    TYPE_P s;
289
    LIST(TYPE_P)t = algebra->types;
2 7u83 290
 
291
    /* Search for uses */
7 7u83 292
    while (!IS_NULL_list(t)) {
293
	s = DEREF_ptr(HEAD_list(t));
294
	s0 = DEREF_type(s);
295
	if (TAG_type(s0) == tag) {
296
	    TYPE_P rr = DEREF_ptr(type_ptr_etc_sub(s0));
297
	    if (EQ_ptr(r, rr)) return(s);
2 7u83 298
	}
7 7u83 299
	t = TAIL_list(t);
2 7u83 300
    }
7 7u83 301
    s = MAKE_ptr(SIZE_type);
302
    MAKE_type_ptr_etc(tag, 0, r, s0);
303
    COPY_type(s, s0);
304
    CONS_ptr(s, algebra->types, algebra->types);
305
    (void)compound_identity(s, depth);
306
    return(s);
2 7u83 307
}
308
 
309
 
310
/*
7 7u83 311
 * CHECK FOR UNDEFINED TYPES
312
 *
313
 * This routine scans the list of all types for any which remain undefined
314
 * at the end of the compilation.  It also calculates the sizes of all
315
 * the defined types.
316
 */
2 7u83 317
 
7 7u83 318
void
319
check_types(void)
2 7u83 320
{
7 7u83 321
    LIST(TYPE_P)t = algebra->types;
322
    while (!IS_NULL_list(t)) {
323
	TYPE_P s = DEREF_ptr(HEAD_list(t));
324
	TYPE s0 = DEREF_type(s);
325
	if (IS_type_undef(s0)) {
326
	    char *nm = name_type(s);
327
	    error(ERROR_SERIOUS, "Type %s used but not defined", nm);
2 7u83 328
	} else {
7 7u83 329
	    int sz = size_type(s, 0);
330
	    COPY_int(type_size(s0), sz);
2 7u83 331
	}
7 7u83 332
	t = TAIL_list(t);
2 7u83 333
    }
7 7u83 334
    return;
2 7u83 335
}
336
 
337
 
338
/*
7 7u83 339
 * FIND LIST OF DERIVED TYPES
340
 *
341
 * This routine builds up a list of all the types used in the derivation
342
 * of t.
343
 */
2 7u83 344
 
7 7u83 345
static LIST(TYPE_P)
346
derived_types(TYPE_P t, LIST(TYPE_P)p)
2 7u83 347
{
7 7u83 348
    TYPE t0;
349
    unsigned tag;
350
    LIST(TYPE_P)q = p;
351
    while (!IS_NULL_list(q)) {
352
	TYPE_P s = DEREF_ptr(HEAD_list(q));
353
	if (EQ_ptr(s, t)) {
354
		return(p);
355
	}
356
	q = TAIL_list(q);
2 7u83 357
    }
7 7u83 358
    CONS_ptr(t, p, p);
359
    t0 = DEREF_type(t);
360
    tag = TAG_type(t0);
361
    switch (tag) {
2 7u83 362
 
7 7u83 363
	case type_ident_tag: {
2 7u83 364
	    /* Identity definition */
7 7u83 365
	    IDENTITY_P r = DEREF_ptr(type_ident_id(t0));
366
	    TYPE_P s = DEREF_ptr(ident_defn(r));
367
	    p = derived_types(s, p);
368
	    break;
2 7u83 369
	}
370
 
7 7u83 371
	case type_structure_tag: {
2 7u83 372
	    /* Structure components */
7 7u83 373
	    STRUCTURE_P r = DEREF_ptr(type_structure_struc(t0));
374
	    LIST(COMPONENT_P)c = DEREF_list(str_defn(r));
375
	    while (!IS_NULL_list(c)) {
376
		COMPONENT_P cmp = DEREF_ptr(HEAD_list(c));
377
		TYPE_P s = DEREF_ptr(cmp_type(cmp));
378
		p = derived_types(s, p);
379
		c = TAIL_list(c);
2 7u83 380
	    }
7 7u83 381
	    break;
2 7u83 382
	}
383
 
7 7u83 384
	case type_onion_tag: {
2 7u83 385
	    /* Union components, fields and maps */
7 7u83 386
	    UNION_P r = DEREF_ptr(type_onion_un(t0));
387
	    LIST(COMPONENT_P)c = DEREF_list(un_s_defn(r));
388
	    LIST(FIELD_P)f = DEREF_list(un_u_defn(r));
389
	    LIST(MAP_P)m = DEREF_list(un_map(r));
390
	    while (!IS_NULL_list(c)) {
391
		COMPONENT_P cmp = DEREF_ptr(HEAD_list(c));
392
		TYPE_P s = DEREF_ptr(cmp_type(cmp));
393
		p = derived_types(s, p);
394
		c = TAIL_list(c);
2 7u83 395
	    }
7 7u83 396
	    while (!IS_NULL_list(f)) {
397
		FIELD_P fld = DEREF_ptr(HEAD_list(f));
398
		c = DEREF_list(fld_defn(fld));
399
		while (!IS_NULL_list(c)) {
400
		    COMPONENT_P cmp = DEREF_ptr(HEAD_list(c));
401
		    TYPE_P s = DEREF_ptr(cmp_type(cmp));
402
		    p = derived_types(s, p);
403
		    c = TAIL_list(c);
2 7u83 404
		}
7 7u83 405
		f = TAIL_list(f);
2 7u83 406
	    }
7 7u83 407
	    while (!IS_NULL_list(m)) {
408
		MAP_P map = DEREF_ptr(HEAD_list(m));
409
		LIST(ARGUMENT_P)a = DEREF_list(map_args(map));
410
		TYPE_P s = DEREF_ptr(map_ret_type(map));
411
		p = derived_types(s, p);
412
		while (!IS_NULL_list(a)) {
413
		    ARGUMENT_P arg = DEREF_ptr(HEAD_list(a));
414
		    s = DEREF_ptr(arg_type(arg));
415
		    p = derived_types(s, p);
416
		    a = TAIL_list(a);
2 7u83 417
		}
7 7u83 418
		m = TAIL_list(m);
2 7u83 419
	    }
7 7u83 420
	    break;
2 7u83 421
	}
422
 
7 7u83 423
	case type_list_tag:
424
	case type_ptr_tag:
425
	case type_stack_tag:
426
	case type_vec_tag:
427
	case type_vec_ptr_tag: {
2 7u83 428
	    /* Pointer subtypes */
7 7u83 429
	    TYPE_P s = DEREF_ptr(type_ptr_etc_sub(t0));
430
	    p = derived_types(s, p);
431
	    break;
2 7u83 432
	}
433
    }
7 7u83 434
    return(p);
2 7u83 435
}
436
 
437
 
438
/*
7 7u83 439
 * IMPORT A LIST OF TYPES
440
 *
441
 * This routine imports all the types in the list t.
442
 */
2 7u83 443
 
7 7u83 444
static void
445
import_type_list(LIST(TYPE_P)t)
2 7u83 446
{
7 7u83 447
    while (!IS_NULL_list(t)) {
448
	TYPE_P s = DEREF_ptr(HEAD_list(t));
449
	TYPE s0 = DEREF_type(s);
450
	unsigned tag = TAG_type(s0);
451
	switch (tag) {
452
	    case type_primitive_tag: {
453
		PRIMITIVE_P p = DEREF_ptr(type_primitive_prim(s0));
454
		CONS_ptr(p, algebra->primitives, algebra->primitives);
455
		goto register_lab;
2 7u83 456
	    }
7 7u83 457
	    case type_ident_tag: {
458
		IDENTITY_P p = DEREF_ptr(type_ident_id(s0));
459
		CONS_ptr(p, algebra->identities, algebra->identities);
460
		goto register_lab;
2 7u83 461
	    }
7 7u83 462
	    case type_enumeration_tag: {
463
		ENUM_P p = DEREF_ptr(type_enumeration_en(s0));
464
		CONS_ptr(p, algebra->enumerations, algebra->enumerations);
465
		goto register_lab;
2 7u83 466
	    }
7 7u83 467
	    case type_structure_tag: {
468
		STRUCTURE_P p = DEREF_ptr(type_structure_struc(s0));
469
		CONS_ptr(p, algebra->structures, algebra->structures);
470
		goto register_lab;
2 7u83 471
	    }
7 7u83 472
	    case type_onion_tag: {
473
		UNION_P p = DEREF_ptr(type_onion_un(s0));
474
		CONS_ptr(p, algebra->unions, algebra->unions);
475
		goto register_lab;
2 7u83 476
	    }
477
	    register_lab : {
7 7u83 478
		TYPE_P r = register_type(s);
479
		if (!EQ_ptr(r, s)) {
480
		    error(ERROR_SERIOUS,
2 7u83 481
			    "Can't import previously used type %s",
7 7u83 482
			    name_type(s));
2 7u83 483
		}
7 7u83 484
		break;
2 7u83 485
	    }
486
	    default : {
7 7u83 487
		TYPE_P p = DEREF_ptr(type_ptr_etc_sub(s0));
488
		(void)compound_type(tag, p, 0);
489
		break;
2 7u83 490
	    }
491
	}
7 7u83 492
	t = TAIL_list(t);
2 7u83 493
    }
7 7u83 494
    return;
2 7u83 495
}
496
 
497
 
498
/*
7 7u83 499
 * IMPORT A SINGLE ITEM FROM AN ALGEBRA
500
 *
501
 * This routine imports the type named nm from the algebra alg into the
502
 * current algebra.
503
 */
2 7u83 504
 
7 7u83 505
void
506
import_type(char *alg, char *nm)
2 7u83 507
{
7 7u83 508
    TYPE_P t;
509
    LIST(TYPE_P)p;
510
    ALGEBRA_DEFN *a = find_algebra(alg);
511
    if (a == NULL) {
512
	error(ERROR_SERIOUS, "Algebra %s not defined", alg);
513
	return;
514
    } else if (a == algebra) {
515
	error(ERROR_SERIOUS, "Can't import from current algebra");
516
	return;
2 7u83 517
    }
7 7u83 518
    t = find_type(a, nm);
519
    if (IS_type_undef(DEREF_type(t))) {
520
	error(ERROR_SERIOUS, "Type %s::%s not defined", alg, nm);
521
	return;
2 7u83 522
    }
7 7u83 523
    p = derived_types(t, NULL_list(TYPE_P));
524
    import_type_list(p);
525
    while (!IS_NULL_list(p)) {
526
	DESTROY_CONS_ptr(destroy_calculus, t, p, p);
527
	UNUSED(t);
2 7u83 528
    }
7 7u83 529
    return;
2 7u83 530
}
531
 
532
 
533
/*
7 7u83 534
 * IMPORT AN ENTIRE ALGEBRA
535
 *
536
 * This routine imports all the types in the algebra alg into the current
537
 * algebra.
538
 */
2 7u83 539
 
7 7u83 540
void
541
import_algebra(char *alg)
2 7u83 542
{
7 7u83 543
    ALGEBRA_DEFN *a = find_algebra(alg);
544
    if (a == NULL) {
545
	error(ERROR_SERIOUS, "Algebra %s not defined", alg);
546
	return;
547
    } else if (a == algebra) {
548
	error(ERROR_SERIOUS, "Can't import from current algebra");
549
	return;
2 7u83 550
    }
7 7u83 551
    import_type_list(a->types);
552
    return;
2 7u83 553
}
554
 
555
 
556
/*
7 7u83 557
 * FIND THE SIZE OF A TYPE
558
 *
559
 * This routine calculates the size of the type t.
560
 */
2 7u83 561
 
7 7u83 562
int
563
size_type(TYPE_P t, int depth)
2 7u83 564
{
7 7u83 565
    TYPE t0 = DEREF_type(t);
566
    int sz = DEREF_int(type_size(t0));
567
    if (sz) {
568
	    return(sz);
569
    }
2 7u83 570
 
7 7u83 571
    if (depth > MAX_TYPE_DEPTH) {
572
	error(ERROR_SERIOUS, "Cyclic type definition involving %s",
573
	      name_type(t));
574
	return(1);
2 7u83 575
    }
576
 
7 7u83 577
    switch (TAG_type(t0)) {
578
	case type_ident_tag: {
579
	    IDENTITY_P i = DEREF_ptr(type_ident_id(t0));
580
	    TYPE_P_P s = ident_defn(i);
581
	    sz = size_type(DEREF_ptr(s), depth + 1);
582
	    break;
2 7u83 583
	}
584
 
7 7u83 585
	case type_structure_tag: {
586
	    STRUCTURE_P str = DEREF_ptr(type_structure_struc(t0));
587
	    LIST(COMPONENT_P)c = DEREF_list(str_defn(str));
588
	    sz = 0;
589
	    while (!IS_NULL_list(c)) {
590
		TYPE_P_P s;
591
		s = cmp_type(DEREF_ptr(HEAD_list(c)));
592
		sz += size_type(DEREF_ptr(s), depth + 1);
593
		c = TAIL_list(c);
2 7u83 594
	    }
7 7u83 595
	    break;
2 7u83 596
	}
597
 
7 7u83 598
	case type_primitive_tag: sz = SIZE_PRIM; break;
599
	case type_enumeration_tag: sz = SIZE_ENUM; break;
600
	case type_onion_tag: sz = SIZE_UNION; break;
601
	case type_ptr_tag: sz = SIZE_PTR; break;
602
	case type_list_tag: sz = SIZE_LIST; break;
603
	case type_stack_tag: sz = SIZE_STACK; break;
604
	case type_vec_tag: sz = SIZE_VEC; break;
605
	case type_vec_ptr_tag: sz = SIZE_VEC_PTR; break;
2 7u83 606
 
607
	default : {
7 7u83 608
	    error(ERROR_SERIOUS, "Can't take size of type %s", name_type(t));
609
	    sz = 1;
610
	    break;
2 7u83 611
	}
612
    }
7 7u83 613
    return(sz);
2 7u83 614
}
615
 
616
 
617
/*
7 7u83 618
 * FIND THE NAME OF A TYPE
619
 *
620
 * This routine finds the long name of the type t.
621
 */
2 7u83 622
 
7 7u83 623
char *
624
name_type(TYPE_P t)
2 7u83 625
{
7 7u83 626
    CLASS_ID_P id;
627
    TYPE t0 = DEREF_type(t);
628
    switch (TAG_type(t0))EXHAUSTIVE {
629
	case type_primitive_tag: {
630
	    PRIMITIVE_P a = DEREF_ptr(type_primitive_prim(t0));
631
	    id = DEREF_ptr(prim_id(a));
632
	    break;
2 7u83 633
	}
7 7u83 634
	case type_ident_tag: {
635
	    IDENTITY_P a = DEREF_ptr(type_ident_id(t0));
636
	    id = DEREF_ptr(ident_id(a));
637
	    break;
2 7u83 638
	}
7 7u83 639
	case type_enumeration_tag: {
640
	    ENUM_P a = DEREF_ptr(type_enumeration_en(t0));
641
	    id = DEREF_ptr(en_id(a));
642
	    break;
2 7u83 643
	}
7 7u83 644
	case type_structure_tag: {
645
	    STRUCTURE_P a = DEREF_ptr(type_structure_struc(t0));
646
	    id = DEREF_ptr(str_id(a));
647
	    break;
2 7u83 648
	}
7 7u83 649
	case type_onion_tag: {
650
	    UNION_P a = DEREF_ptr(type_onion_un(t0));
651
	    id = DEREF_ptr(un_id(a));
652
	    break;
2 7u83 653
	}
7 7u83 654
	case type_quote_tag: {
655
	    char *a = DEREF_string(type_quote_defn(t0));
656
	    return(a);
2 7u83 657
	}
7 7u83 658
	case type_ptr_tag: {
659
	    return("PTR");
2 7u83 660
	}
7 7u83 661
	case type_list_tag: {
662
	    return("LIST");
2 7u83 663
	}
7 7u83 664
	case type_stack_tag: {
665
	    return("STACK");
2 7u83 666
	}
7 7u83 667
	case type_vec_tag: {
668
	    return("VEC");
2 7u83 669
	}
7 7u83 670
	case type_vec_ptr_tag: {
671
	    return("VEC_PTR");
2 7u83 672
	}
7 7u83 673
	case type_undef_tag: {
674
	    char *a = DEREF_string(type_undef_name(t0));
675
	    return(a);
2 7u83 676
	}
677
    }
7 7u83 678
    last_id = id;
679
    return(DEREF_string(cid_name(id)));
2 7u83 680
}
681
 
682
 
683
/*
7 7u83 684
 * FIND THE AUXILIARY NAME OF A TYPE
685
 *
686
 * This routine finds the short name of the type t.
687
 */
2 7u83 688
 
7 7u83 689
char *
690
name_aux_type(TYPE_P t)
2 7u83 691
{
7 7u83 692
    CLASS_ID_P id;
693
    TYPE t0 = DEREF_type(t);
694
    switch (TAG_type(t0))EXHAUSTIVE {
695
	case type_primitive_tag: {
696
	    PRIMITIVE_P a = DEREF_ptr(type_primitive_prim(t0));
697
	    id = DEREF_ptr(prim_id(a));
698
	    break;
2 7u83 699
	}
7 7u83 700
	case type_ident_tag: {
701
	    IDENTITY_P a = DEREF_ptr(type_ident_id(t0));
702
	    return(name_aux_type(DEREF_ptr(ident_defn(a))));
2 7u83 703
	}
7 7u83 704
	case type_enumeration_tag: {
705
	    ENUM_P a = DEREF_ptr(type_enumeration_en(t0));
706
	    id = DEREF_ptr(en_id(a));
707
	    break;
2 7u83 708
	}
7 7u83 709
	case type_structure_tag: {
710
	    STRUCTURE_P a = DEREF_ptr(type_structure_struc(t0));
711
	    id = DEREF_ptr(str_id(a));
712
	    break;
2 7u83 713
	}
7 7u83 714
	case type_onion_tag: {
715
	    UNION_P a = DEREF_ptr(type_onion_un(t0));
716
	    id = DEREF_ptr(un_id(a));
717
	    break;
2 7u83 718
	}
7 7u83 719
	case type_quote_tag: {
720
	    char *a = DEREF_string(type_quote_defn(t0));
721
	    return(a);
2 7u83 722
	}
7 7u83 723
	case type_ptr_tag: {
724
	    return("ptr");
2 7u83 725
	}
7 7u83 726
	case type_list_tag: {
727
	    return("list");
2 7u83 728
	}
7 7u83 729
	case type_stack_tag: {
730
	    return("stack");
2 7u83 731
	}
7 7u83 732
	case type_vec_tag: {
733
	    return("vec");
2 7u83 734
	}
7 7u83 735
	case type_vec_ptr_tag: {
736
	    return("vec_ptr");
2 7u83 737
	}
7 7u83 738
	case type_undef_tag: {
739
	    char *a = DEREF_string(type_undef_name(t0));
740
	    return(a);
2 7u83 741
	}
742
    }
7 7u83 743
    last_id = id;
744
    return(DEREF_string(cid_name_aux(id)));
2 7u83 745
}
746
 
747
 
748
/*
7 7u83 749
 * CHECK FOR COMPLEX TYPES
750
 *
751
 * This routine checks whether a type is complex in the sense that it
752
 * requires the statement versions of COPY and DEREF rather than the
753
 * expression versions.
754
 */
2 7u83 755
 
7 7u83 756
int
757
is_complex_type(TYPE_P t)
2 7u83 758
{
7 7u83 759
    TYPE t0 = DEREF_type(t);
760
    switch (TAG_type(t0)) {
761
	case type_structure_tag:
762
	case type_vec_tag:
763
	case type_vec_ptr_tag: {
764
	    return(1);
2 7u83 765
	}
7 7u83 766
	case type_ident_tag: {
767
	    IDENTITY_P r = DEREF_ptr(type_ident_id(t0));
768
	    TYPE_P s = DEREF_ptr(ident_defn(r));
769
	    return(is_complex_type(s));
2 7u83 770
	}
771
    }
7 7u83 772
    return(0);
2 7u83 773
}