$30 off During Our Annual Pro Sale. View Details »

インタプリタを作ってまなぶ Rust らしい書き方

インタプリタを作ってまなぶ Rust らしい書き方

Rust LT#2 発表用資料です.「Rust らしい」というと少しおこがましいですが,他の言語から Rust に入ってこられた方向けに少し考えてみました.

本日使用したコード例はこちら→https://github.com/yuk1ty/simple-interpreter-rs

Yuki Toyoda

August 01, 2018
Tweet

More Decks by Yuki Toyoda

Other Decks in Technology

Transcript

  1. 3VTU-5ʙ͍·࢖͏ʂ3VTUʙ
    ΠϯλϓϦλΛ࡞ͬͯ·ͳͿ
    3VTUΒ͍͠ॻ͖ํ
    !IFMMPZVL

    View Slide

  2. ࣗݾ঺հ
    ͱΑͩΏ͏͖
    αΠόʔΤʔδΣϯτ
    ΞυςΫελδΦॴଐ
    ීஈ͸ 4DBMBΤϯδχΞ
    3VTU޷͖
    ݴޠॲཧܥ޷͖
    ฒྻॲཧ޷͖
    !IFMMPZVL

    View Slide

  3. ࠓ೔࿩͢͜ͱ
    ΠϯλϓϦλͱ͸ʁ
    3VCZ͔Β 3VTU΁

    View Slide

  4. ΠϯλϓϦλΛ࡞ͬͨ͜ͱͷ͋Δํ
    !

    View Slide

  5. ιʔείʔυΛղऍͯ͠ந৅ߏจ໦Λ࡞Δ
    ໦Λղੳ࣮ͯ͠ߦ಺༰ΛධՁ͢Δ
    ΠϯλϓϦλͱ͸ʁ
    ۩ମతʹԿΛ͢Δ΋ͷʁ

    View Slide

  6. ଍͠ࢉͱֻ͚ࢉɼ਺஋ͷେখൺֱ
    ܭࢉͷ༏ઌॱҐ͸ߟ͑ͳ͍
    ม਺΋ѻ͑Δ
    ਓྗͰߏจ໦Λ౉͢ɼύʔαʔΛ࡞Βͳ͍
    ؆໿ΛԿճ͔ىͯ݁͜͠ՌΛಘΔ
    ΠϯλϓϦλͱ͸ʁ
    ࠓճͭ͘ΔΠϯλϓϦλ

    View Slide

  7. ந৅ߏจ໦ʁ
    !

    View Slide

  8. ΠϯλϓϦλͱ͸ʁ
    ந৅ߏจ໦ͬͯͲ͏͍͏΋ͷʁ
    ιʔείʔυΛղऍͯ͠τʔΫϯʹ௚͢
    ௚͞ΕͨτʔΫϯ͸໦ߏ଄ʹͳ͍ͬͯΔ

    View Slide

  9. ΠϯλϓϦλͱ͸ʁ
    ந৅ߏจ໦ͬͯͲ͏͍͏΋ͷʁ




    View Slide

  10. ΠϯλϓϦλͱ͸ʁ
    ͨͱ͑͹࣮૷͢Δͱ͜Μͳײ͡
    Add(
    Multiply(Number(1), Number(2)),
    Multiply(Number(3), Number(4)),
    );

    View Slide

  11. ΠϯλϓϦλͱ͸ʁ
    ࠓճͭ͘ΔτʔΫϯ
    ଍͠ࢉ"EE
    ֻ͚ࢉ.VMUJQMZ
    ΑΓখ͍͞-FTT5IBO
    ਺஋/VNCFS
    ม਺7BS
    ਅِ஋#PPM7BMVF

    View Slide

  12. ؆໿ʁ
    !

    View Slide

  13. ؔ਺Λద༻ͯ݁͠ՌΛ·ͱΊΔ͜ͱ
    ׬ྃ৚݅Λຬͨ͢·ͰԿ౓΋؆໿͢Δ
    ΠϯλϓϦλͱ͸ʁ
    ؆໿ͱ͸ʁ

    View Slide


  14. ؆໿

    ؆໿

    ؆໿

    ΠϯλϓϦλͱ͸ʁ
    ਺ࣜΛ؆໿ͯ͠ܭࢉ͢Δͱ

    View Slide

  15. ΠϯλϓϦλͱ͸ʁ
    ࠓճͷαϯϓϧϓϩάϥϜͩͱ
    // impl Token ͷதͰ͢
    pub fn reduce(&self, env: &HashMap) -> Token {
    use Token::*;
    match self {
    (…)
    &Add(ref blv, ref brv) if blv.is_reducible() => {
    Add(Box::new(blv.reduce(env)), brv.clone())
    }
    &Add(ref blv, ref brv) if brv.is_reducible() => {
    Add(blv.clone(), Box::new(brv.reduce(env)))
    }
    &Add(ref blv, ref brv) => match **blv {
    Number(left_value) => match **brv {
    Number(right_value) => Number(left_value +
    right_value),
    _ => panic!("Unexpected error in Add!"),
    },
    _ => panic!("Unexpected error in Add!"),
    },
    (…)

    View Slide

  16. 3VCZ͔Β 3VTU΁

    View Slide

  17. 3VCZ͔Β 3VTU΁
    3VCZͷίʔυΛ 3VTUʹ௚ͯ͠ΈΑ͏
    ΏΔ;ΘͰ͍͖·͢!

    View Slide

  18. 3VCZ͔Β 3VTU΁
    3VCZͷίʔυΛ 3VTUͰॻ͘ͱʜ
    DMBTTWTFOVN
    ࠶ؼॲཧͷѻ͍ํ
    ݁ՌΛҰ࣌อଘ͍ͨ͠ͱ͖

    View Slide

  19. 3VTUͷ FOVN ͸୅਺తσʔλܕʹͳͬͯ
    ͓ΓɼύλʔϯϚονͰ͖Δ
    3VCZ͔Β 3VTU΁
    DMBTTWTFOVN

    View Slide

  20. ͳͷͰɼ
    Ͳ͜Λ୅਺తσʔλܕͰ࣮૷Ͱ͖Δ͔Λ·ͣ
    ߟ͑ΔͱɼεοΩϦ࣮ͨ͠૷ʹͳΓ΍͍͢!
    3VCZ͔Β 3VTU΁
    DMBTTWTFOVN

    View Slide

  21. 3VCZ͔Β 3VTU΁
    3VCZͰ͸ DMBTTͰදݱ͢Δ͕ʜ
    class Number < Struct.new(:value)
    end
    class Var < Struct.new(:value)
    end
    class Add < Struct.new(:left, :right)
    end
    class Multiply < Struct.new(:left, :right)
    end
    class LessThan < Struct.new(:left, :right)
    end
    class BoolValue < Struct.new(:bool)
    end

    View Slide

  22. 3VCZ͔Β 3VTU΁
    3VTUͰ͸ FOVN ͰදݱͰ͖Δ
    #[derive(Clone)]
    pub enum Token {
    Number(i32),
    BoolValue(bool),
    Var(String),
    Add(Box, Box),
    Multiply(Box, Box),
    LessThan(Box, Box),
    }

    View Slide

  23. 3VCZ͔Β 3VTU΁
    3VCZ͸ؔ਺Λ DMBTTʹॻ͘
    class Number < Struct.new(:value)
    def reducible?
    false
    end
    end
    class Add < Struct.new(:left, :right)
    def reducible?
    true
    end
    end
    (…)

    View Slide

  24. 3VCZ͔Β 3VTU΁
    3VTU͸ύλʔϯϚον͕࢖͑Δ
    impl Token {
    pub fn is_reducible(&self) -> bool {
    use Token::*;
    match *self {
    Number(_) => false,
    BoolValue(_) => false,
    Var(_) => true,
    Add(_, _) => true,
    Multiply(_, _) => true,
    LessThan(_, _) => true,
    }
    }
    }

    View Slide

  25. #PY5
    3VCZ͔Β 3VTU΁
    ࠶ؼॲཧͷѻ͍ํ

    View Slide

  26. ώʔϓ্ͷσʔλʹର͢ΔϙΠϯλ
    #PYΛ࢖͏͜ͱͰώʔϓʹσʔλΛอଘ
    3VCZ͔Β 3VTU΁
    #PY5

    View Slide

  27. 3VTU͸ίϯύΠϧ࣌ʹܕͷαΠζΛܾΊΔ
    ͔͠͠࠶ؼߏ଄͸αΠζ͕ܾ·Βͳ͍
    #PYΛ࢖͏ͱαΠζΛܾఆͰ͖Δ
    3VCZ͔Β 3VTU΁
    ࠶ؼߏ଄ʹ#PY5͕ඞཁͳཧ༝

    View Slide

  28. 3VCZ͔Β 3VTU΁
    ଟ͘ͷݴޠͰ͸࠶ىߏ଄΋ී௨ʹѻ͑Δ
    class Number < Struct.new(:value)
    end
    class Var < Struct.new(:value)
    end
    class Add < Struct.new(:left, :right)
    end
    class Multiply < Struct.new(:left, :right)
    end
    class LessThan < Struct.new(:left, :right)
    end
    class BoolValue < Struct.new(:bool)
    end

    View Slide

  29. 3VCZ͔Β 3VTU΁
    ଟ͘ͷݴޠͰ͸࠶ىߏ଄΋ී௨ʹѻ͑Δ
    class Number < Struct.new(:value)
    end
    class Var < Struct.new(:value)
    end
    class Add < Struct.new(:left, :right)
    end
    class Multiply < Struct.new(:left, :right)
    end
    class LessThan < Struct.new(:left, :right)
    end
    class BoolValue < Struct.new(:bool)
    end
    ࣮ߦ͔ͯ͠Β
    ελοΫΦʔόʔϑϩʔͨ͠Γ͢Δ

    View Slide

  30. 3VCZ͔Β 3VTU΁
    3VTUͰ͸ #PY5Λ༻͍Δඞཁ͋Γ
    #[derive(Clone)]
    pub enum Token {
    Number(i32),
    BoolValue(bool),
    Var(String),
    Add(Box, Box),
    Multiply(Box, Box),
    LessThan(Box, Box),
    }

    View Slide

  31. NVU TFMG
    3VCZ͔Β 3VTU΁
    ݁ՌΛҰ࣌อଘ͍ͨ͠ͱ͖

    View Slide

  32. 3VCZ͔Β 3VTU΁
    ঢ়ଶͷอଘॲཧ͸Ͳ͏ͨ͠Βʜ
    class Machine < Struct.new(:expression)
    def step
    self.expression = expression.reduce
    end
    def run
    while expression.reducible?
    puts expression
    step
    end
    puts expression
    end
    end

    View Slide

  33. 3VCZ͔Β 3VTU΁
    NVU Λ࢖ͬͯ௚ͯ͠ΈΔ
    impl Machine {
    (…)
    pub fn run(&mut self) {
    let environment = HashMap::new();
    while self.expression.is_reducible() {
    println!("{}", &self.expression);
    self.step(&environment);
    }
    println!("{}", &self.expression);
    }
    fn step(&mut self, environment: &HashMap) {
    self.expression = self.expression.reduce(environment);
    }
    }

    View Slide

  34. ·ͱΊ
    ୅਺తσʔλܕΛ্खʹ࢖͓͏
    ࠶ؼॲཧ΍࠶ؼߏ଄ʹ͸एׯ஫ҙ͕ඞཁ
    https://github.com/yuk1ty/simple-interpreter-rs
    ˞3VCZͷίʔυ͸ޙ೔্͛·͢ʂ

    View Slide

  35. 3VTU-5ʙ͍·࢖͏ʂ3VTUʙ
    ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide