1	package antlr.collections.impl;
2	
3	/** A Linked List Implementation (not thread-safe for simplicity) */
4	import antlr.collections.List;
5	import antlr.collections.Stack;
6	import java.util.Enumeration;
7	import java.util.NoSuchElementException;
8	import antlr.collections.impl.LLCell;
9	
10	/** A Simple Linked List Impl. (adds to the tail) (has an enumeration)
11	 * @author Terence Parr
12	 * <a href=http://www.MageLang.com>MageLang Institute</a>
13	 */
14	public class LList implements List, Stack {
15		protected LLCellLLCellhead, tail=null;
16		protected int length=0;
17	
18	
19		/** Add an object to the end of the list.
20		 * @param o the object to add
21		 */
22		public void add(Object o) { append(o); }
23		/** Append an object to the end of the list.
24		 * @param o the object to append
25		 */
26		public void append(Object o) {
27			LLCell n = new LLCell(o);
28			if ( length==0 ) {
29				head=tail=n;
30				length=1;
31			}
32			else {
33				tail.next = n;
34				tail=n;
35				length++;
36			}
37		}
38		/**Delete the object at the head of the list.
39		 * @return the object found at the head of the list.
40		 * @exception NoSuchElementException if the list is empty.
41		 */
42		protected Object deleteHead() throws NoSuchElementException {
43			if ( head==null ) throw new NoSuchElementException();
44			Object o = head.data;
45			head = head.next;
46			length--;
47			return o;
48		}
49		/**Get the ith element in the list.
50		 * @param i the index (from 0) of the requested element.
51		 * @return the object at index i
52		 * NoSuchElementException is thrown if i out of range
53		 */
54		public Object elementAt(int i) throws NoSuchElementException {
55			int j=0;
56			for (LLCell p = head; p!=null; p=p.next) {
57				if ( i==j ) return p.data;
58				j++;
59			}
60			throw new NoSuchElementException();
61		}
62		/**Return an enumeration of the list elements */
63		public Enumeration elements() { return new LLEnumeration(this); }
64		/** How high is the stack? */
65		public int height() { return length; }
66		/** Answers whether or not an object is contained in the list
67		 * @param o the object to test for inclusion.
68		 * @return true if object is contained else false.
69		 */
70		public boolean includes(Object o) {
71			for (LLCell p = head; p!=null; p=p.next) {
72				if ( p.data.equals(o) ) return true;
73			}
74			return false;
75		}
76		// The next two methods make LLQueues and LLStacks easier.
77		
78		/** Insert an object at the head of the list.
79		 * @param o the object to add
80		 */
81		protected void insertHead(Object o) {
82			LLCell c = head;
83			head = new LLCell(o);
84			head.next = c;
85			length++;
86			if ( tail==null ) tail = head;
87		}
88		/**Return the length of the list.*/
89		public int length() { return length; }
90		/** Pop the top element of the stack off.
91		 * @return the top of stack that was popped off.
92		 * @exception NoSuchElementException if the stack is empty.
93		 */
94		public Object pop() throws NoSuchElementException {
95			Object o = deleteHead();
96			return o;
97		}
98		// Satisfy the Stack interface now.
99		
100		/** Push an object onto the stack.
101		 * @param o the object to push
102		 */
103		public void push(Object o) { insertHead(o); }
104		public Object top() throws NoSuchElementException {
105			if ( head==null ) throw new NoSuchElementException();
106			return head.data;
107		}
108	}
109