fix tests

This commit is contained in:
Protryon 2021-03-07 06:48:02 -08:00
parent 1f49d8bc44
commit a6bf66f864
5 changed files with 30 additions and 68 deletions

View File

@ -186,7 +186,7 @@ macro_rules! const_int_bimap {
impl ConstInt {
const_int_op!(raw_value, String, x, format!("{}", x));
const_int_map!(value_negate, x, x.overflowing_neg().0);
const_int_map!(value_negate, x, x.checked_neg()?);
const_int_map!(value_bit_negate, x, !x);
@ -267,61 +267,18 @@ impl ConstInt {
Type::Integer(self.get_int_type())
}
fn parse_signed(int_type: &IntegerType, raw: u128) -> Option<ConstInt> {
Some(match int_type {
IntegerType::I8 => ConstInt::I8(raw.try_into().ok()?),
IntegerType::I16 => ConstInt::I16(raw.try_into().ok()?),
IntegerType::I32 => ConstInt::I32(raw.try_into().ok()?),
IntegerType::I64 => ConstInt::I64(raw.try_into().ok()?),
IntegerType::I128 => ConstInt::I128(raw.try_into().ok()?),
_ => panic!("illegal type passed to parse_signed"),
})
}
pub fn parse(int_type: &IntegerType, value: &str, span: &Span) -> Result<ConstInt, AsgConvertError> {
let raw: u128 = value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?;
Ok(match int_type {
// IntegerType::I8 => ConstInt::I8(raw.try_into().map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?),
// IntegerType::I16 => ConstInt::I16(raw.try_into().map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?),
// IntegerType::I32 => ConstInt::I32(raw.try_into().map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?),
// IntegerType::I64 => ConstInt::I64(raw.try_into().map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?),
// IntegerType::I128 => ConstInt::I128(raw.try_into().map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?),
IntegerType::U8 => ConstInt::U8(
raw.try_into()
.map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?,
),
IntegerType::U16 => ConstInt::U16(
raw.try_into()
.map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?,
),
IntegerType::U32 => ConstInt::U32(
raw.try_into()
.map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?,
),
IntegerType::U64 => ConstInt::U64(
raw.try_into()
.map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?,
),
IntegerType::U128 => ConstInt::U128(
raw.try_into()
.map_err(|_| AsgConvertError::overflowed_const_int(&value, span))?,
),
signed_type => {
if let Some(parsed) = Self::parse_signed(signed_type, raw) {
parsed
} else if let Some(_parsed) = Self::parse_signed(signed_type, raw - 1) {
match int_type {
IntegerType::I8 => ConstInt::I8(raw as i8),
IntegerType::I16 => ConstInt::I16(raw as i16),
IntegerType::I32 => ConstInt::I32(raw as i32),
IntegerType::I64 => ConstInt::I64(raw as i64),
IntegerType::I128 => ConstInt::I128(raw as i128),
_ => panic!("illegal type passed to parse_signed"),
}
} else {
return Err(AsgConvertError::overflowed_const_int(&value, span));
}
}
IntegerType::I8 => ConstInt::I8(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::I16 => ConstInt::I16(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::I32 => ConstInt::I32(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::I64 => ConstInt::I64(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::I128 => ConstInt::I128(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::U8 => ConstInt::U8(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::U16 => ConstInt::U16(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::U32 => ConstInt::U32(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::U64 => ConstInt::U64(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
IntegerType::U128 => ConstInt::U128(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
})
}
}

View File

@ -244,10 +244,6 @@ impl AsgConvertError {
Self::new_from_span(format!("failed to parse int value '{}'", value), span)
}
pub fn overflowed_const_int(value: &str, span: &Span) -> Self {
Self::new_from_span(format!("const int value is overflowed for type '{}'", value), span)
}
pub fn unsigned_negation(span: &Span) -> Self {
Self::new_from_span("cannot negate unsigned integer".to_string(), span)
}

View File

@ -67,6 +67,7 @@ impl std::ops::Add for &Span {
impl std::ops::Add for Span {
type Output = Self;
#[allow(clippy::comparison_chain)]
fn add(self, other: Self) -> Self {
if self.line_start == other.line_stop {
Span {

View File

@ -42,10 +42,7 @@ pub enum IntegerType {
impl IntegerType {
pub fn is_signed(&self) -> bool {
use IntegerType::*;
match self {
I8 | I16 | I32 | I64 | I128 => true,
_ => false,
}
matches!(self, I8 | I16 | I32 | I64 | I128)
}
}

View File

@ -365,14 +365,25 @@ impl ParserContext {
}
let mut inner = self.parse_access_expression()?;
for op in ops.into_iter().rev() {
let operation = match op.token {
Token::Not => UnaryOperation::Not,
Token::Minus => UnaryOperation::Negate,
Token::BitNot => UnaryOperation::BitNot,
_ => unimplemented!(),
};
// hack for const signed integer overflow issues
if matches!(operation, UnaryOperation::Negate) {
if let Expression::Value(ValueExpression::Integer(type_, value, span)) = inner {
inner = Expression::Value(ValueExpression::Integer(type_, format!("-{}", value), &op.span + &span));
continue;
} else if let Expression::Value(ValueExpression::Implicit(value, span)) = inner {
inner = Expression::Value(ValueExpression::Implicit(format!("-{}", value), &op.span + &span));
continue;
}
}
inner = Expression::Unary(UnaryExpression {
span: &op.span + inner.span(),
op: match op.token {
Token::Not => UnaryOperation::Not,
Token::Minus => UnaryOperation::Negate,
Token::BitNot => UnaryOperation::BitNot,
_ => unimplemented!(),
},
op: operation,
inner: Box::new(inner),
});
}