import java.util.Random; class Value { int value; Value(int v) { value = v; } } class Links { int head = -1, tail = -1; Links(int h, int t) { head = h; tail = t; } } class Cell { boolean atom; boolean marked = false; int prev = -1, next = -1; Object info = null; // either Value or Links; } class Heap { final int maxHeap = 6, maxRoot = 50, empty = -1; int rootCnt = 0; boolean OK = true; Cell[] heap = new Cell[maxHeap]; int[] roots = new int[maxRoot]; int freeCells = empty, nonFreeCells = empty; Random rd = new Random(10); Heap() { for (int i = maxHeap-1; i >= 0; i--) { heap[i] = new Cell(); freeCells = insert(i,freeCells); } for (int i = maxRoot-1; i >= 0; i--) roots[i] = empty; } void updateHead(int p, int q) { // Lisp's rplaca; if (roots[p] != empty && !heap[roots[p]].atom) ((Links)heap[roots[p]].info).head = roots[q]; } void updateTail(int p, int q) { // Lisp's rplacd; if (roots[p] != empty && !heap[roots[p]].atom) ((Links)heap[roots[p]].info).tail = roots[q]; } int detach(int cell, int list) { if (heap[cell].next != empty) heap[heap[cell].next].prev = heap[cell].prev; if (heap[cell].prev != empty) heap[heap[cell].prev].next = heap[cell].next; if (cell == list) // head of the list; return heap[cell].next; else return list; } int insert(int cell, int list) { heap[cell].prev = empty; if (cell == list) // don't create a circular list; heap[cell].next = empty; else heap[cell].next = list; if (list != empty) heap[list].prev = cell; return cell; } void collect() { int p, markDescendants = empty, markedCells = empty; for (p = 0; p < rootCnt; p++) { if (roots[p] != empty) { nonFreeCells = detach(roots[p],nonFreeCells); markDescendants = insert(roots[p],markDescendants); heap[roots[p]].marked = true; } } printList(markDescendants,"markDescendants C1 "+p); for (p = markDescendants; p != empty; p = markDescendants) { markDescendants = detach(p,markDescendants); markedCells = insert(p,markedCells); if (!heap[p].atom) { if (!heap[((Links)heap[p].info).head].marked) { nonFreeCells = detach(((Links)heap[p].info).head,nonFreeCells); markDescendants = insert(((Links)heap[p].info).head,markDescendants); heap[((Links)heap[p].info).head].marked = true; } if (!heap[((Links)heap[p].info).tail].marked) { nonFreeCells = detach(((Links)heap[p].info).tail,nonFreeCells); markDescendants = insert(((Links)heap[p].info).tail,markDescendants); heap[((Links)heap[p].info).tail].marked = true; } } } printList(markedCells,"MarkedCells"); for (p = markedCells; p != empty; p = heap[p].next) heap[p].marked = false; freeCells = nonFreeCells; nonFreeCells = markedCells; } boolean allocateAux(int p) { if (p == maxRoot) { System.out.println("No room for new roots"); return !OK; } if (freeCells == empty) collect(); if (freeCells == empty) { System.out.println("No room in heap for new cells"); return !OK; } if (p == rootCnt) rootCnt++; roots[p] = freeCells; //System.out.print("roots2: "+p+" "+rootCnt+" "); for (int i = 0; i < rootCnt; i++) System.out.print(roots[i] + " "); System.out.println(); freeCells = detach(roots[p],freeCells); nonFreeCells = insert(roots[p],nonFreeCells); return OK; } void allocateAtom (int p, int val) { // an instance of Lisp's setf; //System.out.println("a t o m (" + p + " " + roots[p] + " " + val + " " + rootCnt); if (allocateAux(p) == OK) { heap[roots[p]].atom = true; heap[roots[p]].info = new Value(val); } } void allocateNonAtom(int p, int q, int r) { // Lisp's cons; if (allocateAux(p) == OK) { heap[roots[p]].atom = false; heap[roots[p]].info = new Links(roots[q],roots[r]); } } void deallocate(int p) { if (rootCnt > 0) if (Math.abs(rd.nextInt()) % 2 == 0) roots[p] = roots[--rootCnt]; // remove variable when exiting a block; else roots[p] = empty; // set variable to null; } void printList(int list, String name) { System.out.print(name + ": "); int i; for (i = list; i != empty; i = heap[i].next) { System.out.print("(" + i + " "); if (heap[i].atom) System.out.print(((Value)heap[i].info).value); else if (heap[i].info != null) System.out.print(((Links)heap[i].info).head + " " + ((Links)heap[i].info).tail); System.out.print(") "); } System.out.println(); } void printHeap() { System.out.print("roots: "); for (int i = 0; i < rootCnt; i++) System.out.print(roots[i] + " "); System.out.println(); for (int i = 0; i < maxHeap; i++) { System.out.print("(" + i + ": " + heap[i].prev + " " + heap[i].next + " "+ heap[i].atom + " " + heap[i].marked + " "); if (heap[i].atom) System.out.print(((Value)heap[i].info).value); else if (heap[i].info != null) System.out.print(((Links)heap[i].info).head + " " + ((Links)heap[i].info).tail); System.out.print(") "); } System.out.println(); printList(freeCells,"FreeCells"); printList(nonFreeCells,"NonFreeCells"); } }