view src/clojure/lang/LazySeq.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line source
1 /**
2 * Copyright (c) Rich Hickey. All rights reserved.
3 * The use and distribution terms for this software are covered by the
4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 * which can be found in the file epl-v10.html at the root of this distribution.
6 * By using this software in any fashion, you are agreeing to be bound by
7 * the terms of this license.
8 * You must not remove this notice, or any other, from this software.
9 **/
11 /* rich Jan 31, 2009 */
13 package clojure.lang;
15 import java.util.*;
17 public final class LazySeq extends Obj implements ISeq, List{
19 private IFn fn;
20 private Object sv;
21 private ISeq s;
23 public LazySeq(IFn fn){
24 this.fn = fn;
25 }
27 private LazySeq(IPersistentMap meta, ISeq s){
28 super(meta);
29 this.fn = null;
30 this.s = s;
31 }
33 public Obj withMeta(IPersistentMap meta){
34 return new LazySeq(meta, seq());
35 }
37 final synchronized Object sval(){
38 if(fn != null)
39 {
40 try
41 {
42 sv = fn.invoke();
43 fn = null;
44 }
45 catch(Exception e)
46 {
47 throw new RuntimeException(e);
48 }
49 }
50 if(sv != null)
51 return sv;
52 return s;
53 }
55 final synchronized public ISeq seq(){
56 sval();
57 if(sv != null)
58 {
59 Object ls = sv;
60 sv = null;
61 while(ls instanceof LazySeq)
62 {
63 ls = ((LazySeq)ls).sval();
64 }
65 s = RT.seq(ls);
66 }
67 return s;
68 }
70 public int count(){
71 int c = 0;
72 for(ISeq s = seq(); s != null; s = s.next())
73 ++c;
74 return c;
75 }
77 public Object first(){
78 seq();
79 if(s == null)
80 return null;
81 return s.first();
82 }
84 public ISeq next(){
85 seq();
86 if(s == null)
87 return null;
88 return s.next();
89 }
91 public ISeq more(){
92 seq();
93 if(s == null)
94 return PersistentList.EMPTY;
95 return s.more();
96 }
98 public ISeq cons(Object o){
99 return RT.cons(o, seq());
100 }
102 public IPersistentCollection empty(){
103 return PersistentList.EMPTY;
104 }
106 public boolean equiv(Object o){
107 return equals(o);
108 }
110 public int hashCode(){
111 return Util.hash(seq());
112 }
114 public boolean equals(Object o){
115 ISeq s = seq();
116 if(s != null)
117 return s.equiv(o);
118 else
119 return (o instanceof Sequential || o instanceof List) && RT.seq(o) == null;
120 }
123 // java.util.Collection implementation
125 public Object[] toArray(){
126 return RT.seqToArray(seq());
127 }
129 public boolean add(Object o){
130 throw new UnsupportedOperationException();
131 }
133 public boolean remove(Object o){
134 throw new UnsupportedOperationException();
135 }
137 public boolean addAll(Collection c){
138 throw new UnsupportedOperationException();
139 }
141 public void clear(){
142 throw new UnsupportedOperationException();
143 }
145 public boolean retainAll(Collection c){
146 throw new UnsupportedOperationException();
147 }
149 public boolean removeAll(Collection c){
150 throw new UnsupportedOperationException();
151 }
153 public boolean containsAll(Collection c){
154 for(Object o : c)
155 {
156 if(!contains(o))
157 return false;
158 }
159 return true;
160 }
162 public Object[] toArray(Object[] a){
163 if(a.length >= count())
164 {
165 ISeq s = seq();
166 for(int i = 0; s != null; ++i, s = s.next())
167 {
168 a[i] = s.first();
169 }
170 if(a.length > count())
171 a[count()] = null;
172 return a;
173 }
174 else
175 return toArray();
176 }
178 public int size(){
179 return count();
180 }
182 public boolean isEmpty(){
183 return seq() == null;
184 }
186 public boolean contains(Object o){
187 for(ISeq s = seq(); s != null; s = s.next())
188 {
189 if(Util.equiv(s.first(), o))
190 return true;
191 }
192 return false;
193 }
195 public Iterator iterator(){
196 return new SeqIterator(seq());
197 }
199 //////////// List stuff /////////////////
200 private List reify(){
201 return new ArrayList(this);
202 }
204 public List subList(int fromIndex, int toIndex){
205 return reify().subList(fromIndex, toIndex);
206 }
208 public Object set(int index, Object element){
209 throw new UnsupportedOperationException();
210 }
212 public Object remove(int index){
213 throw new UnsupportedOperationException();
214 }
216 public int indexOf(Object o){
217 ISeq s = seq();
218 for(int i = 0; s != null; s = s.next(), i++)
219 {
220 if(Util.equiv(s.first(), o))
221 return i;
222 }
223 return -1;
224 }
226 public int lastIndexOf(Object o){
227 return reify().lastIndexOf(o);
228 }
230 public ListIterator listIterator(){
231 return reify().listIterator();
232 }
234 public ListIterator listIterator(int index){
235 return reify().listIterator(index);
236 }
238 public Object get(int index){
239 return RT.nth(this, index);
240 }
242 public void add(int index, Object element){
243 throw new UnsupportedOperationException();
244 }
246 public boolean addAll(int index, Collection c){
247 throw new UnsupportedOperationException();
248 }
251 }