summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2009-02-02 15:14:48 +0000
committerRich Hickey <richhickey@gmail.com>2009-02-02 15:14:48 +0000
commit65528bfe81d605eab6fe3e475ada08f55bcc5ab5 (patch)
tree784cdb4a36f8e3fa35edf00dab9453d134356bea
parent961bb483ff08f6508390a6467d0758efe2c1ba85 (diff)
[lazy] interim checkin
-rw-r--r--src/clj/clojure/core.clj8
-rw-r--r--src/clj/clojure/core_print.clj8
-rw-r--r--src/jvm/clojure/lang/ASeq.java7
-rw-r--r--src/jvm/clojure/lang/Compile.java4
-rw-r--r--src/jvm/clojure/lang/Compiler.java23
-rw-r--r--src/jvm/clojure/lang/LazySeq.java194
-rw-r--r--src/jvm/clojure/lang/RT.java48
7 files changed, 256 insertions, 36 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 3d13eba0..fc25a32a 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -407,7 +407,6 @@
[first-expr & rest-expr]
(list 'new 'clojure.lang.LazyCons (list `fn (list [] first-expr) (list* [(gensym)] rest-expr))))
-
(defmacro lazy-seq
"Takes a body of expressions that returns an ISeq or nil, and yields
a Seqable object that will invoke the body only the first time seq
@@ -415,7 +414,7 @@
seq calls. Any closed over locals will be cleared prior to the tail
call of body."
[& body]
- (list 'new 'clojure.lang.Delay$Seq (list* '#^{:once true} fn* [] body)))
+ (list* '#^{:once true :super-name "clojure/lang/LazySeq"} fn* [] body))
(defn concat
"Returns a lazy sequence representing the concatenation of the elements in the supplied colls."
@@ -1420,8 +1419,9 @@
f should accept number-of-colls arguments."
([f coll]
(lazy-seq
- (when (seq coll)
- (cons (f (first coll)) (map f (more coll))))))
+ (let [s (seq coll)]
+ (when s
+ (cons (f (first s)) (map f (more s)))))))
([f c1 c2]
(lazy-seq
(when (and (seq c1) (seq c2))
diff --git a/src/clj/clojure/core_print.clj b/src/clj/clojure/core_print.clj
index 59b045b3..b2589f6f 100644
--- a/src/clj/clojure/core_print.clj
+++ b/src/clj/clojure/core_print.clj
@@ -101,12 +101,12 @@
(print-dup (str o) w))
w))
-(defmethod print-dup clojure.lang.AFn [o, #^Writer w]
+(defmethod print-dup clojure.lang.Fn [o, #^Writer w]
(print-ctor o (fn [o w]) w))
-(prefer-method print-dup clojure.lang.IPersistentCollection clojure.lang.AFn)
-(prefer-method print-dup java.util.Map clojure.lang.AFn)
-(prefer-method print-dup java.util.Collection clojure.lang.AFn)
+(prefer-method print-dup clojure.lang.IPersistentCollection clojure.lang.Fn)
+(prefer-method print-dup java.util.Map clojure.lang.Fn)
+(prefer-method print-dup java.util.Collection clojure.lang.Fn)
(defmethod print-method Boolean [o, #^Writer w]
(.write w (str o)))
diff --git a/src/jvm/clojure/lang/ASeq.java b/src/jvm/clojure/lang/ASeq.java
index c4f4f7ca..f658ee91 100644
--- a/src/jvm/clojure/lang/ASeq.java
+++ b/src/jvm/clojure/lang/ASeq.java
@@ -110,8 +110,11 @@ public ISeq cons(Object o){
return new Cons(o, this);
}
-public ISeq rest(){
- return RT.seq(more());
+final public ISeq rest(){
+ Seqable m = more();
+ if(m == null)
+ return null;
+ return m.seq();
}
// java.util.Collection implementation
diff --git a/src/jvm/clojure/lang/Compile.java b/src/jvm/clojure/lang/Compile.java
index 0f3948b1..37d2c102 100644
--- a/src/jvm/clojure/lang/Compile.java
+++ b/src/jvm/clojure/lang/Compile.java
@@ -23,10 +23,10 @@ import java.io.IOException;
public class Compile{
private static final String PATH_PROP = "clojure.compile.path";
-private static final Var compile_path = RT.var("clojure.core", "*compile-path*");
-private static final Var compile = RT.var("clojure.core", "compile");
public static void main(String[] args) throws Exception{
+ final Var compile_path = RT.var("clojure.core", "*compile-path*");
+ final Var compile = RT.var("clojure.core", "compile");
OutputStreamWriter out = (OutputStreamWriter) RT.OUT.get();
PrintWriter err = (PrintWriter) RT.ERR.get();
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index efd52ab6..4e75daff 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -2818,6 +2818,7 @@ static public class FnExpr implements Expr{
PersistentVector constants;
int constantsID;
boolean onceOnly = false;
+ String superName = null;
public final IPersistentCollection methods(){
return methods;
@@ -2899,7 +2900,11 @@ static public class FnExpr implements Expr{
static Expr parse(C context, ISeq form, String name) throws Exception{
FnExpr fn = new FnExpr(tagOf(form));
FnMethod enclosingMethod = (FnMethod) METHOD.get();
- fn.onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), Keyword.intern(null, "once")));
+ if(((IMeta)form.first()).meta() != null)
+ {
+ fn.onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), Keyword.intern(null, "once")));
+ fn.superName = (String) RT.get(RT.meta(form.first()), Keyword.intern(null, "super-name"));
+ }
//fn.thisName = name;
String basename = enclosingMethod != null ?
(enclosingMethod.fn.name + "$")
@@ -3014,7 +3019,8 @@ static public class FnExpr implements Expr{
// ClassVisitor cv = new TraceClassVisitor(new CheckClassAdapter(cw), new PrintWriter(System.out));
//ClassVisitor cv = new TraceClassVisitor(cw, new PrintWriter(System.out));
cv.visit(V1_5, ACC_PUBLIC + ACC_SUPER, internalName, null,
- isVariadic() ? "clojure/lang/RestFn" : "clojure/lang/AFunction", null);
+ superName != null ? superName :
+ (isVariadic() ? "clojure/lang/RestFn" : "clojure/lang/AFunction"), null);
String source = (String) SOURCE.get();
int lineBefore = (Integer) LINE_BEFORE.get();
int lineAfter = (Integer) LINE_AFTER.get() + 1;
@@ -3105,7 +3111,9 @@ static public class FnExpr implements Expr{
ctorgen.visitLineNumber(line, ctorgen.mark());
ctorgen.visitLabel(start);
ctorgen.loadThis();
- if(isVariadic()) //RestFn ctor takes reqArity arg
+ if(superName != null)
+ ctorgen.invokeConstructor(Type.getObjectType(superName),afnctor);
+ else if(isVariadic()) //RestFn ctor takes reqArity arg
{
ctorgen.push(variadicMethod.reqParms.count());
ctorgen.invokeConstructor(restFnType, restfnctor);
@@ -3176,7 +3184,8 @@ static public class FnExpr implements Expr{
for (int i = 0; i < constants.count(); i++)
{
- if (constants.nth(i) instanceof String)
+ Object o = constants.nth(i);
+ if (o instanceof String)
{
clinitgen.push((String)constants.nth(i));
}
@@ -3185,15 +3194,15 @@ static public class FnExpr implements Expr{
String cs = null;
try
{
- cs = RT.printString(constants.nth(i));
+ cs = RT.printString(o);
}
catch (Exception e)
{
throw new RuntimeException("Can't embed object in code, maybe print-dup not defined: "
- + constants.nth(i));
+ + o);
}
if (cs.length() == 0)
- throw new RuntimeException("Can't embed unreadable object in code: " + constants.nth(i));
+ throw new RuntimeException("Can't embed unreadable object in code: " + o);
if (cs.startsWith("#<"))
throw new RuntimeException("Can't embed unreadable object in code: " + cs);
diff --git a/src/jvm/clojure/lang/LazySeq.java b/src/jvm/clojure/lang/LazySeq.java
new file mode 100644
index 00000000..567be35b
--- /dev/null
+++ b/src/jvm/clojure/lang/LazySeq.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+ * which can be found in the file epl-v10.html 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 Jan 31, 2009 */
+
+package clojure.lang;
+
+import java.util.*;
+
+public class LazySeq extends AFn implements Seqable, IPersistentCollection, List, Sequential, Sequence {
+ static final ISeq DUMMY = new Cons(null, null);
+
+ private ISeq s = DUMMY;
+
+ final synchronized public ISeq seq() {
+ if(s == DUMMY)
+ {
+ try
+ {
+ s = (ISeq) invoke();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ return s;
+ }
+
+ public int count() {
+ int c = 0;
+ for (ISeq s = seq(); s != null; s = s.rest())
+ ++c;
+ return c;
+ }
+
+ public IPersistentCollection cons(Object o) {
+ return RT.cons(o, seq());
+ }
+
+ public IPersistentCollection empty() {
+ return null;
+ }
+
+ public boolean equiv(Object o) {
+ ISeq s = seq();
+ return s == o || (s != null && s.equiv(o));
+ }
+
+ public int hashCode() {
+ return Util.hash(seq());
+ }
+
+ public boolean equals(Object o) {
+ ISeq s = seq();
+ return s == o || (s != null && s.equals(o));
+ }
+
+
+// java.util.Collection implementation
+
+ public Object[] toArray() {
+ return RT.seqToArray(seq());
+ }
+
+ public boolean add(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean remove(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean addAll(Collection c) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean retainAll(Collection c) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean removeAll(Collection c) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean containsAll(Collection c) {
+ for (Object o : c)
+ {
+ if (!contains(o))
+ return false;
+ }
+ return true;
+ }
+
+ public Object[] toArray(Object[] a) {
+ if (a.length >= count())
+ {
+ ISeq s = seq();
+ for (int i = 0; s != null; ++i, s = s.rest())
+ {
+ a[i] = s.first();
+ }
+ if (a.length > count())
+ a[count()] = null;
+ return a;
+ }
+ else
+ return toArray();
+ }
+
+ public int size() {
+ return count();
+ }
+
+ public boolean isEmpty() {
+ return count() == 0;
+ }
+
+ public boolean contains(Object o) {
+ for (ISeq s = seq(); s != null; s = s.rest())
+ {
+ if (Util.equiv(s.first(), o))
+ return true;
+ }
+ return false;
+ }
+
+ public Iterator iterator() {
+ return new SeqIterator(seq());
+ }
+
+ //////////// List stuff /////////////////
+ private List reify() {
+ return new ArrayList(this);
+ }
+
+ public List subList(int fromIndex, int toIndex) {
+ return reify().subList(fromIndex, toIndex);
+ }
+
+ public Object set(int index, Object element) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object remove(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ public int indexOf(Object o) {
+ ISeq s = seq();
+ for (int i = 0; s != null; s = s.rest(), i++)
+ {
+ if (Util.equiv(s.first(), o))
+ return i;
+ }
+ return -1;
+ }
+
+ public int lastIndexOf(Object o) {
+ return reify().lastIndexOf(o);
+ }
+
+ public ListIterator listIterator() {
+ return reify().listIterator();
+ }
+
+ public ListIterator listIterator(int index) {
+ return reify().listIterator(index);
+ }
+
+ public Object get(int index) {
+ return RT.nth(this, index);
+ }
+
+ public void add(int index, Object element) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean addAll(int index, Collection c) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index d64cfa7d..50a4baae 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -497,7 +497,11 @@ static ISeq seqFrom(Object coll){
else if(coll instanceof Map)
return seq(((Map) coll).entrySet());
else
- throw new IllegalArgumentException("Don't know how to create ISeq from: " + coll.getClass().getSimpleName());
+ {
+ Class c = coll.getClass();
+ Class sc = c.getSuperclass();
+ throw new IllegalArgumentException("Don't know how to create ISeq from: " + c.getSimpleName());
+ }
}
static public ISeq keys(Object coll){
@@ -577,22 +581,30 @@ static public ISeq rest(Object x){
}
static public Seqable more(Object x){
- Seqable ret = null;
if(x instanceof ISeq)
- ret = ((ISeq) x).more();
- else
- {
- ISeq seq = seq(x);
- if(seq == null)
- ret = PersistentList.EMPTY;
- else
- ret = seq.more();
- }
- if(ret == null)
- ret = PersistentList.EMPTY;
-// throw new IllegalStateException("nil more");
- return ret;
-}
+ return ((ISeq) x).more();
+ ISeq seq = seq(x);
+ if(seq == null)
+ return null;
+ return seq.more();
+}
+
+//static public Seqable more(Object x){
+// Seqable ret = null;
+// if(x instanceof ISeq)
+// ret = ((ISeq) x).more();
+// else
+// {
+// ISeq seq = seq(x);
+// if(seq == null)
+// ret = PersistentList.EMPTY;
+// else
+// ret = seq.more();
+// }
+// if(ret == null)
+// ret = PersistentList.EMPTY;
+// return ret;
+//}
static public ISeq rrest(Object x){
return rest(rest(x));
@@ -1231,7 +1243,9 @@ static public void print(Object x, Writer w) throws Exception{
if(x instanceof Obj)
{
Obj o = (Obj) x;
- if(RT.count(o.meta()) > 0 && readably && booleanCast(PRINT_META.get()))
+ if(RT.count(o.meta()) > 0 &&
+ ((readably && booleanCast(PRINT_META.get()))
+ || booleanCast(PRINT_DUP.get())))
{
IPersistentMap meta = o.meta();
w.write("#^");