]> git.lizzy.rs Git - rust.git/commitdiff
refactor away the closures and `Event` enum
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Thu, 9 Jun 2016 08:52:45 +0000 (10:52 +0200)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Thu, 9 Jun 2016 08:56:23 +0000 (10:56 +0200)
src/interpreter/mod.rs
src/interpreter/stepper.rs

index 1942727e47694613f79269b889eb0c4efa6147e0..b581e860d78483f7357993b88b1cce2efaec5967 100644 (file)
@@ -395,17 +395,7 @@ fn maybe_report<T>(&self, r: EvalResult<T>) -> EvalResult<T> {
 
     fn run(&mut self) -> EvalResult<()> {
         let mut stepper = stepper::Stepper::new(self);
-        let mut done = false;
-        while !done {
-            use self::stepper::Event::*;
-            stepper.step(|event| match event {
-                Block(b) => trace!("// {:?}", b),
-                Assignment(a) => trace!("{:?}", a),
-                Terminator(t) => trace!("{:?}", t.kind),
-                Done => done = true,
-                _ => {},
-            })?;
-        }
+        while stepper.step()? {}
         Ok(())
     }
 
index 60eae047f1bf114ab7abb5b61d41273b194b82ce..50aaba1d73f133436966d74ebbbe25f0b8577f07 100644 (file)
 use std::rc::Rc;
 use memory::Pointer;
 
-pub enum Event<'a, 'tcx: 'a> {
-    Block(mir::BasicBlock),
-    Return,
-    Call,
-    Constant,
-    Assignment(&'a mir::Statement<'tcx>),
-    Terminator(&'a mir::Terminator<'tcx>),
-    Done,
-}
-
 pub struct Stepper<'fncx, 'a: 'fncx, 'b: 'a + 'mir, 'mir: 'fncx, 'tcx: 'b>{
     fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>,
 
@@ -41,8 +31,8 @@ pub(super) fn new(fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>) -> Self {
         }
     }
 
-    fn statement<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F, stmt: &mir::Statement<'tcx>) -> EvalResult<()> {
-        f(Event::Assignment(stmt));
+    fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<()> {
+        trace!("{:?}", stmt);
         let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind;
         let result = self.fncx.eval_assignment(lvalue, rvalue);
         self.fncx.maybe_report(result)?;
@@ -50,30 +40,28 @@ fn statement<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F, stmt: &mir:
         Ok(())
     }
 
-    fn terminator<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F, terminator: &mir::Terminator<'tcx>) -> EvalResult<()> {
+    fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> EvalResult<()> {
         // after a terminator we go to a new block
         self.fncx.frame_mut().stmt = 0;
         let term = {
-            f(Event::Terminator(terminator));
+            trace!("{:?}", terminator.kind);
             let result = self.fncx.eval_terminator(terminator);
             self.fncx.maybe_report(result)?
         };
         match term {
-            TerminatorTarget::Block => f(Event::Block(self.fncx.frame().next_block)),
             TerminatorTarget::Return => {
-                f(Event::Return);
                 self.fncx.pop_stack_frame();
             },
-            TerminatorTarget::Call => f(Event::Call),
+            TerminatorTarget::Block |
+            TerminatorTarget::Call => trace!("// {:?}", self.fncx.frame().next_block),
         }
         Ok(())
     }
 
     // returns true as long as there are more things to do
-    pub fn step<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
+    pub fn step(&mut self) -> EvalResult<bool> {
         if self.fncx.stack.is_empty() {
-            f(Event::Done);
-            return Ok(());
+            return Ok(false);
         }
 
         let block = self.fncx.frame().next_block;
@@ -92,10 +80,11 @@ pub fn step<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResul
                 mir: &mir,
             }.visit_statement(block, stmt);
             if self.constants.is_empty() {
-                return self.statement(f, stmt);
+                self.statement(stmt)?;
             } else {
-                return self.extract_constants(f);
+                self.extract_constants()?;
             }
+            return Ok(true);
         }
 
         let terminator = basic_block.terminator();
@@ -109,19 +98,22 @@ pub fn step<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResul
             mir: &mir,
         }.visit_terminator(block, terminator);
         if self.constants.is_empty() {
-            self.terminator(f, terminator)
+            self.terminator(terminator)?;
         } else {
-            self.extract_constants(f)
+            self.extract_constants()?;
         }
+        Ok(true)
     }
 
-    fn extract_constants<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
+    fn extract_constants(&mut self) -> EvalResult<()> {
         assert!(!self.constants.is_empty());
         for (cid, span, return_ptr, mir) in self.constants.drain(..) {
-            f(Event::Constant);
+            trace!("queuing a constant");
             self.fncx.push_stack_frame(cid.def_id, span, mir, cid.substs, Some(return_ptr));
         }
-        self.step(f)
+        // self.step() can't be "done", so it can't return false
+        assert!(self.step()?);
+        Ok(())
     }
 }