/****************************************************************************** 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; } }