From b97cafbbfcced4d3d5da0b2ca5bf04ba86e6cfa9 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu Date: Wed, 3 Aug 2022 12:55:24 -0700 Subject: [PATCH] Add support for Rem, RemWrapped, and Mod to passes --- .../src/code_generation/visit_expressions.rs | 3 +++ .../src/type_checking/check_expressions.rs | 18 ++++++++++++++++++ compiler/passes/src/type_checking/checker.rs | 12 ++++++++++++ 3 files changed, 33 insertions(+) diff --git a/compiler/passes/src/code_generation/visit_expressions.rs b/compiler/passes/src/code_generation/visit_expressions.rs index cc0e68cd03..296d2fc7b0 100644 --- a/compiler/passes/src/code_generation/visit_expressions.rs +++ b/compiler/passes/src/code_generation/visit_expressions.rs @@ -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"), diff --git a/compiler/passes/src/type_checking/check_expressions.rs b/compiler/passes/src/type_checking/check_expressions.rs index d71c9a73ca..9bf02ab290 100644 --- a/compiler/passes/src/type_checking/check_expressions.rs +++ b/compiler/passes/src/type_checking/check_expressions.rs @@ -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()); diff --git a/compiler/passes/src/type_checking/checker.rs b/compiler/passes/src/type_checking/checker.rs index 5f753ac06b..5f3539faa6 100644 --- a/compiler/passes/src/type_checking/checker.rs +++ b/compiler/passes/src/type_checking/checker.rs @@ -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, 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, span: Span) { self.check_type(