/src/sys/dotnet/fan/sys/Func.cs
C# | 403 lines | 322 code | 47 blank | 34 comment | 21 complexity | 06aa2d14a37bd9aeaf4e95a5a1e203ed MD5 | raw file
Possible License(s): CC-BY-SA-3.0
- //
- // Copyright (c) 2006, Brian Frank and Andy Frank
- // Licensed under the Academic Free License version 3.0
- //
- // History:
- // 23 Jul 07 Andy Frank Creation
- //
- namespace Fan.Sys
- {
- /// <summary>
- /// Func models an executable subroutine.
- /// </summary>
- public abstract class Func : FanObj
- {
- //////////////////////////////////////////////////////////////////////////
- // Methods
- //////////////////////////////////////////////////////////////////////////
- public override Type @typeof() { return Sys.FuncType; }
- public abstract Type returns();
- public abstract long arity();
- public abstract List @params();
- public override abstract bool isImmutable();
- public abstract Method method();
- public abstract object callList(List args);
- public abstract object callOn(object target, List args);
- public abstract object call();
- public abstract object call(object a);
- public abstract object call(object a, object b);
- public abstract object call(object a, object b, object c);
- public abstract object call(object a, object b, object c, object d);
- public abstract object call(object a, object b, object c, object d, object e);
- public abstract object call(object a, object b, object c, object d, object e, object f);
- public abstract object call(object a, object b, object c, object d, object e, object f, object g);
- public abstract object call(object a, object b, object c, object d, object e, object f, object g, object h);
- public override object toImmutable()
- {
- if (isImmutable()) return this;
- throw NotImmutableErr.make().val;
- }
- // Hooks used by compiler to generate runtime const field checks for it-blocks
- public virtual void enterCtor(object o) {}
- public virtual void exitCtor() {}
- public virtual void checkInCtor(object o) {}
- //////////////////////////////////////////////////////////////////////////
- // Indirect
- //////////////////////////////////////////////////////////////////////////
- public static readonly int MaxIndirectParams = 8; // max callX()
- /// <summary>
- /// Indirect is the base class for the IndirectX classes, which are
- /// used as the common base classes for closures and general purpose
- /// functions. An Indirect method takes a funcType for it's type,
- /// and also extends Func for the callList() implementations.
- /// </summary>
- public abstract class Indirect : Func
- {
- protected Indirect(FuncType type) { this.m_type = type; }
- public string name() { return GetType().Name; }
- public override Type @typeof() { return m_type; }
- public override string toStr() { return m_type.signature(); }
- public override bool isImmutable() { return false; }
- public override Method method() { return null; }
- public Err.Val tooFewArgs(int given) { return Err.make("Too few arguments: " + given + " < " + m_type.m_params.Length).val; }
- public override Type returns() { return m_type.m_ret; }
- public override long arity() { return m_type.m_params.Length; }
- public override List @params()
- {
- // lazily build params list
- if (m_params == null) m_params = m_type.toMethodParams().ro();
- return m_params;
- }
- public override object callOn(object obj, List args)
- {
- List flat = args.dup();
- flat.insert(0, obj);
- return callList(flat);
- }
- FuncType m_type;
- private List m_params;
- }
- public abstract class Indirect0 : Indirect
- {
- protected Indirect0(FuncType type) : base(type) {}
- protected Indirect0() : base(type0) {}
- public override object callList(List args) { return call(); }
- public override abstract object call();
- public override object call(object a) { return call(); }
- public override object call(object a, object b) { return call(); }
- public override object call(object a, object b, object c) { return call(); }
- public override object call(object a, object b, object c, object d) { return call(); }
- public override object call(object a, object b, object c, object d, object e) { return call(); }
- public override object call(object a, object b, object c, object d, object e, object f) { return call(); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(); }
- }
- public abstract class Indirect1 : Indirect
- {
- protected Indirect1(FuncType type) : base(type) {}
- protected Indirect1() : base(type1) {}
- public override object callList(List args) { return call(args.get(0)); }
- public override object call() { throw tooFewArgs(0); }
- public override abstract object call(object a);
- public override object call(object a, object b) { return call(a); }
- public override object call(object a, object b, object c) { return call(a); }
- public override object call(object a, object b, object c, object d) { return call(a); }
- public override object call(object a, object b, object c, object d, object e) { return call(a); }
- public override object call(object a, object b, object c, object d, object e, object f) { return call(a); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a); }
- public override void enterCtor(object o) { this.m_inCtor = o; }
- public override void exitCtor() { this.m_inCtor = null; }
- public override void checkInCtor(object it)
- {
- if (it == m_inCtor) return;
- string msg = it == null ? "null" : FanObj.@typeof(it).qname();
- throw ConstErr.make(msg).val;
- }
- internal object m_inCtor;
- }
- public abstract class Indirect2 : Indirect
- {
- protected Indirect2(FuncType type) : base(type) {}
- protected Indirect2() : base(type2) {}
- public override object callList(List args) { return call(args.get(0), args.get(1)); }
- public override object call() { throw tooFewArgs(0); }
- public override object call(object a) { throw tooFewArgs(1); }
- public override abstract object call(object a, object b);
- public override object call(object a, object b, object c) { return call(a, b); }
- public override object call(object a, object b, object c, object d) { return call(a, b); }
- public override object call(object a, object b, object c, object d, object e) { return call(a, b); }
- public override object call(object a, object b, object c, object d, object e, object f) { return call(a, b); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b); }
- }
- public abstract class Indirect3 : Indirect
- {
- protected Indirect3(FuncType type) : base(type) {}
- protected Indirect3() : base(type3) {}
- public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2)); }
- public override object call() { throw tooFewArgs(0); }
- public override object call(object a) { throw tooFewArgs(1); }
- public override object call(object a, object b) { throw tooFewArgs(2); }
- public override abstract object call(object a, object b, object c);
- public override object call(object a, object b, object c, object d) { return call(a, b, c); }
- public override object call(object a, object b, object c, object d, object e) { return call(a, b, c); }
- public override object call(object a, object b, object c, object d, object e, object f) { return call(a, b, c); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b, c); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c); }
- }
- public abstract class Indirect4 : Indirect
- {
- protected Indirect4(FuncType type) : base(type) {}
- protected Indirect4() : base(type4) {}
- public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3)); }
- public override object call() { throw tooFewArgs(0); }
- public override object call(object a) { throw tooFewArgs(1); }
- public override object call(object a, object b) { throw tooFewArgs(2); }
- public override object call(object a, object b, object c) { throw tooFewArgs(3); }
- public override abstract object call(object a, object b, object c, object d);
- public override object call(object a, object b, object c, object d, object e) { return call(a, b, c, d); }
- public override object call(object a, object b, object c, object d, object e, object f) { return call(a, b, c, d); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b, c, d); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c, d); }
- }
- public abstract class Indirect5 : Indirect
- {
- protected Indirect5(FuncType type) : base(type) {}
- public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4)); }
- public override object call() { throw tooFewArgs(0); }
- public override object call(object a) { throw tooFewArgs(1); }
- public override object call(object a, object b) { throw tooFewArgs(2); }
- public override object call(object a, object b, object c) { throw tooFewArgs(3); }
- public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
- public override abstract object call(object a, object b, object c, object d, object e);
- public override object call(object a, object b, object c, object d, object e, object f) { return call(a, b, c, d, e); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b, c, d, e); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c, d, e); }
- }
- public abstract class Indirect6 : Indirect
- {
- protected Indirect6(FuncType type) : base(type) {}
- public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4), args.get(5)); }
- public override object call() { throw tooFewArgs(0); }
- public override object call(object a) { throw tooFewArgs(1); }
- public override object call(object a, object b) { throw tooFewArgs(2); }
- public override object call(object a, object b, object c) { throw tooFewArgs(3); }
- public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
- public override object call(object a, object b, object c, object d, object e) { throw tooFewArgs(5); }
- public override abstract object call(object a, object b, object c, object d, object e, object f);
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return call(a, b, c, d, e, f); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c, d, e, f); }
- }
- public abstract class Indirect7 : Indirect
- {
- protected Indirect7(FuncType type) : base(type) {}
- public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4), args.get(5), args.get(6)); }
- public override object call() { throw tooFewArgs(0); }
- public override object call(object a) { throw tooFewArgs(1); }
- public override object call(object a, object b) { throw tooFewArgs(2); }
- public override object call(object a, object b, object c) { throw tooFewArgs(3); }
- public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
- public override object call(object a, object b, object c, object d, object e) { throw tooFewArgs(5); }
- public override object call(object a, object b, object c, object d, object e, object f) { throw tooFewArgs(6); }
- public override abstract object call(object a, object b, object c, object d, object e, object f, object g);
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return call(a, b, c, d, e, f, g); }
- }
- public abstract class Indirect8 : Indirect
- {
- protected Indirect8(FuncType type) : base(type) {}
- public override object callList(List args) { return call(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4), args.get(5), args.get(6), args.get(7)); }
- public override object call() { throw tooFewArgs(0); }
- public override object call(object a) { throw tooFewArgs(1); }
- public override object call(object a, object b) { throw tooFewArgs(2); }
- public override object call(object a, object b, object c) { throw tooFewArgs(3); }
- public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
- public override object call(object a, object b, object c, object d, object e) { throw tooFewArgs(5); }
- public override object call(object a, object b, object c, object d, object e, object f) { throw tooFewArgs(6); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { throw tooFewArgs(7); }
- public override abstract object call(object a, object b, object c, object d, object e, object f, object g, object h);
- }
- public abstract class IndirectX : Indirect
- {
- protected IndirectX(FuncType type) : base(type) {}
- public override abstract object callList(List args);
- public override object call() { throw tooFewArgs(0); }
- public override object call(object a) { throw tooFewArgs(1); }
- public override object call(object a, object b) { throw tooFewArgs(2); }
- public override object call(object a, object b, object c) { throw tooFewArgs(3); }
- public override object call(object a, object b, object c, object d) { throw tooFewArgs(4); }
- public override object call(object a, object b, object c, object d, object e) { throw tooFewArgs(5); }
- public override object call(object a, object b, object c, object d, object e, object f) { throw tooFewArgs(6); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { throw tooFewArgs(7); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { throw tooFewArgs(8); }
- }
- //////////////////////////////////////////////////////////////////////////
- // Retype
- //////////////////////////////////////////////////////////////////////////
- public Func retype(Type t)
- {
- try
- {
- return new Wrapper((FuncType)t, this);
- }
- catch (System.InvalidCastException)
- {
- throw ArgErr.make("Not a Func type: " + t).val;
- }
- }
- internal class Wrapper : Indirect
- {
- internal Wrapper(FuncType t, Func orig) : base(t) { m_orig = orig; }
- public override bool isImmutable() { return m_orig.isImmutable(); }
- public override Method method() { return m_orig.method(); }
- public override object callOn(object target, List args) { return m_orig.callOn(target, args); }
- public override object callList(List args) { return m_orig.callList(args); }
- public override object call() { return m_orig.call(); }
- public override object call(object a) { return m_orig.call(a); }
- public override object call(object a, object b) { return m_orig.call(a, b); }
- public override object call(object a, object b, object c) { return m_orig.call(a, b, c); }
- public override object call(object a, object b, object c, object d) { return m_orig.call(a, b, c, d); }
- public override object call(object a, object b, object c, object d, object e) { return m_orig.call(a, b, c, d, e); }
- public override object call(object a, object b, object c, object d, object e, object f) { return m_orig.call(a, b, c, d, e, f); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return m_orig.call(a, b, c, d, e, f, g); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return m_orig.call(a, b, c, d, e, f, g, h); }
- Func m_orig;
- }
- //////////////////////////////////////////////////////////////////////////
- // Bind
- //////////////////////////////////////////////////////////////////////////
- public Func bind(List args)
- {
- if (args.sz() == 0) return this;
- if (args.sz() > @params().sz()) throw ArgErr.make("args.size > params.size").val;
- Type[] newParams = new Type[@params().sz()-args.sz()];
- for (int i=0; i<newParams.Length; ++i)
- newParams[i] = ((Param)@params().get(args.sz()+i)).m_type;
- FuncType newType = new FuncType(newParams, this.returns());
- return new BindFunc(newType, this, args);
- }
- internal class BindFunc : Indirect
- {
- internal BindFunc (FuncType type, Func orig, List bound)
- : base(type)
- {
- this.m_orig = orig;
- this.m_bound = bound.ro();
- }
- public override Method method() { return null; }
- public override bool isImmutable()
- {
- if (this.m_isImmutable == null)
- {
- bool isImmutable = false;
- if (m_orig.isImmutable())
- {
- isImmutable = true;
- for (int i=0; i<m_bound.sz(); ++i)
- {
- object obj = m_bound.get(i);
- if (obj != null && !FanObj.isImmutable(obj))
- { isImmutable = false; break; }
- }
- }
- this.m_isImmutable = Boolean.valueOf(isImmutable);
- }
- return this.m_isImmutable.booleanValue();
- }
- // this isn't a very optimized implementation
- public override object call() { return callList(new List(Sys.ObjType, new object[] {})); }
- public override object call(object a) { return callList(new List(Sys.ObjType, new object[] {a})); }
- public override object call(object a, object b) { return callList(new List(Sys.ObjType, new object[] {a,b})); }
- public override object call(object a, object b, object c) { return callList(new List(Sys.ObjType, new object[] {a,b,c})); }
- public override object call(object a, object b, object c, object d) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d})); }
- public override object call(object a, object b, object c, object d, object e) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d,e})); }
- public override object call(object a, object b, object c, object d, object e, object f) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d,e,f})); }
- public override object call(object a, object b, object c, object d, object e, object f, object g) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d,e,f,g})); }
- public override object call(object a, object b, object c, object d, object e, object f, object g, object h) { return callList(new List(Sys.ObjType, new object[] {a,b,c,d,e,f,g,h})); }
- public override object callList(List args)
- {
- int origReq = m_orig.@params().sz();
- int haveSize = m_bound.sz() + args.sz();
- Method m = m_orig.method();
- if (m != null)
- {
- origReq = m.minParams();
- if (haveSize > origReq) origReq = haveSize;
- }
- if (origReq <= m_bound.sz()) return m_orig.callList(m_bound);
- object[] temp = new object[haveSize];
- m_bound.copyInto(temp, 0, m_bound.sz());
- args.copyInto(temp, m_bound.sz(), temp.Length-m_bound.sz());
- return m_orig.callList(new List(Sys.ObjType, temp));
- }
- public override object callOn(object obj, List args)
- {
- int origSize = m_orig.@params().sz();
- object[] temp = new object[origSize];
- m_bound.copyInto(temp, 0, m_bound.sz());
- temp[m_bound.sz()] = obj;
- args.copyInto(temp, m_bound.sz()+1, temp.Length-m_bound.sz()-1);
- return m_orig.callList(new List(Sys.ObjType, temp));
- }
- private readonly Func m_orig;
- private readonly List m_bound;
- private Boolean m_isImmutable;
- }
- //////////////////////////////////////////////////////////////////////////
- // Fields
- //////////////////////////////////////////////////////////////////////////
- internal static readonly object[] noArgs = new object[0];
- internal static readonly FuncType type0 = new FuncType(new Type[] {}, Sys.ObjType);
- internal static readonly FuncType type1 = new FuncType(new Type[] { Sys.ObjType }, Sys.ObjType);
- internal static readonly FuncType type2 = new FuncType(new Type[] { Sys.ObjType, Sys.ObjType }, Sys.ObjType);
- internal static readonly FuncType type3 = new FuncType(new Type[] { Sys.ObjType, Sys.ObjType, Sys.ObjType }, Sys.ObjType);
- internal static readonly FuncType type4 = new FuncType(new Type[] { Sys.ObjType, Sys.ObjType, Sys.ObjType, Sys.ObjType }, Sys.ObjType);
- }
- }