1 /*
2    File: dcg_code.c
3    Generated on Thu Feb 24 15:41:57 2005
4 
5    Copyright (C) 2008 Marc Seutter
6 
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 
20    CVS ID: "$Id: dcg_code.c,v 1.8 2008/06/28 13:03:45 marcs Exp $"
21 */
22 
23 /* standard includes */
24 #include <stdio.h>
25 
26 /* support lib includes */
27 #include <dcg.h>
28 #include <dcg_error.h>
29 #include <dcg_alloc.h>
30 #include <dcg_string.h>
31 #include <dcg_xput.h>
32 
33 /* local includes */
34 #include "dcg_code.h"
35 
36 /* Allocate new def_list */
init_def_list(int room)37 def_list init_def_list (int room)
38 	{ def_list new = (def_list) dcg_malloc (sizeof (struct str_def_list));
39 	  int safe_room = (room < 2)?2:room;
40 	  new -> size = 0;
41 	  new -> room = safe_room;
42 	  new -> array = (def *) dcg_calloc (safe_room, sizeof (def));
43 	  return (new);
44 	};
45 
46 /* Allocate new stat_list */
init_stat_list(int room)47 stat_list init_stat_list (int room)
48 	{ stat_list new = (stat_list) dcg_malloc (sizeof (struct str_stat_list));
49 	  int safe_room = (room < 2)?2:room;
50 	  new -> size = 0;
51 	  new -> room = safe_room;
52 	  new -> array = (stat *) dcg_calloc (safe_room, sizeof (stat));
53 	  return (new);
54 	};
55 
56 /* Allocate new field_list */
init_field_list(int room)57 field_list init_field_list (int room)
58 	{ field_list new = (field_list) dcg_malloc (sizeof (struct str_field_list));
59 	  int safe_room = (room < 2)?2:room;
60 	  new -> size = 0;
61 	  new -> room = safe_room;
62 	  new -> array = (field *) dcg_calloc (safe_room, sizeof (field));
63 	  return (new);
64 	};
65 
66 /* Allocate new vfield_list */
init_vfield_list(int room)67 vfield_list init_vfield_list (int room)
68 	{ vfield_list new = (vfield_list) dcg_malloc (sizeof (struct str_vfield_list));
69 	  int safe_room = (room < 2)?2:room;
70 	  new -> size = 0;
71 	  new -> room = safe_room;
72 	  new -> array = (vfield *) dcg_calloc (safe_room, sizeof (vfield));
73 	  return (new);
74 	};
75 
76 /* Allocate new type_list */
init_type_list(int room)77 type_list init_type_list (int room)
78 	{ type_list new = (type_list) dcg_malloc (sizeof (struct str_type_list));
79 	  int safe_room = (room < 2)?2:room;
80 	  new -> size = 0;
81 	  new -> room = safe_room;
82 	  new -> array = (type *) dcg_calloc (safe_room, sizeof (type));
83 	  return (new);
84 	};
85 
86 /* Allocate new string_list */
init_string_list(int room)87 string_list init_string_list (int room)
88 	{ string_list new = (string_list) dcg_malloc (sizeof (struct str_string_list));
89 	  int safe_room = (room < 2)?2:room;
90 	  new -> size = 0;
91 	  new -> room = safe_room;
92 	  new -> array = (string *) dcg_calloc (safe_room, sizeof (string));
93 	  return (new);
94 	};
95 
96 /* Announce to use 'room' chunks for def_list */
room_def_list(def_list l,int room)97 void room_def_list (def_list l, int room)
98 	{ if (room <= l -> room) return;
99 	  dcg_recalloc ((char **) &l -> array, room, sizeof (def));
100 	  l -> room = room;
101 	};
102 
103 /* Announce to use 'room' chunks for stat_list */
room_stat_list(stat_list l,int room)104 void room_stat_list (stat_list l, int room)
105 	{ if (room <= l -> room) return;
106 	  dcg_recalloc ((char **) &l -> array, room, sizeof (stat));
107 	  l -> room = room;
108 	};
109 
110 /* Announce to use 'room' chunks for field_list */
room_field_list(field_list l,int room)111 void room_field_list (field_list l, int room)
112 	{ if (room <= l -> room) return;
113 	  dcg_recalloc ((char **) &l -> array, room, sizeof (field));
114 	  l -> room = room;
115 	};
116 
117 /* Announce to use 'room' chunks for vfield_list */
room_vfield_list(vfield_list l,int room)118 void room_vfield_list (vfield_list l, int room)
119 	{ if (room <= l -> room) return;
120 	  dcg_recalloc ((char **) &l -> array, room, sizeof (vfield));
121 	  l -> room = room;
122 	};
123 
124 /* Announce to use 'room' chunks for type_list */
room_type_list(type_list l,int room)125 void room_type_list (type_list l, int room)
126 	{ if (room <= l -> room) return;
127 	  dcg_recalloc ((char **) &l -> array, room, sizeof (type));
128 	  l -> room = room;
129 	};
130 
131 /* Announce to use 'room' chunks for string_list */
room_string_list(string_list l,int room)132 void room_string_list (string_list l, int room)
133 	{ if (room <= l -> room) return;
134 	  dcg_recalloc ((char **) &l -> array, room, sizeof (string));
135 	  l -> room = room;
136 	};
137 
138 /* Allocate new def record for constructor Primitive */
new_Primitive(string lhs)139 def new_Primitive (string lhs)
140 	{ def new = (def) dcg_malloc (sizeof (struct str_def));
141 	  new -> lhs = lhs;
142 	  new -> nrlsts = int_nil;
143 	  new -> implsts = int_nil;
144 	  new -> tag = TAGPrimitive;
145 	  return (new);
146 	};
147 
148 /* Allocate new def record for constructor Enum */
new_Enum(string lhs,string_list elems)149 def new_Enum (string lhs,
150 		string_list elems)
151 	{ def new = (def) dcg_malloc (sizeof (struct str_def));
152 	  new -> lhs = lhs;
153 	  new -> nrlsts = int_nil;
154 	  new -> implsts = int_nil;
155 	  new -> tag = TAGEnum;
156 	  new -> Enum.elems = elems;
157 	  return (new);
158 	};
159 
160 /* Allocate new def record for constructor Record */
new_Record(string lhs,field_list fixed,vfield_list variant)161 def new_Record (string lhs,
162 		field_list fixed, vfield_list variant)
163 	{ def new = (def) dcg_malloc (sizeof (struct str_def));
164 	  new -> lhs = lhs;
165 	  new -> nrlsts = int_nil;
166 	  new -> implsts = int_nil;
167 	  new -> tag = TAGRecord;
168 	  new -> Record.fixed = fixed;
169 	  new -> Record.variant = variant;
170 	  return (new);
171 	};
172 
173 /* Allocate new stat record for constructor Use */
new_Use(type_list utype)174 stat new_Use (type_list utype)
175 	{ stat new = (stat) dcg_malloc (sizeof (struct str_stat));
176 	  new -> tag = TAGUse;
177 	  new -> Use.utype = utype;
178 	  return (new);
179 	};
180 
181 /* Allocate new stat record for constructor Import */
new_Import(string imp)182 stat new_Import (string imp)
183 	{ stat new = (stat) dcg_malloc (sizeof (struct str_stat));
184 	  new -> tag = TAGImport;
185 	  new -> Import.imp = imp;
186 	  return (new);
187 	};
188 
189 /* Allocate new field record */
new_field(string fname,type ftype,int ftrav)190 field new_field (string fname, type ftype, int ftrav)
191 	{ field new = (field) dcg_malloc (sizeof (struct str_field));
192 	  new -> fname = fname;
193 	  new -> ftype = ftype;
194 	  new -> ftrav = ftrav;
195 	  return (new);
196 	};
197 
198 /* Allocate new vfield record */
new_vfield(string cons,field_list parts)199 vfield new_vfield (string cons, field_list parts)
200 	{ vfield new = (vfield) dcg_malloc (sizeof (struct str_vfield));
201 	  new -> cons = cons;
202 	  new -> parts = parts;
203 	  return (new);
204 	};
205 
206 /* Allocate new type record for constructor Tname */
new_Tname(string tname)207 type new_Tname (string tname)
208 	{ type new = (type) dcg_malloc (sizeof (struct str_type));
209 	  new -> tag = TAGTname;
210 	  new -> Tname.tname = tname;
211 	  return (new);
212 	};
213 
214 /* Allocate new type record for constructor Tlist */
new_Tlist(type etyp)215 type new_Tlist (type etyp)
216 	{ type new = (type) dcg_malloc (sizeof (struct str_type));
217 	  new -> tag = TAGTlist;
218 	  new -> Tlist.etyp = etyp;
219 	  return (new);
220 	};
221 
222 /* Recursively detach a def */
detach_def(def * optr)223 void detach_def (def *optr)
224 	{ def old = (def) dcg_predetach ((char **) optr);
225 	  if (old == def_nil) return;
226 	  detach_string (&(old -> lhs));
227 	  switch (old -> tag)
228 	     { case TAGPrimitive:
229 		  break;
230 	       case TAGEnum:
231 		  detach_string_list (&(old -> Enum.elems));
232 		  break;
233 	       case TAGRecord:
234 		  detach_field_list (&(old -> Record.fixed));
235 		  detach_vfield_list (&(old -> Record.variant));
236 		  break;
237 	       default:
238 		  bad_tag ((int) old -> tag, "detach_def");
239 	     };
240 	  dcg_detach ((char **) &old);
241 	};
242 
243 /* Recursively detach a stat */
detach_stat(stat * optr)244 void detach_stat (stat *optr)
245 	{ stat old = (stat) dcg_predetach ((char **) optr);
246 	  if (old == stat_nil) return;
247 	  switch (old -> tag)
248 	     { case TAGUse:
249 		  detach_type_list (&(old -> Use.utype));
250 		  break;
251 	       case TAGImport:
252 		  detach_string (&(old -> Import.imp));
253 		  break;
254 	       default:
255 		  bad_tag ((int) old -> tag, "detach_stat");
256 	     };
257 	  dcg_detach ((char **) &old);
258 	};
259 
260 /* Recursively detach a field */
detach_field(field * optr)261 void detach_field (field *optr)
262 	{ field old = (field) dcg_predetach ((char **) optr);
263 	  if (old == field_nil) return;
264 	  detach_string (&(old -> fname));
265 	  detach_type (&(old -> ftype));
266 	  detach_int (&(old -> ftrav));
267 	  dcg_detach ((char **) &old);
268 	};
269 
270 /* Recursively detach a vfield */
detach_vfield(vfield * optr)271 void detach_vfield (vfield *optr)
272 	{ vfield old = (vfield) dcg_predetach ((char **) optr);
273 	  if (old == vfield_nil) return;
274 	  detach_string (&(old -> cons));
275 	  detach_field_list (&(old -> parts));
276 	  dcg_detach ((char **) &old);
277 	};
278 
279 /* Recursively detach a type */
detach_type(type * optr)280 void detach_type (type *optr)
281 	{ type old = (type) dcg_predetach ((char **) optr);
282 	  if (old == type_nil) return;
283 	  switch (old -> tag)
284 	     { case TAGTname:
285 		  detach_string (&(old -> Tname.tname));
286 		  break;
287 	       case TAGTlist:
288 		  detach_type (&(old -> Tlist.etyp));
289 		  break;
290 	       default:
291 		  bad_tag ((int) old -> tag, "detach_type");
292 	     };
293 	  dcg_detach ((char **) &old);
294 	};
295 
296 /* Recursively detach a def_list */
detach_def_list(def_list * lp)297 void detach_def_list (def_list *lp)
298 	{ int ix;
299 	  def_list old = (def_list) dcg_predetach ((char **) lp);
300 	  if (old == def_list_nil) return;
301 	  for (ix = 0; ix < old -> size; ix++)
302 	     detach_def (&(old -> array[ix]));
303 	  dcg_detach ((char **) &(old -> array));
304 	  dcg_detach ((char **) &old);
305 	};
306 
307 /* Recursively detach a stat_list */
detach_stat_list(stat_list * lp)308 void detach_stat_list (stat_list *lp)
309 	{ int ix;
310 	  stat_list old = (stat_list) dcg_predetach ((char **) lp);
311 	  if (old == stat_list_nil) return;
312 	  for (ix = 0; ix < old -> size; ix++)
313 	     detach_stat (&(old -> array[ix]));
314 	  dcg_detach ((char **) &(old -> array));
315 	  dcg_detach ((char **) &old);
316 	};
317 
318 /* Recursively detach a field_list */
detach_field_list(field_list * lp)319 void detach_field_list (field_list *lp)
320 	{ int ix;
321 	  field_list old = (field_list) dcg_predetach ((char **) lp);
322 	  if (old == field_list_nil) return;
323 	  for (ix = 0; ix < old -> size; ix++)
324 	     detach_field (&(old -> array[ix]));
325 	  dcg_detach ((char **) &(old -> array));
326 	  dcg_detach ((char **) &old);
327 	};
328 
329 /* Recursively detach a vfield_list */
detach_vfield_list(vfield_list * lp)330 void detach_vfield_list (vfield_list *lp)
331 	{ int ix;
332 	  vfield_list old = (vfield_list) dcg_predetach ((char **) lp);
333 	  if (old == vfield_list_nil) return;
334 	  for (ix = 0; ix < old -> size; ix++)
335 	     detach_vfield (&(old -> array[ix]));
336 	  dcg_detach ((char **) &(old -> array));
337 	  dcg_detach ((char **) &old);
338 	};
339 
340 /* Recursively detach a type_list */
detach_type_list(type_list * lp)341 void detach_type_list (type_list *lp)
342 	{ int ix;
343 	  type_list old = (type_list) dcg_predetach ((char **) lp);
344 	  if (old == type_list_nil) return;
345 	  for (ix = 0; ix < old -> size; ix++)
346 	     detach_type (&(old -> array[ix]));
347 	  dcg_detach ((char **) &(old -> array));
348 	  dcg_detach ((char **) &old);
349 	};
350 
351 /* Recursively detach a string_list */
detach_string_list(string_list * lp)352 void detach_string_list (string_list *lp)
353 	{ int ix;
354 	  string_list old = (string_list) dcg_predetach ((char **) lp);
355 	  if (old == string_list_nil) return;
356 	  for (ix = 0; ix < old -> size; ix++)
357 	     detach_string (&(old -> array[ix]));
358 	  dcg_detach ((char **) &(old -> array));
359 	  dcg_detach ((char **) &old);
360 	};
361 
362 /* Detach a def_list without detaching elements */
nonrec_detach_def_list(def_list * lp)363 void nonrec_detach_def_list (def_list *lp)
364 	{ def_list old = (def_list) dcg_predetach ((char **) lp);
365 	  if (old == def_list_nil) return;
366 	  dcg_detach ((char **) &(old -> array));
367 	  dcg_detach ((char **) &old);
368 	};
369 
370 /* Detach a stat_list without detaching elements */
nonrec_detach_stat_list(stat_list * lp)371 void nonrec_detach_stat_list (stat_list *lp)
372 	{ stat_list old = (stat_list) dcg_predetach ((char **) lp);
373 	  if (old == stat_list_nil) return;
374 	  dcg_detach ((char **) &(old -> array));
375 	  dcg_detach ((char **) &old);
376 	};
377 
378 /* Detach a field_list without detaching elements */
nonrec_detach_field_list(field_list * lp)379 void nonrec_detach_field_list (field_list *lp)
380 	{ field_list old = (field_list) dcg_predetach ((char **) lp);
381 	  if (old == field_list_nil) return;
382 	  dcg_detach ((char **) &(old -> array));
383 	  dcg_detach ((char **) &old);
384 	};
385 
386 /* Detach a vfield_list without detaching elements */
nonrec_detach_vfield_list(vfield_list * lp)387 void nonrec_detach_vfield_list (vfield_list *lp)
388 	{ vfield_list old = (vfield_list) dcg_predetach ((char **) lp);
389 	  if (old == vfield_list_nil) return;
390 	  dcg_detach ((char **) &(old -> array));
391 	  dcg_detach ((char **) &old);
392 	};
393 
394 /* Detach a type_list without detaching elements */
nonrec_detach_type_list(type_list * lp)395 void nonrec_detach_type_list (type_list *lp)
396 	{ type_list old = (type_list) dcg_predetach ((char **) lp);
397 	  if (old == type_list_nil) return;
398 	  dcg_detach ((char **) &(old -> array));
399 	  dcg_detach ((char **) &old);
400 	};
401 
402 /* Detach a string_list without detaching elements */
nonrec_detach_string_list(string_list * lp)403 void nonrec_detach_string_list (string_list *lp)
404 	{ string_list old = (string_list) dcg_predetach ((char **) lp);
405 	  if (old == string_list_nil) return;
406 	  dcg_detach ((char **) &(old -> array));
407 	  dcg_detach ((char **) &old);
408 	};
409 
410 /* Append element to def_list */
append_def_list(def_list l,def el)411 def_list append_def_list (def_list l, def el)
412 	{ dcg_cknonshared ((char *) l);
413 	  if (l -> size == l -> room)
414 	     room_def_list (l, l -> size << 1);
415 	  l -> array[l -> size] = el;
416 	  l -> size++;
417 	  return (l);
418 	};
419 
420 /* Append element to stat_list */
append_stat_list(stat_list l,stat el)421 stat_list append_stat_list (stat_list l, stat el)
422 	{ dcg_cknonshared ((char *) l);
423 	  if (l -> size == l -> room)
424 	     room_stat_list (l, l -> size << 1);
425 	  l -> array[l -> size] = el;
426 	  l -> size++;
427 	  return (l);
428 	};
429 
430 /* Append element to field_list */
append_field_list(field_list l,field el)431 field_list append_field_list (field_list l, field el)
432 	{ dcg_cknonshared ((char *) l);
433 	  if (l -> size == l -> room)
434 	     room_field_list (l, l -> size << 1);
435 	  l -> array[l -> size] = el;
436 	  l -> size++;
437 	  return (l);
438 	};
439 
440 /* Append element to vfield_list */
append_vfield_list(vfield_list l,vfield el)441 vfield_list append_vfield_list (vfield_list l, vfield el)
442 	{ dcg_cknonshared ((char *) l);
443 	  if (l -> size == l -> room)
444 	     room_vfield_list (l, l -> size << 1);
445 	  l -> array[l -> size] = el;
446 	  l -> size++;
447 	  return (l);
448 	};
449 
450 /* Append element to type_list */
append_type_list(type_list l,type el)451 type_list append_type_list (type_list l, type el)
452 	{ dcg_cknonshared ((char *) l);
453 	  if (l -> size == l -> room)
454 	     room_type_list (l, l -> size << 1);
455 	  l -> array[l -> size] = el;
456 	  l -> size++;
457 	  return (l);
458 	};
459 
460 /* Append element to string_list */
append_string_list(string_list l,string el)461 string_list append_string_list (string_list l, string el)
462 	{ dcg_cknonshared ((char *) l);
463 	  if (l -> size == l -> room)
464 	     room_string_list (l, l -> size << 1);
465 	  l -> array[l -> size] = el;
466 	  l -> size++;
467 	  return (l);
468 	};
469 
470 /* Concatenate two def_lists */
concat_def_list(def_list l1,def_list l2)471 def_list concat_def_list (def_list l1, def_list l2)
472 	{ int ix;
473 	  dcg_cknonshared ((char *) l1);
474 	  room_def_list (l1, l1 -> size + l2 -> size);
475 	  for (ix = 0; ix < l2 -> size; ix++)
476 	     l1 -> array[l1 -> size + ix] = l2 -> array[ix];
477 	  l1 -> size += l2 -> size;
478 	  return (l1);
479 	};
480 
481 /* Concatenate two stat_lists */
concat_stat_list(stat_list l1,stat_list l2)482 stat_list concat_stat_list (stat_list l1, stat_list l2)
483 	{ int ix;
484 	  dcg_cknonshared ((char *) l1);
485 	  room_stat_list (l1, l1 -> size + l2 -> size);
486 	  for (ix = 0; ix < l2 -> size; ix++)
487 	     l1 -> array[l1 -> size + ix] = l2 -> array[ix];
488 	  l1 -> size += l2 -> size;
489 	  return (l1);
490 	};
491 
492 /* Concatenate two field_lists */
concat_field_list(field_list l1,field_list l2)493 field_list concat_field_list (field_list l1, field_list l2)
494 	{ int ix;
495 	  dcg_cknonshared ((char *) l1);
496 	  room_field_list (l1, l1 -> size + l2 -> size);
497 	  for (ix = 0; ix < l2 -> size; ix++)
498 	     l1 -> array[l1 -> size + ix] = l2 -> array[ix];
499 	  l1 -> size += l2 -> size;
500 	  return (l1);
501 	};
502 
503 /* Concatenate two vfield_lists */
concat_vfield_list(vfield_list l1,vfield_list l2)504 vfield_list concat_vfield_list (vfield_list l1, vfield_list l2)
505 	{ int ix;
506 	  dcg_cknonshared ((char *) l1);
507 	  room_vfield_list (l1, l1 -> size + l2 -> size);
508 	  for (ix = 0; ix < l2 -> size; ix++)
509 	     l1 -> array[l1 -> size + ix] = l2 -> array[ix];
510 	  l1 -> size += l2 -> size;
511 	  return (l1);
512 	};
513 
514 /* Concatenate two type_lists */
concat_type_list(type_list l1,type_list l2)515 type_list concat_type_list (type_list l1, type_list l2)
516 	{ int ix;
517 	  dcg_cknonshared ((char *) l1);
518 	  room_type_list (l1, l1 -> size + l2 -> size);
519 	  for (ix = 0; ix < l2 -> size; ix++)
520 	     l1 -> array[l1 -> size + ix] = l2 -> array[ix];
521 	  l1 -> size += l2 -> size;
522 	  return (l1);
523 	};
524 
525 /* Concatenate two string_lists */
concat_string_list(string_list l1,string_list l2)526 string_list concat_string_list (string_list l1, string_list l2)
527 	{ int ix;
528 	  dcg_cknonshared ((char *) l1);
529 	  room_string_list (l1, l1 -> size + l2 -> size);
530 	  for (ix = 0; ix < l2 -> size; ix++)
531 	     l1 -> array[l1 -> size + ix] = l2 -> array[ix];
532 	  l1 -> size += l2 -> size;
533 	  return (l1);
534 	};
535 
536 /* Insert element into def_list at pos 'pos' */
insert_def_list(def_list l,int pos,def el)537 def_list insert_def_list (def_list l, int pos, def el)
538 	{ int ix;
539 	  dcg_cknonshared ((char *) l);
540 	  if ((pos < 0) || (pos > l -> size))
541 	     panic ("insert_def_list: position %d out of range", pos);
542 	  if (l -> size == l -> room)
543 	     room_def_list (l, l -> size << 1);
544 	  for (ix = l -> size; pos < ix; ix--)
545 	     l -> array[ix] = l -> array[ix-1];
546 	  l -> array[pos] = el;
547 	  l -> size++;
548 	  return (l);
549 	};
550 
551 /* Insert element into stat_list at pos 'pos' */
insert_stat_list(stat_list l,int pos,stat el)552 stat_list insert_stat_list (stat_list l, int pos, stat el)
553 	{ int ix;
554 	  dcg_cknonshared ((char *) l);
555 	  if ((pos < 0) || (pos > l -> size))
556 	     panic ("insert_stat_list: position %d out of range", pos);
557 	  if (l -> size == l -> room)
558 	     room_stat_list (l, l -> size << 1);
559 	  for (ix = l -> size; pos < ix; ix--)
560 	     l -> array[ix] = l -> array[ix-1];
561 	  l -> array[pos] = el;
562 	  l -> size++;
563 	  return (l);
564 	};
565 
566 /* Insert element into field_list at pos 'pos' */
insert_field_list(field_list l,int pos,field el)567 field_list insert_field_list (field_list l, int pos, field el)
568 	{ int ix;
569 	  dcg_cknonshared ((char *) l);
570 	  if ((pos < 0) || (pos > l -> size))
571 	     panic ("insert_field_list: position %d out of range", pos);
572 	  if (l -> size == l -> room)
573 	     room_field_list (l, l -> size << 1);
574 	  for (ix = l -> size; pos < ix; ix--)
575 	     l -> array[ix] = l -> array[ix-1];
576 	  l -> array[pos] = el;
577 	  l -> size++;
578 	  return (l);
579 	};
580 
581 /* Insert element into vfield_list at pos 'pos' */
insert_vfield_list(vfield_list l,int pos,vfield el)582 vfield_list insert_vfield_list (vfield_list l, int pos, vfield el)
583 	{ int ix;
584 	  dcg_cknonshared ((char *) l);
585 	  if ((pos < 0) || (pos > l -> size))
586 	     panic ("insert_vfield_list: position %d out of range", pos);
587 	  if (l -> size == l -> room)
588 	     room_vfield_list (l, l -> size << 1);
589 	  for (ix = l -> size; pos < ix; ix--)
590 	     l -> array[ix] = l -> array[ix-1];
591 	  l -> array[pos] = el;
592 	  l -> size++;
593 	  return (l);
594 	};
595 
596 /* Insert element into type_list at pos 'pos' */
insert_type_list(type_list l,int pos,type el)597 type_list insert_type_list (type_list l, int pos, type el)
598 	{ int ix;
599 	  dcg_cknonshared ((char *) l);
600 	  if ((pos < 0) || (pos > l -> size))
601 	     panic ("insert_type_list: position %d out of range", pos);
602 	  if (l -> size == l -> room)
603 	     room_type_list (l, l -> size << 1);
604 	  for (ix = l -> size; pos < ix; ix--)
605 	     l -> array[ix] = l -> array[ix-1];
606 	  l -> array[pos] = el;
607 	  l -> size++;
608 	  return (l);
609 	};
610 
611 /* Insert element into string_list at pos 'pos' */
insert_string_list(string_list l,int pos,string el)612 string_list insert_string_list (string_list l, int pos, string el)
613 	{ int ix;
614 	  dcg_cknonshared ((char *) l);
615 	  if ((pos < 0) || (pos > l -> size))
616 	     panic ("insert_string_list: position %d out of range", pos);
617 	  if (l -> size == l -> room)
618 	     room_string_list (l, l -> size << 1);
619 	  for (ix = l -> size; pos < ix; ix--)
620 	     l -> array[ix] = l -> array[ix-1];
621 	  l -> array[pos] = el;
622 	  l -> size++;
623 	  return (l);
624 	};
625 
626 /* Delete element from def_list at pos 'pos' */
delete_def_list(def_list l,int pos)627 def_list delete_def_list (def_list l, int pos)
628 	{ int ix;
629 	  dcg_cknonshared ((char *) l);
630 	  if ((pos < 0) || (pos >= l -> size))
631 	     panic ("delete_def_list: position %d out of range", pos);
632 	  for (ix = pos; ix < l -> size - 1; ix++)
633 	     l -> array[ix] = l -> array[ix+1];
634 	  l -> size--;
635 	  return (l);
636 	};
637 
638 /* Delete element from stat_list at pos 'pos' */
delete_stat_list(stat_list l,int pos)639 stat_list delete_stat_list (stat_list l, int pos)
640 	{ int ix;
641 	  dcg_cknonshared ((char *) l);
642 	  if ((pos < 0) || (pos >= l -> size))
643 	     panic ("delete_stat_list: position %d out of range", pos);
644 	  for (ix = pos; ix < l -> size - 1; ix++)
645 	     l -> array[ix] = l -> array[ix+1];
646 	  l -> size--;
647 	  return (l);
648 	};
649 
650 /* Delete element from field_list at pos 'pos' */
delete_field_list(field_list l,int pos)651 field_list delete_field_list (field_list l, int pos)
652 	{ int ix;
653 	  dcg_cknonshared ((char *) l);
654 	  if ((pos < 0) || (pos >= l -> size))
655 	     panic ("delete_field_list: position %d out of range", pos);
656 	  for (ix = pos; ix < l -> size - 1; ix++)
657 	     l -> array[ix] = l -> array[ix+1];
658 	  l -> size--;
659 	  return (l);
660 	};
661 
662 /* Delete element from vfield_list at pos 'pos' */
delete_vfield_list(vfield_list l,int pos)663 vfield_list delete_vfield_list (vfield_list l, int pos)
664 	{ int ix;
665 	  dcg_cknonshared ((char *) l);
666 	  if ((pos < 0) || (pos >= l -> size))
667 	     panic ("delete_vfield_list: position %d out of range", pos);
668 	  for (ix = pos; ix < l -> size - 1; ix++)
669 	     l -> array[ix] = l -> array[ix+1];
670 	  l -> size--;
671 	  return (l);
672 	};
673 
674 /* Delete element from type_list at pos 'pos' */
delete_type_list(type_list l,int pos)675 type_list delete_type_list (type_list l, int pos)
676 	{ int ix;
677 	  dcg_cknonshared ((char *) l);
678 	  if ((pos < 0) || (pos >= l -> size))
679 	     panic ("delete_type_list: position %d out of range", pos);
680 	  for (ix = pos; ix < l -> size - 1; ix++)
681 	     l -> array[ix] = l -> array[ix+1];
682 	  l -> size--;
683 	  return (l);
684 	};
685 
686 /* Delete element from string_list at pos 'pos' */
delete_string_list(string_list l,int pos)687 string_list delete_string_list (string_list l, int pos)
688 	{ int ix;
689 	  dcg_cknonshared ((char *) l);
690 	  if ((pos < 0) || (pos >= l -> size))
691 	     panic ("delete_string_list: position %d out of range", pos);
692 	  for (ix = pos; ix < l -> size - 1; ix++)
693 	     l -> array[ix] = l -> array[ix+1];
694 	  l -> size--;
695 	  return (l);
696 	};
697 
698 /* Comparison test for a def */
cmp_def(def a,def b)699 int cmp_def (def a, def b)
700 	{ int s;
701 	  if (a == b) return (0);
702 	  if (a == def_nil) return (-1);
703 	  if (b == def_nil) return (1);
704 	  if ((s = cmp_string (a -> lhs, b -> lhs))) return (s);
705 	  if ((s = cmp_int ((int)(a -> tag), (int)(b -> tag)))) return (s);
706 	  switch (a -> tag)
707 	     { case TAGPrimitive:
708 		  break;
709 	       case TAGEnum:
710 		  if ((s = cmp_string_list (a -> Enum.elems, b -> Enum.elems))) return (s);
711 		  break;
712 	       case TAGRecord:
713 		  if ((s = cmp_field_list (a -> Record.fixed, b -> Record.fixed))) return (s);
714 		  if ((s = cmp_vfield_list (a -> Record.variant, b -> Record.variant))) return (s);
715 		  break;
716 	       default:
717 		  bad_tag (a -> tag, "cmp_def");
718 	     };
719 	  return (0);
720 	};
721 
722 /* Comparison test for a stat */
cmp_stat(stat a,stat b)723 int cmp_stat (stat a, stat b)
724 	{ int s;
725 	  if (a == b) return (0);
726 	  if (a == stat_nil) return (-1);
727 	  if (b == stat_nil) return (1);
728 	  if ((s = cmp_int ((int)(a -> tag), (int)(b -> tag)))) return (s);
729 	  switch (a -> tag)
730 	     { case TAGUse:
731 		  if ((s = cmp_type_list (a -> Use.utype, b -> Use.utype))) return (s);
732 		  break;
733 	       case TAGImport:
734 		  if ((s = cmp_string (a -> Import.imp, b -> Import.imp))) return (s);
735 		  break;
736 	       default:
737 		  bad_tag (a -> tag, "cmp_stat");
738 	     };
739 	  return (0);
740 	};
741 
742 /* Comparison test for a field */
cmp_field(field a,field b)743 int cmp_field (field a, field b)
744 	{ int s;
745 	  if (a == b) return (0);
746 	  if (a == field_nil) return (-1);
747 	  if (b == field_nil) return (1);
748 	  if ((s = cmp_string (a -> fname, b -> fname))) return (s);
749 	  if ((s = cmp_type (a -> ftype, b -> ftype))) return (s);
750 	  if ((s = cmp_int (a -> ftrav, b -> ftrav))) return (s);
751 	  return (0);
752 	};
753 
754 /* Comparison test for a vfield */
cmp_vfield(vfield a,vfield b)755 int cmp_vfield (vfield a, vfield b)
756 	{ int s;
757 	  if (a == b) return (0);
758 	  if (a == vfield_nil) return (-1);
759 	  if (b == vfield_nil) return (1);
760 	  if ((s = cmp_string (a -> cons, b -> cons))) return (s);
761 	  if ((s = cmp_field_list (a -> parts, b -> parts))) return (s);
762 	  return (0);
763 	};
764 
765 /* Comparison test for a type */
cmp_type(type a,type b)766 int cmp_type (type a, type b)
767 	{ int s;
768 	  if (a == b) return (0);
769 	  if (a == type_nil) return (-1);
770 	  if (b == type_nil) return (1);
771 	  if ((s = cmp_int ((int)(a -> tag), (int)(b -> tag)))) return (s);
772 	  switch (a -> tag)
773 	     { case TAGTname:
774 		  if ((s = cmp_string (a -> Tname.tname, b -> Tname.tname))) return (s);
775 		  break;
776 	       case TAGTlist:
777 		  if ((s = cmp_type (a -> Tlist.etyp, b -> Tlist.etyp))) return (s);
778 		  break;
779 	       default:
780 		  bad_tag (a -> tag, "cmp_type");
781 	     };
782 	  return (0);
783 	};
784 
785 /* Comparison test for a def_list */
cmp_def_list(def_list a,def_list b)786 int cmp_def_list (def_list a, def_list b)
787 	{ int ix, stat, size;
788 	  if (a == b) return (0);
789 	  if (a == def_list_nil) return (-1);
790 	  if (b == def_list_nil) return (1);
791 	  size = a -> size;
792 	  if (b -> size < size) size = b -> size;
793 	  for (ix = 0; ix < size; ix++)
794 	     if ((stat = cmp_def (a -> array[ix], b -> array[ix])))
795 		return (stat);
796 	  return (cmp_int (a -> size, b -> size));
797 	};
798 
799 /* Comparison test for a stat_list */
cmp_stat_list(stat_list a,stat_list b)800 int cmp_stat_list (stat_list a, stat_list b)
801 	{ int ix, stat, size;
802 	  if (a == b) return (0);
803 	  if (a == stat_list_nil) return (-1);
804 	  if (b == stat_list_nil) return (1);
805 	  size = a -> size;
806 	  if (b -> size < size) size = b -> size;
807 	  for (ix = 0; ix < size; ix++)
808 	     if ((stat = cmp_stat (a -> array[ix], b -> array[ix])))
809 		return (stat);
810 	  return (cmp_int (a -> size, b -> size));
811 	};
812 
813 /* Comparison test for a field_list */
cmp_field_list(field_list a,field_list b)814 int cmp_field_list (field_list a, field_list b)
815 	{ int ix, stat, size;
816 	  if (a == b) return (0);
817 	  if (a == field_list_nil) return (-1);
818 	  if (b == field_list_nil) return (1);
819 	  size = a -> size;
820 	  if (b -> size < size) size = b -> size;
821 	  for (ix = 0; ix < size; ix++)
822 	     if ((stat = cmp_field (a -> array[ix], b -> array[ix])))
823 		return (stat);
824 	  return (cmp_int (a -> size, b -> size));
825 	};
826 
827 /* Comparison test for a vfield_list */
cmp_vfield_list(vfield_list a,vfield_list b)828 int cmp_vfield_list (vfield_list a, vfield_list b)
829 	{ int ix, stat, size;
830 	  if (a == b) return (0);
831 	  if (a == vfield_list_nil) return (-1);
832 	  if (b == vfield_list_nil) return (1);
833 	  size = a -> size;
834 	  if (b -> size < size) size = b -> size;
835 	  for (ix = 0; ix < size; ix++)
836 	     if ((stat = cmp_vfield (a -> array[ix], b -> array[ix])))
837 		return (stat);
838 	  return (cmp_int (a -> size, b -> size));
839 	};
840 
841 /* Comparison test for a type_list */
cmp_type_list(type_list a,type_list b)842 int cmp_type_list (type_list a, type_list b)
843 	{ int ix, stat, size;
844 	  if (a == b) return (0);
845 	  if (a == type_list_nil) return (-1);
846 	  if (b == type_list_nil) return (1);
847 	  size = a -> size;
848 	  if (b -> size < size) size = b -> size;
849 	  for (ix = 0; ix < size; ix++)
850 	     if ((stat = cmp_type (a -> array[ix], b -> array[ix])))
851 		return (stat);
852 	  return (cmp_int (a -> size, b -> size));
853 	};
854 
855 /* Comparison test for a string_list */
cmp_string_list(string_list a,string_list b)856 int cmp_string_list (string_list a, string_list b)
857 	{ int ix, stat, size;
858 	  if (a == b) return (0);
859 	  if (a == string_list_nil) return (-1);
860 	  if (b == string_list_nil) return (1);
861 	  size = a -> size;
862 	  if (b -> size < size) size = b -> size;
863 	  for (ix = 0; ix < size; ix++)
864 	     if ((stat = cmp_string (a -> array[ix], b -> array[ix])))
865 		return (stat);
866 	  return (cmp_int (a -> size, b -> size));
867 	};
868 
869 /* Estimate printing a def */
est_def(def old)870 int est_def (def old)
871 	{ int size = 0;
872 	  if (old == def_nil) return (2);
873 	  size += est_string (old -> lhs) + 2;
874 	  size += PTRWIDTH;
875 	  size += PTRWIDTH;
876 	  switch (old -> tag)
877 	     { case TAGPrimitive:
878 		  size += 11;
879 		  break;
880 	       case TAGEnum:
881 		  size += 6;
882 		  size += est_string_list (old -> Enum.elems) + 2;
883 		  break;
884 	       case TAGRecord:
885 		  size += 8;
886 		  size += est_field_list (old -> Record.fixed) + 2;
887 		  size += est_vfield_list (old -> Record.variant) + 2;
888 		  break;
889 	       default:
890 		  bad_tag (old -> tag, "est_def");
891 	     };
892 	  return (size + 2);
893 	};
894 
895 /* Estimate printing a stat */
est_stat(stat old)896 int est_stat (stat old)
897 	{ int size = 0;
898 	  if (old == stat_nil) return (2);
899 	  switch (old -> tag)
900 	     { case TAGUse:
901 		  size += 5;
902 		  size += est_type_list (old -> Use.utype) + 2;
903 		  break;
904 	       case TAGImport:
905 		  size += 8;
906 		  size += est_string (old -> Import.imp) + 2;
907 		  break;
908 	       default:
909 		  bad_tag (old -> tag, "est_stat");
910 	     };
911 	  return (size + 2);
912 	};
913 
914 /* Estimate printing a field */
est_field(field old)915 int est_field (field old)
916 	{ int size = 0;
917 	  if (old == field_nil) return (2);
918 	  size += est_string (old -> fname) + 2;
919 	  size += est_type (old -> ftype) + 2;
920 	  size += est_int (old -> ftrav) + 2;
921 	  return (size + 2);
922 	};
923 
924 /* Estimate printing a vfield */
est_vfield(vfield old)925 int est_vfield (vfield old)
926 	{ int size = 0;
927 	  if (old == vfield_nil) return (2);
928 	  size += est_string (old -> cons) + 2;
929 	  size += est_field_list (old -> parts) + 2;
930 	  return (size + 2);
931 	};
932 
933 /* Estimate printing a type */
est_type(type old)934 int est_type (type old)
935 	{ int size = 0;
936 	  if (old == type_nil) return (2);
937 	  switch (old -> tag)
938 	     { case TAGTname:
939 		  size += 7;
940 		  size += est_string (old -> Tname.tname) + 2;
941 		  break;
942 	       case TAGTlist:
943 		  size += 7;
944 		  size += est_type (old -> Tlist.etyp) + 2;
945 		  break;
946 	       default:
947 		  bad_tag (old -> tag, "est_type");
948 	     };
949 	  return (size + 2);
950 	};
951 
952 /* Estimate printing a def_list */
est_def_list(def_list old)953 int est_def_list (def_list old)
954 	{ int ix;
955 	  int size = 0;
956 	  if (old == def_list_nil) return (2);
957 	  if (!old -> size) return (2);
958 	  for (ix = 0; ix < old -> size; ix++)
959 	     size += est_def (old -> array[ix]) + 2;
960 	  return (size + 2);
961 	};
962 
963 /* Estimate printing a stat_list */
est_stat_list(stat_list old)964 int est_stat_list (stat_list old)
965 	{ int ix;
966 	  int size = 0;
967 	  if (old == stat_list_nil) return (2);
968 	  if (!old -> size) return (2);
969 	  for (ix = 0; ix < old -> size; ix++)
970 	     size += est_stat (old -> array[ix]) + 2;
971 	  return (size + 2);
972 	};
973 
974 /* Estimate printing a field_list */
est_field_list(field_list old)975 int est_field_list (field_list old)
976 	{ int ix;
977 	  int size = 0;
978 	  if (old == field_list_nil) return (2);
979 	  if (!old -> size) return (2);
980 	  for (ix = 0; ix < old -> size; ix++)
981 	     size += est_field (old -> array[ix]) + 2;
982 	  return (size + 2);
983 	};
984 
985 /* Estimate printing a vfield_list */
est_vfield_list(vfield_list old)986 int est_vfield_list (vfield_list old)
987 	{ int ix;
988 	  int size = 0;
989 	  if (old == vfield_list_nil) return (2);
990 	  if (!old -> size) return (2);
991 	  for (ix = 0; ix < old -> size; ix++)
992 	     size += est_vfield (old -> array[ix]) + 2;
993 	  return (size + 2);
994 	};
995 
996 /* Estimate printing a type_list */
est_type_list(type_list old)997 int est_type_list (type_list old)
998 	{ int ix;
999 	  int size = 0;
1000 	  if (old == type_list_nil) return (2);
1001 	  if (!old -> size) return (2);
1002 	  for (ix = 0; ix < old -> size; ix++)
1003 	     size += est_type (old -> array[ix]) + 2;
1004 	  return (size + 2);
1005 	};
1006 
1007 /* Estimate printing a string_list */
est_string_list(string_list old)1008 int est_string_list (string_list old)
1009 	{ int ix;
1010 	  int size = 0;
1011 	  if (old == string_list_nil) return (2);
1012 	  if (!old -> size) return (2);
1013 	  for (ix = 0; ix < old -> size; ix++)
1014 	     size += est_string (old -> array[ix]) + 2;
1015 	  return (size + 2);
1016 	};
1017 
1018 /* Pretty print a def */
ppp_def(FILE * f,int horiz,int ind,def old)1019 void ppp_def (FILE *f, int horiz, int ind, def old)
1020 	{ int mhoriz;
1021 	  if (old == def_nil) { pppstring (f, "<>"); return; };
1022 	  mhoriz = horiz || (est_def (old) + ind < MAXWIDTH);
1023 	  pppdelim (f, mhoriz, ind, '(');
1024 	  ppp_string (f, mhoriz, ind + 2, old -> lhs);
1025 	  pppdelim (f, mhoriz, ind, ',');
1026 	  ppp_vptr (f, mhoriz, ind + 2, (vptr) old -> nrlsts);
1027 	  pppdelim (f, mhoriz, ind, ',');
1028 	  ppp_vptr (f, mhoriz, ind + 2, (vptr) old -> implsts);
1029 	  pppdelim (f, mhoriz, ind, ',');
1030 	  switch (old -> tag)
1031 	     { case TAGPrimitive:
1032 		  pppstring (f, "Primitive");
1033 		  break;
1034 	       case TAGEnum:
1035 		  pppstring (f, "Enum");
1036 		  pppdelim (f, mhoriz, ind, ',');
1037 		  ppp_string_list (f, mhoriz, ind + 2, old -> Enum.elems);
1038 		  break;
1039 	       case TAGRecord:
1040 		  pppstring (f, "Record");
1041 		  pppdelim (f, mhoriz, ind, ',');
1042 		  ppp_field_list (f, mhoriz, ind + 2, old -> Record.fixed);
1043 		  pppdelim (f, mhoriz, ind, ',');
1044 		  ppp_vfield_list (f, mhoriz, ind + 2, old -> Record.variant);
1045 		  break;
1046 	       default:
1047 		  bad_tag (old -> tag, "ppp_def");
1048 	     };
1049 	  pppdelim (f, mhoriz, ind, ')');
1050 	};
1051 
1052 /* Pretty print a stat */
ppp_stat(FILE * f,int horiz,int ind,stat old)1053 void ppp_stat (FILE *f, int horiz, int ind, stat old)
1054 	{ int mhoriz;
1055 	  if (old == stat_nil) { pppstring (f, "<>"); return; };
1056 	  mhoriz = horiz || (est_stat (old) + ind < MAXWIDTH);
1057 	  pppdelim (f, mhoriz, ind, '(');
1058 	  switch (old -> tag)
1059 	     { case TAGUse:
1060 		  pppstring (f, "Use");
1061 		  pppdelim (f, mhoriz, ind, ',');
1062 		  ppp_type_list (f, mhoriz, ind + 2, old -> Use.utype);
1063 		  break;
1064 	       case TAGImport:
1065 		  pppstring (f, "Import");
1066 		  pppdelim (f, mhoriz, ind, ',');
1067 		  ppp_string (f, mhoriz, ind + 2, old -> Import.imp);
1068 		  break;
1069 	       default:
1070 		  bad_tag (old -> tag, "ppp_stat");
1071 	     };
1072 	  pppdelim (f, mhoriz, ind, ')');
1073 	};
1074 
1075 /* Pretty print a field */
ppp_field(FILE * f,int horiz,int ind,field old)1076 void ppp_field (FILE *f, int horiz, int ind, field old)
1077 	{ int mhoriz;
1078 	  if (old == field_nil) { pppstring (f, "<>"); return; };
1079 	  mhoriz = horiz || (est_field (old) + ind < MAXWIDTH);
1080 	  pppdelim (f, mhoriz, ind, '(');
1081 	  ppp_string (f, mhoriz, ind + 2, old -> fname);
1082 	  pppdelim (f, mhoriz, ind, ',');
1083 	  ppp_type (f, mhoriz, ind + 2, old -> ftype);
1084 	  pppdelim (f, mhoriz, ind, ',');
1085 	  ppp_int (f, mhoriz, ind + 2, old -> ftrav);
1086 	  pppdelim (f, mhoriz, ind, ')');
1087 	};
1088 
1089 /* Pretty print a vfield */
ppp_vfield(FILE * f,int horiz,int ind,vfield old)1090 void ppp_vfield (FILE *f, int horiz, int ind, vfield old)
1091 	{ int mhoriz;
1092 	  if (old == vfield_nil) { pppstring (f, "<>"); return; };
1093 	  mhoriz = horiz || (est_vfield (old) + ind < MAXWIDTH);
1094 	  pppdelim (f, mhoriz, ind, '(');
1095 	  ppp_string (f, mhoriz, ind + 2, old -> cons);
1096 	  pppdelim (f, mhoriz, ind, ',');
1097 	  ppp_field_list (f, mhoriz, ind + 2, old -> parts);
1098 	  pppdelim (f, mhoriz, ind, ')');
1099 	};
1100 
1101 /* Pretty print a type */
ppp_type(FILE * f,int horiz,int ind,type old)1102 void ppp_type (FILE *f, int horiz, int ind, type old)
1103 	{ int mhoriz;
1104 	  if (old == type_nil) { pppstring (f, "<>"); return; };
1105 	  mhoriz = horiz || (est_type (old) + ind < MAXWIDTH);
1106 	  pppdelim (f, mhoriz, ind, '(');
1107 	  switch (old -> tag)
1108 	     { case TAGTname:
1109 		  pppstring (f, "Tname");
1110 		  pppdelim (f, mhoriz, ind, ',');
1111 		  ppp_string (f, mhoriz, ind + 2, old -> Tname.tname);
1112 		  break;
1113 	       case TAGTlist:
1114 		  pppstring (f, "Tlist");
1115 		  pppdelim (f, mhoriz, ind, ',');
1116 		  ppp_type (f, mhoriz, ind + 2, old -> Tlist.etyp);
1117 		  break;
1118 	       default:
1119 		  bad_tag (old -> tag, "ppp_type");
1120 	     };
1121 	  pppdelim (f, mhoriz, ind, ')');
1122 	};
1123 
1124 /* Pretty print a def_list */
ppp_def_list(FILE * f,int horiz,int ind,def_list old)1125 void ppp_def_list (FILE *f, int horiz, int ind, def_list old)
1126 	{ int ix, mhoriz;
1127 	  if (old == def_list_nil) { pppstring (f, "<>"); return; };
1128 	  if (!old -> size) { pppstring (f, "[]"); return; };
1129 	  mhoriz = horiz || (est_def_list (old) + ind < MAXWIDTH);
1130 	  pppdelim (f, mhoriz, ind, '[');
1131 	  for (ix = 0; ix < old -> size; ix++)
1132 	     { ppp_def (f, mhoriz, ind + 2, old -> array[ix]);
1133 	       if (ix != old -> size - 1) pppdelim (f, mhoriz, ind, ',');
1134 	     };
1135 	  pppdelim (f, mhoriz, ind, ']');
1136 	};
1137 
1138 /* Pretty print a stat_list */
ppp_stat_list(FILE * f,int horiz,int ind,stat_list old)1139 void ppp_stat_list (FILE *f, int horiz, int ind, stat_list old)
1140 	{ int ix, mhoriz;
1141 	  if (old == stat_list_nil) { pppstring (f, "<>"); return; };
1142 	  if (!old -> size) { pppstring (f, "[]"); return; };
1143 	  mhoriz = horiz || (est_stat_list (old) + ind < MAXWIDTH);
1144 	  pppdelim (f, mhoriz, ind, '[');
1145 	  for (ix = 0; ix < old -> size; ix++)
1146 	     { ppp_stat (f, mhoriz, ind + 2, old -> array[ix]);
1147 	       if (ix != old -> size - 1) pppdelim (f, mhoriz, ind, ',');
1148 	     };
1149 	  pppdelim (f, mhoriz, ind, ']');
1150 	};
1151 
1152 /* Pretty print a field_list */
ppp_field_list(FILE * f,int horiz,int ind,field_list old)1153 void ppp_field_list (FILE *f, int horiz, int ind, field_list old)
1154 	{ int ix, mhoriz;
1155 	  if (old == field_list_nil) { pppstring (f, "<>"); return; };
1156 	  if (!old -> size) { pppstring (f, "[]"); return; };
1157 	  mhoriz = horiz || (est_field_list (old) + ind < MAXWIDTH);
1158 	  pppdelim (f, mhoriz, ind, '[');
1159 	  for (ix = 0; ix < old -> size; ix++)
1160 	     { ppp_field (f, mhoriz, ind + 2, old -> array[ix]);
1161 	       if (ix != old -> size - 1) pppdelim (f, mhoriz, ind, ',');
1162 	     };
1163 	  pppdelim (f, mhoriz, ind, ']');
1164 	};
1165 
1166 /* Pretty print a vfield_list */
ppp_vfield_list(FILE * f,int horiz,int ind,vfield_list old)1167 void ppp_vfield_list (FILE *f, int horiz, int ind, vfield_list old)
1168 	{ int ix, mhoriz;
1169 	  if (old == vfield_list_nil) { pppstring (f, "<>"); return; };
1170 	  if (!old -> size) { pppstring (f, "[]"); return; };
1171 	  mhoriz = horiz || (est_vfield_list (old) + ind < MAXWIDTH);
1172 	  pppdelim (f, mhoriz, ind, '[');
1173 	  for (ix = 0; ix < old -> size; ix++)
1174 	     { ppp_vfield (f, mhoriz, ind + 2, old -> array[ix]);
1175 	       if (ix != old -> size - 1) pppdelim (f, mhoriz, ind, ',');
1176 	     };
1177 	  pppdelim (f, mhoriz, ind, ']');
1178 	};
1179 
1180 /* Pretty print a type_list */
ppp_type_list(FILE * f,int horiz,int ind,type_list old)1181 void ppp_type_list (FILE *f, int horiz, int ind, type_list old)
1182 	{ int ix, mhoriz;
1183 	  if (old == type_list_nil) { pppstring (f, "<>"); return; };
1184 	  if (!old -> size) { pppstring (f, "[]"); return; };
1185 	  mhoriz = horiz || (est_type_list (old) + ind < MAXWIDTH);
1186 	  pppdelim (f, mhoriz, ind, '[');
1187 	  for (ix = 0; ix < old -> size; ix++)
1188 	     { ppp_type (f, mhoriz, ind + 2, old -> array[ix]);
1189 	       if (ix != old -> size - 1) pppdelim (f, mhoriz, ind, ',');
1190 	     };
1191 	  pppdelim (f, mhoriz, ind, ']');
1192 	};
1193 
1194 /* Pretty print a string_list */
ppp_string_list(FILE * f,int horiz,int ind,string_list old)1195 void ppp_string_list (FILE *f, int horiz, int ind, string_list old)
1196 	{ int ix, mhoriz;
1197 	  if (old == string_list_nil) { pppstring (f, "<>"); return; };
1198 	  if (!old -> size) { pppstring (f, "[]"); return; };
1199 	  mhoriz = horiz || (est_string_list (old) + ind < MAXWIDTH);
1200 	  pppdelim (f, mhoriz, ind, '[');
1201 	  for (ix = 0; ix < old -> size; ix++)
1202 	     { ppp_string (f, mhoriz, ind + 2, old -> array[ix]);
1203 	       if (ix != old -> size - 1) pppdelim (f, mhoriz, ind, ',');
1204 	     };
1205 	  pppdelim (f, mhoriz, ind, ']');
1206 	};
1207 
1208 /* Recursively save a def */
save_def(FILE * f,def old)1209 void save_def (FILE *f, def old)
1210 	{ /* save fixed fields before variant ones */
1211 	  save_string (f, old -> lhs);
1212 	  savechar (f, (char) old -> tag);
1213 	  switch (old -> tag)
1214 	     { case TAGPrimitive:
1215 		  break;
1216 	       case TAGEnum:
1217 		  save_string_list (f, old -> Enum.elems);
1218 		  break;
1219 	       case TAGRecord:
1220 		  save_field_list (f, old -> Record.fixed);
1221 		  save_vfield_list (f, old -> Record.variant);
1222 		  break;
1223 	       default:
1224 		  bad_tag (old -> tag, "save_def");
1225 	     };
1226 	};
1227 
1228 /* Recursively save a stat */
save_stat(FILE * f,stat old)1229 void save_stat (FILE *f, stat old)
1230 	{ /* save fixed fields before variant ones */
1231 	  savechar (f, (char) old -> tag);
1232 	  switch (old -> tag)
1233 	     { case TAGUse:
1234 		  save_type_list (f, old -> Use.utype);
1235 		  break;
1236 	       case TAGImport:
1237 		  save_string (f, old -> Import.imp);
1238 		  break;
1239 	       default:
1240 		  bad_tag (old -> tag, "save_stat");
1241 	     };
1242 	};
1243 
1244 /* Recursively save a field */
save_field(FILE * f,field old)1245 void save_field (FILE *f, field old)
1246 	{ /* save fixed fields before variant ones */
1247 	  save_string (f, old -> fname);
1248 	  save_type (f, old -> ftype);
1249 	  save_int (f, old -> ftrav);
1250 	};
1251 
1252 /* Recursively save a vfield */
save_vfield(FILE * f,vfield old)1253 void save_vfield (FILE *f, vfield old)
1254 	{ /* save fixed fields before variant ones */
1255 	  save_string (f, old -> cons);
1256 	  save_field_list (f, old -> parts);
1257 	};
1258 
1259 /* Recursively save a type */
save_type(FILE * f,type old)1260 void save_type (FILE *f, type old)
1261 	{ /* save fixed fields before variant ones */
1262 	  savechar (f, (char) old -> tag);
1263 	  switch (old -> tag)
1264 	     { case TAGTname:
1265 		  save_string (f, old -> Tname.tname);
1266 		  break;
1267 	       case TAGTlist:
1268 		  save_type (f, old -> Tlist.etyp);
1269 		  break;
1270 	       default:
1271 		  bad_tag (old -> tag, "save_type");
1272 	     };
1273 	};
1274 
1275 /* Recursively save a def_list */
save_def_list(FILE * f,def_list l)1276 void save_def_list (FILE *f, def_list l)
1277 	{ int ix;
1278 	  savesize (f, l -> size);
1279 	  for (ix = 0; ix < l -> size; ix++)
1280 	     save_def (f, l -> array[ix]);
1281 	};
1282 
1283 /* Recursively save a stat_list */
save_stat_list(FILE * f,stat_list l)1284 void save_stat_list (FILE *f, stat_list l)
1285 	{ int ix;
1286 	  savesize (f, l -> size);
1287 	  for (ix = 0; ix < l -> size; ix++)
1288 	     save_stat (f, l -> array[ix]);
1289 	};
1290 
1291 /* Recursively save a field_list */
save_field_list(FILE * f,field_list l)1292 void save_field_list (FILE *f, field_list l)
1293 	{ int ix;
1294 	  savesize (f, l -> size);
1295 	  for (ix = 0; ix < l -> size; ix++)
1296 	     save_field (f, l -> array[ix]);
1297 	};
1298 
1299 /* Recursively save a vfield_list */
save_vfield_list(FILE * f,vfield_list l)1300 void save_vfield_list (FILE *f, vfield_list l)
1301 	{ int ix;
1302 	  savesize (f, l -> size);
1303 	  for (ix = 0; ix < l -> size; ix++)
1304 	     save_vfield (f, l -> array[ix]);
1305 	};
1306 
1307 /* Recursively save a type_list */
save_type_list(FILE * f,type_list l)1308 void save_type_list (FILE *f, type_list l)
1309 	{ int ix;
1310 	  savesize (f, l -> size);
1311 	  for (ix = 0; ix < l -> size; ix++)
1312 	     save_type (f, l -> array[ix]);
1313 	};
1314 
1315 /* Recursively save a string_list */
save_string_list(FILE * f,string_list l)1316 void save_string_list (FILE *f, string_list l)
1317 	{ int ix;
1318 	  savesize (f, l -> size);
1319 	  for (ix = 0; ix < l -> size; ix++)
1320 	     save_string (f, l -> array[ix]);
1321 	};
1322 
1323 /* Recursively load a def */
load_def(FILE * f,def * x)1324 int load_def (FILE *f, def *x)
1325 	{ /* load fixed fields before variant ones */
1326 	  def new = (def) dcg_malloc (sizeof (struct str_def));
1327 	  char ch;
1328 	  if (!load_string (f, &new -> lhs)) return (0);
1329 	  new -> nrlsts = int_nil;
1330 	  new -> implsts = int_nil;
1331 	  if (!loadchar (f, &ch)) return (0);
1332 	  new -> tag = (tags_def) ch;
1333 	  switch (new -> tag)
1334 	     { case TAGPrimitive:
1335 		  break;
1336 	       case TAGEnum:
1337 		  if (!load_string_list (f, &new -> Enum.elems)) return (0);
1338 		  break;
1339 	       case TAGRecord:
1340 		  if (!load_field_list (f, &new -> Record.fixed)) return (0);
1341 		  if (!load_vfield_list (f, &new -> Record.variant)) return (0);
1342 		  break;
1343 	       default:
1344 		  bad_tag (new -> tag, "load_def");
1345 	     };
1346 	  *x = new;
1347 	  return (1);
1348 	};
1349 
1350 /* Recursively load a stat */
load_stat(FILE * f,stat * x)1351 int load_stat (FILE *f, stat *x)
1352 	{ /* load fixed fields before variant ones */
1353 	  stat new = (stat) dcg_malloc (sizeof (struct str_stat));
1354 	  char ch;
1355 	  if (!loadchar (f, &ch)) return (0);
1356 	  new -> tag = (tags_stat) ch;
1357 	  switch (new -> tag)
1358 	     { case TAGUse:
1359 		  if (!load_type_list (f, &new -> Use.utype)) return (0);
1360 		  break;
1361 	       case TAGImport:
1362 		  if (!load_string (f, &new -> Import.imp)) return (0);
1363 		  break;
1364 	       default:
1365 		  bad_tag (new -> tag, "load_stat");
1366 	     };
1367 	  *x = new;
1368 	  return (1);
1369 	};
1370 
1371 /* Recursively load a field */
load_field(FILE * f,field * x)1372 int load_field (FILE *f, field *x)
1373 	{ /* load fixed fields before variant ones */
1374 	  field new = (field) dcg_malloc (sizeof (struct str_field));
1375 	  if (!load_string (f, &new -> fname)) return (0);
1376 	  if (!load_type (f, &new -> ftype)) return (0);
1377 	  if (!load_int (f, &new -> ftrav)) return (0);
1378 	  *x = new;
1379 	  return (1);
1380 	};
1381 
1382 /* Recursively load a vfield */
load_vfield(FILE * f,vfield * x)1383 int load_vfield (FILE *f, vfield *x)
1384 	{ /* load fixed fields before variant ones */
1385 	  vfield new = (vfield) dcg_malloc (sizeof (struct str_vfield));
1386 	  if (!load_string (f, &new -> cons)) return (0);
1387 	  if (!load_field_list (f, &new -> parts)) return (0);
1388 	  *x = new;
1389 	  return (1);
1390 	};
1391 
1392 /* Recursively load a type */
load_type(FILE * f,type * x)1393 int load_type (FILE *f, type *x)
1394 	{ /* load fixed fields before variant ones */
1395 	  type new = (type) dcg_malloc (sizeof (struct str_type));
1396 	  char ch;
1397 	  if (!loadchar (f, &ch)) return (0);
1398 	  new -> tag = (tags_type) ch;
1399 	  switch (new -> tag)
1400 	     { case TAGTname:
1401 		  if (!load_string (f, &new -> Tname.tname)) return (0);
1402 		  break;
1403 	       case TAGTlist:
1404 		  if (!load_type (f, &new -> Tlist.etyp)) return (0);
1405 		  break;
1406 	       default:
1407 		  bad_tag (new -> tag, "load_type");
1408 	     };
1409 	  *x = new;
1410 	  return (1);
1411 	};
1412 
1413 /* Recursively load a def_list */
load_def_list(FILE * f,def_list * l)1414 int load_def_list (FILE *f, def_list *l)
1415 	{ int ix, size;
1416 	  def_list new;
1417 	  if (!loadsize (f, &size)) return (0);
1418 	  new = init_def_list (size);
1419 	  new -> size = size;
1420 	  for (ix = 0; ix < size; ix++)
1421 	     if (!load_def (f, &new -> array[ix])) return (0);
1422 	  *l = new;
1423 	  return (1);
1424 	};
1425 
1426 /* Recursively load a stat_list */
load_stat_list(FILE * f,stat_list * l)1427 int load_stat_list (FILE *f, stat_list *l)
1428 	{ int ix, size;
1429 	  stat_list new;
1430 	  if (!loadsize (f, &size)) return (0);
1431 	  new = init_stat_list (size);
1432 	  new -> size = size;
1433 	  for (ix = 0; ix < size; ix++)
1434 	     if (!load_stat (f, &new -> array[ix])) return (0);
1435 	  *l = new;
1436 	  return (1);
1437 	};
1438 
1439 /* Recursively load a field_list */
load_field_list(FILE * f,field_list * l)1440 int load_field_list (FILE *f, field_list *l)
1441 	{ int ix, size;
1442 	  field_list new;
1443 	  if (!loadsize (f, &size)) return (0);
1444 	  new = init_field_list (size);
1445 	  new -> size = size;
1446 	  for (ix = 0; ix < size; ix++)
1447 	     if (!load_field (f, &new -> array[ix])) return (0);
1448 	  *l = new;
1449 	  return (1);
1450 	};
1451 
1452 /* Recursively load a vfield_list */
load_vfield_list(FILE * f,vfield_list * l)1453 int load_vfield_list (FILE *f, vfield_list *l)
1454 	{ int ix, size;
1455 	  vfield_list new;
1456 	  if (!loadsize (f, &size)) return (0);
1457 	  new = init_vfield_list (size);
1458 	  new -> size = size;
1459 	  for (ix = 0; ix < size; ix++)
1460 	     if (!load_vfield (f, &new -> array[ix])) return (0);
1461 	  *l = new;
1462 	  return (1);
1463 	};
1464 
1465 /* Recursively load a type_list */
load_type_list(FILE * f,type_list * l)1466 int load_type_list (FILE *f, type_list *l)
1467 	{ int ix, size;
1468 	  type_list new;
1469 	  if (!loadsize (f, &size)) return (0);
1470 	  new = init_type_list (size);
1471 	  new -> size = size;
1472 	  for (ix = 0; ix < size; ix++)
1473 	     if (!load_type (f, &new -> array[ix])) return (0);
1474 	  *l = new;
1475 	  return (1);
1476 	};
1477 
1478 /* Recursively load a string_list */
load_string_list(FILE * f,string_list * l)1479 int load_string_list (FILE *f, string_list *l)
1480 	{ int ix, size;
1481 	  string_list new;
1482 	  if (!loadsize (f, &size)) return (0);
1483 	  new = init_string_list (size);
1484 	  new -> size = size;
1485 	  for (ix = 0; ix < size; ix++)
1486 	     if (!load_string (f, &new -> array[ix])) return (0);
1487 	  *l = new;
1488 	  return (1);
1489 	};
1490 
1491 /* Recursively duplicate a def */
rdup_def(def old)1492 def rdup_def (def old)
1493 	{ /* allocate new record */
1494 	  def new;
1495 	  if (old == def_nil) return (old);
1496 	  new = (def) dcg_malloc (sizeof (struct str_def));
1497 	  /* duplicate fixed fields before variant ones */
1498 	  new -> lhs = rdup_string (old -> lhs);
1499 	  new -> tag = old -> tag;
1500 	  switch (old -> tag)
1501 	     { case TAGPrimitive:
1502 		  break;
1503 	       case TAGEnum:
1504 		  new -> Enum.elems = rdup_string_list (old -> Enum.elems);
1505 		  break;
1506 	       case TAGRecord:
1507 		  new -> Record.fixed = rdup_field_list (old -> Record.fixed);
1508 		  new -> Record.variant = rdup_vfield_list (old -> Record.variant);
1509 		  break;
1510 	       default:
1511 		  bad_tag (old -> tag, "rdup_def");
1512 	     };
1513 	  return (new);
1514 	};
1515 
1516 /* Recursively duplicate a stat */
rdup_stat(stat old)1517 stat rdup_stat (stat old)
1518 	{ /* allocate new record */
1519 	  stat new;
1520 	  if (old == stat_nil) return (old);
1521 	  new = (stat) dcg_malloc (sizeof (struct str_stat));
1522 	  /* duplicate fixed fields before variant ones */
1523 	  new -> tag = old -> tag;
1524 	  switch (old -> tag)
1525 	     { case TAGUse:
1526 		  new -> Use.utype = rdup_type_list (old -> Use.utype);
1527 		  break;
1528 	       case TAGImport:
1529 		  new -> Import.imp = rdup_string (old -> Import.imp);
1530 		  break;
1531 	       default:
1532 		  bad_tag (old -> tag, "rdup_stat");
1533 	     };
1534 	  return (new);
1535 	};
1536 
1537 /* Recursively duplicate a field */
rdup_field(field old)1538 field rdup_field (field old)
1539 	{ /* allocate new record */
1540 	  field new;
1541 	  if (old == field_nil) return (old);
1542 	  new = (field) dcg_malloc (sizeof (struct str_field));
1543 	  /* duplicate fixed fields before variant ones */
1544 	  new -> fname = rdup_string (old -> fname);
1545 	  new -> ftype = rdup_type (old -> ftype);
1546 	  new -> ftrav = rdup_int (old -> ftrav);
1547 	  return (new);
1548 	};
1549 
1550 /* Recursively duplicate a vfield */
rdup_vfield(vfield old)1551 vfield rdup_vfield (vfield old)
1552 	{ /* allocate new record */
1553 	  vfield new;
1554 	  if (old == vfield_nil) return (old);
1555 	  new = (vfield) dcg_malloc (sizeof (struct str_vfield));
1556 	  /* duplicate fixed fields before variant ones */
1557 	  new -> cons = rdup_string (old -> cons);
1558 	  new -> parts = rdup_field_list (old -> parts);
1559 	  return (new);
1560 	};
1561 
1562 /* Recursively duplicate a type */
rdup_type(type old)1563 type rdup_type (type old)
1564 	{ /* allocate new record */
1565 	  type new;
1566 	  if (old == type_nil) return (old);
1567 	  new = (type) dcg_malloc (sizeof (struct str_type));
1568 	  /* duplicate fixed fields before variant ones */
1569 	  new -> tag = old -> tag;
1570 	  switch (old -> tag)
1571 	     { case TAGTname:
1572 		  new -> Tname.tname = rdup_string (old -> Tname.tname);
1573 		  break;
1574 	       case TAGTlist:
1575 		  new -> Tlist.etyp = rdup_type (old -> Tlist.etyp);
1576 		  break;
1577 	       default:
1578 		  bad_tag (old -> tag, "rdup_type");
1579 	     };
1580 	  return (new);
1581 	};
1582 
1583 /* Recursively duplicate a def_list */
rdup_def_list(def_list old)1584 def_list rdup_def_list (def_list old)
1585 	{ def_list new;
1586 	  int ix;
1587 	  if (old == def_list_nil) return (old);
1588 	  new = init_def_list (old -> size);
1589 	  for (ix = 0; ix < old -> size; ix++)
1590 	     app_def_list (new, rdup_def (old -> array[ix]));
1591 	  return (new);
1592 	};
1593 
1594 /* Recursively duplicate a stat_list */
rdup_stat_list(stat_list old)1595 stat_list rdup_stat_list (stat_list old)
1596 	{ stat_list new;
1597 	  int ix;
1598 	  if (old == stat_list_nil) return (old);
1599 	  new = init_stat_list (old -> size);
1600 	  for (ix = 0; ix < old -> size; ix++)
1601 	     app_stat_list (new, rdup_stat (old -> array[ix]));
1602 	  return (new);
1603 	};
1604 
1605 /* Recursively duplicate a field_list */
rdup_field_list(field_list old)1606 field_list rdup_field_list (field_list old)
1607 	{ field_list new;
1608 	  int ix;
1609 	  if (old == field_list_nil) return (old);
1610 	  new = init_field_list (old -> size);
1611 	  for (ix = 0; ix < old -> size; ix++)
1612 	     app_field_list (new, rdup_field (old -> array[ix]));
1613 	  return (new);
1614 	};
1615 
1616 /* Recursively duplicate a vfield_list */
rdup_vfield_list(vfield_list old)1617 vfield_list rdup_vfield_list (vfield_list old)
1618 	{ vfield_list new;
1619 	  int ix;
1620 	  if (old == vfield_list_nil) return (old);
1621 	  new = init_vfield_list (old -> size);
1622 	  for (ix = 0; ix < old -> size; ix++)
1623 	     app_vfield_list (new, rdup_vfield (old -> array[ix]));
1624 	  return (new);
1625 	};
1626 
1627 /* Recursively duplicate a type_list */
rdup_type_list(type_list old)1628 type_list rdup_type_list (type_list old)
1629 	{ type_list new;
1630 	  int ix;
1631 	  if (old == type_list_nil) return (old);
1632 	  new = init_type_list (old -> size);
1633 	  for (ix = 0; ix < old -> size; ix++)
1634 	     app_type_list (new, rdup_type (old -> array[ix]));
1635 	  return (new);
1636 	};
1637 
1638 /* Recursively duplicate a string_list */
rdup_string_list(string_list old)1639 string_list rdup_string_list (string_list old)
1640 	{ string_list new;
1641 	  int ix;
1642 	  if (old == string_list_nil) return (old);
1643 	  new = init_string_list (old -> size);
1644 	  for (ix = 0; ix < old -> size; ix++)
1645 	     app_string_list (new, rdup_string (old -> array[ix]));
1646 	  return (new);
1647 	};
1648 
1649