diff --git a/crates/erg_compiler/context/initialize/classes.rs b/crates/erg_compiler/context/initialize/classes.rs index 7e4617c5f..63a394c3d 100644 --- a/crates/erg_compiler/context/initialize/classes.rs +++ b/crates/erg_compiler/context/initialize/classes.rs @@ -569,6 +569,27 @@ impl Context { ValueObj::builtin_class(Int), ); int.register_trait(Int, int_floordiv); + // needed for implementing `%` operator + let mut int_div = Self::builtin_methods(Some(poly(DIV, vec![ty_tp(Int)])), 2); + int_div.register_builtin_erg_impl( + OP_DIV, + fn1_met(Int, Int, Float), + Const, + Visibility::BUILTIN_PUBLIC, + ); + int_div.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + None, + ValueObj::builtin_class(Float), + ); + int_div.register_builtin_const( + MOD_OUTPUT, + Visibility::BUILTIN_PUBLIC, + None, + ValueObj::builtin_class(Int), + ); + int.register_trait(Int, int_div); let mut int_pos = Self::builtin_methods(Some(mono(POS)), 2); int_pos.register_builtin_const( OUTPUT, @@ -708,6 +729,27 @@ impl Context { ValueObj::builtin_class(Nat), ); nat.register_trait(Nat, nat_floordiv); + // needed for implementing `%` operator + let mut nat_div = Self::builtin_methods(Some(poly(DIV, vec![ty_tp(Nat)])), 2); + nat_div.register_builtin_erg_impl( + OP_DIV, + fn1_met(Nat, Nat, Float), + Const, + Visibility::BUILTIN_PUBLIC, + ); + nat_div.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + None, + ValueObj::builtin_class(Float), + ); + nat_div.register_builtin_const( + MOD_OUTPUT, + Visibility::BUILTIN_PUBLIC, + None, + ValueObj::builtin_class(Nat), + ); + nat.register_trait(Nat, nat_div); let mut nat_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2); nat_mutizable.register_builtin_const( MUTABLE_MUT_TYPE, diff --git a/crates/erg_compiler/ty/free.rs b/crates/erg_compiler/ty/free.rs index d440c5ba4..a0f18b6b5 100644 --- a/crates/erg_compiler/ty/free.rs +++ b/crates/erg_compiler/ty/free.rs @@ -215,6 +215,7 @@ impl Constraint { } } + /// :> Sub, <: Sup pub fn get_sub_sup(&self) -> Option<(&Type, &Type)> { match self { Self::Sandwiched { sub, sup, .. } => Some((sub, sup)), @@ -1075,6 +1076,7 @@ impl Free { self.constraint().and_then(|c| c.get_sub().cloned()) } + /// :> Sub, <: Super pub fn get_subsup(&self) -> Option<(Type, Type)> { self.constraint() .and_then(|c| c.get_sub_sup().map(|(sub, sup)| (sub.clone(), sup.clone()))) diff --git a/tests/should_ok/operators.er b/tests/should_ok/operators.er index e941db3a9..db4ec398b 100644 --- a/tests/should_ok/operators.er +++ b/tests/should_ok/operators.er @@ -1,3 +1,10 @@ +assert 1 + 1 == 2 +assert 1 - 1 == 0 +assert 1 * 1 == 1 +assert nat(1 / 1) == 1 +assert 1 % 1 == 0 +assert 1 ** 1 == 1 + assert 1 in [1, 2] assert 1 in (1, 2) assert 1 in {1, 2}