Wild Life  2.29
 All Data Structures Files Functions Variables Typedefs Macros
copy.c
Go to the documentation of this file.
1 /* Copyright 1991 Digital Equipment Corporation.
2 ** All Rights Reserved.
3 *****************************************************************/
4 /* $Id: copy.c,v 1.2 1994/12/08 23:21:30 duchier Exp $ */
5 
6 #include "defs.h"
7 
8 
9 
10 /****************************************************************************/
11 
12 /* New translation routines for Wild_Life */
13 /* These routines work for any size structure. */
14 /* They are based on a hash table with buckets and timestamp. */
15 /* This allows fast clearing of the table and fast insertion */
16 /* and lookup. */
17 
18 
19 
20 static struct hashentry hashtable[HASHSIZE];
21 static struct hashbucket *hashbuckets; /* Array of buckets */
22 static long hashtime; /* Currently valid timestamp */
23 static long hashfree; /* Index into array of buckets */
24 static long numbuckets; /* Total number of buckets; initially=NUMBUCKETS */
25 
26 
27 /* #define HASHSTATS 1000 20.8 */
28 /* long hashstats[HASHSTATS]; 20.8 */
29 
30 
31 /******** INIT_COPY()
32  Execute once upon startup of Wild_Life.
33 */
34 void init_copy()
35 {
36  long i;
37 
38  /* for(i=0; i<HASHSTATS; i++) hashstats[i]=0; 20.8 */
39 
40  for(i=0; i<HASHSIZE; i++) hashtable[i].timestamp = 0;
41  hashtime = 0;
43  hashbuckets = (struct hashbucket *)
44  malloc(NUMBUCKETS * sizeof(struct hashbucket));
45 }
46 
47 
48 /******** CLEAR_COPY()
49  Erase the hash table.
50  This must be done as a prelude to any copying operation.
51 */
52 void clear_copy()
53 {
54  hashtime++;
55  hashfree=0;
56 }
57 
58 
59 /******** INSERT_TRANSLATION(a,b,info)
60  Add the translation of address A to address B in the translation table.
61  Also add an info field.
62 */
63 /* static */ void insert_translation(a,b,info)
64 ptr_psi_term a;
65 ptr_psi_term b;
66 long info;
67 {
68  long index;
69  long lastbucket;
70 
71  /* Ensure there are free buckets by doubling their number if necessary */
72  if (hashfree >= numbuckets) {
73  numbuckets *= 2;
74  hashbuckets = (struct hashbucket *)
75  realloc((void *) hashbuckets, numbuckets * sizeof(struct hashbucket));
76  /* *** Do error handling here *** */
77  traceline("doubled the number of hashbuckets to %d\n", numbuckets);
78  }
79 
80  /* Add a bucket to the beginning of the list */
81  index = HASH(a);
82  if (hashtable[index].timestamp == hashtime)
83  lastbucket = hashtable[index].bucketindex;
84  else {
85  lastbucket = HASHEND;
86  hashtable[index].timestamp = hashtime;
87  }
89  hashbuckets[hashfree].old_value = a;
90  hashbuckets[hashfree].new_value = b;
91  hashbuckets[hashfree].info = info;
92  hashbuckets[hashfree].next = lastbucket;
93  hashfree++;
94 }
95 
96 
97 /******** TRANSLATE(a,info)
98  Get the translation of address A and the info field stored with it.
99  Return NULL if none is found.
100 */
101 /* static */ ptr_psi_term translate(a,infoptr) /* RM: Jan 27 1993 */
102 ptr_psi_term a;
103 long **infoptr;
104 {
105  long index;
106  /* long i; 20.8 */
107  long bucket;
108 
109  index = HASH(a);
110  if (hashtable[index].timestamp != hashtime) return NULL;
111  bucket = hashtable[index].bucketindex;
112  /* i=0; 20.8 */
113  while (bucket != HASHEND && hashbuckets[bucket].old_value != a) {
114  /* i++; 20.8 */
115  bucket = hashbuckets[bucket].next;
116  }
117  /* hashstats[i]++; 20.8 */
118  if (bucket != HASHEND) {
119  *infoptr = &hashbuckets[bucket].info;
120  return (hashbuckets[bucket].new_value);
121  }
122  else
123  return NULL;
124 }
125 
126 
127 /****************************************************************************/
128 
129 
130 /******** COPY_TREE(t)
131  Return a pointer to a copy of the binary tree t.
132  Structure sharing between trees is not preserved by this routine,
133  this is not a problem seeing that coreferences in the nodes will ensure
134  coherence.
135 */
136 
137 
138 
139 static ptr_node copy_tree(t, copy_flag, heap_flag)
140 ptr_node t;
141 long copy_flag, heap_flag;
142 {
143  ptr_node r;
144  ptr_psi_term t1,t2;
145 
146  /* if (t) { RM: Dec 15 1992 this test is useless */
147 
148  if (HEAPDONE(t)) return t;
149  r=NEW(t,node);
150  r->key = t->key;
151  r->left = (t->left) ? copy_tree(t->left,copy_flag,heap_flag) : NULL;
152  t1 = (ptr_psi_term)(t->data);
153  t2 = copy(t1,copy_flag,heap_flag);
154  r->data = (GENERIC) t2;
155  r->right = (t->right) ? copy_tree(t->right,copy_flag,heap_flag) : NULL;
156 
157  /* } else r=NULL; */
158 
159  return r;
160 }
161 
162 
163 
164 /******** COPY(t)
165  This is the workhorse of the interpreter (alas!).
166  All copy-related routines are non-interruptible by the garbage collector.
167 
168  Make a copy in the STACK or in the HEAP of psi_term t, which is located in
169  the HEAP. A copy is done whenever invoking a rule, so it had better be fast.
170  This routine uses hash tables with buckets and partial inlining for speed.
171 
172  The following three versions of copy all rename their variables and return
173  a completely dereferenced object:
174 
175  u=exact_copy(t,hf) u is an exact copy of t.
176  u=quote_copy(t,hf) u is a copy of t that is recursively marked evaluated.
177  u=eval_copy(t,hf) u is a copy of t that is recursively marked unevaluated.
178 
179  This version of copy is an incremental copy to the heap. It copies only
180  those parts of a psi_term that are on the stack, leaving the others
181  unchanged:
182 
183  u=inc_heap_copy(t) u is an exact copy of t, on the heap. This is like
184  hf==HEAP, except that objects already on the heap are
185  untouched. Relies on no pointers from heap to stack.
186 
187  hf = heap_flag. hf = HEAP or STACK means allocate in the HEAP or STACK.
188  Marking eval/uneval is done by modifying the STATUS field of the copied
189  psi_term.
190  In eval_copy, a term's status is set to 0 if the term or any subterm needs
191  evaluation.
192  Terms are dereferenced when copying them to the heap.
193 */
194 
196 ptr_psi_term t;
197 long heap_flag;
198 { to_heap=FALSE; return (copy(t, EXACT_FLAG, heap_flag)); }
199 
201 ptr_psi_term t;
202 long heap_flag;
203 { to_heap=FALSE; return (copy(t, QUOTE_FLAG, heap_flag)); }
204 
205 ptr_psi_term eval_copy(t, heap_flag)
206 ptr_psi_term t;
207 long heap_flag;
208 { to_heap=FALSE; return (copy(t, EVAL_FLAG, heap_flag)); }
209 
210 /* There is a bug in inc_heap_copy */
212 ptr_psi_term t;
213 { to_heap=TRUE; return (copy(t, EXACT_FLAG, TRUE)); }
214 
215 static long curr_status;
216 
217 
218 
219 ptr_psi_term copy(t, copy_flag, heap_flag)
220  ptr_psi_term t;
221  long copy_flag,heap_flag;
222 {
223  ptr_psi_term u;
224  long old_status;
225  long local_copy_flag;
226  long *infoptr;
227 
228 
229  if ((u=t)) {
230  deref_ptr(t); /* Always dereference when copying */
231 
232  if (HEAPDONE(t)) return t;
233  u = translate(t,&infoptr);
234 
235  if (u && *infoptr!=QUOTE_STUB) { /* 24.8 */
236  /* If it was eval-copied before, then quote it now. */
237  if (*infoptr==EVAL_FLAG && copy_flag==QUOTE_FLAG) { /* 24.8 25.8 */
238  mark_quote_c(t,heap_flag);
239  *infoptr=QUOTE_FLAG; /* I.e. don't touch this term any more */
240  }
241  if (copy_flag==EVAL_FLAG) { /* PVR 14.2.94 */
242  /* If any subterm has zero curr_status (i.e., if u->status==0),
243  then so does the whole term: */
244  old_status=curr_status;
245  curr_status=u->status;
246  if (curr_status) curr_status=old_status;
247  }
248  }
249  else {
251  Errorline("psi-term too large -- get a bigger Life!\n");
252  (void)abort_life(TRUE);
253  longjmp(env,FALSE); /* Back to main loop */ /* RM: Feb 15 1993 */
254  }
255  if (copy_flag==EVAL_FLAG && !t->type->evaluate_args) /* 24.8 25.8 */
256  local_copy_flag=QUOTE_FLAG; /* All arguments will be quoted 24.8 */
257  else /* 24.8 */
258  local_copy_flag=copy_flag;
259  if (copy_flag==EVAL_FLAG) {
260  old_status = curr_status;
261  curr_status = 4;
262  }
263  if (u) { /* 15.9 */
264  *infoptr=QUOTE_FLAG;
265  local_copy_flag=QUOTE_FLAG;
266  copy_flag=QUOTE_FLAG;
267  }
268  else {
269  u=NEW(t,psi_term);
270  insert_translation(t,u,local_copy_flag); /* 24.8 */
271  }
272  *u = *t;
273  u->resid=NULL; /* 24.8 Don't copy residuations */
274 #ifdef TS
275  u->time_stamp=global_time_stamp; /* 9.6 */
276 #endif
277 
278  if (t->attr_list)
279  u->attr_list=copy_tree(t->attr_list, local_copy_flag, heap_flag);
280 
281  if (copy_flag==EVAL_FLAG) {
282  switch((long)t->type->type_def) {
283  case (long)type_it:
284  if (t->type->properties)
285  curr_status=0;
286  break;
287 
288  case (long)function_it:
289  curr_status=0;
290  break;
291 
292  case (long)global: /* RM: Feb 8 1993 */
293  curr_status=0;
294  break;
295 
296  default:
297  break;
298  }
299  u->status=curr_status;
300  u->flags=curr_status?QUOTED_TRUE:FALSE; /* 14.9 */
301  /* If any subterm has zero curr_status,
302  then so does the whole term: */
303  if (curr_status) curr_status=old_status;
304  } else if (copy_flag==QUOTE_FLAG) {
305  u->status=4;
306  u->flags=QUOTED_TRUE; /* 14.9 */
307  }
308  /* else copy_flag==EXACT_FLAG & u->status=t->status */
309 
310  if (heap_flag==HEAP) {
311  if (t->type==cut) u->value_3=NULL;
312  } else {
313  if (t->type==cut) {
315  traceline("current choice point is %x\n",choice_stack);
316  }
317  }
318  }
319  }
320 
321  return u;
322 }
323 
324 
325 
326 /****************************************************************************/
327 
328 
329 /******** DISTINCT_TREE(t)
330  Return an exact copy of an attribute tree.
331  This is used by APPLY in order to build the calling psi-term which is used
332  for matching.
333 */
335 ptr_node t;
336 {
337  ptr_node n;
338 
339  n=NULL;
340  if (t) {
341  n=STACK_ALLOC(node);
342  n->key=t->key;
343  n->data=t->data;
344  n->left=distinct_tree(t->left);
345  n->right=distinct_tree(t->right);
346  }
347 
348  return n;
349 }
350 
351 
352 /******** DISTINCT_COPY(t)
353  Make a distinct copy of T and T's attribute tree, which are identical to T,
354  only located elsewhere in memory. This is used by apply to build the calling
355  psi-term which is used for matching. Note that this routine is not
356  recursive, i.e. it only copies the main functor & the attribute tree.
357 */
359 ptr_psi_term t;
360 {
361  ptr_psi_term res;
362 
363  res=STACK_ALLOC(psi_term);
364  *res= *t;
365 #ifdef TS
366  res->time_stamp=global_time_stamp; /* 9.6 */
367 #endif
368  /* res->coref=distinct_copy(t->coref); */
369  res->attr_list=distinct_tree(t->attr_list);
370 
371  return res;
372 }
373 
374 
375 /****************************************************************************/
376 
377 /* The new mark_quote to be used from copy. */
378 
379 /* Meaning of the info field in the translation table: */
380 /* With u=translate(t,&infoptr): */
381 /* If infoptr==QUOTE_FLAG then the whole subgraph from u is quoted. */
382 /* If infoptr==EVAL_FLAG then anything is possible. */
383 /* If infoptr==QUOTE_STUB then the term does not exist yet, e.g., there */
384 /* is a cycle in the term & copy(...) has not created it yet, for */
385 /* example X:s(L,t(X),R), where non_strict(t), in which R does not */
386 /* exist when the call to mark_quote_c is done. When the term is */
387 /* later created, it must be created as quoted. */
388 
389 /* Mark a psi-term u (which is a copy of t) as completely evaluated. */
390 /* Only t is given as the argument. */
391 /* Assumes the psi-term is a copy of another psi-term t, which is made through */
392 /* eval_copy. Therefore the copy is accessible through the translation table. */
393 /* Assumes all translation table entries already exist. */
394 /* The infoptr field is updated so that each subgraph is only traversed once. */
395 /* This routine is called only from the main copy routine. */
396 void mark_quote_c(t,heap_flag)
397 ptr_psi_term t;
398 long heap_flag;
399 {
400  // ptr_list l;
401  long *infoptr;
402  ptr_psi_term u;
403 
404  if (t) {
405  deref_ptr(t);
406  u=translate(t,&infoptr);
407  /* assert(u!=NULL); 15.9 */
408  if (u) {
409  if (*infoptr==EVAL_FLAG) {
410  *infoptr=QUOTE_FLAG;
411  u->status=4;
412  u->flags=QUOTED_TRUE; /* 14.9 */
413  mark_quote_tree_c(t->attr_list,heap_flag);
414  }
415  }
416  else { /* u does not exist yet */ /* 15.9 */
417  /* Create a stub & mark it as to-be-quoted. */
418  u=NEW(t,psi_term);
420  }
421  }
422 }
423 
424 void mark_quote_tree_c(n,heap_flag)
425 ptr_node n;
426 long heap_flag;
427 {
428  if (n) {
429  mark_quote_tree_c(n->left,heap_flag);
430  mark_quote_c((ptr_psi_term) (n->data),heap_flag);
431  mark_quote_tree_c(n->right,heap_flag);
432  }
433 }
434 
435 /****************************************************************************/
436 
437 /* A (possibly) correct mark_eval and its companion mark_quote. */
438 
439 /* The translation table is used to record whether a subgraph has already */
440 /* been quoted or not. */
441 
443 
444 /* Mark a psi-term as to be evaluated (i.e. strict), except for arguments */
445 /* of a nonstrict term, which are marked quoted. Set status correctly and */
446 /* propagate zero status upwards. Avoid doing superfluous work: non-shared */
447 /* terms are traversed once; shared terms are traversed at most twice (this */
448 /* only occurs if the first occurrence encountered is strict and a later */
449 /* occurrence is nonstrict). The translation table is used to indicate (1) */
450 /* whether a term has already been traversed, and if so, (2) whether there */
451 /* was a nonstrict traversal (in that case, the info field is FALSE). */
452 void mark_eval(t) /* 24.8 25.8 */
453 ptr_psi_term t;
454 {
455  clear_copy();
457  mark_eval_new(t);
458 }
459 
460 /* Same as above, except that the status is only changed from 0 to 4 when */
461 /* needed; it is never changed from 4 to 0. */
463 ptr_psi_term t;
464 {
465  clear_copy();
467  mark_eval_new(t);
468 }
469 
470 /* Mark a term as quoted. */
472 ptr_psi_term t;
473 {
474  clear_copy();
476  mark_quote_new(t);
477 }
478 
480 ptr_psi_term t;
481 {
482  // ptr_list l;
483  long *infoptr,flag;
484  ptr_psi_term u;
485  long old_status;
486 
487  if (t) {
488  deref_ptr(t);
489  flag = t->type->evaluate_args;
490  u=translate(t,&infoptr);
491  if (u) {
492  /* Quote the subgraph if it was already copied as to be evaluated. */
493  if (!flag && *infoptr) {
494  mark_quote_new(t);
495  *infoptr=FALSE;
496  }
497  /* If any subterm has zero curr_status (i.e., if t->status==0),
498  then so does the whole term: PVR 14.2.94 */
499  old_status=curr_status;
500  curr_status=(long)t->status;
501  if (curr_status) curr_status=old_status;
502  }
503  else {
505  old_status=curr_status;
506  curr_status=4;
507 
508  if (flag) /* 16.9 */
509  mark_eval_tree_new(t->attr_list);
510  else
511  mark_quote_tree_new(t->attr_list);
512 
513  switch((long)t->type->type_def) {
514  case type_it:
515  if (t->type->properties)
516  curr_status=0;
517  break;
518 
519  case function_it:
520  curr_status=0;
521  break;
522 
523  case global: /* RM: Feb 8 1993 */
524  curr_status=0;
525  break;
526 
527  default:
528  break;
529  }
530  if (mark_nonstrict_flag) { /* 25.8 */
531  if (curr_status) {
532  /* Only increase the status, never decrease it: */
533  t->status=curr_status;
534  }
535  }
536  else {
537  t->status=curr_status;
538  t->flags=curr_status?QUOTED_TRUE:FALSE; /* 14.9 */
539  }
540  /* If any subterm has zero curr_status, then so does the whole term: */
541  if (curr_status) curr_status=old_status;
542  }
543  }
544 }
545 
547 ptr_node n;
548 {
549  if (n) {
550  mark_eval_tree_new(n->left);
551  mark_eval_new((ptr_psi_term) (n->data));
552  mark_eval_tree_new(n->right);
553  }
554 }
555 
556 
558 ptr_psi_term t;
559 {
560  // ptr_list l;
561  long *infoptr;
562  ptr_psi_term u;
563 
564  if (t) {
565  deref_ptr(t);
566  u=translate(t,&infoptr);
567 
568  /* Return if the subgraph is already quoted. */
569  if (u && !*infoptr) return;
570 
571  /* Otherwise quote the subgraph */
573  else *infoptr = FALSE; /* sanjay */
574  t->status= 4;
575  t->flags=QUOTED_TRUE; /* 14.9 */
576  mark_quote_tree_new(t->attr_list);
577  }
578 }
579 
580 
582 ptr_node n;
583 {
584  if (n) {
585  mark_quote_tree_new(n->left);
586  mark_quote_new((ptr_psi_term) (n->data));
587  mark_quote_tree_new(n->right);
588  }
589 }
590 
591 
592 /****************************************************************************/
593 
594 /* A more efficient version of mark_quote */
595 /* This version avoids using the translation table by setting a 'visited' */
596 /* in the status field. */
597 
598 extern void mark_quote_tree(); /* A forward declaration */
599 
600 /* Mark a psi-term as completely evaluated. */
601 void mark_quote(t)
602 ptr_psi_term t;
603 {
604  // ptr_list l;
605 
606  if (t && !(t->status&RMASK)) {
607  t->status = 4;
608  t->flags=QUOTED_TRUE; /* 14.9 */
609  t->status |= RMASK;
610  mark_quote(t->coref);
611  mark_quote_tree(t->attr_list);
612  t->status &= ~RMASK;
613  }
614 }
615 
617 ptr_node t;
618 {
619  if (t) {
620  mark_quote_tree(t->left);
621  mark_quote((ptr_psi_term) (t->data));
622  mark_quote_tree(t->right);
623  }
624 }
625 
626 
627 /* Back-trackably mark a psi-term as completely evaluated. */
628 
629 
631 ptr_psi_term t;
632 {
633  // ptr_list l;
634 
635  if (t && !(t->status&RMASK)) {
636  if(t->status!=4 && (GENERIC)t<heap_pointer)/* RM: Jul 16 1993 */
637  push_ptr_value(int_ptr,(GENERIC *)&(t->status));
638  t->status = 4;
639  t->flags=QUOTED_TRUE; /* 14.9 */
640  t->status |= RMASK;
641  bk_mark_quote(t->coref);
642  bk_mark_quote_tree(t->attr_list);
643  t->status &= ~RMASK;
644  }
645 }
646 
648 ptr_node t;
649 {
650  if (t) {
651  bk_mark_quote_tree(t->left);
652  bk_mark_quote((ptr_psi_term) (t->data));
653  bk_mark_quote_tree(t->right);
654  }
655 }
656 
657 
658 /****************************************************************************/
static struct hashentry hashtable[HASHSIZE]
Definition: copy.c:20
static long hashfree
Definition: copy.c:23
#define COPY_THRESHOLD
Definition: def_const.h:68
void mark_eval_new(ptr_psi_term t)
Definition: copy.c:479
#define NUMBUCKETS
Definition: def_const.h:319
ptr_residuation resid
Definition: def_struct.h:173
#define function_it
Definition: def_const.h:362
ptr_psi_term translate(ptr_psi_term a, long **infoptr)
Definition: copy.c:101
#define HEAP
Definition: def_const.h:147
void clear_copy()
Definition: copy.c:52
void push_ptr_value(type_ptr t, GENERIC *p)
Definition: login.c:360
ptr_psi_term exact_copy(ptr_psi_term t, long heap_flag)
Definition: copy.c:195
#define global
Definition: def_const.h:364
static long numbuckets
Definition: copy.c:24
void mark_quote_tree_c(ptr_node n, long heap_flag)
Definition: copy.c:424
#define QUOTE_STUB
Definition: def_const.h:329
#define EXACT_FLAG
Definition: def_const.h:325
void bk_mark_quote_tree(ptr_node t)
Definition: copy.c:647
#define HASHEND
Definition: def_const.h:322
void mark_nonstrict(ptr_psi_term t)
Definition: copy.c:462
void insert_translation(ptr_psi_term a, ptr_psi_term b, long info)
Definition: copy.c:63
GENERIC data
Definition: def_struct.h:185
#define NULL
Definition: def_const.h:203
ptr_node distinct_tree(ptr_node t)
Definition: copy.c:334
ptr_psi_term old_value
Definition: def_struct.h:385
#define NEW(A, TYPE)
Definition: def_macro.h:279
static long hashtime
Definition: copy.c:22
void mark_eval_tree_new(ptr_node n)
Definition: copy.c:546
long abort_life(int nlflag)
Definition: built_ins.c:2124
ptr_node left
Definition: def_struct.h:183
void traceline(char *format,...)
Definition: error.c:157
ptr_psi_term new_value
Definition: def_struct.h:386
#define type_it
Definition: def_const.h:363
#define EVAL_FLAG
Definition: def_const.h:327
ptr_psi_term quote_copy(ptr_psi_term t, long heap_flag)
Definition: copy.c:200
void Errorline(char *format,...)
Definition: error.c:414
#define deref_ptr(P)
Definition: def_macro.h:95
void bk_mark_quote(ptr_psi_term t)
Definition: copy.c:630
char * key
Definition: def_struct.h:182
ptr_psi_term distinct_copy(ptr_psi_term t)
Definition: copy.c:358
#define TRUE
Definition: def_const.h:127
void mark_quote_tree_new(ptr_node n)
Definition: copy.c:581
ptr_psi_term copy(ptr_psi_term t, long copy_flag, long heap_flag)
Definition: copy.c:219
#define RMASK
Definition: def_const.h:159
static ptr_node copy_tree(ptr_node t, long copy_flag, long heap_flag)
Definition: copy.c:139
void mark_eval(ptr_psi_term t)
Definition: copy.c:452
static long curr_status
Definition: copy.c:215
long to_heap
Definition: def_glob.h:264
#define FALSE
Definition: def_const.h:128
GENERIC value_3
Definition: def_struct.h:170
void mark_quote_c(ptr_psi_term t, long heap_flag)
Definition: copy.c:396
long timestamp
Definition: def_struct.h:392
GENERIC heap_pointer
Definition: def_glob.h:12
static struct hashbucket * hashbuckets
Definition: copy.c:21
void mark_quote_new(ptr_psi_term t)
Definition: copy.c:557
ptr_psi_term inc_heap_copy(ptr_psi_term t)
Definition: copy.c:211
#define STACK_ALLOC(A)
Definition: def_macro.h:16
void mark_quote(ptr_psi_term t)
Definition: copy.c:601
long bucketindex
Definition: def_struct.h:393
jmp_buf env
Definition: def_glob.h:236
static long mark_nonstrict_flag
Definition: copy.c:442
struct wl_psi_term * ptr_psi_term
Definition: def_struct.h:34
ptr_definition cut
Definition: def_glob.h:83
#define HASH(A)
Definition: def_macro.h:273
unsigned long global_time_stamp
Definition: login.c:19
#define HEAPDONE(R)
Definition: def_macro.h:291
GENERIC stack_pointer
Definition: def_glob.h:14
#define QUOTE_FLAG
Definition: def_const.h:326
ptr_psi_term eval_copy(ptr_psi_term t, long heap_flag)
Definition: copy.c:205
unsigned long * GENERIC
Definition: def_struct.h:17
#define QUOTED_TRUE
Definition: def_const.h:123
void mark_quote_new2(ptr_psi_term t)
Definition: copy.c:471
void init_copy()
Definition: copy.c:34
ptr_node attr_list
Definition: def_struct.h:171
#define HASHSIZE
Definition: def_const.h:315
void mark_quote_tree()
ptr_choice_point choice_stack
Definition: def_glob.h:51
ptr_node right
Definition: def_struct.h:184
#define int_ptr
Definition: def_const.h:172