@@ -61,6 +61,14 @@ class HaxShiftRight α β where
6161 -/
6262 shiftRight : α → β → RustM α
6363
64+ /--The notation typeclass for left shift that returns a RustM. It enables the
65+ notation `a <<<? b : RustM α` where `a : α` and `b : β`. -/
66+ class HaxShiftLeft α β where
67+ /-- `a <<<? b` computes the panicking left-shift of `a` by `b`. The meaning
68+ of this notation is type-dependent. It panics if `b` exceeds the size of `a`.
69+ -/
70+ shiftLeft : α → β → RustM α
71+
6472/-- The notation typeclass for remainder. This enables the notation `a %? b :
6573RustM α` where `a b : α`. -/
6674class HaxRem α where
@@ -72,6 +80,7 @@ class HaxRem α where
7280@[inherit_doc] infixl :65 " -? " => HaxSub.sub
7381@[inherit_doc] infixl :70 " *? " => HaxMul.mul
7482@[inherit_doc] infixl :75 " >>>? " => HaxShiftRight.shiftRight
83+ @[inherit_doc] infixl :75 " <<<? " => HaxShiftLeft.shiftLeft
7584@[inherit_doc] infixl :70 " %? " => HaxRem.rem
7685@[inherit_doc] infixl :70 " /? " => HaxDiv.div
7786
@@ -85,7 +94,8 @@ class UnSigned (α: Type)
8594 (Mul α),
8695 (Div α),
8796 (Mod α),
88- (ShiftRight α)
97+ (ShiftRight α),
98+ (ShiftLeft α)
8999 where
90100 [deq : DecidableEq α]
91101 width : Nat
@@ -174,6 +184,12 @@ instance {α : Type} [UnSigned α]: HaxShiftRight α α where
174184 if (UnSigned.width α) ≤ (UnSigned.toNat y) then .fail .integerOverflow
175185 else pure (x >>> y)
176186
187+ /- Left shift on unsigned rust integers. Panics when shifting by more than the size -/
188+ instance {α : Type} [UnSigned α]: HaxShiftLeft α α where
189+ shiftLeft x y :=
190+ if (UnSigned.width α) ≤ (UnSigned.toNat y) then .fail .integerOverflow
191+ else pure (x <<< y)
192+
177193/- Signed operations -/
178194class Signed (α: Type )
179195 extends (LE α),
@@ -183,7 +199,8 @@ class Signed (α: Type)
183199 (Mul α),
184200 (Div α),
185201 (Mod α),
186- (ShiftRight α) where
202+ (ShiftRight α),
203+ (ShiftLeft α) where
187204 [dec: DecidableEq α]
188205 width : Nat
189206 toBitVec : α → BitVec width
@@ -274,6 +291,15 @@ instance {α : Type} [Signed α] : HaxShiftRight α α where
274291 else
275292 .fail .integerOverflow
276293
294+ /- Left shifting on signed integers. Panics when shifting by a negative number,
295+ or when shifting by more than the size. -/
296+ instance {α : Type} [Signed α] : HaxShiftLeft α α where
297+ shiftLeft x y :=
298+ if 0 ≤ (Signed.toInt y) && (Signed.toInt y) < Int.ofNat (Signed.width α) then
299+ pure (x <<< y)
300+ else
301+ .fail .integerOverflow
302+
277303/- Check that all operations are implemented -/
278304
279305class Operations α where
@@ -283,6 +309,7 @@ class Operations α where
283309 [instHaxDiv: HaxDiv α]
284310 [instHaxRem: HaxRem α]
285311 [instHaxShiftRight: HaxShiftRight α α]
312+ [instHaxShiftLeft: HaxShiftLeft α α]
286313
287314instance : Operations u8 where
288315instance : Operations u16 where
0 commit comments