カリー化 続々
クロージャを実装できた
関数外の変数に手を出している関数をマークして
関数外の変数を一個のframeにまとめる
var a = 1 var b = 2 sub f(c: Int) print(a + b + c) f(3)
↑これを↓こう変換する
var a = 1 var b = 2 sub f_(frame, c: Int) print(frame.a + frame.b + c) var frame # この辺が変換部分 frame.a = a frame.b = b f = f_.bind(frame) f(3)
CILに変換するときは前回の部分適用でなんとかする
今のつくりはクロージャがネストすると1関数1frameで作っているので、どんどん引数が増える
まぁいっか
ILは笑っちゃうほど長い
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.81.0 // Copyright (c) Microsoft Corporation. All rights reserved. // Metadata version: v4.0.30319 .assembly extern mscorlib { .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } .assembly Global { .hash algorithm 0x00008004 .ver 0:0:0:0 } .module Global // MVID: {3B864071-7E41-437A-9EDF-B63D9808492F} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY // Image base: 0x00CA0000 // ================== GLOBAL METHODS ========================= .method public static class [mscorlib]System.Action`1<int32> f1(int32 A_0) cil managed { // コード サイズ 38 (0x26) .maxstack 2 .locals init (class '##f1' V_0, class [mscorlib]System.Action`1<int32> V_1) IL_0000: newobj instance void '##f1'::.ctor() IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldarg.0 IL_0008: stfld int32 '##f1'::w IL_000d: ldloc.0 IL_000e: ldc.i4.5 IL_000f: stfld int32 '##f1'::z IL_0014: ldloc.0 IL_0015: ldc.i4 0x14 IL_001a: nop IL_001b: nop IL_001c: nop IL_001d: nop IL_001e: call class [mscorlib]System.Action`1<int32> f2(class '##f1', int32) IL_0023: stloc.1 IL_0024: ldloc.1 IL_0025: ret } // end of global method f1 .method public static class [mscorlib]System.Action`1<int32> f2(class '##f1' A_0, int32 A_1) cil managed { // コード サイズ 70 (0x46) .maxstack 3 .locals init (class '##f2' V_0, class [mscorlib]System.Action`1<int32> V_1) IL_0000: newobj instance void '##f2'::.ctor() IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldarg.1 IL_0008: stfld int32 '##f2'::x IL_000d: ldloc.0 IL_000e: ldloc.0 IL_000f: ldfld int32 '##f2'::x IL_0014: stfld int32 '##f2'::y IL_0019: newobj instance void Bind_f3::.ctor() IL_001e: stloc.1 IL_001f: ldloc.1 IL_0020: ldftn void f3(class '##f1', class '##f2', int32) IL_0026: stfld native int Bind_f3::f IL_002b: ldloc.1 IL_002c: ldarg.0 IL_002d: stfld class '##f1' Bind_f3::'##f1' IL_0032: ldloc.1 IL_0033: ldloc.0 IL_0034: stfld class '##f2' Bind_f3::'##f2' IL_0039: ldloc.1 IL_003a: ldftn instance void Bind_f3::Invoke(int32) IL_0040: newobj instance void class [mscorlib]System.Action`1<int32>::.ctor(object, native int) IL_0045: ret } // end of global method f2 .method public static void f3(class '##f1' A_0, class '##f2' A_1, int32 A_2) cil managed { // コード サイズ 65 (0x41) .maxstack 2 .locals init (int32 V_0, int32 V_1, int32 V_2, int32 V_3, int32 V_4) IL_0000: ldc.i4 0xa IL_0005: nop IL_0006: nop IL_0007: nop IL_0008: nop IL_0009: ldarg.1 IL_000a: ldfld int32 '##f2'::x IL_000f: add IL_0010: stloc.0 IL_0011: ldloc.0 IL_0012: ldarg.1 IL_0013: ldfld int32 '##f2'::y IL_0018: add IL_0019: stloc.1 IL_001a: ldloc.1 IL_001b: ldarg.0 IL_001c: ldfld int32 '##f1'::z IL_0021: add IL_0022: stloc.2 IL_0023: ldloc.2 IL_0024: ldarg.0 IL_0025: ldfld int32 '##f1'::w IL_002a: add IL_002b: stloc.3 IL_002c: ldloc.3 IL_002d: ldarg.2 IL_002e: add IL_002f: stloc V_4 IL_0033: nop IL_0034: nop IL_0035: ldloc V_4 IL_0039: nop IL_003a: nop IL_003b: call void [mscorlib]System.Console::WriteLine(int32) IL_0040: ret } // end of global method f3 .method public static void '###.ctor'() cil managed { // コード サイズ 15 (0xf) .maxstack 2 .locals init (class [mscorlib]System.Action`1<int32> V_0) IL_0000: ldc.i4.1 IL_0001: call class [mscorlib]System.Action`1<int32> f1(int32) IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: ldc.i4.2 IL_0009: callvirt instance void class [mscorlib]System.Action`1<int32>::Invoke(!0) IL_000e: ret } // end of global method '###.ctor' .method family static void __EntryPoint() cil managed { .entrypoint // コード サイズ 6 (0x6) .maxstack 0 IL_0000: call void '###.ctor'() IL_0005: ret } // end of global method __EntryPoint // ============================================================= // =============== CLASS MEMBERS DECLARATION =================== .class private auto ansi '##f1' extends [mscorlib]System.Object { .field public int32 w .field public int32 z .method public specialname rtspecialname instance void .ctor() cil managed { // コード サイズ 1 (0x1) .maxstack 0 IL_0000: ret } // end of method '##f1'::.ctor } // end of class '##f1' .class private auto ansi '##f2' extends [mscorlib]System.Object { .field public int32 x .field public int32 y .method public specialname rtspecialname instance void .ctor() cil managed { // コード サイズ 1 (0x1) .maxstack 0 IL_0000: ret } // end of method '##f2'::.ctor } // end of class '##f2' .class private auto ansi Bind_f3 extends [mscorlib]System.Object { .field public native int f .field public class '##f1' '##f1' .field public class '##f2' '##f2' .method public specialname rtspecialname instance void .ctor() cil managed { // コード サイズ 7 (0x7) .maxstack 2 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method Bind_f3::.ctor .method public instance void Invoke(int32 A_1) cil managed { // コード サイズ 30 (0x1e) .maxstack 4 IL_0000: ldarg.0 IL_0001: ldfld class '##f1' Bind_f3::'##f1' IL_0006: ldarg.0 IL_0007: ldfld class '##f2' Bind_f3::'##f2' IL_000c: ldarg A_1 IL_0010: nop IL_0011: nop IL_0012: ldarg.0 IL_0013: ldfld native int Bind_f3::f IL_0018: calli void(class '##f1',class '##f2',int32) IL_001d: ret } // end of method Bind_f3::Invoke } // end of class Bind_f3 // ============================================================= // *********** 逆アセンブルが完了しました ***********************
ところで得正のカレーうどんはうまかった