diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-04-21 20:21:59 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-04-21 20:21:59 +0000 |
commit | a42245c3e9c1cf2c2e54dc31c7bffd91ae32dac8 (patch) | |
tree | 16e579a97f4a87a860782cf56c7e937bf2b2c931 /src | |
parent | 165da010e2c81bab2128231384128b39b7c9a127 (diff) |
revised symbol system
Diffstat (limited to 'src')
-rw-r--r-- | src/cli/runtime/AGenerator.cs | 13 | ||||
-rw-r--r-- | src/cli/runtime/AMap.cs | 4 | ||||
-rw-r--r-- | src/cli/runtime/Accessor.cs | 18 | ||||
-rw-r--r-- | src/cli/runtime/Indexer.cs | 18 | ||||
-rw-r--r-- | src/cli/runtime/Keyword.cs | 30 | ||||
-rw-r--r-- | src/cli/runtime/Namespace.cs | 38 | ||||
-rw-r--r-- | src/cli/runtime/Reflector.cs | 18 | ||||
-rw-r--r-- | src/cli/runtime/Symbol.cs | 67 | ||||
-rw-r--r-- | src/cli/runtime/ThreadLocalData.cs | 22 | ||||
-rw-r--r-- | src/cli/runtime/Var.cs | 20 |
10 files changed, 109 insertions, 139 deletions
diff --git a/src/cli/runtime/AGenerator.cs b/src/cli/runtime/AGenerator.cs index 1cd9ee9a..25532942 100644 --- a/src/cli/runtime/AGenerator.cs +++ b/src/cli/runtime/AGenerator.cs @@ -1,6 +1,15 @@ +/**
+ * 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.
+ **/
+
using System;
-using System.Collections.Generic;
-using System.Text;
+
namespace org.clojure.runtime
{
diff --git a/src/cli/runtime/AMap.cs b/src/cli/runtime/AMap.cs index 76850122..9db0a525 100644 --- a/src/cli/runtime/AMap.cs +++ b/src/cli/runtime/AMap.cs @@ -22,7 +22,7 @@ public class AMap HybridDictionary attrs; public static int INITIAL_SIZE = 7; -public Object put(Symbol key, Object val) +public Object put(Indexer key, Object val) { if(attrs == null) attrs = new HybridDictionary(INITIAL_SIZE); @@ -30,7 +30,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/cli/runtime/Accessor.cs b/src/cli/runtime/Accessor.cs new file mode 100644 index 00000000..1c436334 --- /dev/null +++ b/src/cli/runtime/Accessor.cs @@ -0,0 +1,18 @@ +/**
+ * 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.
+ **/
+
+using System;
+
+namespace org.clojure.runtime
+{
+public class Accessor :Indexer
+ {
+ public String name;
public Namespace ns;
internal Accessor(String name, Namespace ns)
{
this.ns = ns;
this.name = name;
}
public String toString()
{
if(ns == null)
return "#:." + name;
return ns.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
*/
override public Object invoke(ThreadLocalData tld, Object obj) //throws Exception
{
if(obj is 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
*/
override public Object invoke(ThreadLocalData tld, Object obj, Object val) //throws Exception
{
if(obj is AMap)
return ((AMap)obj).put(this,val);
return Reflector.invokeInstanceMember(name,obj,val);
}
override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) //throws Exception
{
return Reflector.invokeInstanceMember(name,arg1,arg2,arg3);
}
override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) //throws Exception
{
return Reflector.invokeInstanceMember(name,arg1,arg2,arg3,arg4);
}
override 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);
}
override 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/cli/runtime/Indexer.cs b/src/cli/runtime/Indexer.cs new file mode 100644 index 00000000..bc792857 --- /dev/null +++ b/src/cli/runtime/Indexer.cs @@ -0,0 +1,18 @@ +/**
+ * 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.
+ **/
+
+using System;
+
+namespace org.clojure.runtime
+{
+ public class Indexer :AFn
+ {
+ }
+}
diff --git a/src/cli/runtime/Keyword.cs b/src/cli/runtime/Keyword.cs index 8748cdf1..6e1bf33b 100644 --- a/src/cli/runtime/Keyword.cs +++ b/src/cli/runtime/Keyword.cs @@ -11,39 +11,21 @@ /* rich Mar 29, 2006 10:39:05 AM */ using System;
+using System.Collections.Specialized;
namespace org.clojure.runtime
{ -public class Keyword : Symbol
+public class Keyword : Indexer
{ -/** - * Used by Namespace.intern() - * - * @param name - * @param ns - */ -internal Keyword(String name, Namespace ns): - base(name, ns) - - { - this.val = this; - this.fn = this; - } - -override public Object getValue(ThreadLocalData tld) - { - return this; - } +static public HybridDictionary table = new HybridDictionary(); -override public Object setValue(ThreadLocalData tld, Object val) - { - throw new InvalidOperationException("Cannot set the value of a keyword"); - } -override public String ToString() +public String name;
override public String ToString() { return ":" + name; } +
public static Keyword intern(String name)
{
lock(table)
{
Keyword sym = (Keyword) table[name];
if(sym == null)
table.Add(name, sym = new Keyword(name));
return sym;
}
}
/**
* Used by Namespace.intern()
*
* @param name
*/
Keyword(String name)
{
this.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
*/
override public Object invoke(ThreadLocalData tld, Object obj) /*throws Exception*/
{
return ((AMap)obj).get(this);
}
/**
* Indexer implements IFn for attr access
* This two arg version is the setter
* @param tld
* @param obj - must be AMap
* @param val
* @return val
*/
override public Object invoke(ThreadLocalData tld, Object obj, Object val) /*throws Exception*/
{
return ((AMap)obj).put(this,val);
} + } }
\ No newline at end of file diff --git a/src/cli/runtime/Namespace.cs b/src/cli/runtime/Namespace.cs index 0a4acdf6..a78b0ed1 100644 --- a/src/cli/runtime/Namespace.cs +++ b/src/cli/runtime/Namespace.cs @@ -26,26 +26,11 @@ static public HybridDictionary table = new HybridDictionary(); /** * String->Symbol - */ -public HybridDictionary symbols = new HybridDictionary(); + */
+public HybridDictionary vars = new HybridDictionary();
+public HybridDictionary accessors = new HybridDictionary(); public String name; -static public Namespace globalNS = new Namespace(""); -static public Namespace keywordNS = new KeywordNamespace("keyword"); - -class KeywordNamespace : Namespace{ - public KeywordNamespace(String name) : base(name) - { - - } - override public Symbol intern(String name) - { - Symbol sym = (Symbol) symbols[name]; - if(sym == null) - symbols.Add(name, sym = new Keyword(name, this)); - return sym; - } -}; Namespace(String name) { @@ -67,17 +52,10 @@ static public Namespace findOrCreate(String name) ns = new Namespace(name); return ns; } - } - -virtual public Symbol intern(String name) - { - lock(symbols) - { - Symbol sym = (Symbol) symbols[name]; - if(sym == null) - symbols.Add(name, sym = new Symbol(name, this)); - return sym; - } - } + }
+
+public Var internVar(String name)
{
lock(vars)
{
Var var = (Var) vars[name];
if(var == null)
vars.Add(name,var = new Var(name, this));
return var;
}
}
+
+public Accessor internAccessor(String name)
{
lock(accessors)
{
Accessor acc = (Accessor) accessors[name];
if(acc == null)
accessors.Add(name, acc = new Accessor(name, this));
return acc;
}
} } } diff --git a/src/cli/runtime/Reflector.cs b/src/cli/runtime/Reflector.cs new file mode 100644 index 00000000..80b2f775 --- /dev/null +++ b/src/cli/runtime/Reflector.cs @@ -0,0 +1,18 @@ +/**
+ * 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.
+ **/
+
+using System;
+
+namespace 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 InvalidOperationException("Sorry, not implemented");
} }
+}
diff --git a/src/cli/runtime/Symbol.cs b/src/cli/runtime/Symbol.cs index 6994114b..2900a93f 100644 --- a/src/cli/runtime/Symbol.cs +++ b/src/cli/runtime/Symbol.cs @@ -11,86 +11,33 @@ /* rich Mar 25, 2006 11:42:47 AM */ using System;
+using System.Collections.Specialized;
namespace org.clojure.runtime
{ -public class Symbol : AFn{ +public class Symbol : AMap{
+
+static public HybridDictionary table = new HybridDictionary(); -public static Object UNBOUND = new Object(); public String name; //const is not equivalent to Java final with init elsewhere -public Namespace ns; -public Object val = UNBOUND; -public IFn fn; //todo, bind to throw stub? public String toString() { - if(ns == Namespace.globalNS) - return name; - if(ns == null) - return "#:" + name; - return ns.name + ":" + name; + return name; } +public static Symbol intern(String name)
{
lock(table)
{
Symbol sym = (Symbol) table[name];
if(sym == null)
table.Add(name, sym = new Symbol(name));
return sym;
}
} /** * Used by Namespace.intern() * @param name * @param ns */ -internal Symbol(String name, Namespace ns) +internal Symbol(String name) { - this.ns = ns; this.name = name; } -virtual public Object getValue(ThreadLocalData tld) - { - Cons binding = tld.getDynamicBinding(this); - if(binding != null) - return binding.first; - if(val == UNBOUND) - throw new InvalidOperationException(name + " is unbound."); - return val; - } - -virtual 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 is 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 - */ -override 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 - */ -override public Object invoke(ThreadLocalData tld, Object obj, Object val) /*throws Exception*/ - { - return ((AMap)obj).put(this,val); - } } } diff --git a/src/cli/runtime/ThreadLocalData.cs b/src/cli/runtime/ThreadLocalData.cs index 0f41ecf8..bb3f8896 100644 --- a/src/cli/runtime/ThreadLocalData.cs +++ b/src/cli/runtime/ThreadLocalData.cs @@ -21,27 +21,7 @@ public const int MULTIPLE_VALUES_LIMIT = 20; public int mvCount = 0; public Object[] mvArray = new Object[MULTIPLE_VALUES_LIMIT]; -HybridDictionary dynamicBindings = new HybridDictionary(); - -public Cons getDynamicBinding(Symbol sym) - { - return (Cons) dynamicBindings[sym]; - } - -public Cons pushDynamicBinding(Symbol sym, Object val) - { - Cons ret = new Cons(val, getDynamicBinding(sym)); - dynamicBindings[sym] = ret; - return ret; - } - - -public Cons popDynamicBinding(Symbol sym) - { - Cons ret = (Cons) getDynamicBinding(sym).rest; - dynamicBindings[sym] = ret; - return ret; - } +internal HybridDictionary dynamicBindings = new HybridDictionary(); public ThreadLocalData(HybridDictionary dynamicBindings) { diff --git a/src/cli/runtime/Var.cs b/src/cli/runtime/Var.cs new file mode 100644 index 00000000..9114ae9e --- /dev/null +++ b/src/cli/runtime/Var.cs @@ -0,0 +1,20 @@ +/**
+ * 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.
+ **/
+
+using System;
+
+namespace org.clojure.runtime
+{
+public class Var : Indexer
+ {
+public String name;
public Namespace ns;
public Cons binding;
public IFn fn; //todo, bind to throw stub?
public IFn setfn;
internal Var(String name, Namespace ns)
{
this.ns = ns;
this.name = name;
}
public String toString()
{
if(ns == null)
return "#:" + name;
return ns.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 InvalidOperationException(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 InvalidOperationException(this.toString() + " is unbound.");
if(val is IFn)
this.fn = (IFn) val;
else
this.fn = null; //todo, bind to throw stub?
return binding.first = val;
}
public Cons getDynamicBinding(ThreadLocalData tld)
{
return (Cons) tld.dynamicBindings[this];
}
public Cons pushDynamicBinding(ThreadLocalData tld, Object val)
{
Cons ret = new Cons(val, getDynamicBinding(tld));
tld.dynamicBindings[this] = ret;
return ret;
}
public Cons popDynamicBinding(ThreadLocalData tld)
{
Cons oldb = getDynamicBinding(tld).rest;
tld.dynamicBindings[this] = oldb;
+ return oldb;
}
override public Object invoke(ThreadLocalData tld) /*throws Exception*/
{
return fn.invoke(tld);
}
override public Object invoke(ThreadLocalData tld, Object arg1) /*throws Exception*/
{
return fn.invoke(tld,arg1);
}
override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2) /*throws Exception*/
{
return fn.invoke(tld,arg1,arg2);
}
override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) /*throws Exception*/
{
return fn.invoke(tld,arg1,arg2,arg3);
}
override public Object invoke(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/
{
return fn.invoke(tld,arg1,arg2,arg3,arg4);
}
override 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);
}
override 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);
}
}
+}
|