summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/org/clojure/runtime/AMap.java4
-rw-r--r--src/org/clojure/runtime/Accessor.java86
-rw-r--r--src/org/clojure/runtime/Indexer.java16
-rw-r--r--src/org/clojure/runtime/Keyword.java57
-rw-r--r--src/org/clojure/runtime/Namespace.java37
-rw-r--r--src/org/clojure/runtime/RT.java3
-rw-r--r--src/org/clojure/runtime/Reflector.java55
-rw-r--r--src/org/clojure/runtime/Symbol.java78
-rw-r--r--src/org/clojure/runtime/ThreadLocalData.java18
-rw-r--r--src/org/clojure/runtime/Var.java133
10 files changed, 377 insertions, 110 deletions
diff --git a/src/org/clojure/runtime/AMap.java b/src/org/clojure/runtime/AMap.java
index 853672e3..5f8965c3 100644
--- a/src/org/clojure/runtime/AMap.java
+++ b/src/org/clojure/runtime/AMap.java
@@ -19,7 +19,7 @@ public class AMap{
IdentityHashMap attrs;
public static final int INITIAL_SIZE = 7;
-public Object put(Symbol key, Object val)
+public Object put(Indexer key, Object val)
{
if(attrs == null)
attrs = new IdentityHashMap(INITIAL_SIZE);
@@ -27,7 +27,7 @@ public Object put(Symbol key, Object val)
return val;
}
-public Object get(Symbol key)
+public Object get(Indexer key)
{
if(attrs == null)
return null;
diff --git a/src/org/clojure/runtime/Accessor.java b/src/org/clojure/runtime/Accessor.java
new file mode 100644
index 00000000..9b74bdf4
--- /dev/null
+++ b/src/org/clojure/runtime/Accessor.java
@@ -0,0 +1,86 @@
+/**
+ * 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 19, 2006 */
+
+package org.clojure.runtime;
+
+public class Accessor extends Indexer{
+
+public final String name;
+public Namespace namespace;
+
+Accessor(String name, Namespace ns)
+ {
+ this.namespace = ns;
+ this.name = name;
+ }
+
+public String toString()
+ {
+ if(namespace == null)
+ return "#:." + name;
+ return namespace.name + ":." + name;
+ }
+
+/**
+ * Indexer implements IFn for attr access
+ * This single arg version is the getter
+ * @param tld
+ * @param obj - must be AMap
+ * @return the value of the attr or nil if not found
+ * @throws Exception
+ */
+public Object invoke(ThreadLocalData tld, Object obj) throws Exception
+ {
+ if(obj instanceof AMap)
+ return ((AMap)obj).get(this);
+ return Reflector.invokeInstanceMember(name,obj);
+ }
+
+/**
+ * Indexer implements IFn for attr access
+ * This two arg version is the setter
+ * @param tld
+ * @param obj - must be AMap
+ * @param val
+ * @return val
+ * @throws Exception
+ */
+public Object invoke(ThreadLocalData tld, Object obj, Object val) throws Exception
+ {
+ if(obj instanceof AMap)
+ return ((AMap)obj).put(this,val);
+ return Reflector.invokeInstanceMember(name,obj,val);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) throws Exception
+ {
+ return Reflector.invokeInstanceMember(name,arg1,arg2,arg3);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception
+ {
+ return Reflector.invokeInstanceMember(name,arg1,arg2,arg3,arg4);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
+ throws Exception
+ {
+ return Reflector.invokeInstanceMember(name,arg1,arg2,arg3,arg4,arg5);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args)
+ throws Exception
+ {
+ return Reflector.invokeInstanceMember(name,arg1,arg2,arg3,arg4,arg5,args);
+ }
+
+}
diff --git a/src/org/clojure/runtime/Indexer.java b/src/org/clojure/runtime/Indexer.java
new file mode 100644
index 00000000..5eebe489
--- /dev/null
+++ b/src/org/clojure/runtime/Indexer.java
@@ -0,0 +1,16 @@
+/**
+ * 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 19, 2006 */
+
+package org.clojure.runtime;
+
+public class Indexer extends AFn{
+}
diff --git a/src/org/clojure/runtime/Keyword.java b/src/org/clojure/runtime/Keyword.java
index 47dc6cbb..822737eb 100644
--- a/src/org/clojure/runtime/Keyword.java
+++ b/src/org/clojure/runtime/Keyword.java
@@ -12,32 +12,65 @@
package org.clojure.runtime;
-public class Keyword extends Symbol{
+import java.util.HashMap;
+
+public class Keyword extends Indexer{
+
+
+final public static HashMap table = new HashMap();
+
+public final String name;
+
+public static Keyword intern(String name)
+ {
+ synchronized(table)
+ {
+ Keyword sym = (Keyword) table.get(name);
+ if(sym == null)
+ table.put(name, sym = new Keyword(name));
+ return sym;
+ }
+ }
/**
* Used by Namespace.intern()
*
* @param name
- * @param ns
+
*/
-Keyword(String name, Namespace ns)
+Keyword(String name)
{
- super(name, ns);
- this.val = this;
- this.fn = this;
+ this.name = name;
}
-public Object getValue(ThreadLocalData tld)
+public String toString()
{
- return this;
+ return ":" + name;
}
-public Object setValue(ThreadLocalData tld, Object val)
+/**
+ * Indexer implements IFn for attr access
+ * This single arg version is the getter
+ * @param tld
+ * @param obj - must be AMap
+ * @return the value of the attr or nil if not found
+ * @throws Exception
+ */
+public Object invoke(ThreadLocalData tld, Object obj) throws Exception
{
- throw new UnsupportedOperationException("Cannot set the value of a keyword");
+ return ((AMap)obj).get(this);
}
-public String toString()
+/**
+ * Indexer implements IFn for attr access
+ * This two arg version is the setter
+ * @param tld
+ * @param obj - must be AMap
+ * @param val
+ * @return val
+ * @throws Exception
+ */
+public Object invoke(ThreadLocalData tld, Object obj, Object val) throws Exception
{
- return ":" + name;
+ return ((AMap)obj).put(this,val);
}
}
diff --git a/src/org/clojure/runtime/Namespace.java b/src/org/clojure/runtime/Namespace.java
index b09adbad..b8bd42d3 100644
--- a/src/org/clojure/runtime/Namespace.java
+++ b/src/org/clojure/runtime/Namespace.java
@@ -24,20 +24,10 @@ static final public HashMap table = new HashMap();
/**
* String->Symbol
*/
-final public HashMap symbols = new HashMap();
+final public HashMap accessors = new HashMap();
+final public HashMap vars = new HashMap();
final public String name;
-static final public Namespace globalNS = new Namespace("");
-static final public Namespace keywordNS = new Namespace("keyword"){
- public Symbol intern(String name)
- {
- Symbol sym = (Symbol) symbols.get(name);
- if(sym == null)
- symbols.put(name, sym = new Keyword(name, this));
- return sym;
- }
-};
-
Namespace(String name)
{
this.name = name;
@@ -60,14 +50,25 @@ static public Namespace findOrCreate(String name)
}
}
-public Symbol intern(String name)
+public Var internVar(String name)
+ {
+ synchronized(vars)
+ {
+ Var var = (Var) vars.get(name);
+ if(var == null)
+ vars.put(name, var = new Var(name, this));
+ return var;
+ }
+ }
+
+public Accessor internAccessor(String name)
{
- synchronized(symbols)
+ synchronized(accessors)
{
- Symbol sym = (Symbol) symbols.get(name);
- if(sym == null)
- symbols.put(name, sym = new Symbol(name, this));
- return sym;
+ Accessor acc = (Accessor) accessors.get(name);
+ if(acc == null)
+ accessors.put(name, acc = new Accessor(name, this));
+ return acc;
}
}
}
diff --git a/src/org/clojure/runtime/RT.java b/src/org/clojure/runtime/RT.java
index 5548f2f9..48ff4ee2 100644
--- a/src/org/clojure/runtime/RT.java
+++ b/src/org/clojure/runtime/RT.java
@@ -16,6 +16,9 @@ import java.util.Iterator;
public class RT{
+ public Object test;
+ public Object test(){return null;}
+
static public Object eq(Object arg1, Object arg2) {
return (arg1 == arg2)?Boolean.TRUE:null;
}
diff --git a/src/org/clojure/runtime/Reflector.java b/src/org/clojure/runtime/Reflector.java
new file mode 100644
index 00000000..1c9cb90f
--- /dev/null
+++ b/src/org/clojure/runtime/Reflector.java
@@ -0,0 +1,55 @@
+/**
+ * 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 19, 2006 */
+
+package org.clojure.runtime;
+
+public class Reflector{
+
+public static Object invokeInstanceMember(String name, Object arg1) throws Exception
+ {
+ return throwNotImplemented();
+ }
+
+public static Object invokeInstanceMember(String name, Object arg1, Object arg2) throws Exception
+ {
+ return throwNotImplemented();
+ }
+
+public static Object invokeInstanceMember(String name, Object arg1, Object arg2, Object arg3) throws Exception
+ {
+ return throwNotImplemented();
+ }
+
+public static Object invokeInstanceMember(String name, Object arg1, Object arg2, Object arg3, Object arg4)
+ throws Exception
+ {
+ return throwNotImplemented();
+ }
+
+public static Object invokeInstanceMember(String name, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
+ throws Exception
+ {
+ return throwNotImplemented();
+ }
+
+public static Object invokeInstanceMember(String name, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5,
+ Cons args)
+ throws Exception
+ {
+ return throwNotImplemented();
+ }
+
+static protected Object throwNotImplemented()
+ {
+ throw new IllegalAccessError("Sorry, not implemented");
+ }
+}
diff --git a/src/org/clojure/runtime/Symbol.java b/src/org/clojure/runtime/Symbol.java
index e95ace2b..d5fd12f1 100644
--- a/src/org/clojure/runtime/Symbol.java
+++ b/src/org/clojure/runtime/Symbol.java
@@ -12,82 +12,40 @@
package org.clojure.runtime;
-public class Symbol extends AFn{
+import java.util.HashMap;
-public final static Object UNBOUND = new Object();
+public class Symbol extends AMap{
+
+final public static HashMap table = new HashMap();
public final String name;
-public Namespace namespace;
-public Object val = UNBOUND;
-public IFn fn; //todo, bind to throw stub?
public String toString()
{
- if(namespace == Namespace.globalNS)
- return name;
- if(namespace == null)
- return "#:" + name;
- return namespace.name + ":" + name;
+ return name;
+ }
+
+public static Symbol intern(String name)
+ {
+ synchronized(table)
+ {
+ Symbol sym = (Symbol) table.get(name);
+ if(sym == null)
+ table.put(name, sym = new Symbol(name));
+ return sym;
+ }
}
/**
- * Used by Namespace.intern()
+ * Used by intern()
* @param name
- * @param ns
*/
-Symbol(String name, Namespace ns)
+Symbol(String name)
{
- this.namespace = ns;
this.name = name;
}
-public Object getValue(ThreadLocalData tld)
- {
- Cons binding = tld.getDynamicBinding(this);
- if(binding != null)
- return binding.first;
- if(val == UNBOUND)
- throw new IllegalStateException(name + " is unbound.");
- return val;
- }
-public Object setValue(ThreadLocalData tld, Object val)
- {
- Cons binding = tld.getDynamicBinding(this);
- if(binding != null)
- return binding.first = val;
- //allow global set to create binding like this?
- if(val instanceof IFn)
- this.fn = (IFn) val;
- else
- this.fn = null; //todo, bind to throw stub?
- return this.val = val;
- }
-/**
- * Symbol implements IFn for attr access
- * This single arg version is the getter
- * @param tld
- * @param obj - must be AMap
- * @return the value of the attr or nil if not found
- * @throws Exception
- */
-public Object invoke(ThreadLocalData tld, Object obj) throws Exception
- {
- return ((AMap)obj).get(this);
- }
-/**
- * Symbol implements IFn for attr access
- * This two arg version is the setter
- * @param tld
- * @param obj - must be AMap
- * @param val
- * @return val
- * @throws Exception
- */
-public Object invoke(ThreadLocalData tld, Object obj, Object val) throws Exception
- {
- return ((AMap)obj).put(this,val);
- }
}
diff --git a/src/org/clojure/runtime/ThreadLocalData.java b/src/org/clojure/runtime/ThreadLocalData.java
index a011af39..67fd0048 100644
--- a/src/org/clojure/runtime/ThreadLocalData.java
+++ b/src/org/clojure/runtime/ThreadLocalData.java
@@ -22,24 +22,6 @@ public Object[] mvArray = new Object[MULTIPLE_VALUES_LIMIT];
IdentityHashMap dynamicBindings = new IdentityHashMap();
-final public Cons getDynamicBinding(Symbol sym)
- {
- return (Cons) dynamicBindings.get(sym);
- }
-
-final public Cons pushDynamicBinding(Symbol sym, Object val)
- {
- Cons ret = new Cons(val, getDynamicBinding(sym));
- dynamicBindings.put(sym, ret);
- return ret;
- }
-
-
-final public Cons popDynamicBinding(Symbol sym)
- {
- return (Cons) dynamicBindings.put(sym, getDynamicBinding(sym).rest);
- }
-
public ThreadLocalData(IdentityHashMap dynamicBindings)
{
this.mvCount = 0;
diff --git a/src/org/clojure/runtime/Var.java b/src/org/clojure/runtime/Var.java
new file mode 100644
index 00000000..e4b3dad3
--- /dev/null
+++ b/src/org/clojure/runtime/Var.java
@@ -0,0 +1,133 @@
+/**
+ * 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 19, 2006 */
+
+package org.clojure.runtime;
+
+public class Var extends AFn{
+
+public final String name;
+public Namespace namespace;
+public Cons binding;
+public IFn fn; //todo, bind to throw stub?
+public IFn setfn;
+
+Var(String name, Namespace ns)
+ {
+ this.namespace = ns;
+ this.name = name;
+ }
+
+public String toString()
+ {
+ if(namespace == null)
+ return "#:" + name;
+ return namespace.name + ":" + name;
+ }
+
+public Var bind(Object val)
+ {
+ if(binding == null)
+ binding = new Cons(val,null);
+ else
+ binding.first = val;
+
+ return this;
+ }
+
+public Cons getBinding(ThreadLocalData tld)
+ {
+ Cons b = getDynamicBinding(tld);
+ if(b != null)
+ return b;
+ return binding;
+ }
+
+public Object getValue(ThreadLocalData tld)
+ {
+ Cons binding = getBinding(tld);
+ if(binding != null)
+ return binding.first;
+ throw new IllegalStateException(this.toString() + " is unbound.");
+ }
+
+public Object setValue(ThreadLocalData tld, Object val)
+ {
+ Cons b = getDynamicBinding(tld);
+ if(b != null)
+ return b.first = val;
+ //allow global set to create binding like this?
+ if(binding == null)
+ throw new IllegalStateException(this.toString() + " is unbound.");
+
+ if(val instanceof IFn)
+ this.fn = (IFn) val;
+ else
+ this.fn = null; //todo, bind to throw stub?
+
+ return binding.first = val;
+ }
+
+final public Cons getDynamicBinding(ThreadLocalData tld)
+ {
+ return (Cons) tld.dynamicBindings.get(this);
+ }
+
+final public Cons pushDynamicBinding(ThreadLocalData tld, Object val)
+ {
+ Cons ret = new Cons(val, getDynamicBinding(tld));
+ tld.dynamicBindings.put(this, ret);
+ return ret;
+ }
+
+final public Cons popDynamicBinding(ThreadLocalData tld)
+ {
+ return (Cons) tld.dynamicBindings.put(this, getDynamicBinding(tld).rest);
+ }
+
+public Object invoke(ThreadLocalData tld) throws Exception
+ {
+ return fn.invoke(tld);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1) throws Exception
+ {
+ return fn.invoke(tld,arg1);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2) throws Exception
+ {
+ return fn.invoke(tld,arg1,arg2);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) throws Exception
+ {
+ return fn.invoke(tld,arg1,arg2,arg3);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception
+ {
+ return fn.invoke(tld,arg1,arg2,arg3,arg4);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
+ throws Exception
+ {
+ return fn.invoke(tld,arg1,arg2,arg3,arg4,arg5);
+ }
+
+public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args)
+ throws Exception
+ {
+ return fn.invoke(tld,arg1,arg2,arg3,arg4,arg5,args);
+ }
+
+}