Permalink
Browse files

tuples

  • Loading branch information...
richhickey committed Jul 16, 2015
1 parent 35563c1 commit 36d665793b43f62cfd22354aced4c6892088abd6
View
@@ -1,28 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Clojure" name="Clojure">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/resources" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/clj" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/jvm" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/clj" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test/clojure" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
<excludeFolder url="file://$MODULE_DIR$/test-classes" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.jsr166-mirror:jsr166y:1.7.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.clojure:test.generative:0.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.clojure:tools.namespace:0.1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.clojure:java.classpath:0.1.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.clojure:test.generative:0.5.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.clojure:tools.namespace:0.2.10" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.clojure:data.generators:0.1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.clojure:test.check:0.5.9" level="project" />
</component>
</module>
</module>
@@ -212,8 +212,8 @@
`(containsKey [this# k#] (not (identical? this# (.valAt this# k# this#))))
`(entryAt [this# k#] (let [v# (.valAt this# k# this#)]
(when-not (identical? this# v#)
(clojure.lang.MapEntry. k# v#))))
`(seq [this#] (seq (concat [~@(map #(list `new `clojure.lang.MapEntry (keyword %) %) base-fields)]
(clojure.lang.Tuple/create k# v#))))
`(seq [this#] (seq (concat [~@(map #(list `clojure.lang.Tuple/create (keyword %) %) base-fields)]
~'__extmap)))
`(iterator [~gs]
(clojure.lang.RecordIterator. ~gs [~@(map keyword base-fields)] (RT/iter ~'__extmap)))
@@ -394,7 +394,7 @@
[]
(iterator [] (.iterator ^Iterable pmap))
(containsKey [k] (contains? pmap k))
(entryAt [k] (when (contains? pmap k) (new clojure.lang.MapEntry k (v k))))
(entryAt [k] (when (contains? pmap k) (clojure.lang.Tuple/create k (v k))))
(valAt ([k] (when (contains? pmap k) (v k)))
([k default] (if (contains? pmap k) (v k) default)))
(cons [m] (conj (snapshot) m))
@@ -404,7 +404,7 @@
(seq [] ((fn thisfn [plseq]
(lazy-seq
(when-let [pseq (seq plseq)]
(cons (new clojure.lang.MapEntry (first pseq) (v (first pseq)))
(cons (clojure.lang.Tuple/create (first pseq) (v (first pseq)))
(thisfn (rest pseq)))))) (keys pmap))))))
View
@@ -267,7 +267,7 @@
(< (int k) cnt)))
(entryAt [this k]
(if (.containsKey this k)
(clojure.lang.MapEntry. k (.nth this (int k)))
(clojure.lang.Tuple/create k (.nth this (int k)))
nil))
clojure.lang.ILookup
@@ -266,7 +266,7 @@ public void remove() {
static final IFn MAKE_ENTRY = new AFn() {
public Object invoke(Object key, Object val) {
return new MapEntry(key, val);
return Tuple.create(key, val);
}
};
@@ -39,9 +39,20 @@ public ISeq rseq(){
}
static boolean doEquals(IPersistentVector v, Object obj){
if(v == obj) return true;
if(obj instanceof List || obj instanceof IPersistentVector)
{
if(obj instanceof IPersistentVector)
{
IPersistentVector ov = (IPersistentVector) obj;
if(ov.count() != v.count())
return false;
for(int i = 0;i< v.count();i++)
{
if(!Util.equals(v.nth(i), ov.nth(i)))
return false;
}
return true;
}
else if(obj instanceof List)
{
Collection ma = (Collection) obj;
if(ma.size() != v.count() || ma.hashCode() != v.hashCode())
return false;
@@ -53,19 +64,8 @@ static boolean doEquals(IPersistentVector v, Object obj){
}
return true;
}
// if(obj instanceof IPersistentVector)
// {
// IPersistentVector ma = (IPersistentVector) obj;
// if(ma.count() != v.count() || ma.hashCode() != v.hashCode())
// return false;
// for(int i = 0; i < v.count(); i++)
// {
// if(!Util.equal(v.nth(i), ma.nth(i)))
// return false;
// }
// }
else
{
{
if(!(obj instanceof Sequential))
return false;
ISeq ms = RT.seq(obj);
@@ -83,7 +83,19 @@ static boolean doEquals(IPersistentVector v, Object obj){
}
static boolean doEquiv(IPersistentVector v, Object obj){
if(obj instanceof List || obj instanceof IPersistentVector)
if(obj instanceof IPersistentVector)
{
IPersistentVector ov = (IPersistentVector) obj;
if(ov.count() != v.count())
return false;
for(int i = 0;i< v.count();i++)
{
if(!Util.equiv(v.nth(i), ov.nth(i)))
return false;
}
return true;
}
else if(obj instanceof List)
{
Collection ma = (Collection) obj;
if(ma.size() != v.count())
@@ -96,17 +108,6 @@ static boolean doEquiv(IPersistentVector v, Object obj){
}
return true;
}
// if(obj instanceof IPersistentVector)
// {
// IPersistentVector ma = (IPersistentVector) obj;
// if(ma.count() != v.count() || ma.hashCode() != v.hashCode())
// return false;
// for(int i = 0; i < v.count(); i++)
// {
// if(!Util.equal(v.nth(i), ma.nth(i)))
// return false;
// }
// }
else
{
if(!(obj instanceof Sequential))
@@ -126,44 +127,42 @@ static boolean doEquiv(IPersistentVector v, Object obj){
}
public boolean equals(Object obj){
if(obj == this)
return true;
return doEquals(this, obj);
}
public boolean equiv(Object obj){
if(obj == this)
return true;
return doEquiv(this, obj);
}
public int hashCode(){
if(_hash == -1)
{
int hash = 1;
Iterator i = iterator();
while(i.hasNext())
for(int i = 0;i<count();i++)
{
Object obj = i.next();
Object obj = nth(i);
hash = 31 * hash + (obj == null ? 0 : obj.hashCode());
}
// int hash = 0;
// for(int i = 0; i < count(); i++)
// {
// hash = Util.hashCombine(hash, Util.hash(nth(i)));
// }
this._hash = hash;
}
return _hash;
}
public int hasheq(){
if(_hasheq == -1) {
// int hash = 1;
// Iterator i = iterator();
// while(i.hasNext())
// {
// Object obj = i.next();
// hash = 31 * hash + Util.hasheq(obj);
// }
// _hasheq = hash;
_hasheq = Murmur3.hashOrdered(this);
int n;
int hash = 1;
for(n=0;n<count();++n)
{
hash = 31 * hash + Util.hasheq(nth(n));
}
_hasheq = Murmur3.mixCollHash(hash, n);
}
return _hasheq;
}
@@ -321,7 +320,7 @@ public IMapEntry entryAt(Object key){
{
int i = ((Number) key).intValue();
if(i >= 0 && i < count())
return new MapEntry(key, nth(i));
return Tuple.create(key, nth(i));
}
return null;
}
@@ -352,7 +351,10 @@ public Object valAt(Object key){
// java.util.Collection implementation
public Object[] toArray(){
return RT.seqToArray(seq());
Object[] ret = new Object[count()];
for(int i=0;i<count();i++)
ret[i] = nth(i);
return ret;
}
public boolean add(Object o){
@@ -153,6 +153,15 @@
final static Type BOOLEAN_OBJECT_TYPE = Type.getType(Boolean.class);
final static Type IPERSISTENTMAP_TYPE = Type.getType(IPersistentMap.class);
final static Type IOBJ_TYPE = Type.getType(IObj.class);
final static Type TUPLE_TYPE = Type.getType(Tuple.class);
final static Method createTupleMethods[] = {Method.getMethod("clojure.lang.IPersistentVector create()"),
Method.getMethod("clojure.lang.Tuple$T1 create(Object)"),
Method.getMethod("clojure.lang.Tuple$T2 create(Object,Object)"),
Method.getMethod("clojure.lang.Tuple$T3 create(Object,Object,Object)"),
Method.getMethod("clojure.lang.Tuple$T4 create(Object,Object,Object,Object)"),
Method.getMethod("clojure.lang.Tuple$T5 create(Object,Object,Object,Object,Object)"),
Method.getMethod("clojure.lang.Tuple$T6 create(Object,Object,Object,Object,Object,Object)")
};
private static final Type[][] ARG_TYPES;
//private static final Type[] EXCEPTION_TYPES = {Type.getType(Exception.class)};
@@ -2904,6 +2913,8 @@ static public String demunge(String mungedName){
final static Type HASHMAP_TYPE = Type.getType(PersistentArrayMap.class);
final static Type HASHSET_TYPE = Type.getType(PersistentHashSet.class);
final static Type VECTOR_TYPE = Type.getType(PersistentVector.class);
final static Type IVECTOR_TYPE = Type.getType(IPersistentVector.class);
final static Type TUPLE_TYPE = Type.getType(Tuple.class);
final static Type LIST_TYPE = Type.getType(PersistentList.class);
final static Type EMPTY_LIST_TYPE = Type.getType(PersistentList.EmptyList.class);
@@ -2920,7 +2931,7 @@ public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
if(coll instanceof IPersistentList)
gen.getStatic(LIST_TYPE, "EMPTY", EMPTY_LIST_TYPE);
else if(coll instanceof IPersistentVector)
gen.getStatic(VECTOR_TYPE, "EMPTY", VECTOR_TYPE);
gen.getStatic(TUPLE_TYPE, "EMPTY", IVECTOR_TYPE);
else if(coll instanceof IPersistentMap)
gen.getStatic(HASHMAP_TYPE, "EMPTY", HASHMAP_TYPE);
else if(coll instanceof IPersistentSet)
@@ -3157,8 +3168,7 @@ else if(constant)
public static class VectorExpr implements Expr{
public final IPersistentVector args;
final static Method vectorMethod = Method.getMethod("clojure.lang.IPersistentVector vector(Object[])");
final static Method vectorMethod = Method.getMethod("clojure.lang.IPersistentVector vector(Object[])");
public VectorExpr(IPersistentVector args){
this.args = args;
@@ -3172,9 +3182,21 @@ public Object eval() {
}
public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
MethodExpr.emitArgsAsArray(args, objx, gen);
gen.invokeStatic(RT_TYPE, vectorMethod);
if(context == C.STATEMENT)
if(args.count() <= Tuple.MAX_SIZE)
{
for(int i = 0; i < args.count(); i++) {
((Expr) args.nth(i)).emit(C.EXPRESSION, objx, gen);
}
gen.invokeStatic(TUPLE_TYPE, createTupleMethods[args.count()]);
}
else
{
MethodExpr.emitArgsAsArray(args, objx, gen);
gen.invokeStatic(RT_TYPE, vectorMethod);
}
if(context == C.STATEMENT)
gen.pop();
}
@@ -3203,7 +3225,7 @@ static public Expr parse(C context, IPersistentVector form) {
.parse(context == C.EVAL ? context : C.EXPRESSION, ((IObj) form).meta()));
else if (constant)
{
PersistentVector rv = PersistentVector.EMPTY;
IPersistentVector rv = Tuple.EMPTY;
for(int i =0;i<args.count();i++)
{
LiteralExpr ve = (LiteralExpr)args.nth(i);
@@ -4699,9 +4721,20 @@ else if(value instanceof IPersistentMap)
}
else if(value instanceof IPersistentVector)
{
emitListAsObjectArray(value, gen);
gen.invokeStatic(RT_TYPE, Method.getMethod(
"clojure.lang.IPersistentVector vector(Object[])"));
IPersistentVector args = (IPersistentVector) value;
if(args.count() <= Tuple.MAX_SIZE)
{
for(int i = 0; i < args.count(); i++) {
emitValue(args.nth(i), gen);
}
gen.invokeStatic(TUPLE_TYPE, createTupleMethods[args.count()]);
}
else
{
emitListAsObjectArray(value, gen);
gen.invokeStatic(RT_TYPE, Method.getMethod(
"clojure.lang.IPersistentVector vector(Object[])"));
}
}
else if(value instanceof PersistentHashSet)
{
@@ -12,19 +12,24 @@
package clojure.lang;
import java.util.RandomAccess;
public class LazilyPersistentVector{
static public IPersistentVector createOwning(Object... items){
if(items.length == 0)
return PersistentVector.EMPTY;
if(items.length <= Tuple.MAX_SIZE)
return Tuple.createFromArray(items);
else if(items.length <= 32)
return new PersistentVector(items.length, 5, PersistentVector.EMPTY_NODE,items);
return PersistentVector.create(items);
}
static public IPersistentVector create(Object obj){
if(obj instanceof IReduceInit)
if((obj instanceof Counted || obj instanceof RandomAccess)
&& RT.count(obj) <= Tuple.MAX_SIZE)
return Tuple.createFromColl(obj);
else if(obj instanceof IReduceInit)
return PersistentVector.create((IReduceInit) obj);
else if(obj instanceof ISeq)
return PersistentVector.create(RT.seq(obj));
@@ -161,7 +161,7 @@ public boolean containsKey(Object key){
public IMapEntry entryAt(Object key){
int i = indexOf(key);
if(i >= 0)
return new MapEntry(array[i],array[i+1]);
return Tuple.create(array[i],array[i+1]);
return null;
}
@@ -318,7 +318,7 @@ public Seq(IPersistentMap meta, Object[] array, int i){
}
public Object first(){
return new MapEntry(array[i],array[i+1]);
return Tuple.create(array[i],array[i+1]);
}
public ISeq next(){
Oops, something went wrong.

0 comments on commit 36d6657

Please sign in to comment.