using Nemerle.Collections; using Nemerle.IO; def gen (g, k) { def l = List.Repeat (null, k); mutable cnt = 1; def tp = l.Map (fun (_) { def n = $ "'p$cnt"; ++cnt; n }); def tps = (tp + ["'r"]).ToString (", "); // def tupl = if (tp.IsEmpty) "object" else tp.ToString (" * "); def tupl_k = if (g) $ "Tuple $tp" else $ "Tuple"; def tupl = if (tp.IsEmpty || ! g) "System.Object" else tupl_k; cnt = -1; def parm_refs = tp.Map (fun (_) { ++cnt; if (g) $ "o.Field$cnt" else $ "o.Field$(cnt + 1)" }).ToString (", "); print ("[DebuggerNonUserCode]\n"); print ("public abstract class Function [$tps]"); when (k != 1) print ($ " : Function [$tupl, 'r]"); def parms = tp.Map (fun (tp) { $ "_ : $tp" }).ToString (", "); print ("\n{\n"); print ($ " public abstract apply ($parms) : 'r;\n"); when (k != 1) if (k == 0) print ($ " public override apply (_ : $tupl) : 'r { apply () }\n"); else print ($ " public override apply (o : $tupl) : 'r { apply ($parm_refs) }\n"); print ("}\n\n"); when (k > 1) { def typed_parms = tp.Map (s => s.Replace ("'p", "a") + " : " + s).ToString (", "); def plain_parms = tp.Map (_.Replace ("'p", "a")).ToString (", "); def type_parms = tp.ToString (", "); print ($ "[DebuggerNonUserCode]\n"); print ($ "public class FunctionFromTuple [$tps] : Function [$tps]\n"); print ($ "{\n"); print ($ " fn : Function [$tupl, 'r];\n"); print ($ " public this (f : Function [$tupl, 'r])\n"); print ($ " {\n fn = f;\n }\n"); print ($ " public override apply ($typed_parms) : 'r\n"); print ($ " {\n fn.apply (Tuple.[$type_parms] ($plain_parms))\n }\n"); print ($ "}\n\n"); print ($ "[DebuggerNonUserCode]\n"); print ($ "public class FunctionVoidFromTuple [$type_parms] : FunctionVoid [$type_parms]\n"); print ($ "{\n"); print ($ " fn : FunctionVoid [$tupl];\n"); print ($ " public this (f : FunctionVoid [$tupl])\n"); print ($ " {\n fn = f;\n }\n"); print ($ " public override apply_void ($typed_parms) : void\n"); print ($ " {\n fn.apply_void (Tuple.[$type_parms] ($plain_parms))\n }\n"); print ($ "}\n\n"); } def tps = tp.ToString (", "); def tpso = (tp + ["System.Object"]).ToString (", "); def tps' = if (tps == "") "" else $" [$tps]"; print ("[DebuggerNonUserCode]\n"); // FuncVoid1 is subtype of FuncNew and other are subtype of FuncVoid with lower parms if (k <= 1) print ("public abstract class FunctionVoid$(tps') : Function [$tpso]\n{\n"); else print ("public abstract class FunctionVoid$(tps') : FunctionVoid [$tupl]\n{\n"); print ($ " public abstract apply_void ($parms) : void;\n"); cnt = 0; def (parms, refs) = List.Split (tp.Map (fun (tp) { ++cnt; ($ "p$cnt : $tp", $ "p$cnt") })); def parms = parms.ToString (", "); def refs = refs.ToString (", "); if (k <= 1) print ($ " public override apply ($parms) : System.Object { apply_void ($refs); null }\n"); else print ($ " public override apply_void (o : $tupl) : void { apply_void ($parm_refs); }\n"); print ("}\n\n"); when (g && k > 1) { def (impl, cl) = if (k > 3) (",\n DisableImplicitConstructor]", "sealed class") else ("]", "struct"); def cnt_to_list (f) { cnt = 0; l.Map (fun (_) { def n = f (cnt); ++cnt; n }); } def tp = cnt_to_list (x => "'p" + x.ToString ()).ToString (", "); def dbgr_flds = cnt_to_list (x => "{Field" + x.ToString () + "}").ToString (", "); print(@" [System.Serializable, Record, StructuralEquality, TupleToString, DebuggerNonUserCode, DebuggerDisplay(""($dbgr_flds)""), StructuralHashCode$impl public $cl Tuple [$tp] { "); for (mutable i = 0; i < k; ++i) print (" public Field$i : 'p$i;\n"); print (" }\n\n"); } } for (mutable i = 0; i < 21; ++i) gen (true, i); print ("}\n");