001: /*
002: * Cons.java
003: *
004: * Copyright 1997 Massachusetts Institute of Technology.
005: * All Rights Reserved.
006: *
007: * Author: Ora Lassila
008: *
009: * $Id: Cons.java,v 1.2 1998/01/22 13:08:38 bmahe Exp $
010: */
011:
012: package org.w3c.tools.sexpr;
013:
014: import java.io.PrintStream;
015: import java.util.Enumeration;
016:
017: /**
018: * Basic class for implementing linked lists a la Lisp.
019: */
020: public class Cons implements SExpr {
021:
022: private Object car;
023: private Object cdr;
024:
025: /**
026: * Initializes a Cons cell with the left and right "subtrees".
027: */
028: public Cons(Object left, Object right) {
029: this .car = left;
030: this .cdr = right;
031: }
032:
033: /**
034: * Initializes a Cons cell with a left subtree only.
035: * Right subtree will be set to <tt>null</tt>.
036: */
037: public Cons(Object left) {
038: this .car = left;
039: this .cdr = null;
040: }
041:
042: /**
043: * Returns the left subtree (i.e. the head) of a cons cell.
044: */
045: public Object left() {
046: return car;
047: }
048:
049: /**
050: * Returns the right subtree (i.e. the tail) of a cons cell.
051: */
052: public Object right() {
053: return cdr;
054: }
055:
056: /**
057: * Returns the tail of a cons cell if it is a list.
058: * Signals an error otherwise (no dotted pairs allowed).
059: *
060: * @exception SExprParserException if the tail is not a Cons or <tt>null<tt>
061: */
062: public Cons rest() throws SExprParserException {
063: Object r = right();
064: if (r == null)
065: return null;
066: else if (r instanceof Cons)
067: return (Cons) r;
068: else
069: throw new SExprParserException("No dotted pairs allowed");
070: }
071:
072: /*
073: * Returns an enumeration of the elements of the list.
074: */
075: public Enumeration elements() {
076: return new ConsEnumeration(this );
077: }
078:
079: public void printExpr(PrintStream stream) {
080: printList(stream, true);
081: }
082:
083: private void printList(PrintStream out, boolean first) {
084: out.print(first ? "(" : " ");
085: SimpleSExprStream.printExpr(left(), out);
086: Object r = right();
087: if (r == null)
088: out.print(")");
089: else if (r instanceof Cons)
090: ((Cons) r).printList(out, false);
091: else {
092: out.print(". ");
093: SimpleSExprStream.printExpr(r, out);
094: out.print(")");
095: }
096: }
097:
098: }
099:
100: class ConsEnumeration implements Enumeration {
101:
102: private Cons current;
103:
104: public ConsEnumeration(Cons head) {
105: this .current = head;
106: }
107:
108: public boolean hasMoreElements() {
109: return current != null;
110: }
111:
112: public Object nextElement() {
113: Object element = null;
114: try {
115: element = current.left();
116: current = current.rest();
117: } catch (SExprParserException e) {
118: // current is a dotted pair
119: current = null;
120: }
121: return element;
122: }
123:
124: }
|