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

インタプリタを作ってまなぶ 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.     ؆໿    ؆໿ 

     ؆໿  ΠϯλϓϦλͱ͸ʁ ਺ࣜΛ؆໿ͯ͠ܭࢉ͢Δͱ
  2. ΠϯλϓϦλͱ͸ʁ ࠓճͷαϯϓϧϓϩάϥϜͩͱ // impl Token ͷதͰ͢ pub fn reduce(&self, env:

    &HashMap<String, Token>) -> 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!"), }, (…)
  3. 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
  4. 3VCZ͔Β 3VTU΁ 3VTUͰ͸ FOVN ͰදݱͰ͖Δ #[derive(Clone)] pub enum Token {

    Number(i32), BoolValue(bool), Var(String), Add(Box<Token>, Box<Token>), Multiply(Box<Token>, Box<Token>), LessThan(Box<Token>, Box<Token>), }
  5. 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 (…)
  6. 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, } } }
  7. 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
  8. 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 ࣮ߦ͔ͯ͠Β ελοΫΦʔόʔϑϩʔͨ͠Γ͢Δ
  9. 3VCZ͔Β 3VTU΁ 3VTUͰ͸ #PY5Λ༻͍Δඞཁ͋Γ #[derive(Clone)] pub enum Token { Number(i32),

    BoolValue(bool), Var(String), Add(Box<Token>, Box<Token>), Multiply(Box<Token>, Box<Token>), LessThan(Box<Token>, Box<Token>), }
  10. 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
  11. 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<String, Token>) { self.expression = self.expression.reduce(environment); } }