Upgrade to Pro — share decks privately, control downloads, hide ads and more …

小さく始めて育てるコンパイラ

Linda_pp
August 05, 2017

 小さく始めて育てるコンパイラ

builderscon 2017 発表資料

Linda_pp

August 05, 2017
Tweet

More Decks by Linda_pp

Other Decks in Technology

Transcript

  1. GoCaml ͱ͸ • https://github.com/rhysd/gocaml • ϛχϚϧͳ OCaml ͷαϒηοτ • ࣮૷4000ߦఔ౓

    • ੩తܕ෇͚ɼܕਪ࿦ɼCݴޠ֦ு • MinCaml (※) ͷ࣮૷ϕʔε • ৄ͘͠͸ GoCon ͷࢿྉΛޚཡ͍ͩ͘͞ɿhttp://bit.ly/2wmG6Us ˞IUUQTHJUIVCDPNFTVNJJNJODBNM 
  2. GoCamlΛʰҭͯΔʱ • MinCaml Λ ࢀߟʹͯ͠ ࠷௿ݶͷػ ೳ࣮૷ • ΄͍͠ػೳΛ ֦ுɾ࣮૷͢

    Δʢଟ૬ܕɼ ந৅σʔλܕɼ ύλʔϯϚο νʣ • ΦϦδφϧ ͷߏจʹஔ ͖׵͑Δɹ ʢ·ͩʣ 
  3. let rec fizzbuzz max = let rec fb n =

    if n % 15 = 0 then println_str "fizzbuzz" else if n % 3 = 0 then println_str "fizz" else if n % 5 = 0 then println_str "buzz" else println_int n in let rec go n = if n = max then () else (fb n; go (n+1)) in go 1 in let max = 100 in fizzbuzz max ؔ਺ఆٛࣜ MFUSFDGYFJOF ωετͨؔ͠਺ఆٛ ϧʔϓ͸ແ͍ͷͰ࠶ ؼؔ਺Λ࢖͏ ৚݅෼ذͷJGࣜ JGFUIFOFFMTFF ؔ਺ݺͼग़͠ GFFʜ ม਺ఆٛ MFUYFJOF ͦͷଞɼ഑ྻɼλϓϧɼ PQUJPOܕͳͲʜ Ϋϩʔδϟ 
  4. ͳͥطଘݴޠͷαϒηοτͱ͠ ͯ·ͣ͸࣮૷͢Δͷ͔ • ߏจͷσβΠϯΛઌʹ΍Ζ͏ͱͯͭ͠·͔ͣͳ͍ • ߏจղੳ͸ίϯύΠϥͷೖΓޱͰ͔͠ͳ͍ͷʹɼͦ͜ʹ ؾΛऔΒΕ͕ͪ • ʮͲ͏͍͏ߏจ͕ྑ͍ͷ͔͸࣮ࡍʹॻ͍ͯಈ͔ͯ͠Έͳ͍ ͱͳ͔ͳ͔෼͔Βͳ͍

    㲗 ίϯύΠϥΛ࣮૷͠ͳ͍ͱಈ͔ ͤͳ͍ʯͱ͍͏δϨϯϚΛղফ͢Δ • ·ͣ͸ಈ͘ίϯύΠϥΛ࣮૷͔ͯ͠Βɼಈ͔͠ͳ͕Βޙ͔ Βࣗ෼ͷݴޠͷߏจΛσβΠϯ͍ͯ͘͠ํ਑ 
  5. GoCaml ͷίϯύΠϥ֓ཁ ιʔε ίʔυ τʔΫ ϯྻ ந৅ߏ จ໦ தؒද ݱ

    --7. *3 Ξηϯ ϒϦ T ΦϒδΣ Ϋτ P ࣮ߦϑΝ Πϧ ϥϯλ ΠϜ P ϥϯλ ΠϜ D ϦϯΧ ࣈ۟ղੳ ߏจղੳ Ћม׵ ܕਪ࿦ ,ਖ਼نԽ Ϋϩʔδϟม׵ (PͰࣗલ࣮૷ --7.͕όοΫΤϯυ $Ͱ࣮૷ MJCHD ৄ͘͠͸IUUQCJUMZXN(6T  ࠷దԽ
  6. ߏจ໦ Ћม׵ ܕਪ࿦ ʢܕνΣοΫʣ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ Ϋϩʔδϟ ม׵ ιʔείʔυΛߏจ໦ʹύʔε͢Δ ʢgoyaccʣ

    શͯͷγϯϘϧʹҰҙͷ ID ΛৼΔɽείʔ ϓΛղܾ ୯૬ܕͷγϯϓϧͳܕγεςϜɽHMܕਪ࿦ ΞϧΰϦζϜΛ࢖ͬͯਪ࿦ ໦ߏ଄͔ΒSSAʢ୯Ұ୅ೖʣܗࣜͷ໋ྩྻ΁ ม׵͢Δ ωετͨؔ͠਺ɾΫϩʔδϟͷղܾ 
  7. GoCaml ୈ1ஈ֊ͷ࣮૷ • ϕʔεͱͳΔ࠷௿ݶͷػೳΛ࣋ͬͨݴޠΛૣ࣮֬͘ʹͭ͘Δ • MinCaml ͸ڭҭ༻ݴޠͳͷͰ࣮૷͕γϯϓϧͰࢀߟʹ͠΍͍͢ɽόοΫ Τϯυ͸LLVMΛ࢖͏ • ΞϧϑΝม׵ɼܕਪ࿦ɼΫϩʔδϟม׵ɼதؒݴޠม׵ɼLLVM

    IRม׵ͳ Ͳͷ֤ஈ֊Ͱ͔ͬ͠ΓςετΛॻ͘ʢ4000ߦͷίʔυϕʔεʹରͯ͠477 ςετέʔεʣ • ಈ͘Α͏ʹͳͬͨΒ࣮ࡍʹॻ͍ͯΈͯυοάϑʔσΟϯά͢Δ ʢquicksort, brainfxxk, n-queens, xorshift128+, …) • ৄ͘͠͸ GoCon2017 ͷεϥΠυ: http://bit.ly/2wmG6Us 
  8. ଟ૬ͳܕγεςϜͱ͸ ͲΜͳܕʹஔ͖׵͑ͯ΋ྑ͍ϓϨʔεϗϧμ ͳܕΛѻ͑ΔܕγεςϜ (* ܕ͸ 'a -> 'a: 'a ʹ͸೚ҙͷܕ͕ೖΔ

    *) let rec id x = x in (* 'a ʹ int ΛೖΕΔ *) print_int (id 10); (* 'a ʹ bool ΛೖΕΔ *) print_bool (id false); (* ܕ͸ 'a option *) let o = None in (* 'a ʹ int ΛೖΕΔ *) match o with Some(i) -> print_int i | None -> (); (* 'a ʹ bool ΛೖΕΔ *) match o with Some(b) -> print_bool b | None -> (); ͭͷ஋͕ෳ਺ͷܕΛ࣋ͯΔΑ͏ʹͳΔ bBbB ˣ JOUJOU CPPMCPPM ʜ 
  9. ଟ૬తͳܕਪ࿦ΞϧΰϦζϜΛ ௐࠪ • Algorithm W • Ұ൪ΦʔιυοΫε • ܕू߹ͱଋറ͞Εͨܕม਺ͷஔ׵දΛ࢖ͬͯ୯ҰԽ͢Δ •

    Algorithm M • ໦ߏ଄ΛϘτϜΞοϓʹḷͬͯਪ࿦͢Δ Algorithm W Λτοϓμ΢ϯʹվྑ ͨ͠΋ͷɽޮ཰΍Τϥʔϝοηʔδ͕վળʢW ͷٯͳͷͰ Mʣ • Level-based Algorithm W • ܕม਺ʹϨϕϧʢfreshnessʣΛಋೖ͢Δ͜ͱͰ Algorhtim W ͷΞϧΰϦζϜ Λγϯϓϧʹ͠ɼޮ཰తʹ͢ΔɽOCaml Ͱ࠾༻͞Ε͍ͯΔ 
  10. Level-based Algorithm W let rec make_pair x = let rec

    f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () NBLF@QBJS͸Ҿ਺ΛYΛͱΓɼʮҾ ਺ZΛऔͬͯYͱZͷϖΞΛฦ͢ ؔ਺ʯΛฦ͢ YΛΩϟϓνϟͨ͠ΫϩʔδϟΛͭ ͘ΓɼͦΕΛฦ͢ NBLF@QBJSΛճผͷܕͷҾ਺Ͱݺͼ ग़ͯ͠ΈΔ 
  11. Level-based Algorithm W • ຌྫ • ɹ :ண໨͍ͯ͠ΔՕॴ • ?a(n):

    Ϩϕϧ n ͷܕม਺ɽ ·ͩܕ͕֬ఆ͍ͯ͠ͳ͍ ʢະଋറʣ • ‘a: ଋറࡁΈͷܕม਺ʢ೚ ҙͷܕ͕ೖΕΔʣ let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () 
  12. Level-based Algorithm W let rec make_pair x = let rec

    f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM $VSSFOU-FWFM ࠷ॳ͸Ϩϕϧ͔Βελʔτ 
  13. Level-based Algorithm W • make_pair: ?a(1) -> ?b(1) • x:

    ?a(1) let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM $VSSFOU-FWFM MFUࣜͰ৽͍͠ม਺͕ಋೖ͞ΕΔͱɼଋറ ͞ΕΔࣜͷதͰϨϕϧ্͕͕Δ ͜ͷ࣌఺Ͱ͸NBLF@QBJS͸Ҿ਺ͷؔ ਺ͱ͍͏͜ͱ͔͠෼͔Βͳ͍ 
  14. Level-based Algorithm W • make_pair: ?a(1) -> ?b(1) • x:

    ?a(1) • f: ?c(2) -> ?d(2) • y: ?c(2) let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM 
  15. Level-based Algorithm W • make_pair: ?a(1) -> ?b(1) • x:

    ?a(1) • f: ?c(2) -> ?a(1) * ?c(2) • y: ?c(2) let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM ࣜ Y Z ͔Β໭Γ஋͸YͱZͷλϓϧ ͩͱ෼͔Δˠ E   B    D   ʢ୯ҰԽʣ 
  16. Level-based Algorithm W • make_pair: ?a(1) -> ?b(1) • x:

    ?a(1) • f: ‘c -> ?a(1) * 'c • y: 'c let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM MFUࣜʹଋറ͞Ε͍ͯΔࣜͷܕਪ࿦͕ऴ Θͬͨ࣌ʹɼର৅ͷม਺ͷܕΛ൚Խ͢Δ G͸೚ҙͷܕ D ͷҾ਺ΛͭऔΓɼͦ ͷܕͷ஋ͱະ஌ͷܕͷ஋ͷϖΞʢ B   bDʣΛฦ͢ 
  17. Level-based Algorithm W • make_pair: ?a(1) -> ('c -> ?a(1)

    * 'c) • x: ?a(1) • f: 'c -> ?a(1) * 'c • y: 'c let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM ࣜG͔ΒNBLF@QBJSͷ໭Γ஋ͷܕ͸G ͱಉ͡ܕͩͱ෼͔Δ C  bD B   bD ʢ୯ҰԽʣ 
  18. Level-based Algorithm W • make_pair: 'a -> ('c -> 'a

    * 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM NBLF@QBJSͷܕΛ൚Խ͢ΔɽҰ൪֎ଆ ͷMFUSFDࣜͷϨϕϧ͸ͳͷͰશͯ ͷະ֬ఆͳܕม਺Λଟ૬ܕʹ֬ఆ͢Δ 
  19. ΠϯελϯεԽ ʢinstantiation) ଟ૬ܕͷม਺͸ෳ਺ͷܕΛऔΔ͜ͱ͕Ͱ͖Δɽଟ૬ܕͷม਺͕ ࢀর͞ΕΔͨͼʹ৽͍͠ܕม਺Λಋೖ͢Δ 2ߦ໨Ͱ͸ม਺ id ͷࢀরͷܕ͸ ?b -> ?bɼint

    ΛҾ਺ʹͨ͠ݺ ͼग़͠Ͱ int -> int ʹͳΔɽ 3ߦ໨Ͱ͸ม਺ id ͷࢀরͷܕ͸ ?c -> ?cɼbool ΛҾ਺ʹͨ͠ݺ ͼग़͠Ͱ bool -> bool ʹͳΔɽ let rec id x = x in (* 'a -> 'a *) id 10; (* int -> int *) id true; (* bool -> bool *) 
  20. Level-based Algorithm W • make_pair: 'a -> ('c -> 'a

    * 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c • pair: 'f -> int * ‘f let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM F   G   F    G  bB bDbB bD ΛΠϯελϯεԽ Ҿ਺͸JOUͳͷͰ F  JOU Ͱɼ໭Γ஋ܕ͔ΒQBJSͷܕ ͸ G  JOU  G  ɽ͜Ε Λ൚Խ 
  21. Level-based Algorithm W • make_pair: 'a -> ('c -> 'a

    * 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c • pair: 'f -> int * ‘f • p: int * bool let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM H  JOU  H  bGJOU bGΛΠϯελϯεԽ Ҿ਺͸CPPMͳͷͰ F   CPPMͰɼ໭Γ஋ܕ͔ΒQͷܕ ͸JOU CPPMɽࠓճ͸ະ֬ఆͷ ܕม਺͕ແ͍ͷͰ൚Խ͸ෆཁ 
  22. Level-based Algorithm W • make_pair: 'a -> ('c -> 'a

    * 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c • pair: 'f -> int * ‘f • p: int * bool • pair2: ‘i -> float * ‘i let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM I   J   I    J  ಉ༷ʹbB bDbB bD ΛΠϯελϯεԽ ͭ໨ͷNBLF@QBJSݺͼ ग़͔͠Β 
  23. Level-based Algorithm W • make_pair: 'a -> ('c -> 'a

    * 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c • pair: 'f -> int * ‘f • p: int * bool • pair2: ‘i -> float * ‘i • p: float * string let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM K  qPBU  K  bGJOU bGΛΠϯελϯεԽ QBJSݺͼग़͔͠Β 
  24. ଟ૬ܕܕਪ࿦ͷ࣮૷·ͱΊ • ࿦จͷࢀর࣮૷Λݟͳ͕Β࣮૷ʢଞʹ΋ occur check ͰϨ ϕϧΛௐઅ͢ΔͳͲͷॲཧ͕͋Δʣ • ଞͷܕਪ࿦ͷ࣮૷ͷςετσʔλΛྲྀ༻͢Δ •

    ޒेཛྷઌੜͷ՝୊ͷςετέʔεͳͲ(※1) • ͳ͔ͥ ML ͕ଟ͍ͷͰͦͷ··࢖͑Δ • ࠷ॳͷஈ֊Ͱ͔ͬ͠ΓςετΛॻ͍͓ͯ͘ͱ֦ு΋ָʹͳ Δ IUUQTXXXGPTLVJTLZPUPVBDKQdJHBSBTIJDMBTTJTMFXUFTUDBTFTIUNM 
  25. δΣωϦΫεͷίʔυੜ੒ͷ࣮ ૷Λௐࠪ • શͯͷ஋Λ1ϫʔυͰදݱ͢ΔʢOCaml, SML/NJ ͳͲʣ • int ΍ float

    ͸ͦͷ··ɼͦΕҎ֎ͷ஋͸ώʔϓͳͲʹͱͬͯϙΠϯλͰѻ͏ • ਖ਼֬ͳ GC ͷͨΊɼϙΠϯλ͔ͦ͏Ͱͳ͍͔൑அ͢ΔͷʹԼҐ̍ϏοτʹλάΛೖΕΔ ඞཁ͕͋Δ • ଟ૬ͳ஋͕औΔܕ͝ͱʹίʔυΛෳ੡͢Δʢmlton, Crystal, C++ (, Rust) ͳͲʣ • i.e. id: ‘a -> ‘a ͕ int -> int ͰΠϯελϯεԽ͞Ε͍ͯΔͳΒ id_int: int -> int Λੜ੒ • ࣮ߦ࣌ͷΦʔόʔϔου͸গͳ͍͕ίʔυαΠζ͕രൃ͠͏Δɽ෼ׂίϯύΠϧ͕೉͍͠ • ܕΫϥεΛఆٛ͠ɼܕΫϥε͝ͱͷ࣮૷Λؔ਺ͷࣙॻͰ౉͢ʢHaskell (,Rust) ͳͲʣ • ࣙॻ͔Βݺͼग़ؔ͢਺ΛҾ͍ͯ͘ΔΦʔόʔϔου͕͋Δ͕ɼ୹͍ؔ਺͸ΠϯϥΠϯԽʹ ΑΓίʔυෳ੡ͱಉ͡ޮՌ͕ظ଴Ͱ͖Δ 
  26. ίʔυෳ੡ʹΑΔδΣωϦΫ ε࣮૷ʢ୯૬Խʣ ΠϯελϯεԽ͝ͱʹ࢖ͬͨܕΛ໊લͷ຤ඌ ʹ͚ͭͯඃΒͳ͍Α͏ʹ͢Δ let rec id x = x

    in let f = id in id 10; id "foo"; f 3.0; f true; let rec id_int x = x in let rec id_string x = x in let rec id_float x = x in let rec id_bool x = x in let f_float = id_float in let f_bool = id_bool in id_int 10; id_string "foo"; f_float 3.0; f_bool true; 
  27. GoCaml ͷߏจΛஔ͖׵͑Δ • Ҏલ C++ Ͱ͍ͭͬͯͨ͘ݴޠ Dachs ͷߏจΛ revise ͯ͠࠷ऴతʹ͸ஔ͖׵͍͑ͨ

    • ࢼ࡞ɿhttps://github.com/rhysd/Dachs/blob/ master/next/compiler/syntax/grammar.go.y • Ruby inspired ͳߏจʢʴ JavaScript ͷ Object ͷΑ͏ͳϨ ίʔυܕͷߏจʣ