/********************************************** This class represents an environment in the environment simulation of Assignment 4, CS 152, Spring 2000. In this assignment the environment is a run-time object in a statically scoped, compiled language, so variables are represented as pairs of offsets. The environment is represented as a Java Stack of Frames. A display is used to avoid linear searches for the appropriate frame at run time. This is the only Environment state variable. The only Environment constructor returns an empty environment; it has no arguments. There are other methods addFrame (that adds a frame given the frame), deleteFrame (that deletes the top frame and takes no argument), lookup (that looks up the value of a variable given two integer offsets), and lookupAndPrint (that prints the value of a variable given two integer offsets, and issues a newline). If the lookup function fails, it raises a OffsetOutOfBoundsException. The lookupAndPrint method prints a simple error message in this case. A display represents the chain of frames accessible from the current frame by following static links. There is a private class Display that represents the display. When a frame is added to or deleted from the environment, the display is recreated from scratch. The Display constructor is responsible for doing this; its sole argument represents the current frame. The only other Display method returns the appropriate frame given the first offset in a pair of offsets (i.e., given an integer). **********************************************/ import java.io.*; import java.util.*; class Environment extends Stack { // This is an exception class for failure // of lookup within the environment private class OffsetOutOfBoundsException extends IOException { public OffsetOutOfBoundsException() {} } private class Display extends Vector { // This constructor recreates the display // beginning at frame f. Note that if // f is null, the display will be empty. public Display(Frame f) { super(5); while (f!=null) { addElement(f); f=f.getStaticLink(); } } // This selector returns the ith frame public Frame getFrame(int i) throws ArrayIndexOutOfBoundsException { return (Frame) elementAt(i);} } // begin Environment // the only state variable private Display display; // This constructor builds an empty // environment. It initializes the // display to be empty. public Environment() { super(); display = new Display(null); } // This method adds the frame f to the // environment by pushing it onto // the stack of frames. It also // recreates the display beginning // at the new top frame f. public void addFrame(Frame f) { addElement(f); display=new Display(f); } // This method deletes the current frame // from the environment by popping it // from the stack of frames. It recreates // the display starting at the new top // frame, if there is one. Otherwise it // creates an empty display by calling the // Display constructor with a null argument. public void deleteFrame() { pop(); if (empty()) display = new Display(null); else display = new Display((Frame) lastElement()); } // This method returns the value of a variable // represented as the offset pair (i,j). // Since a display is used, it need only // get the ith frame from the display and // get the filler of the jth binding of // that frame. // It raises a OffsetOutOfBoundsException if // the lookup for either element of the pair // fails. private FillerClass lookup(int i, int j) throws OffsetOutOfBoundsException { try { Frame f=display.getFrame(i); return f.lookup(j).getFiller(); } catch(ArrayIndexOutOfBoundsException e) { throw new OffsetOutOfBoundsException();} } // This method prints the value of a variable // represented as the offset pair (i,j) by // invoking the Environment lookup method. public void lookupAndPrint(int i, int j) { try { System.out.print(" "); FillerClass fc=lookup(i,j); fc.print(); } catch(OffsetOutOfBoundsException e) { System.out.print(" out of bounds");} } }