summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-04-21 20:21:59 +0000
committerRich Hickey <richhickey@gmail.com>2006-04-21 20:21:59 +0000
commita42245c3e9c1cf2c2e54dc31c7bffd91ae32dac8 (patch)
tree16e579a97f4a87a860782cf56c7e937bf2b2c931 /src
parent165da010e2c81bab2128231384128b39b7c9a127 (diff)
revised symbol system
Diffstat (limited to 'src')
-rw-r--r--src/cli/runtime/AGenerator.cs13
-rw-r--r--src/cli/runtime/AMap.cs4
-rw-r--r--src/cli/runtime/Accessor.cs18
-rw-r--r--src/cli/runtime/Indexer.cs18
-rw-r--r--src/cli/runtime/Keyword.cs30
-rw-r--r--src/cli/runtime/Namespace.cs38
-rw-r--r--src/cli/runtime/Reflector.cs18
-rw-r--r--src/cli/runtime/Symbol.cs67
-rw-r--r--src/cli/runtime/ThreadLocalData.cs22
-rw-r--r--src/cli/runtime/Var.cs20
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); } }
+}