diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/org/clojure/runtime/AMap.java | 4 | ||||
-rw-r--r-- | src/org/clojure/runtime/Accessor.java | 86 | ||||
-rw-r--r-- | src/org/clojure/runtime/Indexer.java | 16 | ||||
-rw-r--r-- | src/org/clojure/runtime/Keyword.java | 57 | ||||
-rw-r--r-- | src/org/clojure/runtime/Namespace.java | 37 | ||||
-rw-r--r-- | src/org/clojure/runtime/RT.java | 3 | ||||
-rw-r--r-- | src/org/clojure/runtime/Reflector.java | 55 | ||||
-rw-r--r-- | src/org/clojure/runtime/Symbol.java | 78 | ||||
-rw-r--r-- | src/org/clojure/runtime/ThreadLocalData.java | 18 | ||||
-rw-r--r-- | src/org/clojure/runtime/Var.java | 133 |
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); + } + +} |