1
Fork 0

Implement unary operators for integers.

This commit is contained in:
Scott Olson 2015-11-12 17:24:43 -06:00
parent b099391aaf
commit 71f70e95ed
2 changed files with 37 additions and 19 deletions

View file

@ -8,7 +8,7 @@ use syntax::attr::AttrMetaMethods;
enum Value { enum Value {
Uninit, Uninit,
Bool(bool), Bool(bool),
Int(i64), Int(i64), // FIXME: Should be bit-width aware.
} }
struct Interpreter<'tcx> { struct Interpreter<'tcx> {
@ -58,32 +58,45 @@ impl<'tcx> Interpreter<'tcx> {
fn eval_rvalue(&mut self, rvalue: &mir::Rvalue) -> Value { fn eval_rvalue(&mut self, rvalue: &mir::Rvalue) -> Value {
use rustc_mir::repr::Rvalue::*; use rustc_mir::repr::Rvalue::*;
use rustc_mir::repr::BinOp::*; use rustc_mir::repr::BinOp::*;
use rustc_mir::repr::UnOp::*;
match *rvalue { match *rvalue {
Use(ref operand) => self.eval_operand(operand), Use(ref operand) => self.eval_operand(operand),
BinaryOp(bin_op, ref left, ref right) => { BinaryOp(bin_op, ref left, ref right) => {
match (self.eval_operand(left), self.eval_operand(right)) { match (self.eval_operand(left), self.eval_operand(right)) {
(Value::Int(l), Value::Int(r)) => match bin_op { (Value::Int(l), Value::Int(r)) => {
Add => Value::Int(l + r), match bin_op {
Sub => Value::Int(l - r), Add => Value::Int(l + r),
Mul => Value::Int(l * r), Sub => Value::Int(l - r),
Div => Value::Int(l / r), Mul => Value::Int(l * r),
Rem => Value::Int(l % r), Div => Value::Int(l / r),
BitXor => Value::Int(l ^ r), Rem => Value::Int(l % r),
BitAnd => Value::Int(l & r), BitXor => Value::Int(l ^ r),
BitOr => Value::Int(l | r), BitAnd => Value::Int(l & r),
Shl => Value::Int(l << r), BitOr => Value::Int(l | r),
Shr => Value::Int(l >> r), Shl => Value::Int(l << r),
Eq => Value::Bool(l == r), Shr => Value::Int(l >> r),
Lt => Value::Bool(l < r), Eq => Value::Bool(l == r),
Le => Value::Bool(l <= r), Lt => Value::Bool(l < r),
Ne => Value::Bool(l != r), Le => Value::Bool(l <= r),
Ge => Value::Bool(l >= r), Ne => Value::Bool(l != r),
Gt => Value::Bool(l > r), Ge => Value::Bool(l >= r),
}, Gt => Value::Bool(l > r),
}
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
UnaryOp(un_op, ref operand) => {
match (un_op, self.eval_operand(operand)) {
(Not, Value::Int(n)) => Value::Int(!n),
(Neg, Value::Int(n)) => Value::Int(-n),
_ => unimplemented!(),
}
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }

View file

@ -6,6 +6,11 @@ fn ret() -> i32 {
1 1
} }
#[miri_run(expected = "Int(-1)")]
fn neg() -> i32 {
-1
}
#[miri_run(expected = "Int(3)")] #[miri_run(expected = "Int(3)")]
fn add() -> i32 { fn add() -> i32 {
1 + 2 1 + 2