Add support for Rem, RemWrapped, and Mod to passes

This commit is contained in:
Pranav Gaddamadugu 2022-08-03 12:55:24 -07:00
parent 7ff84af785
commit b97cafbbfc
3 changed files with 33 additions and 0 deletions

View File

@ -68,6 +68,7 @@ impl<'a> CodeGenerator<'a> {
BinaryOperation::Gt => String::from("gt"),
BinaryOperation::Lte => String::from("lte"),
BinaryOperation::Lt => String::from("lt"),
BinaryOperation::Mod => String::from("mod"),
BinaryOperation::Mul => String::from("mul"),
BinaryOperation::MulWrapped => String::from("mul.w"),
BinaryOperation::Nand => String::from("nand"),
@ -77,6 +78,8 @@ impl<'a> CodeGenerator<'a> {
BinaryOperation::BitwiseOr => String::from("or"),
BinaryOperation::Pow => String::from("pow"),
BinaryOperation::PowWrapped => String::from("pow.w"),
BinaryOperation::Rem => String::from("rem"),
BinaryOperation::RemWrapped => String::from("rem.w"),
BinaryOperation::Shl => String::from("shl"),
BinaryOperation::ShlWrapped => String::from("shl.w"),
BinaryOperation::Shr => String::from("shr"),

View File

@ -398,6 +398,24 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
return_incorrect_type(t1, t2, destination)
}
BinaryOperation::Rem | BinaryOperation::RemWrapped => {
// Only integer types.
self.assert_int_type(destination, input.span());
let t1 = self.visit_expression(&input.left, destination);
let t2 = self.visit_expression(&input.right, destination);
return_incorrect_type(t1, t2, destination)
}
BinaryOperation::Mod => {
// Only unsigned integer types.
self.assert_unsigned_int_type(destination, input.span());
let t1 = self.visit_expression(&input.left, destination);
let t2 = self.visit_expression(&input.right, destination);
return_incorrect_type(t1, t2, destination)
}
BinaryOperation::Pow => {
// Operation returns field or integer types.
self.assert_field_int_type(destination, input.span());

View File

@ -55,6 +55,8 @@ const INT_TYPES: [Type; 10] = [
const SIGNED_INT_TYPES: [Type; 5] = [Type::I8, Type::I16, Type::I32, Type::I64, Type::I128];
const UNSIGNED_INT_TYPES: [Type; 5] = [Type::U8, Type::U16, Type::U32, Type::U64, Type::U128];
const MAGNITUDE_TYPES: [Type; 3] = [Type::U8, Type::U16, Type::U32];
impl<'a> TypeChecker<'a> {
@ -176,6 +178,16 @@ impl<'a> TypeChecker<'a> {
)
}
/// Emits an error to the handler if the given type is not an unsigned integer.
pub(crate) fn assert_unsigned_int_type(&self, type_: &Option<Type>, span: Span) {
self.check_type(
|type_: &Type| UNSIGNED_INT_TYPES.contains(type_),
types_to_string(&UNSIGNED_INT_TYPES),
type_,
span,
)
}
/// Emits an error to the handler if the given type is not a magnitude (u8, u16, u32).
pub(crate) fn assert_magnitude_type(&self, type_: &Option<Type>, span: Span) {
self.check_type(