/******************************************************************************

			UNSW Prolog (version 4)

			Written by Claude Sammut
		     Department of Computer Science
		     University of New South Wales
		   (and St. Joseph's U., Philadelphia)

		   Copyright (c)  1983 - Claude Sammut

******************************************************************************/





		/*	GARBAGE COLLECTOR (incomplete)	*/

#include "g.h"

#define MARK(x)  x = (pval) (((int) x) | 1)
#define MARKED(x) (((int) x) & 1)
#define UNMARK(x) x = (pval) (((int) x) & ~1)

extern binding *stack;
extern environment *env_stack;
extern short sp, env;
extern integer *stack_int;

static int in_use;

trace_stack()
{
	register environment *p;
	register i;

	in_use = 0;
	for (p = &(env_stack[env]); p >= env_stack; p--)
		mark((p -> parent == -1 ? stack : &(stack[env_stack[p -> parent].sp])), &(stack[p -> sp]));
	printf("Bindings in use: %d\n", in_use);
	printf("Global stack: %d\n", sp + 1);
	printf("Local stack: %d\n", env + 1);

	for (i = sp; i >= 0; i--)
		UNMARK(stack[i].termv);
}


static
mark(base, sp)
binding *base, *sp;
{
	register pval t;

	while (sp >= base)
		if (MARKED(sp -> termv)) return;
		else {
			in_use++;
			t = sp -> termv;
			MARK(sp -> termv);
			if (t != (pval) stack_int)
				follow(t, sp -> framev);
		}
}


#ifdef PRINC_VAR
#define START 0
#else
#define START 1
#endif


static
follow(t, f)
pval t;
binding *f;
{
	register i;

	switch(TYPE(t))
	{
	   case ATOM	:
	   case INT	:
	   case STRING	:
	   case PREDEF	: break;
	   case VAR	: mark(&stack[t -> v.offset], f);
			  break;
	   case LIST	: follow(t -> c.term[0], f);
			  follow(t -> c.term[1], f);
			  break;
	   case FN	: for (i = START; i <= t -> c.size; i++)
				follow(t -> c.term[i], f);
			  break;
	}
}

