Implement unary operators for integers.
This commit is contained in:
parent
b099391aaf
commit
71f70e95ed
2 changed files with 37 additions and 19 deletions
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue