Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 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
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
 
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
Line 14... Line 44...
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
 
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
 
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
 
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
Line 60... Line 90...
60
 * Revision 1.2  1995/10/11  17:10:00  currie
90
 * Revision 1.2  1995/10/11  17:10:00  currie
61
 * avs errors
91
 * avs errors
62
 *
92
 *
63
 * Revision 1.1  1995/04/06  10:44:05  currie
93
 * Revision 1.1  1995/04/06  10:44:05  currie
64
 * Initial revision
94
 * Initial revision
65
 *
95
 *
66
 * Revision 1.1  1995/04/06  10:44:05  currie
96
 * Revision 1.1  1995/04/06  10:44:05  currie
67
 * Initial revision
97
 * Initial revision
68
 *
98
 *
69
***********************************************************************/
99
***********************************************************************/
70
 
100
 
71
 
101
 
72
 
102
 
73
 
103
 
74
#include "config.h"
104
#include "config.h"
75
#include "common_types.h"
105
#include "common_types.h"
76
#include "externs.h"
106
#include "externs.h"
77
#include "xalloc.h"
107
#include "xalloc.h"
78
#include "installglob.h"
108
#include "installglob.h"
Line 99... Line 129...
99
  /* the list of unused returned cells */
129
  /* the list of unused returned cells */
100
exp freelist;	/* init by init_exp */
130
exp freelist;	/* init by init_exp */
101
  /* the number of unused cells in the block */
131
  /* the number of unused cells in the block */
102
int exps_left;	/* init by init_exp */
132
int exps_left;	/* init by init_exp */
103
 
133
 
104
  /* the next free pointer in the block which is used if the freelist
134
/* the next free pointer in the block which is used if the freelist is empty */
105
     is empty */
-
 
106
static exp next_exp_ptr;	/* no need to init */
135
static exp next_exp_ptr;	/* no need to init */
107
 
136
 
108
 
137
 
109
  /* the types used to record a list of blocks for reuse, if
138
/* the types used to record a list of blocks for reuse, if separate_units is
-
 
139
 * set */
110
     separate_units is set */
140
struct expalloc_cell_t {
111
struct expalloc_cell_t {struct expalloc_cell_t * tl; exp hd;};
141
	struct expalloc_cell_t *tl;
-
 
142
	exp hd;
-
 
143
};
112
typedef struct expalloc_cell_t expalloc_cell;
144
typedef struct expalloc_cell_t expalloc_cell;
113
 
145
 
114
static expalloc_cell * alloc_list = (expalloc_cell *)0;
146
static expalloc_cell *alloc_list = (expalloc_cell *)0;
115
		/* good init for the whole run */
147
/* good init for the whole run */
116
static expalloc_cell * alloc_freelist = (expalloc_cell *)0;
148
static expalloc_cell *alloc_freelist = (expalloc_cell *)0;
117
		/* good init for the whole run */
149
/* good init for the whole run */
118
 
150
 
119
 
151
 
120
static char  ic_buff[21];	/* no init needed */
152
static char  ic_buff[21];	/* no init needed */
121
 
153
 
122
/* IDENTITY */
154
/* IDENTITY */
123
 
155
 
124
static int current_alloc_size = 20000;
156
static int current_alloc_size = 20000;
125
 
157
 
126
/* PROCEDURES */
158
/* PROCEDURES */
127
 
159
 
128
void altered PROTO_S ( ( exp, exp ) ) ;
160
void altered(exp, exp);
129
 
161
 
130
exp next_exp
162
exp
131
    PROTO_Z ()
163
next_exp(void)
132
{
164
{
133
  exp res;
165
  exp res;
134
  if (freelist != nilexp)
166
  if (freelist != nilexp) {
135
    {  /* first try to allocate fron the freelist */
167
      /* first try to allocate fron the freelist */
136
      res = freelist;
168
      res = freelist;
137
      freelist = son(freelist);
169
      freelist = son(freelist);
138
      return res;
170
      return res;
139
    };
171
  }
140
 
172
 
141
    /* if the freelist is empty we allocate from a block of exps */
173
    /* if the freelist is empty we allocate from a block of exps */
142
  if (exps_left == 0)
174
  if (exps_left == 0) {
143
   {  /* if the block is empty we must allocate another */
175
    /* if the block is empty we must allocate another */
144
     if (alloc_freelist)
176
    if (alloc_freelist) {
145
       {  /* if there is anything in this list of blocks we can reuse
177
      /* if there is anything in this list of blocks we can reuse
146
             it and we do not need to calloc */
178
       * it and we do not need to calloc */
147
         exps_left = current_alloc_size;
179
      exps_left = current_alloc_size;
148
         next_exp_ptr = alloc_freelist -> hd;
180
      next_exp_ptr = alloc_freelist->hd;
149
         alloc_freelist = alloc_freelist -> tl;
181
      alloc_freelist = alloc_freelist->tl;
150
       }
-
 
151
     else
182
    } else {
152
       {  /* otherwise we must calloc a new block */
183
      /* otherwise we must calloc a new block */
153
         exps_left = current_alloc_size;
184
      exps_left = current_alloc_size;
154
         next_exp_ptr = (exp)xcalloc(exps_left, sizeof(struct exp_t));
185
      next_exp_ptr = (exp)xcalloc(exps_left, sizeof(struct exp_t));
155
          { /* and if we are after the start of tagdefs we put
186
      { /* and if we are after the start of tagdefs we put
156
               the block on to alloc_list so that it can be reused
187
	   the block on to alloc_list so that it can be reused
157
               for the next unit */
188
	   for the next unit */
158
            expalloc_cell * temp =
189
	expalloc_cell * temp =
159
               (expalloc_cell *)xmalloc(sizeof(expalloc_cell));
190
	    (expalloc_cell *)xmalloc(sizeof(expalloc_cell));
160
            temp -> tl = alloc_list;
191
	temp->tl = alloc_list;
161
            temp -> hd = next_exp_ptr;
192
	temp->hd = next_exp_ptr;
162
            alloc_list = temp;
193
	alloc_list = temp;
163
          };
194
      }
164
       };
195
    }
165
   };
196
  }
166
 
197
 
167
  --exps_left;
198
  --exps_left;
168
  res = next_exp_ptr++;
199
  res = next_exp_ptr++;
169
  return res;
200
  return res;
170
}
201
}
171
 
202
 
-
 
203
 
172
void set_large_alloc
204
void
173
    PROTO_Z ()
205
set_large_alloc(void)
174
{
206
{
175
  /* called at the start of tagdefs */
207
  /* called at the start of tagdefs */
176
  alloc_freelist = alloc_list;
208
  alloc_freelist = alloc_list;
177
  freelist = nilexp;
209
  freelist = nilexp;
178
  exps_left = 0;
210
  exps_left = 0;
179
  return;
211
  return;
180
}
212
}
181
 
213
 
-
 
214
 
182
   /* create a new exp */
215
/* create a new exp */
-
 
216
 
183
exp getexp
217
exp
184
    PROTO_N ( (s, b, l, sn, px, pr, n, tg) )
-
 
185
    PROTO_T ( shape s X exp b X int l X exp sn X exp px X prop pr X int n X unsigned char tg )
218
getexp(shape s, exp b, int l, exp sn, exp px, prop pr, int n, unsigned char tg)
186
{
219
{
187
  exp res = next_exp();
220
  exp res = next_exp();
188
  sh(res) = s;
221
  sh(res) = s;
189
  bro(res) = b;
222
  bro(res) = b;
190
  if (l)
223
  if (l) {
191
   setlast(res);
224
   setlast(res);
192
  else
225
  } else {
193
   clearlast(res);
226
   clearlast(res);
-
 
227
  }
194
  son(res) = sn;
228
  son(res) = sn;
195
  pt(res) = px;
229
  pt(res) = px;
196
  props(res) = pr;
230
  props(res) = pr;
197
  no(res) = n;
231
  no(res) = n;
198
  name(res) = tg;
232
  name(res) = tg;
Line 201... Line 235...
201
  dgf(res) = nildiag;
235
  dgf(res) = nildiag;
202
#endif
236
#endif
203
  return res;
237
  return res;
204
}
238
}
205
 
239
 
-
 
240
 
206
exp copyexp
241
exp
207
    PROTO_N ( (e) )
-
 
208
    PROTO_T ( exp e )
242
copyexp(exp e)
209
{
243
{
210
  exp res = next_exp();
244
  exp res = next_exp();
211
  *res = *e;
245
  *res = *e;
212
  return res;
246
  return res;
213
}
247
}
-
 
248
 
-
 
249
 
-
 
250
/* makes a new shape */
214
 
251
 
215
  /* makes a new shape */
-
 
216
exp getshape
252
exp
217
    PROTO_N ( (l, sn, px, pr, n, tg) )
-
 
218
    PROTO_T ( int l X alignment sn X alignment px X alignment pr X int n X unsigned char tg )
253
getshape(int l, alignment sn, alignment px, alignment pr, int n,
-
 
254
	 unsigned char tg)
219
{
255
{
220
  exp res = next_exp();
256
  exp res = next_exp();
221
  if (l)
257
  if (l) {
222
   setlast(res);
258
   setlast(res);
223
  else
259
  } else {
224
   clearlast(res);
260
   clearlast(res);
-
 
261
  }
225
  res ->sonf.ald = sn;
262
  res->sonf.ald = sn;
226
  res -> ptf.ald = px;
263
  res->ptf.ald = px;
227
  res -> brof.ald = pr;
264
  res->brof.ald = pr;
228
  no(res) = n;
265
  no(res) = n;
229
  name(res) = tg;
266
  name(res) = tg;
230
  return res;
267
  return res;
231
}
268
}
232
 
269
 
233
  /* return an exp cell to the freelist */
-
 
234
void retcell
-
 
235
    PROTO_N ( (e) )
-
 
236
    PROTO_T ( exp e )
-
 
237
{
-
 
238
  son(e) = freelist;
-
 
239
  freelist = (e);
-
 
240
  return;
-
 
241
}
-
 
242
 
-
 
243
 
270
 
244
  /* true if part is inside whole */
271
/* return an exp cell to the freelist */
-
 
272
 
-
 
273
void
-
 
274
retcell(exp e)
-
 
275
{
-
 
276
  son(e) = freelist;
-
 
277
  freelist = (e);
245
int internal_to
278
  return;
-
 
279
}
-
 
280
 
-
 
281
 
246
    PROTO_N ( (whole, part) )
282
/* true if part is inside whole */
-
 
283
int
247
    PROTO_T ( exp whole X exp part )
284
internal_to(exp whole, exp part)
248
{
285
{
249
  int f = 1;
286
  int f = 1;
250
  exp q = part;
287
  exp q = part;
251
  while (q != whole && q != nilexp &&
288
  while (q != whole && q != nilexp &&
252
      !(name (q) == ident_tag && isglob (q))) {
289
	 !(name(q) == ident_tag && isglob(q))) {
253
    f = (int)(last (q));
290
    f = (int)(last(q));
254
    q = bro (q);
291
    q = bro(q);
255
  };
292
  }
256
  /* ascend from part until we reach either whole or top of tree */
293
  /* ascend from part until we reach either whole or top of tree */
257
  return (f && q == whole);
294
  return(f && q == whole);
258
}
295
}
259
 
296
 
260
static void kill_el PROTO_S ((exp e, exp scope));
-
 
261
 
297
 
-
 
298
static void kill_el(exp e, exp scope);
-
 
299
 
262
  /* kill an exp, return it and its components to the freelist,
300
/* kill an exp, return it and its components to the freelist, if necessary
263
     if necessary remove uses of tags and labels, and propagate
301
 * remove uses of tags and labels, and propagate changes to identity and
264
     changes to identity and variable declarations and to labels
-
 
265
     but not outside scope */
302
 * variable declarations and to labels but not outside scope */
-
 
303
 
266
void kill_exp
304
void
267
    PROTO_N ( (e, scope) )
-
 
268
    PROTO_T ( exp e X exp scope )
305
kill_exp(exp e, exp scope)
269
{
306
{
270
  if (e != nilexp) {
307
  if (e != nilexp) {
271
    unsigned char n = name (e);
308
    unsigned char n = name(e);
272
 
309
 
273
 
310
 
274
    if (n == name_tag) {
311
    if (n == name_tag) {
275
      exp q = son (e);
312
      exp q = son(e);
276
#ifdef NEWDIAGS
313
#ifdef NEWDIAGS
277
      if (!isdiaginfo(e))
314
      if (!isdiaginfo(e)) {
278
	--no (son (e));		/* decrease usage count */
315
	--no(son(e));		/* decrease usage count */
-
 
316
      }
279
#else
317
#else
280
      --no (son (e));		/* decrease usage count */
318
      --no(son(e));		/* decrease usage count */
281
#endif
319
#endif
282
      while (pt (q) != e)
320
      while (pt(q) != e) {
283
	q = pt (q);
321
	q = pt(q);
284
      pt (q) = pt (e);		/* remove from usage list */
-
 
285
      if (
322
      }
286
          no (son (e)) == 0 &&
323
      pt(q) = pt(e);		/* remove from usage list */
287
	  son (son (e)) != nilexp &&
324
      if (no(son(e)) == 0 && son(son(e)) != nilexp &&
288
	  bro (son (son (e))) != nilexp &&
325
	  bro(son(son(e))) != nilexp &&
289
	  (scope == nilexp || internal_to (scope, son (e))))
326
	 (scope == nilexp || internal_to(scope, son(e)))) {
290
	IGNORE check (son (e), scope);
327
	IGNORE check(son(e), scope);
-
 
328
      }
291
      /* check the declaration if now no use */
329
      /* check the declaration if now no use */
292
      retcell (e);
330
      retcell(e);
293
      return;
331
      return;
294
    };
332
    }
295
 
333
 
296
    if (n == solve_tag) {
334
    if (n == solve_tag) {
297
      int looping;
335
      int looping;
298
      if (!last (son (e))) {
336
      if (!last(son(e))) {
299
	exp t = bro (son (e));
337
	exp t = bro(son(e));
300
	do {
338
	do {
301
	  no (son (t)) = 0;
339
	  no(son(t)) = 0;
302
	  looping = !last (t);
340
	  looping = !last(t);
303
	  t = bro (t);
341
	  t = bro(t);
304
	}
-
 
305
	while (looping);
342
	} while (looping);
306
      };
343
      }
307
      if (pt(e) != nilexp)
344
      if (pt(e) != nilexp) {
308
        son (pt (e)) = nilexp;
345
        son(pt(e)) = nilexp;
-
 
346
      }
309
      kill_el (son (e), scope);
347
      kill_el(son(e), scope);
310
      retcell (e);
348
      retcell(e);
311
      return;
349
      return;
312
    };
350
    }
313
 
351
 
314
    if (n == ident_tag) {
352
    if (n == ident_tag) {
315
      ++no (e);
353
      ++no(e);
316
      kill_el (son (e), scope);
354
      kill_el(son(e), scope);
317
#ifdef NEWDIAGS
355
#ifdef NEWDIAGS
318
      if (diagnose && pt(e))	/* allow diags to hold on to id */
356
      if (diagnose && pt(e)) {	/* allow diags to hold on to id */
319
	diag_kill_id (e);
357
	diag_kill_id(e);
320
      else
358
      } else
321
#endif
359
#endif
322
      retcell (e);
360
      retcell(e);
323
      return;
361
      return;
324
    };
362
    }
325
 
363
 
326
 
364
 
327
    if (n == labst_tag) {
365
    if (n == labst_tag) {
328
      ++no (e);
366
      ++no(e);
329
      --proc_label_count;
367
      --proc_label_count;
330
      kill_el (bro (son (e)), scope);
368
      kill_el(bro(son(e)), scope);
331
      retcell (son (e));
369
      retcell(son(e));
332
      retcell (e);
370
      retcell(e);
333
      return;
371
      return;
334
    };
372
    }
335
 
373
 
336
    if (n == case_tag) {
374
    if (n == case_tag) {
337
      exp b = bro(son(e));
375
      exp b = bro(son(e));
338
      while (b != nilexp) {
376
      while (b != nilexp) {
339
	exp nextb = bro(b);
377
	exp nextb = bro(b);
340
	int l = last(b);
378
	int l = last(b);
341
	--no(son(pt(b)));
379
	--no(son(pt(b)));
342
	if (son(b) != nilexp) retcell(son(b));
380
	if (son(b) != nilexp) {
-
 
381
	  retcell(son(b));
-
 
382
	}
343
	retcell(b);
383
	retcell(b);
-
 
384
	if (l) {
344
	if (l) break;
385
	  break;
-
 
386
	}
345
	b = nextb;
387
	b = nextb;
346
      }
388
      }
347
      kill_exp (son (e), scope);
389
      kill_exp(son(e), scope);
348
      retcell (e);
390
      retcell(e);
349
      return;
391
      return;
350
    };
392
    }
351
 
393
 
352
    if (n == cond_tag) {
394
    if (n == cond_tag) {
353
      no (son (bro (son (e)))) = 0;
395
      no(son(bro(son(e)))) = 0;
354
      kill_el (son (e), scope);
396
      kill_el(son(e), scope);
355
      retcell (e);
397
      retcell(e);
356
      return;
398
      return;
357
    };
399
    }
358
 
400
 
359
    if (n == rep_tag) {
401
    if (n == rep_tag) {
360
      if (pt(e) != nilexp)
402
      if (pt(e) != nilexp) {
361
        son (pt (e)) = nilexp;
403
        son(pt(e)) = nilexp;
-
 
404
      }
362
      no (son (bro (son (e)))) = 0;
405
      no(son(bro(son(e)))) = 0;
363
      kill_el (son (e), scope);
406
      kill_el(son(e), scope);
364
      retcell (e);
407
      retcell(e);
365
      return;
408
      return;
366
    };
409
    }
367
 
410
 
368
    if (n == real_tag || (n == val_tag && isbigval(e))) {
411
    if (n == real_tag || (n == val_tag && isbigval(e))) {
369
      flpt_ret (no (e));
412
      flpt_ret(no(e));
370
      retcell (e);
413
      retcell(e);
371
      return;
414
      return;
372
    };
415
    }
373
 
416
 
374
    if (n == val_tag) {
417
    if (n == val_tag) {
375
      retcell (e);
418
      retcell(e);
376
      return;
-
 
377
    };
-
 
378
 
-
 
379
    if (n == env_offset_tag || n == string_tag || n==general_env_offset_tag)
-
 
380
     {
-
 
381
      retcell (e);
-
 
382
      return;
419
      return;
-
 
420
    }
-
 
421
 
-
 
422
    if (n == env_offset_tag || n == string_tag || n==general_env_offset_tag) {
-
 
423
      retcell(e);
-
 
424
      return;
383
     };
425
     }
384
 
426
 
385
    {
427
    {
386
      exp p = pt (e);
428
      exp p = pt(e);
387
      if (p != nilexp && (props (son (p)) & 1) == 0) {
429
      if (p != nilexp && (props(son(p)) & 1) == 0) {
388
	/* decrease label usage count */
430
	/* decrease label usage count */
389
	--no (son (p));
431
	--no(son(p));
390
	if (
-
 
391
            no (son (p)) == 0 && !is_loaded_lv(p) &&
432
	if (no(son(p)) == 0 && !is_loaded_lv(p) && bro(son(p)) != nilexp &&
392
	    bro (son (p)) != nilexp &&
-
 
393
	    (scope == nilexp || internal_to (scope, p)))
433
	   (scope == nilexp || internal_to(scope, p))) {
394
	  altered (p, scope);	/* process if now no use of label and not
434
	  /* process if now no use of label and not doing deadvar */
395
				   doing deadvar */
435
	  altered (p, scope);
-
 
436
	}
396
      };
437
      }
397
      kill_el (son (e), scope);
438
      kill_el(son(e), scope);
398
      retcell (e);
439
      retcell(e);
399
      return;
440
      return;
400
    };
441
    }
401
  };
442
  }
402
}
443
}
403
 
444
 
404
 
445
 
405
/* kill the arguments of a construction */
446
/* kill the arguments of a construction */
-
 
447
 
406
static void kill_el
448
static void
407
    PROTO_N ( (e, scope) )
-
 
408
    PROTO_T ( exp e X exp scope )
449
kill_el (exp e, exp scope)
409
{
450
{
410
  if (e != nilexp) {
451
  if (e != nilexp) {
411
    int l;
452
    int l;
412
    exp next;
453
    exp next;
413
    do {
454
    do {
414
      l = (int)(last (e));
455
      l = (int)(last(e));
415
      next = bro (e);
456
      next = bro(e);
416
      kill_exp (e, scope);
457
      kill_exp(e, scope);
417
      e = next;
458
      e = next;
418
    }
459
    }
419
    while (!l && e != nilexp);
460
    while (!l && e != nilexp);
420
  };
461
  }
421
}
462
}
422
 
463
 
423
  /* return the shape delivered by a conditional (or similar construct)
464
  /* return the shape delivered by a conditional (or similar construct)
424
     which delivers an a from one branch and a b from the other */
465
     which delivers an a from one branch and a b from the other */
425
shape lub_shape
466
shape
426
    PROTO_N ( (a, b) )
-
 
427
    PROTO_T ( shape a X shape b )
467
lub_shape(shape a, shape b)
428
{
468
{
429
  int asz = shape_size(a);
469
  int asz = shape_size(a);
430
  int bsz = shape_size(b);
470
  int bsz = shape_size(b);
431
  if (name(a) ==bothd)
471
  if (name(a) ==bothd) {
432
   return b;
472
   return b;
-
 
473
  }
433
  if (name(b) == bothd)
474
  if (name(b) == bothd) {
434
   return a;
475
   return a;
-
 
476
  }
435
  if (asz == bsz && shape_align(a) == shape_align(b))
477
  if (asz == bsz && shape_align(a) == shape_align(b)) {
436
    return (a);
478
    return(a);
-
 
479
  }
437
  return (f_top);
480
  return(f_top);
438
}
481
}
439
 
482
 
440
  /* true if the shapes are equal */
483
  /* true if the shapes are equal */
441
int eq_shape
484
int
442
    PROTO_N ( (a, b) )
-
 
443
    PROTO_T ( shape a X shape b )
485
eq_shape(shape a, shape b)
444
{
486
{
445
  if (name(a) != name(b))
487
  if (name(a) != name(b)) {
446
     return 0;
488
    return 0;
447
  if (shape_size(a)!=shape_size(b) ||
489
  }
448
           is_signed(a)!=is_signed(b) ||
490
  if (shape_size(a) != shape_size(b) || is_signed(a) != is_signed(b) ||
449
           shape_align(a)!=shape_align(b) ||
491
      shape_align(a) !=shape_align(b) || al1(a) !=al1(b)) {
450
           al1(a)!=al1(b))
-
 
451
     return 0;
492
    return 0;
-
 
493
  }
452
  if (name(a) == nofhd)
494
  if (name(a) == nofhd) {
453
     return 1;
495
    return 1;
454
  else
496
  } else {
455
     return (al2(a)==al2(b));
497
    return(al2(a) ==al2(b));
-
 
498
  }
456
}
499
}
457
 
500
 
458
  /* source of numbers for local labels */
501
  /* source of numbers for local labels */
459
int next_lab
502
int
460
    PROTO_Z ()
503
next_lab(void)
461
{
504
{
462
  return crt_labno++;
505
  return crt_labno++;
463
}
506
}
464
 
507
 
465
char *intchars
508
char *
466
    PROTO_N ( (n) )
-
 
467
    PROTO_T ( int n )
509
intchars(int n)
468
{
510
{
469
  int  r, d;
511
  int r, d;
470
  char *ind;
512
  char *ind;
471
 
513
 
472
  ind = &ic_buff[19];
514
  ind = &ic_buff[19];
473
  ic_buff[20] = 0;
515
  ic_buff[20] = 0;
474
  d = (n < 0) ? -n : n;
516
  d = (n < 0) ? -n : n;
Line 476... Line 518...
476
  do {
518
  do {
477
    r = d % 10;
519
    r = d % 10;
478
    d = d / 10;
520
    d = d / 10;
479
    *ind = (char)(r + 48); /* CAST:jmf: must be in 48:57 */
521
    *ind = (char)(r + 48); /* CAST:jmf: must be in 48:57 */
480
    --ind;
522
    --ind;
481
  }
-
 
482
  while (d != 0);
523
  } while (d != 0);
483
  if (n < 0) {
524
  if (n < 0) {
484
    *ind = '-';
525
    *ind = '-';
485
    --ind;
526
    --ind;
486
  };
527
  }
487
 
528
 
488
  return (ind + 1);
529
  return(ind + 1);
489
}
530
}
490
 
531
 
491
 
532
 
492
void case_item
533
void
493
    PROTO_N ( (i) )
-
 
494
    PROTO_T ( exp i )
534
case_item(exp i)
495
{
535
{
496
  exp l = global_case;
536
  exp l = global_case;
497
  exp t = l;
537
  exp t = l;
498
  int go = 1;
538
  int go = 1;
499
  exp  newhigh = (son (i) == nilexp) ? i : son (i);
539
  exp newhigh = (son(i) == nilexp)? i : son(i);
500
  exp  thigh;
540
  exp thigh;
501
  exp  nlow,
-
 
502
        nhigh;
541
  exp nlow, nhigh;
503
 
542
 
504
  while (go && bro (t) != nilexp) {
543
  while (go && bro(t) != nilexp) {
505
    exp j = bro (t);
544
    exp j = bro(t);
506
    exp  highj = (son (j) == nilexp) ? j : son (j);
545
    exp  highj = (son(j) == nilexp)? j : son(j);
507
    if (docmp_f((int)f_greater_than, i, highj))
546
    if (docmp_f((int)f_greater_than, i, highj)) {
508
      t = bro (t);
547
      t = bro(t);
509
    else
548
    } else {
510
      go = 0;
549
      go = 0;
-
 
550
    }
511
  };
551
  }
512
 
552
 
513
  if (t != l) {
553
  if (t != l) {
514
    thigh = (son (t) == nilexp) ? t : son (t);
554
    thigh = (son(t) == nilexp)? t : son(t);
515
  }
-
 
516
  else {
555
  } else {
517
    SET(thigh);
556
    SET(thigh);
518
  };
-
 
519
 
-
 
520
  if (bro (t) != nilexp) {
-
 
521
    nlow = bro (t);
-
 
522
    nhigh = (son (bro (t)) == nilexp) ? nlow : son (bro (t));
-
 
523
  }
557
  }
-
 
558
 
-
 
559
  if (bro(t) != nilexp) {
-
 
560
    nlow = bro(t);
-
 
561
    nhigh = (son(bro(t)) == nilexp)? nlow : son(bro(t));
524
  else {
562
  } else {
525
    SET(nlow); SET(nhigh);
563
    SET(nlow); SET(nhigh);
526
  };
564
  }
527
 
565
 
528
  if (t != l && docmp_f((int)f_less_than_or_equal, i, thigh))
566
  if (t != l && docmp_f((int)f_less_than_or_equal, i, thigh)) {
529
    failer (CASE_OVERLAP);
567
    failer(CASE_OVERLAP);
-
 
568
  }
530
  if (bro (t) != nilexp &&
569
  if (bro(t) != nilexp &&
531
	 docmp_f((int)f_greater_than_or_equal, newhigh, nlow))
570
      docmp_f((int)f_greater_than_or_equal, newhigh, nlow)) {
532
    failer (CASE_OVERLAP);
571
    failer(CASE_OVERLAP);
-
 
572
  }
533
 
573
 
534
  if (isbigval(i) || isbigval(newhigh)) {
574
  if (isbigval(i) || isbigval(newhigh)) {
535
    bro (i) = bro (t);
575
    bro(i) = bro(t);
536
    bro (t) = i;
576
    bro(t) = i;
537
    return;
577
    return;
538
  };
578
  }
539
 
579
 
540
  if (t != l && (no(i)-1) == no(thigh) && pt (i) == pt (t)) {
580
  if (t != l && (no(i) -1) == no(thigh) && pt(i) == pt(t)) {
541
    if (bro (t) != nilexp && (no(newhigh)+1) == no(nlow)
581
    if (bro(t) != nilexp && (no(newhigh) +1) == no(nlow) &&
542
	&& pt (i) == pt (bro (t))) {
582
	pt(i) == pt(bro(t))) {
543
      if (son (bro (t)) != nilexp) {
583
      if (son(bro(t)) != nilexp) {
544
	if (son (t) != nilexp)
584
	if (son(t) != nilexp) {
545
	  retcell (son (t));
585
	  retcell(son(t));
-
 
586
	}
546
	son (t) = son (bro (t));
587
	son(t) = son(bro(t));
547
	bro (t) = bro (bro (t));
588
	bro(t) = bro(bro(t));
548
	return;
589
	return;
549
      };
590
      }
550
      if (son (t) != nilexp) {
591
      if (son(t) != nilexp) {
551
	no (son (t)) = no(nhigh);
592
	no(son(t)) = no(nhigh);
552
	bro (t) = bro (bro (t));
593
	bro(t) = bro(bro(t));
553
	return;
594
	return;
554
      };
595
      }
555
      setson (t, getexp (slongsh, nilexp, 1, nilexp, nilexp, 0,
596
      setson(t, getexp(slongsh, nilexp, 1, nilexp, nilexp, 0, no(nhigh), 0));
556
			  no(nhigh), 0));
-
 
557
      bro (t) = bro (bro (t));
597
      bro(t) = bro(bro(t));
558
      return;
598
      return;
559
    };
599
    }
560
    if (son (t) != nilexp) {
600
    if (son(t) != nilexp) {
561
      no (son (t)) = no(newhigh);
601
      no(son(t)) = no(newhigh);
562
      return;
602
      return;
563
    };
603
    }
564
    setson (t, getexp (slongsh, nilexp, 1, nilexp,
604
    setson(t, getexp(slongsh, nilexp, 1, nilexp, nilexp, 0, no(newhigh), 0));
565
			 nilexp, 0, no(newhigh), 0));
-
 
566
    return;
605
    return;
567
  };
606
  }
568
 
607
 
569
  if (bro (t) != nilexp && (no(newhigh) + 1) == no(nlow)
608
  if (bro(t) != nilexp && (no(newhigh) + 1) == no(nlow) &&
570
      && pt (i) == pt (bro (t))) {
609
      pt(i) == pt(bro(t))) {
571
    if (son (bro (t)) != nilexp) {
610
    if (son(bro(t)) != nilexp) {
572
      no (bro (t)) = no(i);
611
      no(bro(t)) = no(i);
573
      return;
-
 
574
    };
-
 
575
    if (son (i) != nilexp) {
-
 
576
      no (son (i)) = no(nhigh);
-
 
577
      bro (i) = bro (bro (t));
-
 
578
      bro (t) = i;
-
 
579
      return;
612
      return;
580
    };
613
    }
-
 
614
    if (son(i) != nilexp) {
-
 
615
      no(son(i)) = no(nhigh);
-
 
616
      bro(i) = bro(bro(t));
-
 
617
      bro(t) = i;
-
 
618
      return;
-
 
619
    }
581
    son (i) = bro (t);
620
    son(i) = bro(t);
582
    bro (i) = bro (bro (t));
621
    bro(i) = bro(bro(t));
583
    bro (t) = i;
622
    bro(t) = i;
584
    return;
623
    return;
585
  };
624
  }
586
 
625
 
587
  bro (i) = bro (t);
626
  bro(i) = bro(t);
588
  bro (t) = i;
627
  bro(t) = i;
589
  return;
628
  return;
590
}
629
}
591
 
630
 
592
 
631
 
593
/*******************************************************************
632
/*******************************************************************
594
  scan_solve is part of the process of reading a solve construction.
633
  scan_solve is part of the process of reading a solve construction.
595
  It scans the exp e, to increment the count of labels used by e.
634
  It scans the exp e, to increment the count of labels used by e.
596
 *******************************************************************/
635
 *******************************************************************/
597
void scan_solve
636
void
598
    PROTO_N ( (e) )
-
 
599
    PROTO_T ( exp e )
637
scan_solve(exp e)
600
{
638
{
601
  unsigned char  n = name (e);
639
  unsigned char n = name(e);
602
  switch (n) {
640
  switch (n) {
603
    case name_tag:
641
    case name_tag:
604
    case make_lv_tag:
642
    case make_lv_tag:
605
    case env_offset_tag:
643
    case env_offset_tag:
606
    case general_env_offset_tag:
644
    case general_env_offset_tag:
607
      return;
645
      return;
608
    case clear_tag:
646
    case clear_tag:
609
      return;
647
      return;
610
    case ident_tag: {
648
    case ident_tag:
611
	scan_solve (son (e));
649
	scan_solve(son(e));
612
	scan_solve (bro (son (e)));
650
	scan_solve(bro(son(e)));
613
	return;
651
	return;
614
      };
-
 
615
    case case_tag:
652
    case case_tag: {
616
      {
-
 
617
	exp t = son (e);
653
	exp t = son(e);
618
	while (!last (t)) {
654
	while (!last(t)) {
619
	  exp s = son (pt (bro (t)));
655
	  exp s = son(pt(bro(t)));
620
	  if (isvar (s)) {
656
	  if (isvar(s)) {
621
	    ++no (s);
657
	    ++no(s);
622
	  };
658
	  }
623
	  t = bro (t);
659
	  t = bro(t);
624
	};
660
	}
625
	scan_solve (son (e));
661
	scan_solve(son(e));
626
	return;
662
	return;
627
      };
663
    }
628
    default:
664
    default:
629
      {
-
 
630
	if (pt (e) != nilexp) {
665
	if (pt(e) != nilexp) {
631
	  exp s = son (pt (e));
666
	  exp s = son(pt(e));
632
	  if (isvar (s)) {
667
	  if (isvar(s)) {
633
	    ++no (s);
668
	    ++no(s);
634
	  };
669
	  }
635
	};
670
	}
636
	if (son (e) != nilexp) {
671
	if (son(e) != nilexp) {
637
	  exp t = son (e);
672
	  exp t = son(e);
638
	  while (scan_solve (t), !last (t))
673
	  while (scan_solve(t), !last(t)) {
639
	    t = bro (t);
674
	    t = bro(t);
-
 
675
	  }
640
	};
676
	}
641
	return;
677
	return;
642
      };
-
 
643
  };
678
  };
644
}
679
}
-
 
680
 
-
 
681
 
645
/*********************************************************************
682
/*********************************************************************
646
  clean_labelled processes a labelled statement after it has been read.
683
  clean_labelled processes a labelled statement after it has been read.
647
  It places the labelled statements in a good order.
684
  It places the labelled statements in a good order.
648
 *********************************************************************/
685
 *********************************************************************/
649
 
686
 
650
exp clean_labelled
687
exp
651
    PROTO_N ( (main, placelabs) )
-
 
652
    PROTO_T ( exp main X label_list placelabs )
688
clean_labelled(exp main, label_list placelabs)
653
{
689
{
654
  int   i,
-
 
655
        crt_no;
690
  int i, crt_no;
656
  int go = 1;
691
  int go = 1;
657
  shape s;
692
  shape s;
658
  exp r, q;
693
  exp r, q;
659
  int n = placelabs.number;
694
  int n = placelabs.number;
660
  int  *ord;			/* records the order in which the
695
  int *ord;			/* records the order in which the
661
				   statemnts are to be placed */
696
				   statemnts are to be placed */
662
  int   ord_no;
697
  int ord_no;
663
  for (i = 0; i < n; ++i) {	/* set up the labels */
698
  for (i = 0; i < n; ++i) {	/* set up the labels */
664
    exp l = get_lab(placelabs.elems[i]);
699
    exp l = get_lab(placelabs.elems[i]);
665
    exp t = son (l);
700
    exp t = son(l);
666
    no (t) = is_loaded_lv(l);
701
    no(t) = is_loaded_lv(l);
667
    setcrtsolve (t);		/* defined in expmacs = props(t) = 1 */
702
    setcrtsolve (t);		/* defined in expmacs = props(t) = 1 */
668
  };
703
  }
669
  crt_no = 0;
704
  crt_no = 0;
670
  ord = (int *) xcalloc (n, sizeof (int));
705
  ord = (int *)xcalloc(n, sizeof(int));
671
  ord_no = 0;
706
  ord_no = 0;
672
  scan_solve (main);		/* mark the labels used by the initiator
707
  scan_solve (main);		/* mark the labels used by the initiator */
-
 
708
 
673
				*/
709
  while (go) {
674
  while (go) {			/* continue as long as we have added a
710
    /* continue as long as we have added a statement */
675
				   statement */
-
 
676
    go = 0;
711
    go = 0;
677
    for (i = 0; i < n; ++i) {	/* look for unprocessed but used sts */
712
    for (i = 0; i < n; ++i) {	/* look for unprocessed but used sts */
678
      int   j = ((i + crt_no) % n);
713
      int j = ((i + crt_no)% n);
679
      exp t = get_lab(placelabs.elems[j]);
714
      exp t = get_lab(placelabs.elems[j]);
680
      if ((props (son (t)) & 8) == 0 && no (son (t)) != 0) {
715
      if ((props(son(t)) & 8) == 0 && no(son(t)) != 0) {
681
	/* we have found an unprocessed but used statement */
716
	/* we have found an unprocessed but used statement */
682
	go = 1;
717
	go = 1;
683
	props (son (t)) = 5;
718
	props(son(t)) = 5;
684
	scan_solve (t);		/* now scan it to mark the things it uses
719
	scan_solve (t);		/* now scan it to mark the things it uses */
685
				*/
-
 
686
	props (son (t)) = (prop)((props (son (t)) & 0xfb) | 8);
720
	props(son(t)) = (prop)((props(son(t)) & 0xfb) | 8);
687
	ord[ord_no++] = j;
721
	ord[ord_no++] = j;
688
      };
722
      }
689
    };
723
    }
690
  };
724
  }
691
  s = sh (main);
725
  s = sh(main);
692
  for (i = 0; i < n; ++i) {
726
  for (i = 0; i < n; ++i) {
693
    exp lab = get_lab(placelabs.elems[i]);
727
    exp lab = get_lab(placelabs.elems[i]);
694
    exp t = son (lab);
728
    exp t = son(lab);
695
    if ((props (t) & 8) != 8) {
729
    if ((props(t) & 8) != 8) {
696
      kill_exp (bro (t), bro (t));/* remove unwanted statements */
730
      /* remove unwanted statements */
-
 
731
      kill_exp (bro(t), bro(t));
697
 
732
    } else {
-
 
733
      /* form the result shape of the whole */
-
 
734
      s = lub_shape(s, sh(lab));
698
    }
735
    }
699
    else
-
 
700
      s = lub_shape (s, sh (lab));
-
 
701
    /* form the result shape of the whole */
-
 
702
  };
736
  }
703
  r = getexp (s, nilexp, 0, main, crt_repeat, 0, 0, solve_tag);
737
  r = getexp(s, nilexp, 0, main, crt_repeat, 0, 0, solve_tag);
704
  q = main;
738
  q = main;
705
  for (i = 0; i < ord_no; ++i) {/* set up the solve with the statements in
739
  for (i = 0; i < ord_no; ++i) {
706
				   the order specified by ord */
740
    /* set up the solve with the statements in the order specified by ord */
707
    clearlast (q);
741
    clearlast(q);
708
    bro (q) = get_lab(placelabs.elems[ord[i]]);
742
    bro(q) = get_lab(placelabs.elems[ord[i]]);
709
    q = bro (q);
743
    q = bro(q);
710
    props (son (q)) = (prop)(props(son(q)) & 0xfe);
744
    props(son(q)) = (prop)(props(son(q)) & 0xfe);
711
  };
745
  }
712
  son (crt_repeat) = r;
746
  son(crt_repeat) = r;
713
  crt_repeat = bro(crt_repeat);
747
  crt_repeat = bro(crt_repeat);
714
  setfather(r, q);
748
  setfather(r, q);
715
  return (r);
749
  return(r);
716
}
750
}
-
 
751
 
717
 
752
 
718
/* find the (unique) downward reference to e */
753
/* find the (unique) downward reference to e */
-
 
754
 
719
exp * refto
755
exp *
720
    PROTO_N ( (f, e) )
-
 
721
    PROTO_T ( exp f X exp e )
756
refto(exp f, exp e)
722
{
757
{
723
  exp * x = &son (f);
758
  exp *x = &son(f);
724
  while (*x != e)
759
  while (*x != e) {
725
    x = &bro (*x);
760
    x = &bro(*x);
-
 
761
  }
726
  return (x);
762
  return(x);
727
}
763
}
-
 
764
 
728
 
765
 
729
/* find the father of u */
766
/* find the father of u */
-
 
767
 
730
exp father
768
exp
731
    PROTO_N ( (e) )
-
 
732
    PROTO_T ( exp e )
769
father(exp e)
733
{
770
{
734
  if (e == nilexp)
771
  if (e == nilexp) {
735
    return (e);
772
    return(e);
-
 
773
  }
736
  while (!last (e))
774
  while (!last(e)) {
737
    e = bro (e);
775
    e = bro(e);
-
 
776
  }
738
  return (bro (e));
777
  return(bro(e));
739
}
778
}
740
 
779
 
-
 
780
 
741
/* auxiliary routine for altered, looks up
781
/* auxiliary routine for altered, looks up in the tree n levels, checking */
742
   in the tree n levels, checking */
-
 
-
 
782
 
743
static void altaux
783
static void
744
    PROTO_N ( (e, n, scope) )
-
 
745
    PROTO_T ( exp e X int n X exp scope )
784
altaux(exp e, int n, exp scope)
746
{
785
{
747
  exp f;
786
  exp f;
748
  if (bro (e) == nilexp || e == scope ||
-
 
749
      (name (e) == ident_tag && isglob (e)))
787
  if (bro(e) == nilexp || e == scope || (name(e) == ident_tag && isglob(e))) {
750
    return;			/* ignore if top of tree */
788
    /* ignore if top of tree */
751
  f = father (e);
-
 
752
  if (f == nilexp || bro (f) == nilexp ||
-
 
753
      (name (f) == ident_tag && isglob (f)))
-
 
754
    return;			/* ignore if top of tree */
-
 
755
  if (name (f) == 0) {
-
 
756
    altaux (f, n, scope);
-
 
757
    return;
789
    return;
758
  };
790
  }
-
 
791
  f = father(e);
-
 
792
  if (f == nilexp || bro(f) == nilexp || (name(f) == ident_tag && isglob(f))) {
-
 
793
    /* ignore if top of tree */
-
 
794
    return;
-
 
795
  }
-
 
796
  if (name(f) == 0) {
-
 
797
    altaux(f, n, scope);
-
 
798
    return;
-
 
799
  }
759
  if (!check (f, scope) && n > 1) {
800
  if (!check(f, scope) && n > 1) {
760
    /* do check until n is exhausted */
801
    /* do check until n is exhausted */
761
    altaux (f, n - 1, scope);
802
    altaux(f, n - 1, scope);
762
    return;
803
    return;
763
  };
804
  }
764
}
805
}
-
 
806
 
765
 
807
 
766
/* e has been altered. see if any exp
-
 
767
   higher up the tree can now recognise an
808
/* e has been altered. see if any exp higher up the tree can now recognise an
768
   optimisation (using check) */
809
 * optimisation (using check) */
-
 
810
 
769
void altered
811
void
770
    PROTO_N ( (e, scope) )
-
 
771
    PROTO_T ( exp e X exp scope )
812
altered (exp e, exp scope)
772
{
813
{
773
  altaux (e, 1, scope);
814
  altaux(e, 1, scope);
774
}
815
}
775
 
816
 
776
/* replace old by e, and (if not doing
817
/* replace old by e, and (if not doing deadvar) check whether any consequential
777
   deadvar) check whether any
-
 
778
   consequential optimisations are
818
 * optimisations are possible */
779
   possible */
819
 
780
void replace
820
void
781
    PROTO_N ( (old, e, scope) )
-
 
782
    PROTO_T ( exp old X exp e X exp scope )
821
replace(exp old, exp e, exp scope)
783
{
822
{
784
  exp f = father (old);
823
  exp f = father(old);
785
  exp * ref = refto (f, old);
824
  exp * ref = refto(f, old);
786
  if (last (*ref))
825
  if (last(*ref)) {
787
    setlast (e);
826
    setlast(e);
788
  else
827
  } else {
789
    clearlast (e);
828
    clearlast(e);
-
 
829
  }
790
  bro (e) = bro (*ref);
830
  bro(e) = bro(*ref);
791
  *ref = e;
831
  *ref = e;
792
  if (scope == old)
832
  if (scope == old) {
793
    return;
833
    return;
-
 
834
  }
794
  altered (e, scope);
835
  altered(e, scope);
795
}
836
}
-
 
837
 
796
 
838
 
797
/* copy a labelled statement and put links
839
/* copy a labelled statement and put links into pt so that copies of uses of
798
   into pt so that copies of uses of the
-
 
799
   original can refer to the copy */
840
 * the original can refer to the copy */
-
 
841
 
800
void copy_labst
842
void
801
    PROTO_N ( (e) )
-
 
802
    PROTO_T ( exp e )
843
copy_labst(exp e)
803
{
844
{
804
  exp t = copyexp (e);
845
  exp t = copyexp(e);
805
  exp d = copyexp (son (e));
846
  exp d = copyexp(son(e));
806
  setcopy(e);
847
  setcopy(e);
807
  no (t) = 0;
848
  no(t) = 0;
808
  no (d) = 0;
849
  no(d) = 0;
809
  pt (d) = pt (e);
850
  pt(d) = pt(e);
810
  pt (t) = nilexp;
851
  pt(t) = nilexp;
811
  pt (e) = t;
852
  pt(e) = t;
812
  son (t) = d;
853
  son(t) = d;
813
  ++proc_label_count;
854
  ++proc_label_count;
814
}
855
}
815
 
856
 
-
 
857
 
816
/* end the copy of a labelled statement
858
/* end the copy of a labelled statement and restore the original state */
817
   and restore the original state */
-
 
-
 
859
 
818
exp undo_labst
860
exp
819
    PROTO_N ( (e) )
-
 
820
    PROTO_T ( exp e )
861
undo_labst(exp e)
821
{
862
{
822
  exp r = pt (e);
863
  exp r = pt(e);
823
  pt (e) = pt (son (r));
864
  pt(e) = pt(son(r));
824
  clearcopy(e);
865
  clearcopy(e);
825
  return (r);
866
  return(r);
826
}
867
}
827
 
868
 
828
exp copy_res PROTO_S ( ( exp, exp, exp ) ) ;
-
 
829
exp copy PROTO_S ( ( exp ) ) ;
-
 
830
 
869
 
831
/* used to copy cond, repeat and solve so
870
exp copy_res(exp, exp, exp);
832
   that copies of references to the
871
exp copy(exp);
-
 
872
 
833
   labelled statements can refer to the
873
/* used to copy cond, repeat and solve so that copies of references to the
834
   copies of the labelled statements */
874
 * labelled statements can refer to the copies of the labelled statements */
-
 
875
 
835
static exp copy_cpd
876
static
836
    PROTO_N ( (e, new_record, var, lab) )
-
 
837
    PROTO_T ( exp e X exp new_record X exp var X exp lab )
877
exp copy_cpd(exp e, exp new_record, exp var, exp lab)
838
{
878
{
839
  exp t = copyexp (e);
879
  exp t = copyexp(e);
840
  exp q;
880
  exp q;
841
  exp j, c, s, n, k;
881
  exp j, c, s, n, k;
842
 
882
 
-
 
883
  if (new_record != nilexp) {
843
  if (new_record != nilexp) {	/* record the construction */
884
    /* record the construction */
844
    pt (t) = new_record;
885
    pt(t) = new_record;
845
    son (new_record) = t;
886
    son(new_record) = t;
846
  };
887
  }
847
 
888
 
848
  /* copy the labelled statements */
889
  /* copy the labelled statements */
849
  q = bro (son (e));
890
  q = bro(son(e));
850
  copy_labst (q);
891
  copy_labst(q);
851
  while (!last (q)) {
892
  while (!last(q)) {
852
    q = bro (q);
893
    q = bro(q);
853
    copy_labst (q);
894
    copy_labst(q);
854
  }
895
  }
855
 
896
 
856
  /* copy the bodies of the labelled statments */
897
  /* copy the bodies of the labelled statments */
857
  q = bro (son (e));
898
  q = bro(son(e));
858
  while (j = copy_res (bro (son (q)), var, lab),
899
  while (j = copy_res(bro(son(q)), var, lab), c = pt(q), bro(son(c)) = j,
859
      c = pt (q),
-
 
860
      bro (son (c)) = j,
-
 
861
      bro (j) = c,
-
 
862
      setlast (j),
900
	 bro(j) = c, setlast(j), !last(q)) {
863
      !last (q))
-
 
864
    q = bro (q);
901
    q = bro(q);
-
 
902
  }
865
 
903
 
866
  /* copy the lead statement */
904
  /* copy the lead statement */
867
  s = copy_res (son (e), var, lab);
905
  s = copy_res(son(e), var, lab);
868
  son (t) = s;
906
  son(t) = s;
869
  clearlast (s);
907
  clearlast(s);
870
  q = bro (son (e));
908
  q = bro(son(e));
871
  n = s;
909
  n = s;
872
 
910
 
873
  /* restore the labelled statements */
911
  /* restore the labelled statements */
874
  while (k = undo_labst (q),
912
  while (k = undo_labst(q), bro(n) = k, clearlast(n), !last(q)) {
875
      bro (n) = k,
-
 
876
      clearlast (n),
-
 
877
      !last (q)) {
-
 
878
    q = bro (q);
913
    q = bro(q);
879
    n = bro (n);
914
    n = bro(n);
880
  };
915
  }
881
 
916
 
882
  n = bro (n);
917
  n = bro(n);
883
  setlast (n);
918
  setlast(n);
884
  bro (n) = t;
919
  bro(n) = t;
885
  return (t);
920
  return(t);
886
}
921
}
-
 
922
 
887
 
923
 
888
/******************************************************************
924
/******************************************************************
889
  copy copies e and all its sub-cells recursively, amending usage
925
  copy copies e and all its sub-cells recursively, amending usage
890
  counts as necessary. It sets up identifier usage lists for the
926
  counts as necessary. It sets up identifier usage lists for the
891
  declarations which it copies.
927
  declarations which it copies.
892
 ******************************************************************/
928
 ******************************************************************/
893
 
929
 
894
exp copy_res
930
exp
895
    PROTO_N ( (e, var, lab) )
-
 
896
    PROTO_T ( exp e X exp var X exp lab )
931
copy_res(exp e, exp var, exp lab)
897
{
932
{
898
  if (e == nilexp)
933
  if (e == nilexp) {
899
    return (e);
934
    return(e);
900
#ifdef NEWDIAGS
935
#ifdef NEWDIAGS
901
  else
-
 
902
  if (dgf(e) != nildiag)
936
  } else if (dgf(e) != nildiag) {
903
    return copy_res_diag (e, dgf(e), var, lab);
937
    return copy_res_diag(e, dgf(e), var, lab);
904
#endif
938
#endif
905
  else {
939
  } else {
906
    unsigned char n = name (e);
940
    unsigned char n = name(e);
907
 
941
 
908
    if (n == ident_tag) {
942
    if (n == ident_tag) {
909
      exp t = copyexp (e);
943
      exp t = copyexp(e);
910
      exp x = pt (e);		/* remember the usage list */
944
      exp x = pt(e);		/* remember the usage list */
911
      exp s, bs;
945
      exp s, bs;
912
      setcopy (e);		/* mark e as being copied */
946
      setcopy (e);		/* mark e as being copied */
913
      no (t) = 0;		/* clear the usage count */
947
      no(t) = 0;		/* clear the usage count */
914
      pt (e) = t;		/* record the copy in the pt field of the
948
      pt(e) = t;		/* record the copy in the pt field of the
915
				   original */
949
				   original */
916
      pt (t) = nilexp;		/* set the new usage list to empty */
950
      pt(t) = nilexp;		/* set the new usage list to empty */
917
      s = copy_res (son (e), var, lab);	/* copy the definition */
951
      s = copy_res(son(e), var, lab);	/* copy the definition */
918
      bs = copy_res (bro (son (e)), var, lab);/* copy the body */
952
      bs = copy_res(bro(son(e)), var, lab);/* copy the body */
919
      son (t) = s;
953
      son(t) = s;
920
      bro (s) = bs;
954
      bro(s) = bs;
921
      bro (bs) = t;
955
      bro(bs) = t;
922
      clearlast (s);
956
      clearlast(s);
923
      setlast (bs);
957
      setlast(bs);
924
      pt (e) = x;		/* reset the remembered usage list */
958
      pt(e) = x;		/* reset the remembered usage list */
925
      clearcopy (e);		/* remove the copying flag */
959
      clearcopy (e);		/* remove the copying flag */
926
      if (n == ident_tag)
960
      if (n == ident_tag) {
927
	sh (t) = sh (bro (son (t)));/* in case bro(son(t)) is a tuple */
961
	/* in case bro(son(t)) is a tuple */
-
 
962
	sh (t) = sh(bro(son(t)));
-
 
963
      }
928
      return (t);
964
      return(t);
929
    };
965
    }
930
 
966
 
931
    if (n == name_tag) {
967
    if (n == name_tag) {
932
      /* see if the corresponding declaration is being copied and pick up
968
      /* see if the corresponding declaration is being copied and pick up
933
         the correct usage list */
969
         the correct usage list */
934
      exp tp = (copying (son (e)) ? pt (son (e)) : son (e));
970
      exp tp = (copying(son(e))? pt(son(e)): son(e));
935
      exp r = copyexp (e);
971
      exp r = copyexp(e);
936
      son (r) = tp;		/* add this use onto the correct usage
972
      son(r) = tp;		/* add this use onto the correct usage
937
				   list */
973
				   list */
938
      pt (r) = pt (tp);
974
      pt(r) = pt(tp);
939
      pt (tp) = r;
975
      pt(tp) = r;
940
#ifdef NEWDIAGS
976
#ifdef NEWDIAGS
941
      if (!isdiaginfo(r))
977
      if (!isdiaginfo(r))
942
#endif
978
#endif
943
      {
979
      {
944
	++no (tp);		/* increment the correct usage count */
980
	++no(tp);		/* increment the correct usage count */
-
 
981
	if (isglob(tp)) {
945
	if (isglob(tp)) proc_externs = 1;
982
	  proc_externs = 1;
-
 
983
	}
946
      }
984
      }
947
      return (r);
985
      return(r);
948
    };
986
    }
949
 
987
 
950
    if (n == env_offset_tag || n == general_env_offset_tag) {
988
    if (n == env_offset_tag || n == general_env_offset_tag) {
951
      /* see if the corresponding declaration is being copied and pick up
989
      /* see if the corresponding declaration is being copied and pick up
952
         the correct usage list */
990
         the correct usage list */
953
      exp tp = (copying (son (e)) ? pt (son (e)) : son (e));
991
      exp tp = (copying(son(e))? pt(son(e)): son(e));
954
      exp r = copyexp (e);
992
      exp r = copyexp(e);
955
      son (r) = tp;		/* add this use onto the correct usage
993
      son(r) = tp;		/* add this use onto the correct usage
956
				   list */
994
				   list */
957
      return (r);
995
      return(r);
958
    };
996
    }
959
 
997
 
960
    if (n == cond_tag) {
998
    if (n == cond_tag) {
961
      exp z = copy_cpd (e, nilexp, var, lab);
999
      exp z = copy_cpd(e, nilexp, var, lab);
962
      return (z);
1000
      return(z);
963
    };
1001
    }
964
 
1002
 
965
    if (n == rep_tag || n == solve_tag) {
1003
    if (n == rep_tag || n == solve_tag) {
966
      /* we have to update the repeat records */
1004
      /* we have to update the repeat records */
967
      exp record = pt (e);
1005
      exp record = pt(e);
968
      exp z;
1006
      exp z;
969
      if (record != nilexp) {
1007
      if (record != nilexp) {
970
        exp senior = bro (record);
1008
        exp senior = bro(record);
971
        exp new_record = copyexp (record);
1009
        exp new_record = copyexp(record);
972
	if (senior == nilexp) { /* XX008 */
1010
	if (senior == nilexp) {
-
 
1011
	  /* XX008 */
973
	  senior = crt_repeat;
1012
	  senior = crt_repeat;
974
	  bro(new_record) = senior;
1013
	  bro(new_record) = senior;
975
	};
1014
	}
976
        set_copying_solve (record);/* mark as being copied */
1015
        set_copying_solve (record);/* mark as being copied */
977
        pt (record) = new_record;
1016
        pt(record) = new_record;
978
 
1017
 
979
        if (senior != nilexp) {	/* update repeat records */
1018
        if (senior != nilexp) {
-
 
1019
	  /* update repeat records */
980
	  if ((props (senior) & 1) == 1)
1020
	  if ((props(senior) & 1) == 1) {
981
	    bro (new_record) = pt (senior);
1021
	    bro(new_record) = pt(senior);
982
	  else
1022
	  } else {
983
	    ++no (senior);
1023
	    ++no(senior);
-
 
1024
	  }
984
        };
1025
        }
985
        z = copy_cpd (e, new_record, var, lab);
1026
        z = copy_cpd(e, new_record, var, lab);
986
        clear_copying_solve(record);	/* unmark copying flag */
1027
        clear_copying_solve(record);	/* unmark copying flag */
987
      }
-
 
988
      else {
1028
      } else {
989
	z = copy_cpd (e, nilexp, var, lab);
1029
	z = copy_cpd(e, nilexp, var, lab);
990
      };
1030
      }
991
      return (z);
1031
      return(z);
992
    };
1032
    }
993
 
1033
 
994
    if (n == case_tag) {
1034
    if (n == case_tag) {
995
      exp t = copy_res (son (e), var, lab);
1035
      exp t = copy_res(son(e), var, lab);
996
      exp z = copyexp (e);
1036
      exp z = copyexp(e);
997
      exp q = son (e);
1037
      exp q = son(e);
998
      exp p = t;
1038
      exp p = t;
999
      exp labloc, tp;
1039
      exp labloc, tp;
1000
      son (z) = t;
1040
      son(z) = t;
1001
      while (!last (q)) {
1041
      while (!last(q)) {
1002
	setbro (p, copyexp (bro (q)));
1042
	setbro(p, copyexp(bro(q)));
1003
	if (son (bro (q)) != nilexp)
1043
	if (son(bro(q)) != nilexp) {
1004
	  setson (bro (p), copyexp (son (bro (q))));
1044
	  setson(bro(p), copyexp(son(bro(q))));
-
 
1045
	}
1005
	labloc = pt (bro (p));
1046
	labloc = pt(bro(p));
1006
	tp = (copying(labloc)) ? pt (labloc) : labloc;
1047
	tp = (copying(labloc))? pt(labloc): labloc;
1007
	pt (bro (p)) = tp;
1048
	pt(bro(p)) = tp;
1008
	no (son (tp))++;
1049
	no(son(tp)) ++;
1009
	p = bro (p);
1050
	p = bro(p);
1010
	q = bro (q);
1051
	q = bro(q);
1011
      };
1052
      }
1012
      bro (p) = z;
1053
      bro(p) = z;
1013
      if (PIC_code) proc_externs = 1;
1054
      if (PIC_code) {
-
 
1055
	proc_externs = 1;
-
 
1056
      }
1014
      return (z);
1057
      return(z);
1015
    };
1058
    }
1016
 
1059
 
1017
    if (n == real_tag || (n == val_tag && isbigval(e))) {
1060
    if (n == real_tag || (n == val_tag && isbigval(e))) {
1018
      exp z = copyexp (e);
1061
      exp z = copyexp(e);
1019
      flpt f = new_flpt ();
1062
      flpt f = new_flpt();
1020
      flt_copy (flptnos[no (e)], &flptnos[f]);
1063
      flt_copy(flptnos[no(e)], &flptnos[f]);
1021
      no (z) = f;
1064
      no(z) = f;
1022
      if (PIC_code) proc_externs =1;
1065
      if (PIC_code) {
-
 
1066
	proc_externs =1;
-
 
1067
      }
1023
      return (z);
1068
      return(z);
1024
    };
1069
    }
1025
 
1070
 
1026
   if (n == string_tag)
1071
   if (n == string_tag) {
1027
    {
-
 
1028
      exp r = copyexp(e);
1072
      exp r = copyexp(e);
1029
      if (PIC_code) proc_externs =1;
1073
      if (PIC_code) {
-
 
1074
	proc_externs =1;
-
 
1075
      }
1030
      return (r);
1076
      return(r);
1031
    };
1077
    }
1032
 
1078
 
1033
    if (n == res_tag) {
1079
    if (n == res_tag) {
1034
      if (lab != nilexp) {
1080
      if (lab != nilexp) {
1035
	exp go = getexp(f_bottom, nilexp, 0, nilexp, lab,
1081
	exp go = getexp(f_bottom, nilexp, 0, nilexp, lab, 0, 0, goto_tag);
1036
			 0, 0, goto_tag);
-
 
1037
	no(son(lab))++;
1082
	no(son(lab)) ++;
1038
 
1083
 
1039
	if (name(son(e)) == clear_tag) {
1084
	if (name(son(e)) == clear_tag) {
1040
#ifdef NEWDIAGS
1085
#ifdef NEWDIAGS
1041
	  if (extra_diags)
1086
	  if (extra_diags) {
1042
	    diag_inline_result (go);
1087
	    diag_inline_result(go);
-
 
1088
	  }
1043
#endif
1089
#endif
1044
	  return go;
1090
	  return go;
1045
	}
-
 
1046
        else
-
 
1047
        if (var == nilexp) {
1091
	} else if (var == nilexp) {
1048
	  exp_list el;
1092
	  exp_list el;
1049
          exp c = copy(son(e));
1093
	  exp c = copy(son(e));
1050
	  exp s;
1094
	  exp s;
1051
	  el.start = c;
1095
	  el.start = c;
1052
	  el.end = c;
1096
	  el.end = c;
1053
	  el.number = 1;
1097
	  el.number = 1;
1054
	  s = f_sequence(el, go);
1098
	  s = f_sequence(el, go);
1055
#ifdef NEWDIAGS
1099
#ifdef NEWDIAGS
1056
	  if (extra_diags)
1100
	  if (extra_diags) {
1057
	    diag_inline_result (go);
1101
	    diag_inline_result(go);
-
 
1102
	  }
1058
	  return diag_hold_check (s);	/* not inlining */
1103
	  return diag_hold_check(s);	/* not inlining */
1059
#else
1104
#else
1060
          return hold_check(s);
1105
	  return hold_check(s);
1061
#endif
1106
#endif
1062
	}
-
 
1063
	else {
1107
	} else {
1064
	  exp ass;
1108
	  exp ass;
1065
	  exp_list el;
1109
	  exp_list el;
1066
	  exp old_var;
1110
	  exp old_var;
1067
	  exp ident;
1111
	  exp ident;
1068
 
1112
 
1069
	  old_var = copyexp(var);	/* careful - we must not use
1113
	  old_var = copyexp(var);	/* careful - we must not use
1070
					   copy on var because it belongs
1114
					   copy on var because it belongs
1071
					   in the other context recurse!
1115
					   in the other context recurse!
1072
					*/
1116
					*/
1073
	  ident = (copying(son(var))) ? pt(son(var)) : son(var);
1117
	  ident = (copying(son(var)))? pt(son(var)): son(var);
1074
	  pt(old_var) = pt(ident);
1118
	  pt(old_var) = pt(ident);
1075
	  pt(ident) = old_var;
1119
	  pt(ident) = old_var;
1076
	  ++no(ident);
1120
	  ++no(ident);
1077
	  ass = f_assign(old_var, copy(son(e)));
1121
	  ass = f_assign(old_var, copy(son(e)));
1078
	  el.start = ass;
1122
	  el.start = ass;
1079
	  el.end = ass;
1123
	  el.end = ass;
1080
	  el.number = 1;
1124
	  el.number = 1;
1081
#if NEWDIAGS
1125
#if NEWDIAGS
1082
	  if (extra_diags)
1126
	  if (extra_diags) {
1083
	    diag_inline_result (bro(son(ass)));
1127
	    diag_inline_result(bro(son(ass)));
-
 
1128
	  }
1084
#endif
1129
#endif
1085
	  return f_sequence(el, go);
1130
	  return f_sequence(el, go);
1086
	};
1131
	}
1087
      };
1132
      }
1088
 
1133
 
1089
       /* FALL THROUGH if lab == nilexp */
1134
       /* FALL THROUGH if lab == nilexp */
1090
     };
1135
     }
1091
    {
1136
    {
1092
      exp p = pt (e);
1137
      exp p = pt(e);
1093
      exp z = copyexp (e);
1138
      exp z = copyexp(e);
1094
      exp tp;
1139
      exp tp;
1095
      switch (name(e)) {
1140
      switch (name(e)) {
-
 
1141
	case alloca_tag:
1096
	case alloca_tag: case apply_general_tag: has_alloca = 1; break;
1142
	case apply_general_tag:
-
 
1143
	  has_alloca = 1;
-
 
1144
	  break;
1097
	case tail_call_tag: has_alloca = 1; has_setjmp = 1; break;
1145
	case tail_call_tag:
-
 
1146
	  has_alloca = 1;
-
 
1147
	  has_setjmp = 1;
-
 
1148
	  break;
-
 
1149
	case current_env_tag:
-
 
1150
	  uses_crt_env = 1;
1098
	case current_env_tag: uses_crt_env = 1; uses_loc_address = 1;
1151
	  uses_loc_address = 1;
-
 
1152
	  if (in_proc_def) {
1099
		if (in_proc_def) sh(z) = f_pointer(frame_alignment);
1153
	    sh(z) = f_pointer(frame_alignment);
-
 
1154
	  }
1100
		break;
1155
	  break;
1101
        case untidy_return_tag: case local_free_all_tag: case long_jump_tag:
1156
        case untidy_return_tag:
-
 
1157
	case local_free_all_tag:
-
 
1158
	case long_jump_tag:
1102
			has_setjmp = 1; break;
1159
	  has_setjmp = 1; break;
1103
      }
1160
      }
1104
 
1161
 
1105
      if (p != nilexp) {
1162
      if (p != nilexp) {
1106
	/* the pt field must be a label */
1163
	/* the pt field must be a label */
1107
	/* look to see if label is being copied and pick up right
1164
	/* look to see if label is being copied and pick up right
1108
	   statement */
1165
	   statement */
1109
	tp = (copying(p)) ? pt (p) : p;
1166
	tp = (copying(p)) ? pt(p) : p;
1110
	pt (z) = tp;
1167
	pt(z) = tp;
1111
	no (son (tp))++;	/* update label use count */
1168
	no(son(tp))++;	/* update label use count */
1112
      };
1169
      }
1113
 
1170
 
1114
      if (son (e) == nilexp) {
1171
      if (son(e) == nilexp) {
1115
	return (z);
1172
	return(z);
1116
      };
1173
      }
1117
      {
1174
      {
1118
	exp t = son (e);
1175
	exp t = son(e);
1119
	exp q = copy_res (t, var, lab);
1176
	exp q = copy_res(t, var, lab);
1120
	exp ptt = q;
1177
	exp ptt = q;
1121
	while (!last (t)) {	/* copy the arguments */
1178
	while (!last (t)) {	/* copy the arguments */
1122
	  setbro (ptt, copy_res (bro (t), var, lab));
1179
	  setbro(ptt, copy_res(bro(t), var, lab));
1123
	  clearlast (ptt);
1180
	  clearlast(ptt);
1124
	  t = bro (t);
1181
	  t = bro(t);
1125
	  ptt = bro (ptt);
1182
	  ptt = bro(ptt);
1126
	};
1183
	}
1127
	son (z) = q;
1184
	son(z) = q;
1128
	bro (ptt) = z;
1185
	bro(ptt) = z;
1129
	setlast (ptt);
1186
	setlast(ptt);
1130
 
1187
 
1131
	if (n == labst_tag || n == seq_tag)
1188
	if (n == labst_tag || n == seq_tag) {
1132
	  sh (z) = sh (bro (son (z)));
1189
	  /* in case bro(son(z)) is a tuple */
1133
	/* in case bro(son(z)) is a tuple */
1190
	  sh(z) = sh(bro(son(z)));
-
 
1191
	}
1134
 
1192
 
1135
	return (z);
1193
	return(z);
1136
      };
1194
      }
1137
    };
1195
    }
1138
  }
1196
  }
1139
}
1197
}
1140
 
1198
 
-
 
1199
 
1141
exp copy
1200
exp
1142
    PROTO_N ( (e) )
-
 
1143
    PROTO_T ( exp e )
1201
copy(exp e)
1144
{
1202
{
1145
  return copy_res(e, nilexp, nilexp);
1203
  return copy_res(e, nilexp, nilexp);
1146
}
1204
}
1147
 
1205
 
-
 
1206
 
1148
int is_comm
1207
int
1149
    PROTO_N ( ( e ) )
-
 
1150
    PROTO_T ( exp e )
1208
is_comm(exp e)
1151
{
1209
{
1152
    if (no_bss)
1210
  if (no_bss) {
1153
      return 0;
1211
    return 0;
-
 
1212
  }
1154
    switch ( name ( e ) ) {
1213
  switch (name(e)) {
1155
 
1214
 
-
 
1215
  case val_tag:
1156
	case val_tag : return ( no ( e ) ? 0 : 1 ) ;
1216
    return(no(e) ? 0 : 1);
1157
 
1217
 
1158
	case int_to_bitf_tag :
1218
  case int_to_bitf_tag:
-
 
1219
  case chvar_tag:
1159
	case chvar_tag : return ( is_comm ( son ( e ) ) ) ;
1220
    return(is_comm(son(e)));
1160
 
1221
 
1161
	case real_tag : {
1222
  case real_tag: {
1162
	    flpt f = no ( e ) ;
1223
    flpt f = no(e);
1163
	    return ( flptnos [f].sign ? 0 : 1 ) ;
1224
    return(flptnos[f].sign ? 0 : 1);
1164
	}
1225
  }
1165
 
1226
 
1166
	case compound_tag : {
1227
  case compound_tag: {
1167
	    exp t = son ( e ) ;
1228
    exp t = son(e);
1168
	    if ( t == nilexp ) return ( 1 ) ;
1229
    if (t == nilexp) {
-
 
1230
      return(1);
-
 
1231
    }
1169
	    while ( 1 ) {
1232
    while (1) {
1170
		t = bro ( t ) ;
1233
      t = bro(t);
1171
		if ( name ( sh ( t ) ) != bitfhd ) {
1234
      if (name(sh(t)) != bitfhd) {
1172
		    if ( !is_comm ( t ) ) return ( 0 ) ;
1235
	if (!is_comm(t)) {
-
 
1236
	  return(0);
-
 
1237
	}
1173
		} else {
1238
      } else {
1174
		    if ( name ( t ) == val_tag ) {
1239
	if (name(t) == val_tag) {
-
 
1240
	  if (no(t)) {
1175
			if ( no ( t ) ) return ( 0 ) ;
1241
	    return(0);
-
 
1242
	  }
1176
		    } else {
1243
	} else {
1177
			if ( no ( son ( t ) ) ) return ( 0 ) ;
1244
	  if (no(son(t))) {
-
 
1245
	    return(0);
1178
		    }
1246
	  }
1179
		}
1247
	}
-
 
1248
      }
1180
		if ( last ( t ) ) return ( 1 ) ;
1249
      if (last(t)) {
-
 
1250
	return(1);
-
 
1251
      }
1181
		t = bro ( t ) ;
1252
      t = bro(t);
1182
	    }
1253
    }
1183
	    /* Not reached */
1254
    /* Not reached */
1184
	}
1255
  }
1185
 
1256
 
-
 
1257
  case ncopies_tag:
1186
	case ncopies_tag : return ( is_comm ( son ( e ) ) ) ;
1258
    return(is_comm(son(e)));
1187
 
1259
 
1188
	case nof_tag : {
1260
  case nof_tag: {
1189
	    exp t = son ( e ) ;
1261
    exp t = son(e);
1190
	    if ( t == nilexp ) return 1;
1262
    if (t == nilexp) {
-
 
1263
      return 1;
-
 
1264
    }
1191
	    while ( 1 ) {
1265
    while (1) {
1192
		if ( !is_comm ( t ) ) return ( 0 ) ;
1266
      if (!is_comm(t)) {
-
 
1267
	return(0);
-
 
1268
      }
1193
		if ( last ( t ) ) return ( 1 ) ;
1269
      if (last(t)) {
-
 
1270
	return(1);
-
 
1271
      }
1194
		t = bro ( t ) ;
1272
      t = bro(t);
1195
	    }
1273
    }
1196
	    /* Not reached */
1274
    /* Not reached */
1197
	}
1275
  }
1198
 
1276
 
1199
	case concatnof_tag : {
1277
  case concatnof_tag: {
1200
	    exp t = son ( e ) ;
1278
    exp t = son(e);
1201
	    return ( is_comm ( t ) && is_comm ( bro ( t ) ) ) ;
1279
    return(is_comm(t) && is_comm(bro(t)));
1202
	}
1280
  }
1203
 
1281
 
1204
	case clear_tag :
1282
  case clear_tag:
-
 
1283
  case res_tag:
1205
	case res_tag :  return ( 1 ) ;
1284
    return(1);
1206
 
1285
 
-
 
1286
  case null_tag:
1207
	case null_tag : return ( no(e) == 0 ) ;
1287
    return(no(e) == 0);
1208
    }
1288
  }
1209
    return ( 0 ) ;
1289
  return(0);
1210
}
1290
}