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
/*
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 "types.h"
33
#include "eval.h"
34
#include "node.h"
35
#include "shape.h"
36
#include "table.h"
37
#include "tdf.h"
38
#include "utility.h"
39
 
40
 
41
/*
42
    CREATE A NAT CORRESPONDING TO THE VALUE n
43
 
44
    This routine creates a node corresponding to the nat with value n.
45
*/
46
 
47
node *make_nat
48
    PROTO_N ( ( n ) )
49
    PROTO_T ( long n )
50
{
51
    node *p = new_node () ;
52
    p->cons = cons_no ( SORT_nat, ENC_make_nat ) ;
53
    p->son = new_node () ;
54
    p->son->cons = make_construct ( SORT_small_tdfint ) ;
55
    p->son->cons->encoding = n ;
56
    return ( p ) ;
57
}
58
 
59
 
60
/*
61
    CREATE AN INTEGER CORRESPONDING TO THE VALUE n
62
 
63
    This routine creates a node corresponding to the sign bit and the
64
    value of n.
65
*/
66
 
67
node *make_int
68
    PROTO_N ( ( n ) )
69
    PROTO_T ( long n )
70
{
71
    node *p = new_node () ;
72
    if ( n < 0 ) {
73
	p->cons = &true_cons ;
74
	n = -n ;
75
    } else {
76
	p->cons = &false_cons ;
77
    }
78
    p->bro = new_node () ;
79
    p->bro->cons = make_construct ( SORT_small_tdfint ) ;
80
    p->bro->cons->encoding = n ;
81
    return ( p ) ;
82
}
83
 
84
 
85
/*
86
    CREATE A SIGNED_NAT CORRESPONDING TO THE VALUE n
87
 
88
    This routine creates a node corresponding to the signed_nat with value n.
89
*/
90
 
91
static node *make_signed_nat
92
    PROTO_N ( ( n ) )
93
    PROTO_T ( long n )
94
{
95
    node *p = new_node () ;
96
    p->cons = cons_no ( SORT_signed_nat, ENC_make_signed_nat ) ;
97
    p->son = make_int ( n ) ;
98
    return ( p ) ;
99
}
100
 
101
 
102
/*
103
    CREATE A MAKE_INT EXPRESSION CORRESPONDING TO THE VALUE n
104
 
105
    This routine creates a node corresponding to a make_int expression of
106
    shape sh and value n or val.
107
*/
108
 
109
static node *make_int_exp
110
    PROTO_N ( ( sh, n, val ) )
111
    PROTO_T ( node *sh X long n X char *val )
112
{
113
    node *p = new_node () ;
114
    p->cons = cons_no ( SORT_exp, ENC_make_int ) ;
115
    p->son = copy_node ( sh->son ) ;
116
    p->son->bro = make_signed_nat ( n ) ;
117
    if ( val ) {
118
	/* Assign large values */
119
	node *r = p->son->bro->son->bro ;
120
	r->cons = make_construct ( SORT_tdfint ) ;
121
	r->cons->name = val ;
122
    }
123
    p->shape = sh ;
124
    return ( p ) ;
125
}
126
 
127
 
128
/*
129
    IS A NODE A CONSTANT?
130
 
131
    This routine checks whether the node p represents a small integer
132
    constant.  If so it returns the value of the constant via pn.
133
*/
134
 
135
static boolean is_constant
136
    PROTO_N ( ( p, pn ) )
137
    PROTO_T ( node *p X long *pn )
138
{
139
    if ( p ) {
140
	sortname s = p->cons->sortnum ;
141
	long n = p->cons->encoding ;
142
	if ( s == SORT_exp && n == ENC_make_int ) {
143
	    p = p->son->bro ;
144
	    s = p->cons->sortnum ;
145
	    n = p->cons->encoding ;
146
	}
147
	if ( s == SORT_signed_nat && n == ENC_make_signed_nat ) {
148
	    /* Allow signed integer literals */
149
	    long negate = p->son->cons->encoding ;
150
	    p = p->son->bro ;
151
	    s = p->cons->sortnum ;
152
	    n = p->cons->encoding ;
153
	    if ( negate ) n = -n ;
154
	} else if ( s == SORT_nat && n == ENC_make_nat ) {
155
	    /* Allow integer literals */
156
	    p = p->son ;
157
	    s = p->cons->sortnum ;
158
	    n = p->cons->encoding ;
159
	} else if ( s == SORT_bool ) {
160
	    /* Allow boolean literals */
161
	    if ( n == ENC_false ) {
162
		*pn = 0 ;
163
		return ( 1 ) ;
164
	    }
165
	    if ( n == ENC_true ) {
166
		*pn = 1 ;
167
		return ( 1 ) ;
168
	    }
169
	}
170
	if ( s == SORT_small_tdfint ) {
171
	    /* Small constant found */
172
	    *pn = n ;
173
	    return ( 1 ) ;
174
	}
175
    }
176
    return ( 0 ) ;
177
}
178
 
179
 
180
/*
181
    INTEGER TYPE MASKS
182
 
183
    These values give the maximum values for the various known integral
184
    types.
185
*/
186
 
187
static long var_max = 32 ;
188
static unsigned long *var_mask ;
189
 
190
 
191
/*
192
    IS A SHAPE A KNOWN INTEGRAL TYPE?
193
 
194
    This routine checks whether the shape sh represents a known integral
195
    type.  If so it returns the sign via pn and the size via pm.
196
*/
197
 
198
static boolean is_var_width
199
    PROTO_N ( ( sh, pn, pm ) )
200
    PROTO_T ( node *sh X long *pn X long *pm )
201
{
202
    if ( sh && sh->cons->encoding == ENC_integer ) {
203
	if ( sh->son->cons->encoding == ENC_var_width ) {
204
	    node *q = sh->son->son ;
205
	    if ( is_constant ( q, pn ) ) {
206
		if ( is_constant ( q->bro, pm ) ) {
207
		    return ( 1 ) ;
208
		}
209
	    }
210
	}
211
    }
212
    return ( 0 ) ;
213
}
214
 
215
 
216
/*
217
    CALCULATE 1 << n
218
 
219
    This routine calculates '1 << n' as a string of octal digits.
220
*/
221
 
222
static char *shift_one
223
    PROTO_N ( ( n ) )
224
    PROTO_T ( long n )
225
{
226
    long i ;
227
    char buff [100] ;
228
    switch ( n % 3 ) {
229
	case 0 : buff [0] = '1' ; break ;
230
	case 1 : buff [0] = '2' ; break ;
231
	case 2 : buff [0] = '4' ; break ;
232
    }
233
    for ( i = 0 ; i < n / 3 ; i++ ) {
234
	buff [ i + 1 ] = '0' ;
235
    }
236
    return ( string_copy ( buff, ( int ) ( i + 1 ) ) ) ;
237
}
238
 
239
 
240
/*
241
    CALCULATE val - 1
242
 
243
    This routine calculates 'val - 1' for the string of octal digits val,
244
    returning the result as a string of octal digits.
245
*/
246
 
247
static char *minus_one
248
    PROTO_N ( ( val ) )
249
    PROTO_T ( char *val )
250
{
251
    int i, n = ( int ) strlen ( val ) ;
252
    char *res = string_copy ( val, n ) ;
253
    for ( i = n - 1 ; i >= 0 ; i-- ) {
254
	char c = res [i] ;
255
	if ( c != '0' ) {
256
	    res [i] = c - 1 ;
257
	    break ;
258
	}
259
	res [i] = '7' ;
260
    }
261
    if ( res [0] == '0' ) res++ ;
262
    return ( res ) ;
263
}
264
 
265
 
266
/*
267
    EVALUATE A CONSTANT EXPRESSION
268
 
269
    This routine evaluates the constant expression given by the operation
270
    op applied to the operands a and b in the type indicated by the shape
271
    sh.  err gives the associated overflow error treatment, if any.  The
272
    routine returns null if the value cannot be calculated.
273
*/
274
 
275
static node *eval_exp
276
    PROTO_N ( ( op, err, sh, a, b ) )
277
    PROTO_T ( long op X long err X node *sh X long a X long b )
278
{
279
    long c = 0 ;
280
    long sz = 0 ;
281
    long sgn = 0 ;
282
    char *val = null ;
283
 
284
    /* Check result shape */
285
    if ( !is_var_width ( sh, &sgn, &sz ) ) return ( null ) ;
286
    if ( !sgn && ( a < 0 || b < 0 ) ) return ( null ) ;
287
    if ( sz < 1 ) return ( null ) ;
288
    if ( sz > var_max ) {
289
	if ( sz < 256 ) {
290
	    /* Evaluate some special cases */
291
	    if ( op == ENC_shift_left && a == 1 ) {
292
		if ( !sgn && b < sz ) val = shift_one ( b ) ;
293
	    } else if ( op == ENC_negate && a == 1 ) {
294
		if ( !sgn && err == ENC_wrap ) {
295
		    val = shift_one ( sz ) ;
296
		    val = minus_one ( val ) ;
297
		}
298
	    } else if ( op == ENC_minus && a == 0 && b == 1 ) {
299
		if ( !sgn && err == ENC_wrap ) {
300
		    val = shift_one ( sz ) ;
301
		    val = minus_one ( val ) ;
302
		}
303
	    }
304
	    if ( val ) return ( make_int_exp ( sh, c, val ) ) ;
305
	}
306
	return ( null ) ;
307
    }
308
 
309
    /* Evaluate result */
310
    switch ( op ) {
311
	case ENC_abs : {
312
	    c = a ;
313
	    if ( c < 0 ) c = -a ;
314
	    break ;
315
	}
316
	case ENC_and : {
317
	    if ( a < 0 || b < 0 ) return ( null ) ;
318
	    c = ( a & b ) ;
319
	    break ;
320
	}
321
	case ENC_change_variety : {
322
	    c = a ;
323
	    break ;
324
	}
325
	case ENC_div0 :
326
	case ENC_div1 :
327
	case ENC_div2 : {
328
	    if ( a < 0 || b <= 0 ) return ( null ) ;
329
	    c = a / b ;
330
	    break ;
331
	}
332
	case ENC_maximum : {
333
	    c = ( a >= b ? a : b ) ;
334
	    break ;
335
	}
336
	case ENC_minimum : {
337
	    c = ( a < b ? a : b ) ;
338
	    break ;
339
	}
340
	case ENC_minus : {
341
	    c = a - b ;
342
	    break ;
343
	}
344
	case ENC_mult : {
345
	    c = a * b ;
346
	    break ;
347
	}
348
	case ENC_negate : {
349
	    c = -a ;
350
	    break ;
351
	}
352
	case ENC_not : {
353
	    if ( sgn || err != ENC_wrap ) return ( null ) ;
354
	    c = ~a ;
355
	    break ;
356
	}
357
	case ENC_or : {
358
	    if ( a < 0 || b < 0 ) return ( null ) ;
359
	    c = ( a | b ) ;
360
	    break ;
361
	}
362
	case ENC_plus : {
363
	    c = a + b ;
364
	    break ;
365
	}
366
	case ENC_rem0 :
367
	case ENC_rem1 :
368
	case ENC_rem2 : {
369
	    if ( a < 0 || b <= 0 ) return ( null ) ;
370
	    c = a % b ;
371
	    break ;
372
	}
373
	case ENC_shift_left : {
374
	    if ( sgn || err != ENC_wrap ) return ( null ) ;
375
	    if ( b < var_max ) {
376
		unsigned long ua = ( unsigned long ) a ;
377
		unsigned long ub = ( unsigned long ) b ;
378
		c = ( long ) ( ua << ub ) ;
379
	    } else {
380
		c = 0 ;
381
	    }
382
	    break ;
383
	}
384
	case ENC_shift_right : {
385
	    if ( sgn || err != ENC_wrap ) return ( null ) ;
386
	    if ( b < var_max ) {
387
		unsigned long ua = ( unsigned long ) a ;
388
		unsigned long ub = ( unsigned long ) b ;
389
		c = ( long ) ( ua >> ub ) ;
390
	    } else {
391
		c = 0 ;
392
	    }
393
	    break ;
394
	}
395
	case ENC_xor : {
396
	    if ( a < 0 || b < 0 ) return ( null ) ;
397
	    c = ( a ^ b ) ;
398
	    break ;
399
	}
400
	case ENC_power :
401
	case ENC_rotate_left :
402
	case ENC_rotate_right :
403
	default : {
404
	    /* NOT YET IMPLEMENTED */
405
	    return ( null ) ;
406
	}
407
    }
408
 
409
    /* Check for overflow */
410
    if ( sgn ) {
411
	long v = ( long ) var_mask [ sz - 1 ] ;
412
	if ( c < -( v + 1 ) || c > v ) return ( null ) ;
413
    } else {
414
	unsigned long uc ;
415
	unsigned long uv = var_mask [ sz ] ;
416
	if ( c < 0 ) {
417
	    if ( err != ENC_wrap ) return ( null ) ;
418
	    uc = ( unsigned long ) -c ;
419
	    uc = ( ( uv - uc + 1 ) & uv ) ;
420
	    if ( uc > var_mask [ var_max - 1 ] ) {
421
		val = ulong_to_octal ( uc ) ;
422
		uc = 0 ;
423
	    }
424
	} else {
425
	    uc = ( unsigned long ) c ;
426
	    if ( uc > uv ) {
427
		if ( err != ENC_wrap ) return ( null ) ;
428
		uc &= uv ;
429
	    }
430
	}
431
	c = ( long ) uc ;
432
    }
433
 
434
    /* Create the result */
435
    return ( make_int_exp ( sh, c, val ) ) ;
436
}
437
 
438
 
439
/*
440
    EVALUATE A CONSTANT CONDITION
441
 
442
    This routine evaluates the condition tst for the values a and b.  It
443
    returns 0 if the test is false, 1 if it is true and -1 if it cannot
444
    be evaluated.
445
*/
446
 
447
static int eval_test
448
    PROTO_N ( ( tst, a, b ) )
449
    PROTO_T ( long tst X long a X long b )
450
{
451
    int res = 0 ;
452
    switch ( tst ) {
453
	case ENC_equal :
454
	case ENC_not_less_than_and_not_great : {
455
	    if ( a == b ) res = 1 ;
456
	    break ;
457
	}
458
	case ENC_not_equal :
459
	case ENC_less_than_or_greater_than : {
460
	    if ( a != b ) res = 1 ;
461
	    break ;
462
	}
463
	case ENC_greater_than :
464
	case ENC_not_less_than_or_equal : {
465
	    if ( a > b ) res = 1 ;
466
	    break ;
467
	}
468
	case ENC_greater_than_or_equal :
469
	case ENC_not_less_than : {
470
	    if ( a >= b ) res = 1 ;
471
	    break ;
472
	}
473
	case ENC_less_than :
474
	case ENC_not_greater_than_or_equal : {
475
	    if ( a < b ) res = 1 ;
476
	    break ;
477
	}
478
	case ENC_less_than_or_equal :
479
	case ENC_not_greater_than : {
480
	    if ( a <= b ) res = 1 ;
481
	    break ;
482
	}
483
	default : {
484
	    res = -1 ;
485
	    break ;
486
	}
487
    }
488
    return ( res ) ;
489
}
490
 
491
 
492
/*
493
    EVALUATE A DECREMENT EXPRESSION
494
 
495
    This routine evaluates 'p - 1' for the expression node p.  It returns
496
    null if the value cannot be evaluated.
497
*/
498
 
499
static node *eval_decr
500
    PROTO_N ( ( p ) )
501
    PROTO_T ( node *p )
502
{
503
    if ( p->cons->encoding == ENC_make_int ) {
504
	node *sh = p->shape ;
505
	if ( sh == null ) sh = sh_integer ( p->son ) ;
506
	p = p->son->bro ;
507
	if ( p->cons->encoding == ENC_make_signed_nat ) {
508
	    if ( !p->son->cons->encoding ) {
509
		p = p->son->bro ;
510
		if ( p->cons->sortnum == SORT_tdfint ) {
511
		    long c = 0 ;
512
		    char *val = minus_one ( p->cons->name ) ;
513
		    if ( fits_ulong ( val, 1 ) ) {
514
			c = ( long ) octal_to_ulong ( val ) ;
515
			val = null ;
516
		    }
517
		    return ( make_int_exp ( sh, c, val ) ) ;
518
		}
519
	    }
520
	}
521
    }
522
    return ( null ) ;
523
}
524
 
525
 
526
/*
527
    EVALUATE A NODE
528
 
529
    This routine evaluates the node p.  p will not be null.
530
*/
531
 
532
static node *eval_node
533
    PROTO_N ( ( p ) )
534
    PROTO_T ( node *p )
535
{
536
    sortname s = p->cons->sortnum ;
537
    long n = p->cons->encoding ;
538
    if ( s > 0 && n == sort_conds [s] ) {
539
	/* Conditional constructs */
540
	long m = 0 ;
541
	if ( is_constant ( p->son, &m ) ) {
542
	    p = p->son->bro ;
543
	    if ( m == 0 ) p = p->bro ;
544
	    return ( p->son ) ;
545
	}
546
    }
547
    if ( s == SORT_exp ) {
548
	long m1 = 0, m2 = 0 ;
549
	switch ( n ) {
550
	    case ENC_make_int : {
551
		/* Make sure that constants have a shape */
552
		if ( p->shape == null ) p->shape = sh_integer ( p->son ) ;
553
		break ;
554
	    }
555
	    case ENC_change_variety : {
556
		/* Allow for change_variety */
557
		node *r = p->son->bro ;
558
		if ( p->shape == null ) p->shape = sh_integer ( r ) ;
559
		if ( is_constant ( r->bro, &m1 ) ) {
560
		    long err = p->son->cons->encoding ;
561
		    node *q = eval_exp ( n, err, p->shape, m1, m2 ) ;
562
		    if ( q ) p = q ;
563
		}
564
		break ;
565
	    }
566
	    case ENC_integer_test : {
567
		/* Allow for integer_test */
568
		node *r = p->son->bro->bro->bro ;
569
		if ( is_constant ( r, &m1 ) ) {
570
		    if ( is_constant ( r->bro, &m2 ) ) {
571
			long tst = p->son->bro->cons->encoding ;
572
			int res = eval_test ( tst, m1, m2 ) ;
573
			if ( res == 0 ) {
574
			    node *q = new_node () ;
575
			    q->cons = cons_no ( SORT_exp, ENC_goto ) ;
576
			    q->son = copy_node ( p->son->bro->bro ) ;
577
			    return ( q ) ;
578
			}
579
			if ( res == 1 ) {
580
			    node *q = new_node () ;
581
			    q->cons = cons_no ( SORT_exp, ENC_make_top ) ;
582
			    return ( q ) ;
583
			}
584
		    }
585
		}
586
		break ;
587
	    }
588
	    case ENC_conditional : {
589
		/* Allow for conditional */
590
		node *r = p->son->bro ;
591
		if ( is_constant ( r->bro, &m2 ) ) {
592
		    if ( is_constant ( r, &m1 ) ) {
593
			/* First branch terminates */
594
			return ( copy_node ( r ) ) ;
595
		    }
596
		    if ( r->cons->encoding == ENC_goto ) {
597
			if ( eq_node ( p->son, r->son ) ) {
598
			    /* First branch is a jump */
599
			    return ( copy_node ( r->bro ) ) ;
600
			}
601
		    }
602
		}
603
		break ;
604
	    }
605
	    case ENC_sequence : {
606
		/* Allow for sequence */
607
		boolean reached = 1 ;
608
		node *q = null ;
609
		node *r = p->son->son ;
610
		while ( r != null ) {
611
		    if ( is_constant ( r, &m1 ) ) {
612
			if ( reached ) q = r ;
613
		    } else if ( r->cons->encoding == ENC_goto ) {
614
			if ( reached ) q = r ;
615
			reached = 0 ;
616
		    } else if ( r->cons->encoding == ENC_make_top ) {
617
			if ( reached ) q = r ;
618
		    } else {
619
			return ( p ) ;
620
		    }
621
		    r = r->bro ;
622
		}
623
		r = p->son->bro ;
624
		if ( is_constant ( r, &m1 ) ) {
625
		    if ( reached ) q = r ;
626
		} else if ( r->cons->encoding == ENC_goto ) {
627
		    if ( reached ) q = r ;
628
		} else if ( r->cons->encoding == ENC_make_top ) {
629
		    if ( reached ) q = r ;
630
		} else {
631
		    return ( p ) ;
632
		}
633
		q = copy_node ( q ) ;
634
		return ( q ) ;
635
	    }
636
	    case ENC_not : {
637
		/* Unary operations */
638
		node *r = p->son ;
639
		if ( is_constant ( r, &m1 ) ) {
640
		    long err = ENC_wrap ;
641
		    node *q = eval_exp ( n, err, r->shape, m1, m2 ) ;
642
		    if ( q ) p = q ;
643
		}
644
		break ;
645
	    }
646
	    case ENC_abs :
647
	    case ENC_negate : {
648
		/* Unary operations with error treatment */
649
		node *r = p->son->bro ;
650
		if ( is_constant ( r, &m1 ) ) {
651
		    long err = p->son->cons->encoding ;
652
		    node *q = eval_exp ( n, err, r->shape, m1, m2 ) ;
653
		    if ( q ) p = q ;
654
		}
655
		break ;
656
	    }
657
	    case ENC_and :
658
	    case ENC_maximum :
659
	    case ENC_minimum :
660
	    case ENC_or :
661
	    case ENC_rotate_left :
662
	    case ENC_rotate_right :
663
	    case ENC_shift_right :
664
	    case ENC_xor : {
665
		/* Binary operations */
666
		node *r = p->son ;
667
		if ( is_constant ( r, &m1 ) ) {
668
		    if ( is_constant ( r->bro, &m2 ) ) {
669
			long err = ENC_wrap ;
670
			node *q = eval_exp ( n, err, r->shape, m1, m2 ) ;
671
			if ( q ) p = q ;
672
		    }
673
		}
674
		break ;
675
	    }
676
	    case ENC_minus :
677
	    case ENC_mult :
678
	    case ENC_plus :
679
	    case ENC_power :
680
	    case ENC_shift_left : {
681
		/* Binary operations with error treatment */
682
		node *r = p->son->bro ;
683
		if ( is_constant ( r->bro, &m2 ) ) {
684
		    if ( is_constant ( r, &m1 ) ) {
685
			long err = p->son->cons->encoding ;
686
			node *q = eval_exp ( n, err, r->shape, m1, m2 ) ;
687
			if ( q ) p = q ;
688
		    } else if ( n == ENC_minus && m2 == 1 ) {
689
			node *q = eval_decr ( r ) ;
690
			if ( q ) p = q ;
691
		    }
692
		}
693
		break ;
694
	    }
695
	    case ENC_div0 :
696
	    case ENC_div1 :
697
	    case ENC_div2 :
698
	    case ENC_rem0 :
699
	    case ENC_rem1 :
700
	    case ENC_rem2 : {
701
		/* Binary operations with two error treatments */
702
		node *r = p->son->bro->bro ;
703
		if ( is_constant ( r, &m1 ) ) {
704
		    if ( is_constant ( r->bro, &m2 ) ) {
705
			long err = p->son->bro->cons->encoding ;
706
			node *q = eval_exp ( n, err, r->shape, m1, m2 ) ;
707
			if ( q ) p = q ;
708
		    }
709
		}
710
		break ;
711
	    }
712
	}
713
    } else if ( s == SORT_nat ) {
714
	if ( n == ENC_computed_nat ) {
715
	    long m = 0 ;
716
	    if ( is_constant ( p->son, &m ) ) {
717
		if ( m >= 0 ) return ( make_nat ( m ) ) ;
718
	    }
719
	}
720
    } else if ( s == SORT_signed_nat ) {
721
	if ( n == ENC_computed_signed_nat ) {
722
	    long m = 0 ;
723
	    if ( is_constant ( p->son, &m ) ) {
724
		return ( make_signed_nat ( m ) ) ;
725
	    }
726
	    if ( p->son->cons->encoding == ENC_make_int ) {
727
		return ( copy_node ( p->son->son->bro ) ) ;
728
	    }
729
	} else if ( n == ENC_snat_from_nat ) {
730
	    long m1 = 0, m2 = 0 ;
731
	    if ( is_constant ( p->son, &m1 ) ) {
732
		if ( is_constant ( p->son->bro, &m2 ) ) {
733
		    if ( m1 ) m2 = -m2 ;
734
		    return ( make_signed_nat ( m2 ) ) ;
735
		}
736
	    }
737
	}
738
    }
739
    return ( p ) ;
740
}
741
 
742
 
743
/*
744
    RECURSIVELY EVALUATE A NODE
745
 
746
    This routine recursively calls eval_node to evaluate the node p and
747
    all its subnodes.
748
*/
749
 
750
static node *eval_fully
751
    PROTO_N ( ( p ) )
752
    PROTO_T ( node *p )
753
{
754
    if ( p ) {
755
	node *q = p->bro ;
756
	p->son = eval_fully ( p->son ) ;
757
	p = eval_node ( p ) ;
758
	p->bro = eval_fully ( q ) ;
759
    }
760
    return ( p ) ;
761
}
762
 
763
 
764
/*
765
    EVALUATE A TOKEN DEFINITION
766
 
767
    This routine evaluates the definition of the token p.
768
*/
769
 
770
static void eval_tokdef
771
    PROTO_N ( ( p ) )
772
    PROTO_T ( construct *p )
773
{
774
    if ( p->encoding != -1 ) {
775
	tok_info *info = get_tok_info ( p ) ;
776
	info->def = eval_fully ( info->def ) ;
777
    }
778
    return ;
779
}
780
 
781
 
782
/*
783
    EVALUATE AN ALIGNMENT TAG DEFINITION
784
 
785
    This routine evaluates the definition of the alignment tag p.
786
*/
787
 
788
static void eval_aldef
789
    PROTO_N ( ( p ) )
790
    PROTO_T ( construct *p )
791
{
792
    if ( p->encoding != -1 ) {
793
	al_tag_info *info = get_al_tag_info ( p ) ;
794
	info->def = eval_fully ( info->def ) ;
795
    }
796
    return ;
797
}
798
 
799
 
800
/*
801
    EVALUATE A TAG DECLARATION AND DEFINITION
802
 
803
    This routine evaluates the declaration and definition of the tag p.
804
*/
805
 
806
static void eval_tagdef
807
    PROTO_N ( ( p ) )
808
    PROTO_T ( construct *p )
809
{
810
    if ( p->encoding != -1 ) {
811
	tag_info *info = get_tag_info ( p ) ;
812
	info->dec = eval_fully ( info->dec ) ;
813
	info->def = eval_fully ( info->def ) ;
814
    }
815
    return ;
816
}
817
 
818
 
819
/*
820
    EVALUATE ALL TOKEN DEFINITIONS
821
 
822
    This routine evaluates all token, alignment tag and tag definitions.
823
*/
824
 
825
void eval_all
826
    PROTO_Z ()
827
{
828
    long i ;
829
    unsigned long m = 0 ;
830
    var_max = BYTESIZE * ( long ) sizeof ( long ) ;
831
    var_mask = alloc_nof ( unsigned long, var_max + 1 ) ;
832
    var_mask [0] = 0 ;
833
    for ( i = 1 ; i <= var_max ; i++ ) {
834
	m = 2 * m + 1 ;
835
	var_mask [i] = m ;
836
    }
837
    init_shapes () ;
838
    apply_to_all ( eval_tokdef, SORT_token ) ;
839
    apply_to_all ( eval_aldef, SORT_al_tag ) ;
840
    apply_to_all ( eval_tagdef, SORT_tag ) ;
841
    return ;
842
}