Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/algol60/src/tools/tnc/write.c – Rev 2

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | 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 <ctype.h>
33
#include "types.h"
34
#include "file.h"
35
#include "high.h"
36
#include "names.h"
37
#include "node.h"
38
#include "shape.h"
39
#include "table.h"
40
#include "tdf.h"
41
#include "utility.h"
42
#include "write.h"
43
 
44
 
45
/*
46
    FLAGS CONTROLLING OUTPUT OF TOKENS ETC
47
 
48
    The output is in the fully expanded form if verbose is true.  The
49
    shape of each expression is printed if print_shapes is true.  The
50
    flag func_output controls whether the output should be lisp-like
51
    (default) or c-like.
52
*/
53
 
54
boolean verbose = 0 ;
55
boolean print_shapes = 0 ;
56
boolean func_output = 0 ;
57
 
58
 
59
/*
60
    PRINT A NUMBER OF SPACES
61
 
62
    An indentation of d spaces is printed to the output file.
63
*/
64
 
65
void print_spaces
66
    PROTO_N ( ( d ) )
67
    PROTO_T ( int d )
68
{
69
    int n = 2 * d ;
70
    while ( n >= 8 ) {
71
	IGNORE fputc ( '\t', output ) ;
72
	n -= 8 ;
73
    }
74
    while ( n ) {
75
	IGNORE fputc ( ' ', output ) ;
76
	n-- ;
77
    }
78
    return ;
79
}
80
 
81
 
82
/*
83
    PRINT A NODE
84
 
85
    The node p is printed to the output file with an indentation of
86
    d spaces.
87
*/
88
 
89
static boolean print_node
90
    PROTO_N ( ( p, d ) )
91
    PROTO_T ( node *p X int d )
92
{
93
    boolean negate = 0 ;
94
    boolean newline = 0 ;
95
    while ( p ) {
96
	construct *q = p->cons ;
97
	sortname s = q->sortnum ;
98
	long m = q->encoding ;
99
	newline = 0 ;
100
	switch ( s ) {
101
 
102
	    case SORT_tdfbool : {
103
		/* Set neg for subsequent number */
104
		negate = ( boolean ) ( m ? 1 : 0 ) ;
105
		break ;
106
	    }
107
 
108
	    case SORT_bytestream : {
109
		/* Print a bytestream */
110
		newline = print_node ( p->son, d ) ;
111
		break ;
112
	    }
113
 
114
	    case SORT_completion : {
115
		/* Print a completion */
116
		newline = print_node ( p->son, d ) ;
117
		break ;
118
	    }
119
 
120
	    case SORT_small_tdfint : {
121
		/* Print a small number */
122
		long n = q->encoding ;
123
		print_spaces ( d ) ;
124
		if ( negate ) n = -n ;
125
		IGNORE fprintf ( output, "%ld", n ) ;
126
		negate = 0 ;
127
		newline = 1 ;
128
		break ;
129
	    }
130
 
131
	    case SORT_tdfint : {
132
		/* Print a number */
133
		char *num = q->name ;
134
		print_spaces ( d ) ;
135
		if ( fits_ulong ( num, 0 ) ) {
136
		    unsigned long n = octal_to_ulong ( num ) ;
137
		    if ( negate && n ) IGNORE fputc ( '-', output ) ;
138
		    IGNORE fprintf ( output, "%lu", n ) ;
139
		} else {
140
		    if ( negate ) IGNORE fputc ( '-', output ) ;
141
		    IGNORE fprintf ( output, "0%s", num ) ;
142
		}
143
		negate = 0 ;
144
		newline = 1 ;
145
		break ;
146
	    }
147
 
148
	    case SORT_option : {
149
		/* Print an optional argument */
150
		if ( p->son ) {
151
		    newline = print_node ( p->son, d ) ;
152
		} else {
153
		    print_spaces ( d ) ;
154
		    IGNORE fputc ( '-', output ) ;
155
		    newline = 1 ;
156
		}
157
		break ;
158
	    }
159
 
160
	    case SORT_repeat : {
161
		/* Print a repeated argument */
162
		if ( m == 0 ) {
163
		    print_spaces ( d ) ;
164
		    IGNORE fputc ( '|', output ) ;
165
		    newline = 1 ;
166
		} else {
167
		    newline = print_node ( p->son, d ) ;
168
		    if ( func_output ) IGNORE fputc ( ',', output ) ;
169
		    IGNORE fputs ( " |", output ) ;
170
		}
171
		break ;
172
	    }
173
 
174
	    case SORT_tdfstring : {
175
		/* Print a string */
176
		int i, n = ( int ) m ;
177
		print_spaces ( d ) ;
178
		if ( n == -1 ) {
179
		    char *f = ( func_output ? "%s (\n" : "( %s\n" ) ;
180
		    IGNORE fprintf ( output, f, MAKE_STRING ) ;
181
		    newline = print_node ( p->son, d + 1 ) ;
182
		    IGNORE fputs ( " )", output ) ;
183
		} else {
184
		    IGNORE fputc ( '"', output ) ;
185
		    for ( i = 0 ; i < n ; i++ ) {
186
			int c = ( ( q->name [i] ) & 0xff ) ;
187
			if ( isprint ( c ) ) {
188
			    if ( c == '\\' || c == '"' ) {
189
				IGNORE fputc ( '\\', output ) ;
190
			    }
191
			    IGNORE fputc ( c, output ) ;
192
			} else {
193
			    if ( c == '\n' ) {
194
				IGNORE fputs ( "\\n", output ) ;
195
			    } else if ( c == '\t' ) {
196
				IGNORE fputs ( "\\t", output ) ;
197
			    } else {
198
				unsigned co = ( unsigned ) c ;
199
				IGNORE fprintf ( output, "\\%03o", co ) ;
200
			    }
201
			}
202
		    }
203
		    IGNORE fputc ( '"', output ) ;
204
		    newline = 1 ;
205
		}
206
		break ;
207
	    }
208
 
209
	    case SORT_nat : {
210
		/* Print a nat */
211
		if ( m != ENC_make_nat ) goto default_label ;
212
		newline = print_node ( p->son, d ) ;
213
		break ;
214
	    }
215
 
216
	    case SORT_signed_nat : {
217
		/* Print a signed_nat */
218
		if ( m != ENC_make_signed_nat ) goto default_label ;
219
		newline = print_node ( p->son, d ) ;
220
		break ;
221
	    }
222
 
223
	    case SORT_string : {
224
		/* Print a string */
225
		if ( m != ENC_make_string ) goto default_label ;
226
		newline = print_node ( p->son, d ) ;
227
		break ;
228
	    }
229
 
230
	    case SORT_al_tag : {
231
		/* Print an alignment tag */
232
		if ( verbose || m != ENC_make_al_tag || p->son == null ) {
233
		    goto default_label ;
234
		}
235
		newline = print_node ( p->son, d ) ;
236
		break ;
237
	    }
238
 
239
	    case SORT_label : {
240
		/* Print a label */
241
		if ( verbose || m != ENC_make_label || p->son == null ) {
242
		    goto default_label ;
243
		}
244
		newline = print_node ( p->son, d ) ;
245
		break ;
246
	    }
247
 
248
	    case SORT_tag : {
249
		/* Print a tag */
250
		if ( verbose || m != ENC_make_tag || p->son == null ) {
251
		    goto default_label ;
252
		}
253
		newline = print_node ( p->son, d ) ;
254
		break ;
255
	    }
256
 
257
	    case SORT_exp : {
258
		static node special_node ;
259
		if ( print_shapes && p->shape != &special_node ) {
260
		    /* Change exp to show shape */
261
		    node *z = new_node () ;
262
		    z->cons = &exp_shape ;
263
		    z->bro = p->bro ;
264
		    z->son = p ;
265
		    if ( p->shape ) {
266
			z->son->bro = copy_node ( p->shape ) ;
267
		    } else {
268
			z->son->bro = new_node () ;
269
			z->son->bro->cons = &unknown_cons ;
270
		    }
271
		    p->shape = &special_node ;
272
		    p = z ;
273
		    q = p->cons ;
274
		    m = q->encoding ;
275
		}
276
		goto default_label ;
277
	    }
278
 
279
	    default : {
280
		/* Print a simple sort */
281
		default_label : {
282
		    if ( !verbose && m == sort_tokens [s] && p->son &&
283
			 p->son->cons->sortnum == SORT_token ) {
284
			newline = print_node ( p->son, d ) ;
285
		    } else {
286
			print_spaces ( d ) ;
287
			if ( p->son ) {
288
			    char *f = ( func_output ? "%s (\n" : "( %s\n" ) ;
289
			    IGNORE fprintf ( output, f, q->name ) ;
290
			    newline = print_node ( p->son, d + 1 ) ;
291
			    IGNORE fputs ( " )", output ) ;
292
			} else {
293
			    IGNORE fprintf ( output, "%s", q->name ) ;
294
			    newline = 1 ;
295
			}
296
		    }
297
		}
298
		break ;
299
	    }
300
	}
301
	p = p->bro ;
302
	if ( newline && p ) {
303
	    if ( func_output ) IGNORE fputc ( ',', output ) ;
304
	    IGNORE fputc ( '\n', output ) ;
305
	    newline = 0 ;
306
	}
307
    }
308
    return ( newline ) ;
309
}
310
 
311
 
312
/*
313
    PRINT AN EXTERNAL NAME
314
 
315
    The start of a statement with name title concerning the construct
316
    p is output.  dec is true if this is the first statement concerning p.
317
*/
318
 
319
static void print_name
320
    PROTO_N ( ( title, p, dec ) )
321
    PROTO_T ( char *title X construct *p X int dec )
322
{
323
    if ( !func_output ) IGNORE fputs ( "( ", output ) ;
324
    if ( p->ename == null ) IGNORE fprintf ( output, "%s ", LOCAL_DECL ) ;
325
    IGNORE fprintf ( output, "%s", title ) ;
326
    if ( func_output ) IGNORE fputs ( " (", output ) ;
327
    if ( p->ename && p->ename->cons->encoding && dec ) {
328
	char *f = ( func_output ? "\n  %s (\n" : "\n  ( %s\n" ) ;
329
	if ( p->ename->son->cons->sortnum == SORT_tdfstring ) {
330
	    if ( p->ename->son->bro == null ) {
331
		IGNORE fprintf ( output, f, MAKE_STRING_EXTERN ) ;
332
	    } else {
333
		IGNORE fprintf ( output, f, MAKE_CHAIN_EXTERN ) ;
334
	    }
335
	} else {
336
	    IGNORE fprintf ( output, f, MAKE_UNIQUE_EXTERN ) ;
337
	}
338
	IGNORE print_node ( p->ename->son, 2 ) ;
339
	if ( func_output ) {
340
	    IGNORE fputs ( " ),\n  ", output ) ;
341
	} else {
342
	    IGNORE fputs ( " )\n  ", output ) ;
343
	}
344
    } else {
345
	IGNORE fputc ( ' ', output ) ;
346
    }
347
    IGNORE fprintf ( output, "%s", p->name ) ;
348
    return ;
349
}
350
 
351
 
352
/*
353
    ALIGNMENT TAG DECLARATION AUXILIARY PRINTING ROUTINE
354
 
355
    Print the declaration of the alignment tag p.
356
*/
357
 
358
static void print_aldec
359
    PROTO_N ( ( p ) )
360
    PROTO_T ( construct *p )
361
{
362
    if ( p->encoding == -1 ) return ;
363
    print_name ( MAKE_ALDEC, p, 1 ) ;
364
    IGNORE fputs ( ( func_output ? " ) ;\n\n" : " )\n\n" ), output ) ;
365
    return ;
366
}
367
 
368
 
369
/*
370
    ALIGNMENT TAG DEFINITION AUXILIARY PRINTING ROUTINE
371
 
372
    Print the definition of the alignment tag p.
373
*/
374
 
375
static void print_aldef
376
    PROTO_N ( ( p ) )
377
    PROTO_T ( construct *p )
378
{
379
    al_tag_info *info = get_al_tag_info ( p ) ;
380
    if ( p->encoding == -1 ) return ;
381
    if ( info->def == null ) return ;
382
    print_name ( MAKE_ALDEF, p, !show_aldecs ) ;
383
    if ( func_output ) IGNORE fputc ( ',', output ) ;
384
    IGNORE fputc ( '\n', output ) ;
385
    IGNORE print_node ( info->def, 1 ) ;
386
    IGNORE fputs ( ( func_output ? " ) ;\n\n" : " )\n\n" ), output ) ;
387
    return ;
388
}
389
 
390
 
391
/*
392
    TAG DECLARATION AUXILIARY PRINTING ROUTINE
393
 
394
    Print the declaration of the tag p.
395
*/
396
 
397
static void print_tagdec
398
    PROTO_N ( ( p ) )
399
    PROTO_T ( construct *p )
400
{
401
    tag_info *info = get_tag_info ( p ) ;
402
    if ( p->encoding == -1 || info->dec == null ) return ;
403
    switch ( info->var ) {
404
	case 0 : print_name ( MAKE_ID_TAGDEC, p, 1 ) ; break ;
405
	case 1 : print_name ( MAKE_VAR_TAGDEC, p, 1 ) ; break ;
406
	case 2 : print_name ( COMMON_TAGDEC, p, 1 ) ; break ;
407
    }
408
    if ( func_output ) IGNORE fputc ( ',', output ) ;
409
    IGNORE fputc ( '\n', output ) ;
410
    IGNORE print_node ( info->dec, 1 ) ;
411
    IGNORE fputs ( ( func_output ? " ) ;\n\n" : " )\n\n" ), output ) ;
412
    return ;
413
}
414
 
415
 
416
/*
417
    TAG DEFINITION AUXILIARY PRINTING ROUTINE
418
 
419
    Print the definition of the tag p.
420
*/
421
 
422
static void print_tagdef
423
    PROTO_N ( ( p ) )
424
    PROTO_T ( construct *p )
425
{
426
    char *instr ;
427
    tag_info *info = get_tag_info ( p ) ;
428
    node *d = info->def ;
429
    if ( p->encoding == -1 || d == null ) return ;
430
    switch ( info->var ) EXHAUSTIVE {
431
	case 0 : instr = MAKE_ID_TAGDEF ; break ;
432
	case 1 : instr = MAKE_VAR_TAGDEF ; break ;
433
	case 2 : instr = COMMON_TAGDEF ; break ;
434
    }
435
    while ( d ) {
436
	/* Can have multiple definitions */
437
	print_name ( instr, p, !show_tagdecs ) ;
438
	if ( func_output ) IGNORE fputc ( ',', output ) ;
439
	IGNORE fputc ( '\n', output ) ;
440
	IGNORE print_node ( d->son, 1 ) ;
441
	IGNORE fputs ( ( func_output ? " ) ;\n\n" : " )\n\n" ), output ) ;
442
	d = d->bro ;
443
    }
444
    return ;
445
}
446
 
447
 
448
/*
449
    TOKEN DECLARATION AUXILIARY PRINTING ROUTINE
450
 
451
    Print the declaration of the token p.
452
*/
453
 
454
static void print_tokdec
455
    PROTO_N ( ( p ) )
456
    PROTO_T ( construct *p )
457
{
458
    tok_info *info = get_tok_info ( p ) ;
459
    if ( p->encoding == -1 ) return ;
460
    if ( !info->dec ) return ;
461
    print_name ( MAKE_TOKDEC, p, 1 ) ;
462
    if ( func_output ) IGNORE fputc ( ',', output ) ;
463
    IGNORE fputc ( '\n', output ) ;
464
    if ( info->sig ) {
465
	IGNORE print_node ( info->sig, 1 ) ;
466
    } else {
467
	print_spaces ( 1 ) ;
468
	IGNORE fputc ( '-', output ) ;
469
    }
470
    if ( func_output ) IGNORE fputc ( ',', output ) ;
471
    IGNORE fputs ( "\n  ", output ) ;
472
    if ( info->args ) {
473
	int n = 0 ;
474
	char *q = info->args ;
475
	IGNORE fputs ( "( ", output ) ;
476
	while ( *q ) {
477
	    sortname s ;
478
	    q = find_sortname ( q, &s ) ;
479
	    q++ ;
480
	    if ( n++ == 8 ) {
481
		IGNORE fputs ( "\n  ", output ) ;
482
		n = 1 ;
483
	    }
484
	    IGNORE fputs ( sort_name ( s ), output ) ;
485
	    if ( func_output && *q ) IGNORE fputc ( ',', output ) ;
486
	    IGNORE fputc ( ' ', output ) ;
487
	}
488
	IGNORE fputs ( ") ", output ) ;
489
	if ( func_output ) IGNORE fputs ( "-> ", output ) ;
490
    }
491
    IGNORE fputs ( sort_name ( info->res ), output ) ;
492
    IGNORE fputs ( ( func_output ? " ) ;\n\n" : " )\n\n" ), output ) ;
493
    return ;
494
}
495
 
496
 
497
/*
498
    TOKEN DEFINITION AUXILIARY PRINTING ROUTINE
499
 
500
    Print the definition of the token p.
501
*/
502
 
503
static void print_tokdef
504
    PROTO_N ( ( p ) )
505
    PROTO_T ( construct *p )
506
{
507
    tok_info *info = get_tok_info ( p ) ;
508
    if ( p->encoding == -1 ) return ;
509
    if ( !info->dec ) return ;
510
    if ( info->def == null ) return ;
511
    print_name ( MAKE_TOKDEF, p, !show_tagdefs ) ;
512
    if ( func_output ) IGNORE fputc ( ',', output ) ;
513
    IGNORE fputc ( '\n', output ) ;
514
    if ( info->sig ) {
515
	IGNORE print_node ( info->sig, 1 ) ;
516
    } else {
517
	print_spaces ( 1 ) ;
518
	IGNORE fputc ( '-', output ) ;
519
    }
520
    if ( func_output ) IGNORE fputc ( ',', output ) ;
521
    IGNORE fputs ( "\n  ", output ) ;
522
    if ( info->args ) {
523
	int n = 0 ;
524
	construct **q = info->pars ;
525
	IGNORE fputs ( "( ", output ) ;
526
	while ( *q ) {
527
	    tok_info *qinfo = get_tok_info ( *q ) ;
528
	    if ( n++ == 4 ) {
529
		IGNORE fputs ( "\n    ", output ) ;
530
		n = 1 ;
531
	    }
532
	    IGNORE fprintf ( output, "%s %s", sort_name ( qinfo->res ),
533
			     ( *q )->name ) ;
534
	    q++ ;
535
	    if ( func_output && *q ) IGNORE fputc ( ',', output ) ;
536
	    IGNORE fputc ( ' ', output ) ;
537
	}
538
	IGNORE fputs ( ") ", output ) ;
539
	if ( func_output ) IGNORE fputs ( "-> ", output ) ;
540
    }
541
    IGNORE fputs ( sort_name ( info->res ), output ) ;
542
    if ( func_output ) IGNORE fputc ( ',', output ) ;
543
    IGNORE fputc ( '\n', output ) ;
544
    IGNORE print_node ( info->def, 1 ) ;
545
    IGNORE fputs ( ( func_output ? " ) ;\n\n" : " )\n\n" ), output ) ;
546
    return ;
547
}
548
 
549
 
550
/*
551
    PRINT A HIGH-LEVEL SORT
552
 
553
    This routine prints the high level sort h.
554
*/
555
 
556
static void print_high_sort
557
    PROTO_N ( ( h ) )
558
    PROTO_T ( high_sort *h )
559
{
560
    int i, n ;
561
    if ( h->id == SORT_unknown ) return ;
562
    if ( func_output ) {
563
	IGNORE fprintf ( output, "%s ( %s, ", MAKE_SORT, h->name ) ;
564
    } else {
565
	IGNORE fprintf ( output, "( %s %s ", MAKE_SORT, h->name ) ;
566
    }
567
    n = h->no_args ;
568
    if ( n ) {
569
	int m = 0 ;
570
	IGNORE fputs ( "( ", output ) ;
571
	for ( i = 0 ; i < n ; i++ ) {
572
	    if ( m++ == 8 ) {
573
		IGNORE fputs ( "\n  ", output ) ;
574
		m = 1 ;
575
	    }
576
	    IGNORE fputs ( sort_name ( h->args [i] ), output ) ;
577
	    if ( func_output && i < n - 1 ) IGNORE fputc ( ',', output ) ;
578
	    IGNORE fputc ( ' ', output ) ;
579
	}
580
	IGNORE fputs ( ") ", output ) ;
581
	if ( func_output ) IGNORE fputs ( "-> ", output ) ;
582
    }
583
    IGNORE fputs ( sort_name ( h->res ), output ) ;
584
    IGNORE fputs ( ( func_output ? " ) ;\n\n" : " )\n\n" ), output ) ;
585
    return ;
586
}
587
 
588
 
589
/*
590
    MAIN PRINTING ROUTINE
591
 
592
    This routine prints an entire capsule to the output file.
593
*/
594
 
595
void print_capsule
596
    PROTO_Z ()
597
{
598
    if ( high_sorts ) {
599
	int i ;
600
	IGNORE fputs ( "# HIGH-LEVEL SORTS\n\n", output ) ;
601
	for ( i = 0 ; i < crt_high_sort ; i++ ) {
602
	    print_high_sort ( high_sorts + i ) ;
603
	}
604
	IGNORE fputc ( '\n', output ) ;
605
    }
606
    if ( show_tokdecs ) {
607
	IGNORE fputs ( "# TOKEN DECLARATIONS\n\n", output ) ;
608
	apply_to_all ( print_tokdec, SORT_token ) ;
609
	IGNORE fputc ( '\n', output ) ;
610
    }
611
    if ( show_aldecs ) {
612
	IGNORE fputs ( "# ALIGNMENT TAG DECLARATIONS\n\n", output ) ;
613
	apply_to_all ( print_aldec, SORT_al_tag ) ;
614
	IGNORE fputc ( '\n', output ) ;
615
    }
616
    if ( show_tagdecs ) {
617
	IGNORE fputs ( "# TAG DECLARATIONS\n\n", output ) ;
618
	apply_to_all ( print_tagdec, SORT_tag ) ;
619
	IGNORE fputc ( '\n', output ) ;
620
    }
621
    if ( show_tokdefs ) {
622
	IGNORE fputs ( "# TOKEN DEFINITIONS\n\n", output ) ;
623
	apply_to_all ( print_tokdef, SORT_token ) ;
624
	IGNORE fputc ( '\n', output ) ;
625
    }
626
    if ( show_aldefs ) {
627
	IGNORE fputs ( "# ALIGNMENT TAG DEFINITIONS\n\n", output ) ;
628
	apply_to_all ( print_aldef, SORT_al_tag ) ;
629
	IGNORE fputc ( '\n', output ) ;
630
    }
631
    if ( show_tagdefs ) {
632
	IGNORE fputs ( "# TAG DEFINITIONS\n\n", output ) ;
633
	apply_to_all ( print_tagdef, SORT_tag ) ;
634
	IGNORE fputc ( '\n', output ) ;
635
    }
636
    return ;
637
}