summaryrefslogtreecommitdiff
path: root/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/org')
-rw-r--r--src/org/clojure/runtime/AGenerator.java30
-rw-r--r--src/org/clojure/runtime/Cons.java16
-rw-r--r--src/org/clojure/runtime/ISeq.java19
-rw-r--r--src/org/clojure/runtime/Iter.java38
-rw-r--r--src/org/clojure/runtime/IteratorIter.java44
-rw-r--r--src/org/clojure/runtime/RT.java52
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)
{