diff options
Diffstat (limited to 'src/org')
-rw-r--r-- | src/org/clojure/runtime/AGenerator.java | 30 | ||||
-rw-r--r-- | src/org/clojure/runtime/Cons.java | 16 | ||||
-rw-r--r-- | src/org/clojure/runtime/ISeq.java | 19 | ||||
-rw-r--r-- | src/org/clojure/runtime/Iter.java | 38 | ||||
-rw-r--r-- | src/org/clojure/runtime/IteratorIter.java | 44 | ||||
-rw-r--r-- | src/org/clojure/runtime/RT.java | 52 |
6 files changed, 182 insertions, 17 deletions
diff --git a/src/org/clojure/runtime/AGenerator.java b/src/org/clojure/runtime/AGenerator.java new file mode 100644 index 00000000..c6d2875d --- /dev/null +++ b/src/org/clojure/runtime/AGenerator.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) Rich Hickey. All rights reserved. + * The use and distribution terms for this software are covered by the + * Common Public License 1.0 (http://opensource.org/licenses/cpl.php) + * which can be found in the file CPL.TXT at the root of this distribution. + * By using this software in any fashion, you are agreeing to be bound by + * the terms of this license. + * You must not remove this notice, or any other, from this software. + **/ + +/* rich Apr 3, 2006 */ + +package org.clojure.runtime; + +public abstract class AGenerator implements ISeq, Iter{ + +Object __val; +int __state = 0; + +public Object get() + { + return __val; + } + +public Iter iter() + { + //generators get 'primed' by calling iterate once, which pulls up to first yield + return iterate(); + } +} diff --git a/src/org/clojure/runtime/Cons.java b/src/org/clojure/runtime/Cons.java index 22980e74..6d19f019 100644 --- a/src/org/clojure/runtime/Cons.java +++ b/src/org/clojure/runtime/Cons.java @@ -12,7 +12,7 @@ package org.clojure.runtime; -public class Cons extends AMap{ +public class Cons extends AMap implements Iter, ISeq{ public Object first; public Cons rest; @@ -23,4 +23,18 @@ public Cons(Object first, Cons rest) this.rest = rest; } +public Object get() + { + return first; + } + +public Iter iterate() + { + return rest; + } + +public Iter iter() + { + return this; + } } diff --git a/src/org/clojure/runtime/ISeq.java b/src/org/clojure/runtime/ISeq.java new file mode 100644 index 00000000..e5d4c8fa --- /dev/null +++ b/src/org/clojure/runtime/ISeq.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) Rich Hickey. All rights reserved. + * The use and distribution terms for this software are covered by the + * Common Public License 1.0 (http://opensource.org/licenses/cpl.php) + * which can be found in the file CPL.TXT at the root of this distribution. + * By using this software in any fashion, you are agreeing to be bound by + * the terms of this license. + * You must not remove this notice, or any other, from this software. + **/ + +/* rich Apr 3, 2006 */ + +package org.clojure.runtime; + +public interface ISeq{ + +public Iter iter(); + +} diff --git a/src/org/clojure/runtime/Iter.java b/src/org/clojure/runtime/Iter.java new file mode 100644 index 00000000..82e1db5a --- /dev/null +++ b/src/org/clojure/runtime/Iter.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) Rich Hickey. All rights reserved. + * The use and distribution terms for this software are covered by the + * Common Public License 1.0 (http://opensource.org/licenses/cpl.php) + * which can be found in the file CPL.TXT at the root of this distribution. + * By using this software in any fashion, you are agreeing to be bound by + * the terms of this license. + * You must not remove this notice, or any other, from this software. + **/ + +/* rich Apr 3, 2006 10:54:14 AM */ + +package org.clojure.runtime; + + +/** + * Implements a sequential iteration protocol + * <pre> + * for(Iter i = getAnIter();i!=null;i = i.iterate()) + * { + * //use i.get() + * } + * </pre> + */ +public interface Iter{ +/** + * Multiple calls to get() are allowed prior to calling iterate() + * @return the currently referenced item/element/value + */ +public Object get(); + +/** + * This may destroy or otherwise invalidate the object it is called upon + * so always capture and use the return value (even though sometimes you may find it is the same object) + * @return The next iter to use, or null if at end of sequence + */ +public Iter iterate(); +} diff --git a/src/org/clojure/runtime/IteratorIter.java b/src/org/clojure/runtime/IteratorIter.java new file mode 100644 index 00000000..bfcec41a --- /dev/null +++ b/src/org/clojure/runtime/IteratorIter.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) Rich Hickey. All rights reserved. + * The use and distribution terms for this software are covered by the + * Common Public License 1.0 (http://opensource.org/licenses/cpl.php) + * which can be found in the file CPL.TXT at the root of this distribution. + * By using this software in any fashion, you are agreeing to be bound by + * the terms of this license. + * You must not remove this notice, or any other, from this software. + **/ + +/* rich Apr 3, 2006 */ + +package org.clojure.runtime; + +import java.util.Iterator; + +public class IteratorIter implements Iter{ + +Iterator i; +Object val; + +IteratorIter(Iterator i) + { + if(!i.hasNext()) + throw new IllegalStateException("Iterator must have elements to construct Iter"); + this.i = i; + val = i.next(); + } + +public Object get() + { + return val; + } + +public Iter iterate() + { + if(i.hasNext()) + { + val = i.next(); + return this; + } + return null; + } +} diff --git a/src/org/clojure/runtime/RT.java b/src/org/clojure/runtime/RT.java index 4ecabb82..ca49f32f 100644 --- a/src/org/clojure/runtime/RT.java +++ b/src/org/clojure/runtime/RT.java @@ -12,6 +12,8 @@ package org.clojure.runtime; +import java.util.Iterator; + public class RT{ static public Object eq(Object arg1, Object arg2) { @@ -20,32 +22,50 @@ public class RT{ static public Object eql(Object arg1, Object arg2) { if(arg1 == arg2) - return Boolean.TRUE; + return Boolean.TRUE; if(arg1 == null || arg2 == null) - return null; + return null; if(arg1 instanceof Num - && arg1.getClass() == arg2.getClass() - && arg1.equals(arg2)) - return Boolean.TRUE; + && arg1.getClass() == arg2.getClass() + && arg1.equals(arg2)) + return Boolean.TRUE; if(arg1.getClass() == Character.class - && arg2.getClass() == Character.class - && arg1.equals(arg2)) - return Boolean.TRUE; + && arg2.getClass() == Character.class + && arg1.equals(arg2)) + return Boolean.TRUE; return null; } static public Object equal(Object arg1, Object arg2) { if(arg1 == null) - return arg2 == null ? Boolean.TRUE : null; + return arg2 == null ? Boolean.TRUE : null; else if(arg2 == null) return null; - return (eql(arg1,arg2) != null - || (arg1.getClass() == Cons.class - && arg2.getClass() == Cons.class - && equal(((Cons)arg1).first,((Cons)arg2).first)!=null - && equal(((Cons)arg1).rest,((Cons)arg2).rest)!=null)) - ?Boolean.TRUE:null; - } + return (eql(arg1,arg2) != null + || (arg1.getClass() == Cons.class + && arg2.getClass() == Cons.class + && equal(((Cons)arg1).first,((Cons)arg2).first)!=null + && equal(((Cons)arg1).rest,((Cons)arg2).rest)!=null)) + ?Boolean.TRUE:null; + } + +static public Iter iter(Object coll) + { + if(coll == null) + return null; + else if(coll instanceof ISeq) + return ((ISeq) coll).iter(); + else if(coll instanceof Iterator) + { + Iterator i = (Iterator) coll; + if(i.hasNext()) + return new IteratorIter(i); + return null; + } + else + throw new IllegalArgumentException("Don't know how to create Iter from arg"); + } + static public Cons cons(Object x, Cons y) { |