diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-07-05 19:37:11 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-07-05 19:37:11 +0000 |
commit | 8a628fcd1b1e015ef61272df128cf4cbfa323259 (patch) | |
tree | 532d7bff25d7fde94be72c4c985a38a29e6d09b5 /src/cli/runtime/Var.cs | |
parent | e5dcae7b0a24af84476b1192563fa149ad6a4a96 (diff) |
added tcount, removed fn member, now fn vals are dynamically bindable
Diffstat (limited to 'src/cli/runtime/Var.cs')
-rw-r--r-- | src/cli/runtime/Var.cs | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/src/cli/runtime/Var.cs b/src/cli/runtime/Var.cs index 9da1ef31..5df61798 100644 --- a/src/cli/runtime/Var.cs +++ b/src/cli/runtime/Var.cs @@ -15,31 +15,30 @@ namespace clojure.lang {
public class Var : AFn
{
-public readonly Symbol sym;
public Namespace ns;
public Binding binding;
public IFn fn; //todo, bind to throw stub?
public IFn setfn;
volatile IPersistentMap threadBindings = PersistentArrayIdentityMap.EMPTY;
internal Var(Symbol sym, Namespace ns)
{
if(sym.GetType() != typeof(Symbol))
throw new ArgumentException("Only simple symbols can be vars");
this.ns = ns;
this.sym = sym;
}
override public String ToString()
{
if(ns == null)
return "#:" + sym;
return ns.name + ":" + sym;
}
public Var bind(Object val)
{
if(binding == null)
+public readonly Symbol sym;
public Namespace ns;
public Binding binding;
volatile IPersistentMap threadBindings = PersistentArrayIdentityMap.EMPTY;
volatile int tcount = 0;
internal Var(Symbol sym, Namespace ns)
{
if(sym.GetType() != typeof(Symbol))
throw new ArgumentException("Only simple symbols can be vars");
this.ns = ns;
this.sym = sym;
}
override public String ToString()
{
if(ns == null)
return "#:" + sym;
return ns.name + ":" + sym;
}
public Var bind(Object val)
{
if(binding == null)
binding = new Binding(val);
else
binding.val = val;
- if (val is IFn)
- this.fn = (IFn)val;
- else
- this.fn = null; //todo, bind to throw stub?
return this;
}
public Object getValue()
{
+ return this;
}
public Object getValue()
{
Binding binding = getBinding();
if(binding != null)
return binding.val;
throw new InvalidOperationException(this.ToString() + " is unbound.");
}
public Object setValue(Object val)
{
Binding b = getThreadBinding();
if(b != null)
return b.val = val;
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.val = val;
}
+ throw new InvalidOperationException(this.ToString() + " is unbound.");
return binding.val = val;
}
public Binding pushThreadBinding(Object val) {
Binding ret = new Binding(val, getThreadBinding());
setThreadBinding(ret);
+ Interlocked.Increment(ref tcount);
return ret;
}
public void popThreadBinding() {
setThreadBinding(getThreadBinding().rest);
+ Interlocked.Decrement(ref tcount);
}
Binding getBinding()
{
Binding b = getThreadBinding();
if(b != null)
return b;
return binding;
}
Binding getThreadBinding()
{
- if (threadBindings.count() > 0)
+ if (tcount != 0)
return (Binding)threadBindings.get(Thread.CurrentThread);
return null;
}
void setThreadBinding(Binding b) {
Thread thread = Thread.CurrentThread;
IPersistentMap tb;
@@ -52,5 +51,5 @@ Binding getThreadBinding()
{ else
newtb = tb.put(thread, b);
} while (tb != Interlocked.CompareExchange(ref threadBindings, newtb, tb));
-}
override public Object invoke() /*throws Exception*/
{
return fn.invoke();
}
override public Object invoke( Object arg1) /*throws Exception*/
{
return fn.invoke(arg1);
}
override public Object invoke( Object arg1, Object arg2) /*throws Exception*/
{
return fn.invoke(arg1,arg2);
}
override public Object invoke( Object arg1, Object arg2, Object arg3) /*throws Exception*/
{
return fn.invoke(arg1,arg2,arg3);
}
override public Object invoke( Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/
{
return fn.invoke(arg1,arg2,arg3,arg4);
}
override public Object invoke( Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
/*throws Exception*/
{
return fn.invoke(arg1,arg2,arg3,arg4,arg5);
}
override public Object invoke( Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, params Object[] args)
/*throws Exception*/
{
return fn.invoke(arg1,arg2,arg3,arg4,arg5,args);
}
}
+}
private IFn fn(){
return (IFn)getValue();
}
override public Object invoke() /*throws Exception*/
{
return fn().invoke();
}
override public Object invoke( Object arg1) /*throws Exception*/
{
return fn().invoke(arg1);
}
override public Object invoke( Object arg1, Object arg2) /*throws Exception*/
{
return fn().invoke(arg1,arg2);
}
override public Object invoke( Object arg1, Object arg2, Object arg3) /*throws Exception*/
{
return fn().invoke(arg1,arg2,arg3);
}
override public Object invoke( Object arg1, Object arg2, Object arg3, Object arg4) /*throws Exception*/
{
return fn().invoke(arg1,arg2,arg3,arg4);
}
override public Object invoke( Object arg1, Object arg2, Object arg3, Object arg4, Object arg5)
/*throws Exception*/
{
return fn().invoke(arg1,arg2,arg3,arg4,arg5);
}
override public Object invoke( Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, params Object[] args)
/*throws Exception*/
{
return fn().invoke(arg1,arg2,arg3,arg4,arg5,args);
}
}
}
|