Merge pull request #195 from birkenfeld/impl_const_not
const eval: implement ! for integers
This commit is contained in:
commit
202e66708e
1 changed files with 41 additions and 10 deletions
|
@ -105,7 +105,7 @@ impl PartialEq for ConstantVariant {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&ConstantStr(ref ls, ref lsty), &ConstantStr(ref rs, ref rsty)) =>
|
(&ConstantStr(ref ls, ref lsty), &ConstantStr(ref rs, ref rsty)) =>
|
||||||
ls == rs && lsty == rsty,
|
ls == rs && lsty == rsty,
|
||||||
(&ConstantBinary(ref l),&ConstantBinary(ref r)) => l == r,
|
(&ConstantBinary(ref l), &ConstantBinary(ref r)) => l == r,
|
||||||
(&ConstantByte(l), &ConstantByte(r)) => l == r,
|
(&ConstantByte(l), &ConstantByte(r)) => l == r,
|
||||||
(&ConstantChar(l), &ConstantChar(r)) => l == r,
|
(&ConstantChar(l), &ConstantChar(r)) => l == r,
|
||||||
(&ConstantInt(lv, lty), &ConstantInt(rv, rty)) => lv == rv &&
|
(&ConstantInt(lv, lty), &ConstantInt(rv, rty)) => lv == rv &&
|
||||||
|
@ -184,13 +184,7 @@ pub fn constant(cx: &Context, e: &Expr) -> Option<Constant> {
|
||||||
Some(ConstantRepeat(Box::new(v), n.as_u64() as usize))),
|
Some(ConstantRepeat(Box::new(v), n.as_u64() as usize))),
|
||||||
&ExprUnary(op, ref operand) => constant(cx, operand).and_then(
|
&ExprUnary(op, ref operand) => constant(cx, operand).and_then(
|
||||||
|o| match op {
|
|o| match op {
|
||||||
UnNot =>
|
UnNot => constant_not(o),
|
||||||
if let ConstantBool(b) = o.constant {
|
|
||||||
Some(Constant{
|
|
||||||
needed_resolution: o.needed_resolution,
|
|
||||||
constant: ConstantBool(!b),
|
|
||||||
})
|
|
||||||
} else { None },
|
|
||||||
UnNeg => constant_negate(o),
|
UnNeg => constant_negate(o),
|
||||||
UnUniq | UnDeref => Some(o),
|
UnUniq | UnDeref => Some(o),
|
||||||
}),
|
}),
|
||||||
|
@ -227,7 +221,7 @@ fn constant_vec<E: Deref<Target=Expr> + Sized>(cx: &Context, vec: &[E]) -> Optio
|
||||||
for opt_part in vec {
|
for opt_part in vec {
|
||||||
match constant(cx, opt_part) {
|
match constant(cx, opt_part) {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
resolved |= (&p).needed_resolution;
|
resolved |= p.needed_resolution;
|
||||||
parts.push(p)
|
parts.push(p)
|
||||||
},
|
},
|
||||||
None => { return None; },
|
None => { return None; },
|
||||||
|
@ -245,7 +239,7 @@ fn constant_tup<E: Deref<Target=Expr> + Sized>(cx: &Context, tup: &[E]) -> Optio
|
||||||
for opt_part in tup {
|
for opt_part in tup {
|
||||||
match constant(cx, opt_part) {
|
match constant(cx, opt_part) {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
resolved |= (&p).needed_resolution;
|
resolved |= p.needed_resolution;
|
||||||
parts.push(p)
|
parts.push(p)
|
||||||
},
|
},
|
||||||
None => { return None; },
|
None => { return None; },
|
||||||
|
@ -289,6 +283,43 @@ fn constant_if(cx: &Context, cond: &Expr, then: &Block, otherwise:
|
||||||
} else { None }
|
} else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn constant_not(o: Constant) -> Option<Constant> {
|
||||||
|
Some(Constant {
|
||||||
|
needed_resolution: o.needed_resolution,
|
||||||
|
constant: match o.constant {
|
||||||
|
ConstantBool(b) => ConstantBool(!b),
|
||||||
|
ConstantInt(value, ty) => {
|
||||||
|
let (nvalue, nty) = match ty {
|
||||||
|
SignedIntLit(ity, Plus) => {
|
||||||
|
if value == ::std::u64::MAX { return None; }
|
||||||
|
(value + 1, SignedIntLit(ity, Minus))
|
||||||
|
},
|
||||||
|
SignedIntLit(ity, Minus) => {
|
||||||
|
if value == 0 {
|
||||||
|
(1, SignedIntLit(ity, Minus))
|
||||||
|
} else {
|
||||||
|
(value - 1, SignedIntLit(ity, Plus))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnsignedIntLit(ity) => {
|
||||||
|
let mask = match ity {
|
||||||
|
UintTy::TyU8 => ::std::u8::MAX as u64,
|
||||||
|
UintTy::TyU16 => ::std::u16::MAX as u64,
|
||||||
|
UintTy::TyU32 => ::std::u32::MAX as u64,
|
||||||
|
UintTy::TyU64 => ::std::u64::MAX,
|
||||||
|
UintTy::TyUs => { return None; } // refuse to guess
|
||||||
|
};
|
||||||
|
(!value & mask, UnsignedIntLit(ity))
|
||||||
|
}
|
||||||
|
UnsuffixedIntLit(_) => { return None; } // refuse to guess
|
||||||
|
};
|
||||||
|
ConstantInt(nvalue, nty)
|
||||||
|
},
|
||||||
|
_ => { return None; }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn constant_negate(o: Constant) -> Option<Constant> {
|
fn constant_negate(o: Constant) -> Option<Constant> {
|
||||||
Some(Constant{
|
Some(Constant{
|
||||||
needed_resolution: o.needed_resolution,
|
needed_resolution: o.needed_resolution,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue