From c7244afea1bd6254f9417b47a2afaaeee15eee1a Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Thu, 19 Nov 2015 16:49:13 -0600 Subject: [PATCH] Implement SwitchInt (for some match expressions). --- src/interpreter.rs | 16 ++++++++++++---- test/basic.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index 596f539060fc..6f2f604d84ec 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -6,7 +6,7 @@ use syntax::attr::AttrMetaMethods; use std::iter; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] enum Value { Uninit, Bool(bool), @@ -120,11 +120,19 @@ impl<'a, 'tcx> Interpreter<'a, 'tcx> { } } - _ => unimplemented!(), + SwitchInt { ref discr, switch_ty: _, ref values, ref targets } => { + let discr_val = &self.value_stack[self.eval_lvalue(discr)]; + + let index = values.iter().position(|v| *discr_val == self.eval_constant(v)) + .expect("discriminant matched no values"); + + block = targets[index]; + } + // Diverge => unimplemented!(), // Panic { target } => unimplemented!(), // Switch { ref discr, adt_def, ref targets } => unimplemented!(), - // SwitchInt { ref discr, switch_ty, ref values, ref targets } => unimplemented!(), + _ => unimplemented!(), } } @@ -220,7 +228,7 @@ impl<'a, 'tcx> Interpreter<'a, 'tcx> { Uint(_u) => unimplemented!(), Str(ref _s) => unimplemented!(), ByteStr(ref _bs) => unimplemented!(), - Bool(_b) => unimplemented!(), + Bool(b) => Value::Bool(b), Struct(_node_id) => unimplemented!(), Tuple(_node_id) => unimplemented!(), Function(_def_id) => unimplemented!(), diff --git a/test/basic.rs b/test/basic.rs index 99a3fb39ad2c..bd60733b3d07 100644 --- a/test/basic.rs +++ b/test/basic.rs @@ -73,4 +73,38 @@ fn factorial_recursive() -> i32 { fact(10) } +#[miri_run(expected = "Int(1)")] +fn match_bool() -> i32 { + let b = true; + match b { + true => 1, + false => 0, + } +} + +#[miri_run(expected = "Int(20)")] +fn match_int() -> i32 { + let n = 2; + match n { + 0 => 0, + 1 => 10, + 2 => 20, + 3 => 30, + _ => 100, + } +} + +// #[miri_run(expected = "Int(4)")] +// fn match_int_range() -> i32 { +// let n = 42; +// match n { +// 0...9 => 0, +// 10...19 => 1, +// 20...29 => 2, +// 30...39 => 3, +// 40...49 => 4, +// _ => 5, +// } +// } + fn main() {}