implement char handling
This commit is contained in:
parent
579628f56d
commit
2dbd30fa51
@ -28,6 +28,7 @@ pub enum EvalError<'tcx> {
|
||||
ExecuteMemory,
|
||||
ArrayIndexOutOfBounds(Span, u64, u64),
|
||||
Math(Span, ConstMathErr),
|
||||
InvalidChar(u32),
|
||||
}
|
||||
|
||||
pub type EvalResult<'tcx, T> = Result<T, EvalError<'tcx>>;
|
||||
@ -66,6 +67,8 @@ impl<'tcx> Error for EvalError<'tcx> {
|
||||
"array index out of bounds",
|
||||
EvalError::Math(..) =>
|
||||
"mathematical operation failed",
|
||||
EvalError::InvalidChar(..) =>
|
||||
"tried to interpret an invalid 32-bit value as a char",
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,6 +88,8 @@ impl<'tcx> fmt::Display for EvalError<'tcx> {
|
||||
write!(f, "array index {} out of bounds {} at {:?}", index, len, span),
|
||||
EvalError::Math(span, ref err) =>
|
||||
write!(f, "mathematical operation at {:?} failed with {:?}", span, err),
|
||||
EvalError::InvalidChar(c) =>
|
||||
write!(f, "invalid utf8 character: {}", c),
|
||||
_ => write!(f, "{}", self.description()),
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
self.memory.write_bool(ptr, b)?;
|
||||
Ok(ptr)
|
||||
}
|
||||
Char(_c) => unimplemented!(),
|
||||
Char(c) => {
|
||||
let ptr = self.memory.allocate(4);
|
||||
self.memory.write_uint(ptr, c as u32 as u64, 4)?;
|
||||
Ok(ptr)
|
||||
},
|
||||
Struct(_node_id) => unimplemented!(),
|
||||
Tuple(_node_id) => unimplemented!(),
|
||||
Function(_def_id) => unimplemented!(),
|
||||
@ -1371,6 +1375,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
use syntax::ast::{IntTy, UintTy};
|
||||
let val = match (self.memory.pointer_size, &ty.sty) {
|
||||
(_, &ty::TyBool) => PrimVal::Bool(self.memory.read_bool(ptr)?),
|
||||
(_, &ty::TyChar) => {
|
||||
let c = self.memory.read_uint(ptr, 4)? as u32;
|
||||
match ::std::char::from_u32(c) {
|
||||
Some(ch) => PrimVal::Char(ch),
|
||||
None => return Err(EvalError::InvalidChar(c)),
|
||||
}
|
||||
}
|
||||
(_, &ty::TyInt(IntTy::I8)) => PrimVal::I8(self.memory.read_int(ptr, 1)? as i8),
|
||||
(2, &ty::TyInt(IntTy::Is)) |
|
||||
(_, &ty::TyInt(IntTy::I16)) => PrimVal::I16(self.memory.read_int(ptr, 2)? as i16),
|
||||
|
@ -369,6 +369,7 @@ impl<'tcx> Memory<'tcx> {
|
||||
PrimVal::U16(n) => self.write_uint(ptr, n as u64, 2),
|
||||
PrimVal::U32(n) => self.write_uint(ptr, n as u64, 4),
|
||||
PrimVal::U64(n) => self.write_uint(ptr, n as u64, 8),
|
||||
PrimVal::Char(c) => self.write_uint(ptr, c as u32 as u64, 4),
|
||||
PrimVal::IntegerPtr(n) => self.write_uint(ptr, n as u64, pointer_size),
|
||||
PrimVal::FnPtr(_p) |
|
||||
PrimVal::AbstractPtr(_p) => unimplemented!(),
|
||||
|
@ -12,6 +12,7 @@ pub enum PrimVal {
|
||||
AbstractPtr(Pointer),
|
||||
FnPtr(Pointer),
|
||||
IntegerPtr(u64),
|
||||
Char(char),
|
||||
}
|
||||
|
||||
/// returns the result of the operation and whether the operation overflowed
|
||||
@ -127,6 +128,15 @@ pub fn binary_op<'tcx>(bin_op: mir::BinOp, left: PrimVal, right: PrimVal) -> Eva
|
||||
(U16(l), U16(r)) => int_binops!(U16, l, r),
|
||||
(U32(l), U32(r)) => int_binops!(U32, l, r),
|
||||
(U64(l), U64(r)) => int_binops!(U64, l, r),
|
||||
(Char(l), Char(r)) => match bin_op {
|
||||
Eq => Bool(l == r),
|
||||
Ne => Bool(l != r),
|
||||
Lt => Bool(l < r),
|
||||
Le => Bool(l <= r),
|
||||
Gt => Bool(l > r),
|
||||
Ge => Bool(l >= r),
|
||||
_ => panic!("invalid char op: {:?}", bin_op),
|
||||
},
|
||||
|
||||
(Bool(l), Bool(r)) => {
|
||||
Bool(match bin_op {
|
||||
|
5
tests/compile-fail/option_eq.rs
Normal file
5
tests/compile-fail/option_eq.rs
Normal file
@ -0,0 +1,5 @@
|
||||
//error-pattern: can't handle cast: tmp0 as isize (Misc)
|
||||
// no-ignore-x86 ignore-x86_64
|
||||
fn main() {
|
||||
assert_eq!(std::char::from_u32('x' as u32), Some('x'));
|
||||
}
|
9
tests/run-pass/char.rs
Normal file
9
tests/run-pass/char.rs
Normal file
@ -0,0 +1,9 @@
|
||||
fn main() {
|
||||
let c = 'x';
|
||||
assert_eq!(c, 'x');
|
||||
assert!('a' < 'z');
|
||||
assert!('1' < '9');
|
||||
assert_eq!(std::char::from_u32('x' as u32).unwrap(), 'x');
|
||||
// FIXME:
|
||||
// assert_eq!(std::char::from_u32('x' as u32), Some('x'));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user