Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "calculus.h"
33
#include "code.h"
34
#include "common.h"
35
#include "output.h"
36
#include "print.h"
37
#include "suffix.h"
38
#include "type_ops.h"
39
 
40
 
41
/*
42
    PRINT A PRIMITIVE PRINTING ROUTINE
43
 
44
    This routine prints the body of the printing routine for the current
45
    primitive.
46
*/
47
 
48
static void printer_prim
49
    PROTO_Z ()
50
{
51
    output ( "    print_indent ( f_, d_ ) ;\n" ) ;
52
    output ( "    ( void ) fprintf ( f_, \"%%s = \", nm_ ) ;\n" ) ;
53
    output ( "    OUTPUT_%PM ( f_, x_ ) ;\n" ) ;
54
    output ( "    ( void ) fprintf ( f_, \" ;\\n\" ) ;\n" ) ;
55
    return ;
56
}
57
 
58
 
59
/*
60
    PRINT AN ENUMERATION PRINTING ROUTINE
61
 
62
    This routine prints the body of the printing routine for the current
63
    enumeration.
64
*/
65
 
66
static void printer_enum
67
    PROTO_Z ()
68
{
69
    output ( "    print_indent ( f_, d_ ) ;\n" ) ;
70
    output ( "    ( void ) fprintf ( f_, \"%%s = \", nm_ ) ;\n" ) ;
71
    output ( "    switch ( x_ ) {\n" ) ;
72
    LOOP_ENUM_CONST {
73
	output ( "\tcase %EM_%ES : {\n" ) ;
74
	output ( "\t    ( void ) fprintf ( f_, \"%ES ;\\n\" ) ;\n" ) ;
75
	output ( "\t    break ;\n" ) ;
76
	output ( "\t}\n" ) ;
77
    }
78
    output ( "\tdefault : {\n" ) ;
79
    output ( "\t    ( void ) fprintf ( f_, \"%%lu ;\\n\"," ) ;
80
    output ( " ( unsigned long ) x_ ) ;\n" ) ;
81
    output ( "\t    break ;\n" ) ;
82
    output ( "\t}\n" ) ;
83
    output ( "    }\n" ) ;
84
    return ;
85
}
86
 
87
 
88
/*
89
    PRINT A STRUCTURE PRINTING ROUTINE
90
 
91
    This routine prints the body of the printing routine for the current
92
    structure.
93
*/
94
 
95
static void printer_struct
96
    PROTO_Z ()
97
{
98
    output ( "    print_indent ( f_, d_ ) ;\n" ) ;
99
    output ( "    ( void ) fprintf ( f_, \"%%s = {\\n\", nm_ ) ;\n" ) ;
100
    LOOP_STRUCTURE_COMPONENT {
101
	TYPE_P t = DEREF_ptr ( cmp_type ( CRT_COMPONENT ) ) ;
102
	output ( "    PRINT_%TI ( f_, x_.%CN, \"%CN\", d_ + 1 ) ;\n", t ) ;
103
    }
104
    output ( "    print_indent ( f_, d_ ) ;\n" ) ;
105
    output ( "    ( void ) fprintf ( f_, \"}\\n\" ) ;\n" ) ;
106
    return ;
107
}
108
 
109
 
110
/*
111
    PRINT A UNION COMPONENT PRINTING ROUTINE
112
 
113
    This routine prints the code for printing a component of a union.
114
    The argument d gives the token for accessing the component.
115
*/
116
 
117
static void printer_component
118
    PROTO_N ( ( d ) )
119
    PROTO_T ( char *d )
120
{
121
    TYPE_P t = DEREF_ptr ( cmp_type ( CRT_COMPONENT ) ) ;
122
    output ( "\t\t{\n" ) ;
123
    output ( "\t\t    %TT z_ ;\n", t ) ;
124
    output ( "\t\t    " ) ;
125
    print_deref ( t, d, "z_" ) ;
126
    output ( "\t\t    PRINT_%TI ( f_, z_, \"%CN\", d_ + 1 ) ;\n", t ) ;
127
    output ( "\t\t}\n" ) ;
128
    return ;
129
}
130
 
131
 
132
/*
133
    PRINT A UNION PRINTING ROUTINE
134
 
135
    This routine prints the body of the printing routine for the current
136
    primitive.
137
*/
138
 
139
static void printer_union
140
    PROTO_Z ()
141
{
142
    output ( "    print_indent ( f_, d_ ) ;\n" ) ;
143
    output ( "    if ( IS_NULL_%UM ( x_ ) ) {\n" ) ;
144
    output ( "\t( void ) fprintf ( f_, \"%%s = NULL_%UM ;\\n\", nm_ ) ;\n" ) ;
145
    output ( "    } else {\n" ) ;
146
    output ( "\tswitch ( TAG_%UM ( x_ ) ) {\n" ) ;
147
    LOOP_UNION_FIELD {
148
	int al = DEREF_int ( fld_flag ( CRT_FIELD ) ) ;
149
	output ( "\t    case %UM_%FN_tag : {\n" ) ;
150
	if ( al ) {
151
	    output ( "\t\tunsigned alias_ = GET_ALIAS_%UM_%FN ( x_ ) ;\n" ) ;
152
	    output ( "\t\tif ( alias_ ) {\n" ) ;
153
	    output ( "\t\t    ( void ) fprintf ( f_, \"%%s = " ) ;
154
	    output ( "[%%u] ;\\n\", nm_, alias_ ) ;\n" ) ;
155
	    output ( "\t\t    break ;\n" ) ;
156
	    output ( "\t\t}\n" ) ;
157
	    output ( "\t\talias_ = ++crt_%X_alias ;\n" ) ;
158
	    output ( "\t\tSET_ALIAS_%UM_%FN ( x_, alias_ ) ;\n" ) ;
159
	    output ( "\t\t( void ) fprintf ( f_, \"%%s = [%%u] = {\\n\", " ) ;
160
	    output ( "nm_, alias_ ) ;\n" ) ;
161
	} else {
162
	    output ( "\t\t( void ) fprintf ( f_, \"%%s = {\\n\", nm_ ) ;\n" ) ;
163
	}
164
	output ( "\t\tprint_indent ( f_, d_ + 1 ) ;\n" ) ;
165
	output ( "\t\t( void ) fprintf ( f_, \"(tag) = %FN ;\\n\" ) ;\n" ) ;
166
	LOOP_UNION_COMPONENT printer_component ( "%UM_%CN ( x_ )" ) ;
167
	LOOP_FIELD_COMPONENT printer_component ( "%UM_%FN_%CN ( x_ )" ) ;
168
	output ( "\t\tprint_indent ( f_, d_ ) ;\n" ) ;
169
	output ( "\t\t( void ) fprintf ( f_, \"}\\n\" ) ;\n" ) ;
170
	output ( "\t\tbreak ;\n" ) ;
171
	output ( "\t    }\n" ) ;
172
    }
173
    output ( "\t    default : {\n" ) ;
174
    output ( "\t\t( void ) fprintf ( f_, \"%%s = ERROR!\\n\", nm_ ) ;\n" ) ;
175
    output ( "\t\tbreak ;\n" ) ;
176
    output ( "\t    }\n" ) ;
177
    output ( "\t}\n" ) ;
178
    output ( "    }\n" ) ;
179
    return ;
180
}
181
 
182
 
183
/*
184
    PRINT A POINTER PRINTING ROUTINE
185
 
186
    This routine prints the body of the printing routine for a pointer
187
    to s.
188
*/
189
 
190
static void printer_ptr
191
    PROTO_N ( ( s, ptr, nm, i ) )
192
    PROTO_T ( TYPE_P s X char *ptr X char *nm X char *i )
193
{
194
    output ( "%s    print_indent ( f_, d_ ) ;\n", i ) ;
195
    output ( "%s    if ( IS_NULL_ptr ( %s ) ) {\n", i, nm ) ;
196
    output ( "%s\t( void ) fprintf ( f_, ", i ) ;
197
    output ( "\"%%s = NULL_ptr ;\\n\", nm_ ) ;\n" ) ;
198
    output ( "%s    } else if ( d_ < print_ptr_depth ) {\n", i ) ;
199
    output ( "%s\t%TT z_ ;\n", i, s ) ;
200
    output ( "%s\t", i ) ;
201
    print_deref ( s, nm, "z_" ) ;
202
    output ( "%s\t( void ) fprintf ( f_, ", i ) ;
203
    output ( "\"%%s = %s {\\n\", nm_ ) ;\n", ptr ) ;
204
    output ( "%s\tPRINT_%TI ( f_, z_, \"(%TI)\", d_ + 1 ) ;\n", i, s, s ) ;
205
    output ( "%s\tprint_indent ( f_, d_ ) ;\n", i ) ;
206
    output ( "%s\t( void ) fprintf ( f_, \"}\\n\" ) ;\n", i ) ;
207
    output ( "%s    } else {\n", i ) ;
208
    output ( "%s\t( void ) fprintf ( f_, \"%%s = ", i ) ;
209
    output ( "0x%%p ;\\n\", nm_, VOIDSTAR_ptr ( %s ) ) ;\n", nm ) ;
210
    output ( "%s    }\n", i ) ;
211
    return ;
212
}
213
 
214
 
215
/*
216
    PRINT A LIST PRINTING ROUTINE
217
 
218
    This routine prints the body of the printing routine for a list
219
    of s named nm.
220
*/
221
 
222
static void printer_list
223
    PROTO_N ( ( s, nm ) )
224
    PROTO_T ( TYPE_P s X char *nm )
225
{
226
    output ( "    print_indent ( f_, d_ ) ;\n" ) ;
227
    output ( "    ( void ) fprintf ( f_, \"%%s = LIST {\\n\", nm_ ) ;\n" ) ;
228
    output ( "    while ( !IS_NULL_list ( %s ) ) {\n", nm ) ;
229
    output ( "\t%TT z_ ;\n", s ) ;
230
    output ( "\tUN_CONS_%TM ( z_, %s, %s ) ;\n", s, nm, nm ) ;
231
    output ( "\tPRINT_%TI ( f_, z_, \"(%TI)\", d_ + 1 ) ;\n", s, s ) ;
232
    output ( "\tif ( !print_list_expand && !IS_NULL_list ( %s ) ) {\n", nm ) ;
233
    output ( "\t    print_indent ( f_, d_ + 1 ) ;\n" ) ;
234
    output ( "\t    ( void ) fprintf ( f_, \"(tail) = " ) ;
235
    output ( "0x%%p ;\\n\", VOIDSTAR_list ( %s ) ) ;\n", nm ) ;
236
    output ( "\t    break ;\n" ) ;
237
    output ( "\t}\n" ) ;
238
    output ( "    }\n" ) ;
239
    output ( "    print_indent ( f_, d_ ) ;\n" ) ;
240
    output ( "    ( void ) fprintf ( f_, \"}\\n\" ) ;\n" ) ;
241
    return ;
242
}
243
 
244
 
245
/*
246
    PRINT A VECTOR PRINTING ROUTINE
247
 
248
    This routine prints the body of the printing routine for a vector
249
    of s.
250
*/
251
 
252
static void printer_vec
253
    PROTO_N ( ( s ) )
254
    PROTO_T ( TYPE_P s )
255
{
256
    output ( "    print_indent ( f_, d_ ) ;\n" ) ;
257
    output ( "    {\n" ) ;
258
    output ( "\t%X_dim n = DIM_vec ( x_ ) ;\n" ) ;
259
    output ( "\tPTR ( %TT ) y_ = PTR_vec_ptr ( VEC_PTR_vec ( x_ ) ) ;\n", s ) ;
260
    output ( "\t( void ) fprintf ( f_, \"%%s = {\\n\", nm_ ) ;\n" ) ;
261
    output ( "\twhile ( n-- ) {\n" ) ;
262
    printer_ptr ( s, "VEC", "y_", "\t" ) ;
263
    output ( "\t    y_ = STEP_ptr ( y_, SIZE_%TM ) ;\n", s ) ;
264
    output ( "\t}\n" ) ;
265
    output ( "\tprint_indent ( f_, d_ ) ;\n" ) ;
266
    output ( "\t( void ) fprintf ( f_, \"}\\n\" ) ;\n" ) ;
267
    output ( "    }\n" ) ;
268
    return ;
269
}
270
 
271
 
272
/*
273
    PRINT A VECTOR POINTER PRINTING ROUTINE
274
 
275
    This routine prints the body of the printing routine for a vector
276
    pointer to s.
277
*/
278
 
279
static void printer_vec_ptr
280
    PROTO_N ( ( s ) )
281
    PROTO_T ( TYPE_P s )
282
{
283
    output ( "    PTR ( %TT ) y_ = PTR_vec_ptr ( x_ ) ;\n", s ) ;
284
    printer_ptr ( s, "VEC_PTR", "y_", "" ) ;
285
    return ;
286
}
287
 
288
 
289
/*
290
    PRINT ALL PRINTING ROUTINES
291
 
292
    This routine prints all the printing routines.
293
*/
294
 
295
void print_action
296
    PROTO_N ( ( dir ) )
297
    PROTO_T ( char *dir )
298
{
299
    open_file ( dir, PRINT_PREFIX, DEF_SUFFIX ) ;
300
    print_include () ;
301
 
302
    comment ( "Printing function declarations" ) ;
303
    LOOP_TYPE {
304
	TYPE_P t = CRT_TYPE ;
305
	if ( is_identity_type ( t ) ) {
306
	    output ( "#ifndef PRINT_%TI\n", t ) ;
307
	    output ( "#define PRINT_%TI( A, B, C, D ) ", t ) ;
308
	    output ( "PRINT_%TJ ( ( A ), ( B ), ( C ), ( D ) )\n", t ) ;
309
	    output ( "#endif\n\n" ) ;
310
	} else {
311
	    output ( "#ifndef PRINT_%TI\n", t ) ;
312
	    output ( "static void PRINT_%TI ", t ) ;
313
	    output ( "PROTO_S ( ( FILE *, %TT, char *, int ) ) ;\n", t ) ;
314
	    output ( "#endif\n\n" ) ;
315
	}
316
    }
317
    output ( "\n\n" ) ;
318
 
319
    comment ( "Printing variables" ) ;
320
    output ( "static int print_indent_step = 4 ;\n" ) ;
321
    output ( "static int print_ptr_depth = 1 ;\n" ) ;
322
    output ( "static int print_list_expand = 0 ;\n\n\n" ) ;
323
 
324
    comment ( "Printing indentation routine" ) ;
325
    output ( "static void print_indent\n" ) ;
326
    output ( "    PROTO_N ( ( f, d ) )\n" ) ;
327
    output ( "    PROTO_T ( FILE *f X int d )\n" ) ;
328
    output ( "{\n" ) ;
329
    output ( "    int i = print_indent_step * d ;\n" ) ;
330
    output ( "    while ( i-- ) ( void ) fputc ( ' ', f ) ;\n" ) ;
331
    output ( "    return ;\n" ) ;
332
    output ( "}\n\n\n" ) ;
333
 
334
    /* Function definitions */
335
    LOOP_TYPE {
336
	TYPE_P t = CRT_TYPE ;
337
	TYPE t0 = DEREF_type ( t ) ;
338
	unsigned tag = TAG_type ( t0 ) ;
339
	if ( !is_identity_type ( t ) ) {
340
	    /* Function header */
341
	    int is_struct = 0 ;
342
	    output ( "/* Printing routines for %TT */\n\n", t ) ;
343
	    output ( "#ifndef PRINT_%TI\n\n", t ) ;
344
	    output ( "static void PRINT_%TI\n", t ) ;
345
	    output ( "    PROTO_N ( ( f_, x_, nm_, d_ ) )\n" ) ;
346
	    output ( "    PROTO_T ( FILE *f_ X %TT x_ X", t ) ;
347
	    output ( " char *nm_ X int d_ )\n" ) ;
348
	    output ( "{\n" ) ;
349
 
350
	    /* Function body */
351
	    switch ( tag ) {
352
		case type_primitive_tag : {
353
		    PRIMITIVE_P p = DEREF_ptr ( type_primitive_prim ( t0 ) ) ;
354
		    LOOP_PRIMITIVE {
355
			if ( EQ_ptr ( CRT_PRIMITIVE, p ) ) {
356
			    printer_prim () ;
357
			    break ;
358
			}
359
		    }
360
		    break ;
361
		}
362
		case type_enumeration_tag : {
363
		    ENUM_P p = DEREF_ptr ( type_enumeration_en ( t0 ) ) ;
364
		    LOOP_ENUM {
365
			if ( EQ_ptr ( CRT_ENUM, p ) ) {
366
			    printer_enum () ;
367
			    break ;
368
			}
369
		    }
370
		    break ;
371
		}
372
		case type_structure_tag : {
373
		    STRUCTURE_P p = DEREF_ptr ( type_structure_struc ( t0 ) ) ;
374
		    LOOP_STRUCTURE {
375
			if ( EQ_ptr ( CRT_STRUCTURE, p ) ) {
376
			    printer_struct () ;
377
			    break ;
378
			}
379
		    }
380
		    is_struct = 1 ;
381
		    break ;
382
		}
383
		case type_onion_tag : {
384
		    UNION_P p = DEREF_ptr ( type_onion_un ( t0 ) ) ;
385
		    LOOP_UNION {
386
			if ( EQ_ptr ( CRT_UNION, p ) ) {
387
			    printer_union () ;
388
			    break ;
389
			}
390
		    }
391
		    break ;
392
		}
393
		case type_ptr_tag : {
394
		    TYPE_P s = DEREF_ptr ( type_ptr_sub ( t0 ) ) ;
395
		    printer_ptr ( s, "PTR", "x_", "" ) ;
396
		    break ;
397
		}
398
		case type_list_tag : {
399
		    TYPE_P s = DEREF_ptr ( type_list_sub ( t0 ) ) ;
400
		    printer_list ( s, "x_" ) ;
401
		    break ;
402
		}
403
		case type_stack_tag : {
404
		    TYPE_P s = DEREF_ptr ( type_stack_sub ( t0 ) ) ;
405
		    output ( "    LIST ( %TT ) y_ = LIST_stack ( x_ ) ;\n", s ) ;
406
		    printer_list ( s, "y_" ) ;
407
		    break ;
408
		}
409
		case type_vec_tag : {
410
		    TYPE_P s = DEREF_ptr ( type_vec_sub ( t0 ) ) ;
411
		    printer_vec ( s ) ;
412
		    is_struct = 1 ;
413
		    break ;
414
		}
415
		case type_vec_ptr_tag : {
416
		    TYPE_P s = DEREF_ptr ( type_vec_ptr_sub ( t0 ) ) ;
417
		    printer_vec_ptr ( s ) ;
418
		    is_struct = 1 ;
419
		    break ;
420
		}
421
	    }
422
 
423
	    /* Function trailer */
424
	    output ( "    return ;\n" ) ;
425
	    output ( "}\n\n" ) ;
426
 
427
	    /* Debugging routine */
428
	    if ( extra_asserts ) {
429
		char *star = ( is_struct ? "*" : "" ) ;
430
		output ( "#ifdef DEBUG\n\n" ) ;
431
		output ( "void DEBUG_%TI\n", t ) ;
432
		output ( "    PROTO_N ( ( x_ ) )\n" ) ;
433
		output ( "    PROTO_T ( %TT %sx_ )\n", t, star ) ;
434
		output ( "{\n    " ) ;
435
		if ( is_struct ) output ( "if ( x_ ) " ) ;
436
		output ( "PRINT_%TI ( stdout, %sx_, ", t, star ) ;
437
		output ( "\"%TI\", 0 ) ;\n", t ) ;
438
		output ( "    return ;\n" ) ;
439
		output ( "}\n\n" ) ;
440
		output ( "#endif\n\n" ) ;
441
	    }
442
	    output ( "#endif\n\n\n" ) ;
443
	}
444
    }
445
 
446
    close_file () ;
447
    return ;
448
}