public static Callable RecordConstructor(object cd) { RecordConstructorDescriptor ci = RequiresNotNull <RecordConstructorDescriptor>(cd); Type tt = ci.type.Finish(); // this is foo.make(params object[] args) calls constructor(s). Callable pp = ci.type.Constructor as Callable; RecordConstructorDescriptor rcd = ci; List <Callable> init = new List <Callable>(); while (rcd != null) { if (rcd.protocol != null) { init.Add(rcd.protocol); } rcd = rcd.parent; } if (init.Count == 0) { CallTargetN np = delegate(object[] args) { if (ci.type.TotalFieldCount != args.Length) { return(AssertionViolation(ci.type.Name, string.Format("Incorrect number of arguments, expected {0} got {1}", ci.type.TotalFieldCount, args.Length), args)); } return(pp.Call(args)); }; return(Closure.Create(np)); } else { CallTargetN rc = delegate(object[] args) { var instance = ci.type.DefaultConstructor.Call(); var protochain = MakeProtocolCallChain(ci, instance); protochain.Call(args); return(instance); }; return(Closure.Create(rc)); } }
public static object MakeRecordConstructorDescriptor(object rtd, object parent_constructor_descriptor, object protocol) { RecordTypeDescriptor t = RequiresNotNull<RecordTypeDescriptor>(rtd); RecordConstructorDescriptor rcd = new RecordConstructorDescriptor(); rcd.cg = t.cg; rcd.type = t; rcd.protocol = protocol as Callable; rcd.parent = parent_constructor_descriptor as RecordConstructorDescriptor; if (t.type.IsSubclassOf(typeof(Condition))) { SetSymbolValueFast(SymbolTable.StringToObject(t.Name + "-rcd"), rcd); } return rcd; }
static Callable MakeProtocolCallChain(RecordConstructorDescriptor rcd, object instance) { CallTargetN ipc = delegate(object[] iargs) { var nargs = new List <object>(iargs.Length + 1); nargs.Add(instance); nargs.AddRange(iargs); return(rcd.type.DefaultInit.Call(nargs.ToArray())); }; CallTargetN ppp = ipc; if (rcd.parent != null) { var parent = MakeProtocolCallChain(rcd.parent, instance); CallTargetN rr = delegate(object[] args) { parent.Call(args); return(Closure.Create(ipc)); }; ppp = rr; } CallTargetN pc = delegate(object[] args) { var ppc = Closure.Create(ppp); if (rcd.protocol != null) { ppc = ((Callable)rcd.protocol.Call(ppc)); } ppc.Call(args); return(instance); }; return(Closure.Create(pc)); }
public static Callable RecordConstructor(object cd) { RecordConstructorDescriptor ci = RequiresNotNull <RecordConstructorDescriptor>(cd); Type tt = ci.type.Finish(); // this is foo.make(params object[] args) calls constructor(s). Callable pp = ci.type.Constructor as Callable; RecordConstructorDescriptor rcd = ci; List <Callable> init = new List <Callable>(); while (rcd != null) { if (rcd.protocol != null) { init.Add(rcd.protocol); } rcd = rcd.parent; } if (init.Count == 0) { CallTargetN np = delegate(object[] args) { if (ci.type.TotalFieldCount != args.Length) { return(AssertionViolation(ci.type.Name, string.Format("Incorrect number of arguments, expected {0} got {1}", ci.type.TotalFieldCount, args.Length), args)); } return(pp.Call(args)); }; return(Closure.Create(np)); } else { init.Reverse(); CallTargetN np = delegate(object[] args) { Callable ppp = pp; List <object> allargs = new List <object>(); int i = init.Count; Callable collector = null; CallTargetN xxx = delegate(object[] margs) { allargs.AddRange(margs); if (i == 0) { if (ci.type.TotalFieldCount != allargs.Count) { return(AssertionViolation(ci.type.Name, string.Format("Incorrect number of arguments, expected {0} got {1}", ci.type.TotalFieldCount, allargs.Count), allargs.ToArray())); } return(pp.Call(allargs.ToArray())); } else { i--; return(collector); } }; ppp = collector = Closure.Create(xxx) as Callable; foreach (Callable ctr in init) { ppp = ctr.Call(ppp) as Callable; } object result = ppp.Call(args); if (result == collector) { result = collector.Call(); } return(result); }; return(Closure.Create(np)); } }