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

Go でつくる汎用言語処理系 実装戦略

Linda_pp
March 24, 2017

Go でつくる汎用言語処理系 実装戦略

General-purpose Programming Language implemented with Go and LLVM.
Presentation at Go Con Spring 2017

Linda_pp

March 24, 2017
Tweet

More Decks by Linda_pp

Other Decks in Technology

Transcript

  1. Go Ͱͭ͘Δ൚༻ݴޠॲཧܥ
    ࣮૷ઓུ
    General-purpose Programming Language
    implemented with Go
    @ Go Con 2017 Spring

    View Slide

  2. @Linda_pp
    @rhysd

    View Slide

  3. ΞδΣϯμ
    • ؔ਺ܕݴޠ GoCaml
    • GoCaml ͷ࣮૷ with Go&LLVM
    • Զݴޠͷ࣮૷ઓུ

    View Slide

  4. ؔ਺ܕݴޠ GoCaml

    View Slide

  5. GoCaml ͱ͸
    • ϛχϚϧͳ OCaml ͷαϒηοτ
    • ࣮૷4000ߦఔ౓
    • ੩తܕ෇͚ɼܕਪ࿦
    • MinCaml (※) ͷ࣮૷ϕʔε
    • https://github.com/rhysd/gocaml
    ˞IUUQTHJUIVCDPNFTVNJJNJODBNM
    let rec gcd m n =
    if m = 0 then n else
    if m <= n then gcd m (n - m) else
    gcd n (m - n) in
    print_int (gcd 21600 337500)

    View Slide

  6. GoCaml ͷจ๏ʢԋࢉʣ
    • ϓϩάϥϜ͸ʢunit ܕʹධՁ͞ΕΔʣ1ͭͷࣜ
    • γʔέϯεࣜɼ੔਺ԋࢉɼදࣔ
    (* GoCaml: e1; e2 *)
    1; 2; 3;
    -(1 + 2) * 10;
    3.14 *. 3.0 *. 3.0;
    print_bool true;
    ()
    /* Go */
    func main() {
    1; 2; 3
    -(1 + 2) * 10
    3.14 * 3.0 * 3.0
    fmt.Printf("%v", true)
    }

    View Slide

  7. GoCaml ͷจ๏ʢม਺ʣ
    • ม਺ఆٛ
    (* GoCaml: let e1 in e2 *)
    let r = 9.0 in
    let pi = 3.14 in
    let area = r *. r *. pi in
    print_float area;
    (* ࠶ఆٛʢshadowingʣ ΋ OK
    *)
    let r = 4 in
    let area = r * r in
    print_int area
    /* Go */
    func main() {
    r := 9.0
    pi := 3.14
    area := r * r * pi
    fmt.Print(area)
    {
    r := 4
    area := r * r
    fmt.Print(area)
    }
    }

    View Slide

  8. GoCaml ͷจ๏ʢؔ਺ʣ
    (* GoCaml *)
    (* ؔ਺ఆٛ & ద༻*)
    let rec squre x = x *. x in
    squre 3.0;
    (* Ϋϩʔδϟ *)
    let PI = 3.14 in
    let rec f d = PI *. d *. d in
    (* ؔ਺͸஋ͱͯ͠΋࢖͑Δ *)
    let rec compose f g =
    let rec h x = f (g x) in h
    in
    let f =
    compose squre squre
    in
    /* Go */
    func squre(x float64) float64 {
    return x * x
    }
    func main() {
    squre(3.0)
    PI := 3.14
    circle := func(d float64) float64 {
    return PI * d * d
    }
    type F func(f float64) float64
    compose := func(f F, g F) F {
    return func(x float64) float64 {
    return g(f(x))
    }
    }
    f := compose(squre, squre)
    }

    View Slide

  9. GoCaml ͷจ๏ʢtuple, arrayʣ
    (* GoCaml *)
    let arr = Array.make 4 42 in
    print_int arr.(3) in
    arr.(3) <- 99;
    print_int arr.(3)
    let tpl = 1, true, "aaa" in
    let (i, b, s) = tpl in
    print_int i;
    print_int b;
    print_int s;
    /* Go */
    func main() {
    arr := make([]int, 4)
    for i := range arr {
    arr[i] = 42
    }
    fmt.Print(arr[3])
    arr[3] = 99
    fmt.Print(arr[3])
    tpl := struct {
    i int
    b bool
    s string
    }{ 1, true, "aaa" }
    i, b, s := tpl.i, tpl.b, tpl.s
    fmt.Print(i)
    fmt.Print(b)
    fmt.Print(s)
    }

    View Slide

  10. GoCaml ͷͦͷଞͷݴޠػೳ
    • C extension
    • GC (Boehm GC)
    • gdb ͰσόοάͰ͖Δ
    • ϦϙδτϦͷ examples σΟϨΫτϦʹ΋͏গ͠ෳ
    ࡶͳྫ͕͋Γ·͢
    • brainfxxk, N-queens, Xorshift128+, …

    View Slide

  11. GoCaml ͷ࣮૷
    w/ Go & LLVM

    View Slide

  12. ίϯύΠϥ࣮૷ͷجຊํ਑
    ιʔείʔυจࣈྻ → ࣮ߦܗࣜόΠφϦ ΁
    ͷม׵
    ந৅౓ɿେ → খ
    Ұؾʹม׵͢Δͷ͸೉͍͠ͷͰɼঃʑʹந৅౓Λམͱͨ͠σʔλߏ଄Λఆٛ͠ɼ
    ঃʑʹந৅౓ΛԼ͍͛ͯ͘
    ιʔείʔυ → ߏจ໦ → ܕ෇͖தؒදݱ → LLVM IR → ΞηϯϒϦ → ػցޠ

    View Slide

  13. GoCaml ͷίϯύΠϥ࣮૷
    ιʔε
    ίʔυ
    τʔΫ
    ϯྻ
    ந৅ߏ
    จ໦
    தؒද
    ݱ
    --7.
    *3
    Ξηϯ
    ϒϦ T

    ΦϒδΣ
    Ϋτ P

    ࣮ߦϑΝ
    Πϧ
    ϥϯλ
    ΠϜ P

    ϥϯλ
    ΠϜ D


    View Slide

  14. GoCaml ͷίϯύΠϥ࣮૷
    ιʔε
    ίʔυ
    τʔΫ
    ϯྻ
    ந৅ߏ
    จ໦
    தؒද
    ݱ
    --7.
    *3
    Ξηϯ
    ϒϦ T

    ΦϒδΣ
    Ϋτ P

    ࣮ߦϑΝ
    Πϧ
    ϥϯλ
    ΠϜ P

    ϥϯλ
    ΠϜ D

    (PͰࣗલ࣮૷
    --7.
    $ίϯύΠϥ
    ϦϯΧ
    ࣈ۟ղੳ ߏจղੳ ͍Ζ͍Ζ

    View Slide

  15. LLVM (http://llvm.org/) ͱ͸
    • ίϯύΠϥͷόοΫΤϯυ෦෼ΛϞδϡʔϧԽͯ͠ఏ
    ڙ͢ΔϥΠϒϥϦ܈
    • GoCaml Ͱ͸ LLVM IR ͱݺ͹ΕΔ LLVM ಠࣗͷதؒݴ
    ޠ͔Β࠷దԽ&ωΠςΟϒίʔυΛੜ੒͢Δͷʹ࢖͏
    • ࣮૷͸ C++ Ͱ C ͔Β࢖͑Δ API ͱɼ֤ݴޠ͔Β࢖͑
    ΔόΠϯσΟϯάʢެࣜʹ͸ Python, OCaml, Goʣ͕
    ͋Δ

    View Slide

  16. ࣈ۟ղੳ
    • ྫ͑͹ “let a = 42 in a + b” Λ “let”, “a”, “=“, “42”, “in”, “a”, “+”, “b” ʹ෼
    ղ͢Δॲཧ
    • ݹయతʹɼจࣈྻΛ1จࣈͣͭݟ͍ͯͬͯରԠ͢ΔτʔΫϯΛੜ੒͢
    Δ
    • Lexer ͸ Goroutine Ͱ࣮ߦ͞ΕɼτʔΫϯ͸ channel Λ௨ͯ͡ύʔα
    ʹૹΒΕΔ
    • Go ͷ text/template ͷ࣮૷Λࢀߟʹ
    • https://github.com/golang/go/blob/master/src/text/template/parse/lex.go
    ιʔε
    ίʔυ
    τʔΫ
    ϯྻ
    ࣈ۟ղੳ

    View Slide

  17. ߏจղੳ
    • τʔΫϯྻ͔ΒϓϩάϥϜΛ໦ߏ଄Ͱද͢ந৅ߏจ໦ʹม׵͢Δ
    • Go ެࣜπʔϧͷ goyacc Λ࢖ͬͯ YACC ͰύʔαΛఆٛ͠ɼGo
    ͷίʔυΛੜ੒͢Δ
    • https://godoc.org/golang.org/x/tools/cmd/goyacc
    • YACC ͷจ๏ΛֶͿͷ͸ RHG ͷ͕͓͢͢Ί
    • http://i.loveruby.net/ja/rhg/book/yacc.html
    MFUBJOB
    MFUB
    JOU
    WBSB JOU
    τʔΫ
    ϯྻ
    ந৅ߏ
    จ໦
    ߏจղੳ

    View Slide

  18. ந৅ߏจٛͷఆٛ
    • ϊʔυͷΠϯλʔϑΣʔε Node ͱɼ֤ϊʔ
    υͷ۩ମతͳܕΛߏ଄ମͰఆٛ
    • go/ast ͱ΄΅ಉ͡ʢ https://golang.org/pkg/
    go/ast/ ʣ

    View Slide

  19. package main
    import (
    "github.com/rhysd/gocaml/ast"
    "github.com/rhysd/gocaml/lexer"
    "github.com/rhysd/gocaml/token"
    "github.com/rhysd/gocaml/parser"
    )
    func (c *Compiler) Parse(src *Source) (*ast.AST, error) {
    // ࣈ۟ղੳΛߦ͏ Lexer ͷΠϯελϯε
    l := lexer.NewLexer(src)
    // Τϥʔϋϯυϥ
    l.Error = func(msg string, pos token.Position) {
    panic("error")
    }
    // Goroutine Λ࢖࣮ͬͯߦɼl.Tokens channel ʹτʔΫϯ͕ૹΒΕͯ͘Δ
    go l.Lex()
    // ύʔα͸ channel ͝͠ʹτʔΫϯΛड͚औͬͯߏจ໦Λͭ͘Δ
    ast, err := parser.Parse(l.Tokens)
    if err != nil {
    return nil, err
    }
    return ast, nil
    }

    View Slide

  20. தؒදݱ΁ͷม׵
    • ͕͜͜ࠓճͷ࣮૷ͷதͰ͸Ұ൪ॏ͍
    • ߏจ໦͔Βதؒݴޠ΁ͷม׵͸Ϊϟοϓ͕େ
    ͖͍ͷͰঃʑʹந৅౓Λམͱ͍ͯ͘͠
    BEGIN: program
    a$t1 = int 42 ; type=int
    $k4 = int 10 ; type=int
    $k5 = binary + a$t1 $k4 ; type=int
    $k6 = appx print_int $k5 ; type=()
    END: program
    ந৅ߏ
    จ໦
    தؒද
    ݱ
    ͍Ζ͍Ζ
    MFUB
    JOU
    WBSB JOU

    View Slide

  21. தؒදݱ΁ͷม׵
    ߏจ໦ Ћม׵
    ܕਪ࿦
    ʢܕνΣοΫʣ
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    Ϋϩʔδϟ
    ม׵

    ந৅ߏ
    จ໦
    தؒද
    ݱ

    View Slide

  22. ߏจ໦ΛᢞΊΔʢvisitorʣ
    • ߏจ໦ͷ֤ϊʔυΛ८ΔͨΊʹ visitor ύλʔϯΛ࢖͏
    ʢਂ͞༏ઌʣ
    • visit ͷڍಈΛ੍ޚͰ͖ΔΑ͏ʹ͢Δʢvisit Λଧͪ੾Δ
    ͳͲʣ
    • ܕਪ࿦΍ߏจ໦ͷղੳɼҙຯνΣοΫɼதؒݴޠ΁ͷ
    ม׵͸͜ΕΛ༻͍Δ
    • go/ast ͷ ast.Visit ͱಉ͡

    View Slide

  23. ߏจ໦ΛᢞΊΔʢvisitorʣ
    // Visitor ͷΠϯλʔϑΣʔεɽ͜ΕΛ࣮૷ͨ͠ܕ͸ߏจ໦Λ traverse Ͱ͖Δ
    type Visitor interface {
    // ߏจ໦ͷϊʔυΛड͚औͬͯʮࢠͷ visit ʹ࢖͏ visitorʯΛ໭Γ஋Ͱฦ͢
    // nil ͳΒͦ͜Ͱ visit ऴྃ
    Visit(n Node) Visitor
    }
    // Visitor Λߏจ໦ʹద༻
    func Visit(v Visitor, n Node) {
    if v = v.Visit(n); v == nil {
    return
    }
    // ࢠʹ࠶ؼతʹద༻
    switch n := n.(type) {
    case *Add:
    // ଍͠ࢉϊʔυͷͱ͖
    Visit(v, n.Left)
    Visit(v, n.Right)
    case *If:
    // ...
    // શͯͷࢠ͕͋ΔϊʔυͷࢠΛ visit
    }
    }

    View Slide

  24. αม׵
    ֤γϯϘϧʢ֎෦γϯϘϧҎ֎ʣʹ ID Λৼͬ
    ͯม਺໊ΛҰҙʹ͢Δɽ͜ΕͰείʔϓΛج
    ຊతʹؾʹ͠ͳͯ͘ྑ͘ͳΔ
    ߏจ໦ Ћม׵
    // Go ٖࣅίʔυ
    func do_something () {
    x := 42
    y := "aaa"
    {
    x := true
    }
    }
    // Go ٖࣅίʔυ
    func do_something$1 () {
    x$2 := 42
    y$3 := "aaa"
    x$4 := true
    }

    View Slide

  25. ܕਪ࿦
    • γϯϓϧͳ Hindley-Mlner ܕਪ࿦ΞϧΰϦζϜ
    • ߏจ໦ͷ֤ϊʔυʹܕΛ͚͍ͭͯ͘
    • visit ͨ࣌͠఺Ͱܕ͕ෆ໌ͳͱ͜Ζ͸ܕม਺Λಋೖ͠ɼʮݱ࣌఺Ͱ͸ෆ໌ʯͱͯ͠
    ͓͘ɽ࠷ऴతʹͦͷม਺ͷ஋͕෼͔Ε͹ OKɽ
    • ܕม਺ʹ͍ͭͯͷ࿈ཱํఔࣜΛཱͯͯͦΕΛղ͘ײ͡ʢʮղ͘ʯॲཧΛ
    unification ͱ͍͏ʣ
    • ྫ͑͹഑ྻΞΫηε e1.(e2) Ͱ͋Ε͹ e1 ͷܕ͸഑ྻʢཁૉܕͷܕ͸ෆ໌ʣɼ
    e2 ͷܕ͸ intɼධՁ݁Ռ͸ e1 ͷཁૉܕʢ͜ͷ࣌఺Ͱ͸۩ମతʹͦΕ͕Կ͔͸
    ෼͔Βͳ͍ʣͱ͍ͬͨ͜ͱ͕෼͔ΔͷͰɼͦΕΛίʔυʹམͱ͍ͯ͘͠
    Ћม׵
    ܕਪ࿦
    ʢܕνΣοΫʣ

    View Slide

  26. // Go ٖࣅίʔυ
    func lessFirst(a, b) {
    x := a[0]
    y := b[0]
    return x < y
    }
    func main() {
    p := []int{1}
    lessFirst(p, p)
    }
    • lessFirst : ? -> ? -> ?

    View Slide

  27. • lessFirst : (? array) -> ? -> ?
    • x : ?
    // Go ٖࣅίʔυ
    func lessFirst(a, b) {
    x := a[0]
    y := b[0]
    return x < y
    }
    func main() {
    p := []int{1}
    lessFirst(p, p)
    }

    View Slide

  28. • lessFirst : (? array) -> (? array)
    -> ?
    • x : ?
    • y : ?
    // Go ٖࣅίʔυ
    func lessFirst(a, b) {
    x := a[0]
    y := b[0]
    return x < y
    }
    func main() {
    p := []int{1}
    lessFirst(p, p)
    }

    View Slide

  29. • lessFirst : (? array) -> (? array)
    -> bool
    • x : int ͔ bool ͔ float
    • y : int ͔ bool ͔ float
    // Go ٖࣅίʔυ
    func lessFirst(a, b) {
    x := a[0]
    y := b[0]
    return x < y
    }
    func main() {
    p := []int{1}
    lessFirst(p, p)
    }

    View Slide

  30. • lessFirst : (? array) -> (? array)
    -> bool
    • x : int ͔ bool ͔ float
    • y : int ͔ bool ͔ float
    • main : () -> ?
    • p : (int array)
    // Go ٖࣅίʔυ
    func lessFirst(a, b) {
    x := a[0]
    y := b[0]
    return x < y
    }
    func main() {
    p := []int{1}
    lessFirst(p, p)
    }

    View Slide

  31. • lessFirst : (int array) -> (int
    array) -> bool
    • x : int ͔ bool ͔ float
    • y : int ͔ bool ͔ float
    • main : () -> ()
    • p : (int array)
    // Go ٖࣅίʔυ
    func lessFirst(a, b) {
    x := a[0]
    y := b[0]
    return x < y
    }
    func main() {
    p := []int{1}
    lessFirst(p, p)
    }

    View Slide

  32. ܕਪ࿦ͷϝϦοτɾσϝϦοτ
    • ܕ͕߹Θͳ͍ or ܕม਺͕࢒ͬͯ͠·ͬͨ࣌͸ Τϥʔʹͳ
    Δ
    • ܕਪ࿦ʹΑΓɼܕΛҰ੾ॻ͔ͳͯ͘ྑ͍ʢෳࡶͳؔ਺ͷγ
    άωνϟͳͲʣ
    • ܕ͕߹Θͳ͍Τϥʔ͕ग़ͨͱ͖ʹਓؒʹͱͬͯΘ͔ΓͮΒ
    ͍
    • ࠶ؼతͳܕʢؔ਺ͷҾ਺ʹͦͷؔ਺ࣗ਎Λ༩͑ͨ࣌ͳͲʣ
    ͕ਪ࿦Ͱ͖ͳ͍ͷͰ޻෉͕ඞཁ

    View Slide

  33. தؒදݱͷఆٛ
    ܕਪ࿦
    ʢܕνΣοΫʣ
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    CJOU
    C
    JG # #
    C

    C
    BQIJ# #
    B
    [email protected]
    let b = 1 in
    let a =
    if b > 0 then
    b + 10 - 4
    else
    b - 10
    in
    print_int (a * 2)
    # #
    #
    #

    View Slide

  34. தؒදݱͷఆٛ
    ܕਪ࿦
    ʢܕνΣοΫʣ
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    CJOU
    C
    JG # #
    C

    C
    BQIJ# #
    B
    [email protected]
    • ໋ྩ
    • {register} = rhs
    • Ϩδελ΁ͷ୅ೖ͸Ұ౓
    ͖ΓʢSingle Static
    Assignmentʣ
    • ӈลʹ͸1ͭͷૢ࡞ͷΈ
    ͕هड़Ͱ͖Δʢਖ਼نܗʣ
    # #
    #
    #

    View Slide

  35. தؒදݱͷఆٛ
    ܕਪ࿦
    ʢܕνΣοΫʣ
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    CJOU
    C
    JG # #
    C

    C
    BQIJ# #
    B
    [email protected]
    • جຊϒϩοΫ
    • ໋ྩྻΛ૒ํ޲Ϧε
    τͱͯ࣋ͭ͠
    • ଞͷϒϩοΫͱ༗޲
    ඇ८ճάϥϑ (DAG)
    Ͱͭͳ͕Δ
    # #
    #
    #

    View Slide

  36. • Visitor Ͱߏจ໦ΛḷΓͳ͕Β໋ྩྻΛϊʔυ
    ͝ͱʹ࡞੒͍ͯ͘͠
    • if ࣜͰͷ෼ذ΍ؔ਺ͷຊମͳͲͰ৽͍͠ϒϩο
    ΫΛͭ͘Δ
    தؒදݱϑΥʔϚοτ
    ΁ม׵ ܕਪ࿦
    ʢܕνΣοΫʣ
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵

    View Slide

  37. Ϋϩʔδϟม׵
    • தؒදݱʹม׵ͨ͠௚ޙͰ͸·ͩؔ਺ఆٛࣜ
    ͕ωετ͍ͯ͠Δ͕ɼLLVM IR ΍ΞηϯϒϦ
    ͸ؔ਺Λ΋ͪΖΜωετͰ͖ͳ͍
    • ωετͨؔ͠਺ΛτοϓϨϕϧʹҠಈ͢Δॲ
    ཧ͕ඞཁ → Ϋϩʔδϟม׵
    • ࣮͸Ұ൪େม
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    Ϋϩʔδϟ
    ม׵

    View Slide

  38. Ϋϩʔδϟม׵
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    Ϋϩʔδϟ
    ม׵
    // Go ٖࣅίʔυ
    func main() {
    func square(x int) int {
    return x * x
    }
    square(10)
    }
    // ! square ΛτοϓϨϕϧʹҠಈ͢Δͷ͸؆୯
    func square(x int) int {
    return x * x
    }
    func main() {
    square(10)
    }

    View Slide

  39. Ϋϩʔδϟม׵
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    Ϋϩʔδϟ
    ม׵
    // Go ٖࣅίʔυ
    func main() {
    PI := 3.14
    func circle(x float64) float64 {
    return x * x * PI
    }
    circle(3.0)
    }
    // ! ΫϩʔδϟͩͱͲ͏ͳΔʁ
    // PI ΛͲ͏ʹ͔఻ୡ͢Δඞཁ͕͋Δ
    func circle(x float64) float64 {
    return x * x * PI
    }
    func main() {
    PI := 3.14
    circle(3.0)
    }

    View Slide

  40. Ϋϩʔδϟม׵
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    Ϋϩʔδϟ
    ม׵
    // Go ٖࣅίʔυ
    func main() {
    PI := 3.14
    func circle(x float64) float64 {
    return x * x * PI
    }
    circle(3.0)
    }
    // ! ؔ਺಺ʹΩϟϓνϟ͞ΕΔ஋ΛӅΕҾ਺ͱͯ͠౉͢ඞཁ͕͋Δ
    type Captures struct { PI float64 }
    func circle(cap Captures, x float64) float64 {
    PI := cap.PI
    return x * x * PI
    }
    func main() {
    PI := 3.14
    circle(Captures{PI}, 3.0)
    }

    View Slide

  41. • ໋ྩྻΛḷΓɼ࠶ؼతʹؔ਺ఆ͕ٛΩϟϓνϟʢ=ࣗ༝ม਺ʣΛ࣋ͭ
    ͔ௐ΂Δ
    • Ωϟϓνϟ͕͋Ε͹ͦͷؔ਺͸Ϋϩʔδϟͱͯ͠ݺͼग़͠ݩͰΩϟϓ
    νϟΦϒδΣΫτΛ࡞੒
    • ݺͼग़ͨؔ͠਺͕͢ͰʹΫϩʔδϟͰͳ͍ͱ෼͔͍ͬͯΔؔ਺͸Ωϟ
    ϓνϟΦϒδΣΫτΛ࡞੒͠ͳ͍Α͏ʹ͢ΔʢKnown Function
    Optimizationʣ
    • ۩ମతͳ࣮૷ͱͯ͠͸ɼ͋Δؔ਺͕͋ͬͨͱ͖ʹ·ͣ͸ͦͷؔ਺͕ Known Ͱ͋ΔͱԾఆͯ͠ body
    Λ࠶ؼతʹḷΓɼ΋͠Ωϟϓνϟ͕ݟ͔ͭΕ͹લఏ͕ؒҧ͍ͬͯͨͷͰঢ়ଶΛ໭ͯ͠࠶౓ḷΓ௚͢
    Ϋϩʔδϟม׵
    தؒදݱ΁ͷϑΥʔ
    Ϛοτม׵
    Ϋϩʔδϟ
    ม׵

    View Slide

  42. LLVM IR ͷੜ੒ தؒද
    ݱ
    --7.
    *3
    • LLVM ͷ Go binding ϥΠϒϥϦΛ࢖ͬͯதؒදݱ͔Β
    LLVM IR Λੜ੒͢ΔɽجຊϒϩοΫͷதͷ໋ྩྻΛḷΓɼର
    Ԡ͢Δ LLVM IR ͷ໋ྩΛ llvm.IRBuilder Λ࢖ͬͯੜ੒͍ͯ͠
    ͘
    • ͍ͭͰʹ LLVM IR ϨϕϧͰͷ࠷దԽ΋૸ΒͤΔɽΠϯϥΠ
    ϯԽ΍ෆཁίʔυͷআڈͳͲ͔ͳΓͷ࠷దԽΛͯ͘͠ΕΔ
    • ຊ౰͸࠷దԽͱίʔυੜ੒͕Ұ൪ॏ͍ͱ͜Ζ͕ͩɼ͋Δఔ
    ౓ LLVM ʹ೚ͤΒΕΔ

    View Slide

  43. LLVM IR ͷֶश
    • LLVM C ͷ Go binding ʹ͍ͭͯ஌Δʹ͸
    • LLVM ΛόοΫΤϯυͱͨ͠ Go ίϯύΠϥ LLGO ͕ࢀߟʹͳΔɽgo/* Λ࢖ͬ
    ͯதؒදݱΛߏங͠ɼGo binding ͰόΠφϦʹམͱ͍ͯ͠ΔɽJIT Λ࢖ͬͨ
    REPL ΋͋Δ
    • https://godoc.org/llvm.org/llvm/bindings/go/llvmʢLLVM ຊՈͷ Doxygen
    ʹൺ΂ͯʣ͔ͳΓಡΈ΍͍͢ɽ͕ɼࡌͬͯͳ͍΋ͷ΋͋ΔͷͰ஫ҙ
    • LLVM IR ʹ͍ͭͯ஌Δʹ͸
    • Clang ͷు͘ IR ΛோΊΔ: `clang -S -emit-llvm`
    • ϦϑΝϨϯεϚχϡΞϧΛಡΉ http://llvm.org/docs/LangRef.html

    View Slide

  44. Go Ͱॻ͍ͯΈͨײ૝

    ࢥͬͨ΄Ͳॻ͖ʹ͘͘ͳ͍ɽଟগίϐϖతίʔυͰ΋ Go ͔ͩΒ…ͱ
    ཧੑΛࣺͯͯॻ͚Δʢ࣮૷ߦͰݟͯ΋ OCaml ͷ2ഒఔ౓ʣ
    • ֤ϑΣʔζͰ͔ͬ͠ΓςετΛॻ͍͍ͯ͘ͷ͕ॏཁͳͷͰɼGo ͷς
    ετจԽ͸ྑ͍
    • ஈ֊తʹม׵͍֤ͯ͘͠ϑΣʔζΛผύοέʔδʹ͢Δ͜ͱͰ͏͔ͬ
    Γ૬ޓࢀরͯ͠͠·͏ͷΛ๷͛Δ

    ύʔαδΣωϨʔλ΍ LLVM ͷαϙʔτ͕ެࣜͰఏڙ͞Ε͍͍ͯͯΔ
    • Ӭଓతσʔλߏ଄͕ແ͍ͷͰɼ࠶ؼతʹ visit ͯ͠ undo ͢ΔΈ͍ͨͳ
    ॲཧ͕ॻ͖ʹ͍͘

    View Slide

  45. Զݴޠͷ࣮૷ઓུ

    View Slide

  46. GoCaml ࣮૷ͷܦҢ
    Ҏલ C++ ͰίϯύΠϥΛॻ͍͍͕ͯͨ಴࠳ͯ͠͠·ͬͨ
    https://github.com/rhysd/Dachs
    ݪҼ͸
    1. ߏจ໦͔ΒҰؾʹ IR ʹམͱͦ͏ͱͯ͠ม׵ॲཧ͕ෳࡶʹͳ
    Γ͗ͨ͢
    2. ߏจ౶ҥͳͲɼ࠷ॳ͔ΒػೳΛ੝Γ͗ͨ͢
    3. Ϗϧυ͕஗͍ʢ4෼Ҏ্ʣ

    View Slide

  47. ԶݴޠʢDachsʣΛ෮׆ͤ͞Δ
    1. தؒݴޠΛಋೖͨ͠ίϯύΠϥΛॻ͍ͯΈΔʢGoCamlʣ
    2. GoCam ͷίʔυϕʔεΛͳΔ΂͘ྲྀ༻͠ͳ͕ΒϛχϚϧͳݴޠͱ
    ͯ͠ Dachs Λͭ͘ΔʢجຊܕɼϙΠϯλͷ௿ڃͳૢ࡞΍ߏ଄ମఆ
    ٛɼC ֦ுͳͲʣ
    3. ഑ྻ΍ϋογϡͳͲͷجຊతͳσʔλߏ଄͸ Dachs ͷϥΠϒϥϦ
    ͱͯ͠ॻ͘
    4. ηϧϑϗετ͢Δ
    5. ΑΓෳࡶͳݴޠػೳΛ࣮૷͍ͯ͘͠

    View Slide

  48. ͋ΔݴޠͰͦͷݴޠͷॲཧܥΛ࣮૷
    ͢Δʢηϧϑϗετʣͷར఺ͱܽ఺

    υοάϑʔσΟϯά
    • ૣظ͔Βࣗ෼͕࢖͍͍ͨݴޠΛࣗ෼Ͱͭͬͯࣗ͘෼Ͱ࢖͑Δ
    • શͯࣗલͰ࣮૷͠ͳ͚Ε͹ͳΒͳ͍ʢςετϑϨʔϜϫʔΫɼσ
    όοΨͳͲʣ

    όά͕ग़ͨ࣌ͷσόοά͕೉͘͠ͳΔ͔΋ʢͦͷίʔυʹ͋Δͷ
    ͔ɼͦͷίʔυΛίϯύΠϧͨ͠ίϯύΠϥͷίʔυʹ͋Δͷ͔ɼͦ
    ͷίʔυΛίϯύΠϧͨ͠ίϯύΠϥͷίʔυΛίϯύΠϧͨ͠ίʔ
    υʹ͋Δͷ͔…ʣ
    • جຊతʹ͸ 1ͭ໨ͱ2ͭ໨ͷར఺͕࠷ߴͳͷͰηϧϑϗετ͍ͨ͠

    View Slide

  49. Go Ͱηϧϑϗετ͢ΔίϯύΠ
    ϥΛॻ͘ར఺
    • ηϧϑϗετ͢Δࡍ͸طଘͷ࣮૷ΛϗετݴޠΛࣗ
    ෼ࣗ਎Ͱஔ͖׵͍͑ͯ͘
    • ڧྗͳݴޠػೳ/ϥΠϒϥϦ͕࢖͑ΔϗετݴޠͰ
    ࠷ॳʹ࣮૷͢Δͱɼஔ͖׵͑Δͷ͕೉͘͠ͳΔ͸ͣ
    • Go ͸ඇৗʹ؆ૉͳݴޠ࢓༷Λ͍࣋ͬͯΔͷͰɼη
    ϧϑϗετ͢Δࡍʹݴޠͷஔ͖׵ָ͕͑ʹͳΓͦ͏

    View Slide

  50. ·ͱΊ
    • ίϯύΠϥ͸ஈ֊తͳσʔλͷม׵Ͱ͋Δ
    • Go ͱ LLVM ͰίϯύΠϥΛॻ͍ͯΈͨݶΓͰ
    ͸ॻ͖΍͘͢ɼґଘ΋গͳ͘Ͱ͖ͦ͏
    • ૣظʹηϧϑϗετ͢Δʹ͸ɼίϯύΠϥͷ
    ॳظ࣮૷͸ Go Ͱॻ͍͓ͯ͘ͱྑͦ͞͏ʢ͜
    Ε͔Βʣ

    View Slide

  51. ʢऄ଍ʣൃදऀ঺հ
    • C++, Ruby, TypeScript, Vim script
    • C++ ͰίϯύΠϥΛॻ͍͍ͯͨΓɼCrystal ͷॲཧܥΛ͍ͬͯ͡ΈͨΓ
    • Electron + TypeScript + React ͰσεΫτοϓΞϓϦΛॻ͍ͨΓ
    • Vim ϓϥάΠϯΛ60ݸ͙Β͍ॻ͍ͯͨΓ
    • ࠷ۙ͸ Go ͰίϯύΠϥΛॻ͍ͨΓͯ͠·͢
    • ιϑτ΢ΣΞΛͭ͘Δͷָ͕͍͠
    @Linda_pp
    @rhysd

    View Slide