Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
6 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
6 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:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 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;
6 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;
6 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
/**** c-code.c --- SID C code ADT routines.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 **** Commentary:
66
 *
67
 * This file implements the C code ADT used to represent action definitions
68
 * for the C output language.
69
 *
70
 **** Change Log:
71
 * $Log: c-code.c,v $
72
 * Revision 1.1.1.1  1998/01/17  15:57:42  release
73
 * First version to be checked into rolling release.
74
 *
75
 * Revision 1.3  1996/03/01  09:53:12  smf
76
 * c-code.c, c-out-info.c, c-out-info.h, c-output.c:
77
 * 	- improved unreachable code analysis;
78
 * 	- improved some output formatting;
79
 * 	- added support for comment or macro to mark unreachable code.
80
 *
81
 * Revision 1.2  1994/12/15  09:56:23  smf
82
 * Brought into line with OSSG C Coding Standards Document, as per
83
 * "CR94_178.sid+tld-update".
84
 *
85
 * Revision 1.1.1.1  1994/07/25  16:04:17  smf
86
 * Initial import of SID 1.8 non shared files.
87
 *
88
**/
89
 
90
/****************************************************************************/
91
 
92
#include "c-code.h"
93
#include "c-out-key.h"
94
#include "c-output.h"
95
#include "gen-errors.h"
96
#include "name.h"
97
 
98
/*--------------------------------------------------------------------------*/
99
 
100
static void
6 7u83 101
c_code_set_labels(CCodeP code)
2 7u83 102
{
103
    CCodeItemP item;
104
 
105
    for (item = code->head; item; item = item->next) {
106
	if (item->type == CCT_LABEL) {
6 7u83 107
	    NameP name = entry_get_name(item->u.ident);
2 7u83 108
 
6 7u83 109
	    if (!name_has_label(name)) {
110
		name_set_label(name, c_out_next_label());
2 7u83 111
	    }
112
	}
113
    }
114
}
115
 
116
static void
6 7u83 117
c_code_reset_labels(CCodeP code)
2 7u83 118
{
119
    CCodeItemP item;
120
 
121
    for (item = code->head; item; item = item->next) {
122
	if (item->type == CCT_LABEL) {
6 7u83 123
	    NameP name = entry_get_name(item->u.ident);
2 7u83 124
 
6 7u83 125
	    name_reset_label(name);
2 7u83 126
	}
127
    }
128
}
129
 
130
static EntryP
6 7u83 131
c_code_get_translation(SaveRStackP state, TypeBTransP translator, EntryP ident,
132
		       EntryP *type_ref, BoolT *reference_ref,
133
		       EntryP *entry_ref)
2 7u83 134
{
6 7u83 135
    EntryP entry = btrans_get_translation(translator, ident);
2 7u83 136
    EntryP stack_entry;
137
 
6 7u83 138
    ASSERT(entry);
139
    stack_entry = rstack_get_translation(state, entry, type_ref,
140
					 reference_ref);
141
    if ((stack_entry == NIL(EntryP)) && (entry_is_non_local(entry))) {
2 7u83 142
	stack_entry    = entry;
6 7u83 143
	*type_ref      = entry_get_non_local(entry);
2 7u83 144
	*reference_ref = FALSE;
145
    }
6 7u83 146
    ASSERT(stack_entry);
2 7u83 147
    if (entry_ref) {
148
	*entry_ref = entry;
149
    }
6 7u83 150
    return(stack_entry);
2 7u83 151
}
152
 
153
/*--------------------------------------------------------------------------*/
154
 
155
CCodeP
6 7u83 156
c_code_create(CStringP file, unsigned line)
2 7u83 157
{
6 7u83 158
    CCodeP code = ALLOCATE(CCodeT);
2 7u83 159
 
6 7u83 160
    code->head = NIL(CCodeItemP);
2 7u83 161
    code->tail = &(code->head);
162
    code->file = file;
163
    code->line = line;
6 7u83 164
    types_init(&(code->param));
165
    types_init(&(code->result));
166
    return(code);
2 7u83 167
}
168
 
169
void
6 7u83 170
c_code_append_string(CCodeP code, NStringP string)
2 7u83 171
{
6 7u83 172
    CCodeItemP item = ALLOCATE(CCodeItemT);
2 7u83 173
 
6 7u83 174
    item->next    = NIL(CCodeItemP);
2 7u83 175
    item->type    = CCT_STRING;
6 7u83 176
    nstring_assign(&(item->u.string), string);
2 7u83 177
    *(code->tail) = item;
178
    code->tail    = &(item->next);
179
}
180
 
181
void
6 7u83 182
c_code_append_label(CCodeP code, NStringP string)
2 7u83 183
{
6 7u83 184
    CCodeItemP item = ALLOCATE(CCodeItemT);
2 7u83 185
 
6 7u83 186
    item->next    = NIL(CCodeItemP);
2 7u83 187
    item->type    = CCT_LABEL;
6 7u83 188
    nstring_assign(&(item->u.string), string);
2 7u83 189
    *(code->tail) = item;
190
    code->tail    = &(item->next);
191
}
192
 
193
void
6 7u83 194
c_code_append_identifier(CCodeP code, NStringP string)
2 7u83 195
{
6 7u83 196
    CCodeItemP item = ALLOCATE(CCodeItemT);
2 7u83 197
 
6 7u83 198
    item->next    = NIL(CCodeItemP);
2 7u83 199
    item->type    = CCT_IDENT;
6 7u83 200
    nstring_assign(&(item->u.string), string);
2 7u83 201
    *(code->tail) = item;
202
    code->tail    = &(item->next);
203
}
204
 
205
void
6 7u83 206
c_code_append_modifiable(CCodeP code, NStringP string)
2 7u83 207
{
6 7u83 208
    CCodeItemP item = ALLOCATE(CCodeItemT);
2 7u83 209
 
6 7u83 210
    item->next    = NIL(CCodeItemP);
2 7u83 211
    item->type    = CCT_MOD_IDENT;
6 7u83 212
    nstring_assign(&(item->u.string), string);
2 7u83 213
    *(code->tail) = item;
214
    code->tail    = &(item->next);
215
}
216
 
217
void
6 7u83 218
c_code_append_reference(CCodeP code, NStringP string)
2 7u83 219
{
6 7u83 220
    CCodeItemP item = ALLOCATE(CCodeItemT);
2 7u83 221
 
6 7u83 222
    item->next    = NIL(CCodeItemP);
2 7u83 223
    item->type    = CCT_REF_IDENT;
6 7u83 224
    nstring_assign(&(item->u.string), string);
2 7u83 225
    *(code->tail) = item;
226
    code->tail    = &(item->next);
227
}
228
 
229
void
6 7u83 230
c_code_append_exception(CCodeP code)
2 7u83 231
{
6 7u83 232
    CCodeItemP item = ALLOCATE(CCodeItemT);
2 7u83 233
 
6 7u83 234
    item->next    = NIL(CCodeItemP);
2 7u83 235
    item->type    = CCT_EXCEPTION;
236
    *(code->tail) = item;
237
    code->tail    = &(item->next);
238
}
239
 
240
void
6 7u83 241
c_code_append_advance(CCodeP code)
2 7u83 242
{
6 7u83 243
    CCodeItemP item = ALLOCATE(CCodeItemT);
2 7u83 244
 
6 7u83 245
    item->next    = NIL(CCodeItemP);
2 7u83 246
    item->type    = CCT_ADVANCE;
247
    *(code->tail) = item;
248
    code->tail    = &(item->next);
249
}
250
 
251
void
6 7u83 252
c_code_append_terminal(CCodeP code)
2 7u83 253
{
6 7u83 254
    CCodeItemP item = ALLOCATE(CCodeItemT);
2 7u83 255
 
6 7u83 256
    item->next    = NIL(CCodeItemP);
2 7u83 257
    item->type    = CCT_TERMINAL;
258
    *(code->tail) = item;
259
    code->tail    = &(item->next);
260
}
261
 
262
void
6 7u83 263
c_code_check(CCodeP code, BoolT exceptions, BoolT param_op, TypeTupleP param,
264
	     TypeTupleP result, TableP table)
2 7u83 265
{
266
    CCodeItemP item;
267
    EntryP     entry;
268
 
269
    for (item = code->head; item; item = item->next) {
6 7u83 270
	switch (item->type)EXHAUSTIVE {
2 7u83 271
	  case CCT_IDENT:
6 7u83 272
	    entry         = table_add_name(table, &(item->u.string));
2 7u83 273
	    item->u.ident = entry;
6 7u83 274
	    if (((param == NIL(TypeTupleP)) ||
275
		 (!types_contains(param, entry))) &&
276
		((result == NIL(TypeTupleP)) ||
277
		 (!types_contains(result, entry)))) {
278
		E_bad_id_substitution(c_code_file(code), c_code_line(code),
279
				      entry);
2 7u83 280
	    } else if (result) {
6 7u83 281
		name_used(entry_get_name(entry));
2 7u83 282
	    }
283
	    break;
284
	  case CCT_MOD_IDENT:
6 7u83 285
	    entry         = table_add_name(table, &(item->u.string));
2 7u83 286
	    item->u.ident = entry;
287
	    if (exceptions) {
6 7u83 288
		if ((param == NIL(TypeTupleP)) ||
289
		    (!types_mutated(param, entry))) {
290
		    E_bad_mod_id_substitution(c_code_file(code),
291
					      c_code_line(code), entry);
2 7u83 292
		}
293
	    } else {
6 7u83 294
		E_mod_id_in_assign(c_code_file(code), c_code_line(code),
295
				   entry);
2 7u83 296
	    }
297
	    break;
298
	  case CCT_REF_IDENT:
6 7u83 299
	    entry         = table_add_name(table, &(item->u.string));
2 7u83 300
	    item->u.ident = entry;
301
	    if (!param_op) {
6 7u83 302
		if ((param == NIL(TypeTupleP)) ||
303
		    (!types_contains(param, entry))) {
304
		    E_bad_ref_id_substitution(c_code_file(code),
305
					      c_code_line(code), entry);
2 7u83 306
		}
307
	    } else {
6 7u83 308
		E_ref_id_in_param_op(c_code_file(code), c_code_line(code),
309
				     entry);
2 7u83 310
	    }
311
	    break;
312
	  case CCT_LABEL:
6 7u83 313
	    entry         = table_add_name(table, &(item->u.string));
2 7u83 314
	    item->u.ident = entry;
6 7u83 315
	    if ((param == NIL(TypeTupleP)) && (result == NIL(TypeTupleP))) {
316
		E_bad_label_substitution(c_code_file(code),
317
					 c_code_line(code), entry);
2 7u83 318
	    }
319
	    break;
320
	  case CCT_EXCEPTION:
321
	    if (!exceptions) {
6 7u83 322
		E_bad_exception_substitution(c_code_file(code),
323
					     c_code_line(code));
2 7u83 324
	    }
325
	    break;
326
	  case CCT_ADVANCE:
327
	    if (!exceptions) {
6 7u83 328
		E_bad_advance_substitution(c_code_file(code),
329
					   c_code_line(code));
2 7u83 330
	    }
331
	    break;
332
	  case CCT_TERMINAL:
333
	    if (!exceptions) {
6 7u83 334
		E_bad_terminal_substitution(c_code_file(code),
335
					    c_code_line(code));
2 7u83 336
	    }
337
	    break;
338
	  case CCT_STRING:
339
	    break;
340
	}
341
    }
342
    if (result) {
6 7u83 343
	types_check_used(result, E_code_undefined_result, (GenericP)code);
2 7u83 344
	for (item = code->head; item; item = item->next) {
345
	    if (item->type == CCT_IDENT) {
6 7u83 346
		name_not_used(entry_get_name(item->u.ident));
2 7u83 347
	    }
348
	}
349
    }
350
    if (param) {
6 7u83 351
	types_assign(&(code->param), param);
2 7u83 352
    }
353
    if (result) {
6 7u83 354
	types_assign(&(code->result), result);
2 7u83 355
    }
356
}
357
 
358
#ifdef FS_FAST
359
#undef c_code_file
360
#endif /* defined (FS_FAST) */
361
CStringP
6 7u83 362
c_code_file(CCodeP code)
2 7u83 363
{
6 7u83 364
    return(code->file);
2 7u83 365
}
366
#ifdef FS_FAST
6 7u83 367
#define c_code_file(c)	((c)->file)
2 7u83 368
#endif /* defined(FS_FAST) */
369
 
370
#ifdef FS_FAST
371
#undef c_code_line
372
#endif /* defined (FS_FAST) */
373
unsigned
6 7u83 374
c_code_line(CCodeP code)
2 7u83 375
{
6 7u83 376
    return(code->line);
2 7u83 377
}
378
#ifdef FS_FAST
6 7u83 379
#define c_code_line(c)	((c)->line)
2 7u83 380
#endif /* defined(FS_FAST) */
381
 
382
TypeTupleP
6 7u83 383
c_code_param(CCodeP code)
2 7u83 384
{
6 7u83 385
    return(&(code->param));
2 7u83 386
}
387
 
388
TypeTupleP
6 7u83 389
c_code_result(CCodeP code)
2 7u83 390
{
6 7u83 391
    return(&(code->result));
2 7u83 392
}
393
 
394
void
6 7u83 395
c_code_deallocate(CCodeP code)
2 7u83 396
{
397
    CCodeItemP item = code->head;
398
 
399
    while (item) {
400
	CCodeItemP next = item->next;
401
 
6 7u83 402
	switch (item->type)EXHAUSTIVE {
2 7u83 403
	  case CCT_STRING:
6 7u83 404
	    nstring_destroy(&(item->u.string));
2 7u83 405
	    break;
406
	  case CCT_IDENT:
407
	  case CCT_MOD_IDENT:
408
	  case CCT_REF_IDENT:
409
	  case CCT_LABEL:
410
	  case CCT_EXCEPTION:
411
	  case CCT_TERMINAL:
412
	  case CCT_ADVANCE:
413
	    break;
414
	}
6 7u83 415
	DEALLOCATE(item);
2 7u83 416
	item = next;
417
    }
6 7u83 418
    types_destroy(&(code->param));
419
    types_destroy(&(code->result));
420
    DEALLOCATE(code);
2 7u83 421
}
422
 
423
void
6 7u83 424
c_output_c_code_action(COutputInfoP info, CCodeP code, TypeTupleP param,
425
		       TypeTupleP result, SaveRStackP state,
426
		       RuleP handler_rule)
2 7u83 427
{
6 7u83 428
    OStreamP    ostream      = c_out_info_ostream(info);
429
    NStringP    label_prefix = c_out_info_label_prefix(info);
430
    NStringP    in_prefix    = c_out_info_in_prefix(info);
2 7u83 431
    CCodeItemP  item;
432
    EntryP      stack_entry;
433
    EntryP      entry;
434
    EntryP      stack_type;
435
    BoolT       stack_reference;
436
    BoolT       use_cast;
437
    TypeBTransT translator;
438
 
6 7u83 439
    c_code_set_labels(code);
440
    btrans_init(&translator);
441
    btrans_add_translations(&translator, &(code->param), param);
442
    btrans_add_translations(&translator, &(code->result), result);
2 7u83 443
    for (item = code->head; item; item = item->next) {
6 7u83 444
	switch (item->type)EXHAUSTIVE {
2 7u83 445
	  case CCT_STRING:
6 7u83 446
	    write_nstring(ostream, &(item->u.string));
2 7u83 447
	    break;
448
	  case CCT_LABEL:
6 7u83 449
	    write_nstring(ostream, label_prefix);
450
	    write_unsigned(ostream,
451
			   name_get_label(entry_get_name(item->u.ident)));
2 7u83 452
	    break;
453
	  case CCT_IDENT:
6 7u83 454
	    stack_entry = c_code_get_translation(state, &translator,
455
						 item->u.ident, &stack_type,
456
						 &stack_reference, &entry);
457
	    use_cast = (types_contains(param, entry) &&
458
			c_out_info_get_casts(info));
2 7u83 459
	    if (use_cast) {
6 7u83 460
		write_cstring(ostream, "((");
461
		c_output_mapped_key(info, stack_type);
462
		write_cstring(ostream, ") (");
2 7u83 463
	    } else {
6 7u83 464
		write_char(ostream, '(');
2 7u83 465
	    }
466
	    if (stack_reference) {
6 7u83 467
		write_char(ostream, '*');
2 7u83 468
	    }
6 7u83 469
	    c_output_key(info, entry_key(stack_entry), in_prefix);
2 7u83 470
	    if (use_cast) {
6 7u83 471
		write_cstring(ostream, "))");
2 7u83 472
	    } else {
6 7u83 473
		write_char(ostream, ')');
2 7u83 474
	    }
475
	    break;
476
	  case CCT_MOD_IDENT:
6 7u83 477
	    stack_entry = c_code_get_translation(state, &translator,
478
						 item->u.ident, &stack_type,
479
						 &stack_reference,
480
						 NIL(EntryP *));
481
	    write_char(ostream, '(');
2 7u83 482
	    if (stack_reference) {
6 7u83 483
		write_char(ostream, '*');
2 7u83 484
	    }
6 7u83 485
	    c_output_key(info, entry_key(stack_entry), in_prefix);
486
	    write_char(ostream, ')');
2 7u83 487
	    break;
488
	  case CCT_REF_IDENT:
6 7u83 489
	    stack_entry = c_code_get_translation(state, &translator,
490
						 item->u.ident, &stack_type,
491
						 &stack_reference,
492
						 NIL(EntryP *));
493
	    write_char(ostream, '(');
2 7u83 494
	    if (!stack_reference) {
6 7u83 495
		write_char(ostream, '&');
2 7u83 496
	    }
6 7u83 497
	    c_output_key(info, entry_key(stack_entry), in_prefix);
498
	    write_char(ostream, ')');
2 7u83 499
	    break;
500
	  case CCT_EXCEPTION:
6 7u83 501
	    write_cstring(ostream, "goto ");
502
	    write_nstring(ostream, label_prefix);
503
	    write_unsigned(ostream, rule_get_handler_label(handler_rule));
2 7u83 504
	    break;
505
	  case CCT_ADVANCE:
6 7u83 506
	    write_cstring(ostream, "ADVANCE_LEXER");
2 7u83 507
	    break;
508
	  case CCT_TERMINAL:
6 7u83 509
	    write_cstring(ostream, "CURRENT_TERMINAL");
2 7u83 510
	    break;
511
	}
512
    }
6 7u83 513
    btrans_destroy(&translator);
514
    c_code_reset_labels(code);
2 7u83 515
}
516
 
517
void
6 7u83 518
c_output_c_code_basic(COutputInfoP info, CCodeP code, TypeTupleP result,
519
		      SaveRStackP state)
2 7u83 520
{
6 7u83 521
    OStreamP    ostream      = c_out_info_ostream(info);
522
    NStringP    label_prefix = c_out_info_label_prefix(info);
523
    NStringP    in_prefix    = c_out_info_in_prefix(info);
2 7u83 524
    CCodeItemP  item;
525
    EntryP      stack_entry;
526
    EntryP      stack_type;
527
    BoolT       stack_reference;
528
    TypeBTransT translator;
529
 
6 7u83 530
    c_code_set_labels(code);
531
    btrans_init(&translator);
532
    btrans_add_translations(&translator, &(code->result), result);
2 7u83 533
    for (item = code->head; item; item = item->next) {
6 7u83 534
	switch (item->type)EXHAUSTIVE {
2 7u83 535
	  case CCT_STRING:
6 7u83 536
	    write_nstring(ostream, &(item->u.string));
2 7u83 537
	    break;
538
	  case CCT_LABEL:
6 7u83 539
	    write_nstring(ostream, label_prefix);
540
	    write_unsigned(ostream,
541
			   name_get_label(entry_get_name(item->u.ident)));
2 7u83 542
	    break;
543
	  case CCT_IDENT:
6 7u83 544
	    stack_entry = c_code_get_translation(state, &translator,
545
						 item->u.ident, &stack_type,
546
						 &stack_reference,
547
						 NIL(EntryP *));
548
	    c_output_key(info, entry_key(stack_entry), in_prefix);
2 7u83 549
	    break;
550
	  case CCT_MOD_IDENT:
551
	  case CCT_REF_IDENT:
552
	  case CCT_EXCEPTION:
553
	  case CCT_ADVANCE:
554
	  case CCT_TERMINAL:
555
	    UNREACHED;
556
	}
557
    }
6 7u83 558
    btrans_destroy(&translator);
559
    c_code_reset_labels(code);
2 7u83 560
}
561
 
562
void
6 7u83 563
c_output_c_code_assign(COutputInfoP info, CCodeP code, EntryP type,
564
		       EntryP from, EntryP to, BoolT from_reference,
565
		       BoolT to_reference)
2 7u83 566
{
6 7u83 567
    OStreamP   ostream      = c_out_info_ostream(info);
568
    NStringP   label_prefix = c_out_info_label_prefix(info);
569
    NStringP   in_prefix    = c_out_info_in_prefix(info);
2 7u83 570
    BoolT      is_param;
571
    BoolT      use_cast;
572
    CCodeItemP item;
573
 
6 7u83 574
    c_code_set_labels(code);
2 7u83 575
    for (item = code->head; item; item = item->next) {
6 7u83 576
	switch (item->type)EXHAUSTIVE {
2 7u83 577
	  case CCT_STRING:
6 7u83 578
	    write_nstring(ostream, &(item->u.string));
2 7u83 579
	    break;
580
	  case CCT_LABEL:
6 7u83 581
	    write_nstring(ostream, label_prefix);
582
	    write_unsigned(ostream,
583
			   name_get_label(entry_get_name(item->u.ident)));
2 7u83 584
	    break;
585
	  case CCT_IDENT:
6 7u83 586
	    is_param = types_contains(&(code->param), item->u.ident);
587
	    use_cast = (is_param && c_out_info_get_casts(info));
2 7u83 588
	    if (use_cast) {
6 7u83 589
		write_cstring(ostream, "((");
590
		c_output_mapped_key(info, type);
591
		write_cstring(ostream, ") (");
2 7u83 592
	    } else {
6 7u83 593
		write_char(ostream, '(');
2 7u83 594
	    }
595
	    if (is_param) {
596
		if (from_reference) {
6 7u83 597
		    write_char(ostream, '*');
2 7u83 598
		}
6 7u83 599
		c_output_key(info, entry_key(from), in_prefix);
2 7u83 600
	    } else {
601
		if (to_reference) {
6 7u83 602
		    write_char(ostream, '*');
2 7u83 603
		}
6 7u83 604
		c_output_key(info, entry_key(to), in_prefix);
2 7u83 605
	    }
606
	    if (use_cast) {
6 7u83 607
		write_cstring(ostream, "))");
2 7u83 608
	    } else {
6 7u83 609
		write_char(ostream, ')');
2 7u83 610
	    }
611
	    break;
612
	  case CCT_REF_IDENT:
6 7u83 613
	    write_char(ostream, '(');
2 7u83 614
	    if (!from_reference) {
6 7u83 615
		write_char(ostream, '&');
2 7u83 616
	    }
6 7u83 617
	    c_output_key(info, entry_key(from), in_prefix);
618
	    write_char(ostream, ')');
2 7u83 619
	    break;
620
	  case CCT_MOD_IDENT:
621
	  case CCT_EXCEPTION:
622
	  case CCT_ADVANCE:
623
	  case CCT_TERMINAL:
624
	    UNREACHED;
625
	}
626
    }
6 7u83 627
    c_code_reset_labels(code);
2 7u83 628
}
629
 
630
void
6 7u83 631
c_output_c_code_param_assign(COutputInfoP info, CCodeP code, EntryP type,
632
			     EntryP entry)
2 7u83 633
{
6 7u83 634
    OStreamP   ostream      = c_out_info_ostream(info);
635
    NStringP   label_prefix = c_out_info_label_prefix(info);
636
    NStringP   in_prefix    = c_out_info_in_prefix(info);
637
    NStringP   out_prefix   = c_out_info_out_prefix(info);
2 7u83 638
    CCodeItemP item;
639
 
6 7u83 640
    c_code_set_labels(code);
2 7u83 641
    for (item = code->head; item; item = item->next) {
6 7u83 642
	switch (item->type)EXHAUSTIVE {
2 7u83 643
	  case CCT_STRING:
6 7u83 644
	    write_nstring(ostream, &(item->u.string));
2 7u83 645
	    break;
646
	  case CCT_LABEL:
6 7u83 647
	    write_nstring(ostream, label_prefix);
648
	    write_unsigned(ostream,
649
			   name_get_label(entry_get_name(item->u.ident)));
2 7u83 650
	    break;
651
	  case CCT_IDENT:
6 7u83 652
	    if (types_contains(&(code->param), item->u.ident)) {
653
		BoolT use_cast = c_out_info_get_casts(info);
2 7u83 654
 
655
		if (use_cast) {
6 7u83 656
		    write_cstring(ostream, "((");
657
		    c_output_mapped_key(info, type);
658
		    write_cstring(ostream, " *) (");
2 7u83 659
		}
6 7u83 660
		c_output_key(info, entry_key(entry), out_prefix);
2 7u83 661
		if (use_cast) {
6 7u83 662
		    write_cstring(ostream, "))");
2 7u83 663
		}
664
	    } else {
6 7u83 665
		c_output_key(info, entry_key(entry), in_prefix);
2 7u83 666
	    }
667
	    break;
668
	  case CCT_MOD_IDENT:
669
	  case CCT_REF_IDENT:
670
	  case CCT_EXCEPTION:
671
	  case CCT_ADVANCE:
672
	  case CCT_TERMINAL:
673
	    UNREACHED;
674
	}
675
    }
6 7u83 676
    c_code_reset_labels(code);
2 7u83 677
}
678
 
679
void
6 7u83 680
c_output_c_code_result_assign(COutputInfoP info, CCodeP code, EntryP type,
681
			      EntryP entry)
2 7u83 682
{
6 7u83 683
    OStreamP   ostream      = c_out_info_ostream(info);
684
    NStringP   label_prefix = c_out_info_label_prefix(info);
685
    NStringP   in_prefix    = c_out_info_in_prefix(info);
686
    NStringP   out_prefix   = c_out_info_out_prefix(info);
2 7u83 687
    CCodeItemP item;
688
 
6 7u83 689
    c_code_set_labels(code);
2 7u83 690
    for (item = code->head; item; item = item->next) {
6 7u83 691
	switch (item->type)EXHAUSTIVE {
2 7u83 692
	  case CCT_STRING:
6 7u83 693
	    write_nstring(ostream, &(item->u.string));
2 7u83 694
	    break;
695
	  case CCT_LABEL:
6 7u83 696
	    write_nstring(ostream, label_prefix);
697
	    write_unsigned(ostream,
698
			   name_get_label(entry_get_name(item->u.ident)));
2 7u83 699
	    break;
700
	  case CCT_IDENT:
6 7u83 701
	    if (types_contains(&(code->param), item->u.ident)) {
702
		BoolT use_cast = c_out_info_get_casts(info);
2 7u83 703
 
704
		if (use_cast) {
6 7u83 705
		    write_cstring(ostream, "((");
706
		    c_output_mapped_key(info, type);
707
		    write_cstring(ostream, ") (");
2 7u83 708
		}
6 7u83 709
		c_output_key(info, entry_key(entry), in_prefix);
2 7u83 710
		if (use_cast) {
6 7u83 711
		    write_cstring(ostream, "))");
2 7u83 712
		}
713
	    } else {
6 7u83 714
		c_output_key(info, entry_key(entry), out_prefix);
2 7u83 715
	    }
716
	    break;
717
	  case CCT_REF_IDENT:
6 7u83 718
	    write_cstring(ostream, "(&");
719
	    c_output_key(info, entry_key(entry), in_prefix);
720
	    write_char(ostream, ')');
2 7u83 721
	    break;
722
	  case CCT_MOD_IDENT:
723
	  case CCT_EXCEPTION:
724
	  case CCT_ADVANCE:
725
	  case CCT_TERMINAL:
726
	    UNREACHED;
727
	}
728
    }
6 7u83 729
    c_code_reset_labels(code);
2 7u83 730
}
731
 
732
void
6 7u83 733
c_output_c_code(COutputInfoP info, CCodeP code)
2 7u83 734
{
6 7u83 735
    OStreamP   ostream = c_out_info_ostream(info);
2 7u83 736
    CCodeItemP item;
737
 
738
    for (item = code->head; item; item = item->next) {
6 7u83 739
	switch (item->type)EXHAUSTIVE {
2 7u83 740
	  case CCT_STRING:
6 7u83 741
	    write_nstring(ostream, &(item->u.string));
2 7u83 742
	    break;
743
	  case CCT_LABEL:
744
	  case CCT_IDENT:
745
	  case CCT_MOD_IDENT:
746
	  case CCT_REF_IDENT:
747
	  case CCT_EXCEPTION:
748
	  case CCT_ADVANCE:
749
	  case CCT_TERMINAL:
750
	    UNREACHED;
751
	}
752
    }
753
}
754
 
755
/*
756
 * Local variables(smf):
757
 * eval: (include::add-path-entry "../os-interface" "../library")
758
 * eval: (include::add-path-entry "../transforms" "../output" "../generated")
759
 * end:
760
**/