public static CTObject Map(CTObject[] args) { AssertParameterCountAtLeast(MapFunctionName, 2, args); CTProcedure proc = args[0] as CTProcedure; if (proc == null) { throw new TypeError(MapFunctionName, CTProcedure.TypeName, args[0].DisplayType()); } for (int i = 1; i < args.Length; ++i) { if (args[i].GetType() != typeof(CTPair)) { throw new TypeError(MapFunctionName, CTPair.TypeName, args[i].DisplayType()); } } List <CTObject> results = new List <CTObject>(); CTObject[] applyArgs = new CTObject[args.Length - 1]; bool firstListEnded = false; while (!firstListEnded) { for (int i = 1; i < args.Length; ++i) { if (args[i].GetType() == typeof(CTEmptyList)) { firstListEnded = true; break; } else if (args[i].GetType() == typeof(CTPair)) { CTPair arg = (CTPair)args[i]; applyArgs[i - 1] = arg.car; args[i] = arg.cdr; } else { throw new TypeError(MapFunctionName, CTPair.TypeName, args[i].DisplayType()); } } if (!firstListEnded) { results.Add(Apply(proc, applyArgs)); } } return(List(results)); }
private static CTObject Apply(CTProcedure proc, CTObject[] args) { switch (args.Length) { case 0: return(proc.apply0()); case 1: return(proc.apply1(args[0])); case 2: return(proc.apply2(args[0], args[1])); case 3: return(proc.apply3(args[0], args[1], args[2])); case 4: return(proc.apply4(args[0], args[1], args[2], args[3])); case 5: return(proc.apply5(args[0], args[1], args[2], args[3], args[4])); default: return(proc.applyN(args)); } }