package openlist; /** * OpenList is a generic version of immutable 1-directional linked lists. * */ public class Openlist { /** * punctuation for converting Openlist to String */ private static final String defaultLeftParen = "("; private static final String defaultSeparator = " "; private static final String defaultRightParen = ")"; /** * the first item in this Openlist */ private Object first_item; /** * an Openlist of the rest of the items in this Openlist */ private Openlist rest_items; /** * The one-and-only empty list */ public static final Openlist nil = new Openlist(null, null); /** * constructor, intentionally private */ private Openlist(Object first_item, Openlist rest_items) { this.first_item = first_item; this.rest_items = rest_items; } /** * pseudo-constructor: Returns an Openlist consisting of * a first item followed by a list of other items. */ public static Openlist cons(Object first_item, Openlist rest_items) { return new Openlist(first_item, rest_items); } public Openlist cons(Object first_item) { return cons(first_item, this); } /** * return the first element of a non-empty list */ public Object first() { return first_item; } /** * return the list of all but the first element of a non-empty list */ public Openlist rest() { return rest_items; } /** * return true iff this list is the empty list */ public boolean isEmpty() { return this == nil; } /** * return true iff this list is not the empty list */ public boolean nonEmpty() { return this != nil; } /** * return an Openlist containing the arguments * in the order listed. * (n.b. This uses the Java "varargs" construct and an iterator) * As currently written, this depends on the reverse() method. */ public static Openlist list(Object... args) { Openlist rev = Openlist.nil; for( Object arg : args ) { rev = cons(arg, rev); } return rev.reverse(); } /** * Return a list consisting of the elements of this list in reverse. */ public Openlist reverse() { Openlist L = this; Openlist rev = Openlist.nil; while( L.nonEmpty() ) { rev = cons(L.first(), rev); L = L.rest(); } return rev; } /** * Create a string from this Openlist with parens and separators */ public String toString(String leftParen, String separator, String rightParen) { StringBuffer buffer = new StringBuffer(); buffer.append(leftParen); if( nonEmpty() ) { buffer.append(first()); Openlist L = rest(); while( L.nonEmpty() ) { buffer.append(separator); buffer.append(L.first().toString()); // Fix for general case L = L.rest(); } } buffer.append(rightParen); return buffer.toString(); } /** * Create a string from this Openlist using default parens and separators */ public String toString() { return toString(defaultLeftParen, defaultSeparator, defaultRightParen); } }