diff --git a/corelib/src/circuit.cairo b/corelib/src/circuit.cairo index bccbe641129..bd57f889e50 100644 --- a/corelib/src/circuit.cairo +++ b/corelib/src/circuit.cairo @@ -39,6 +39,7 @@ pub struct u384 { pub limb2: u96, pub limb3: u96, } +impl NumericLiteralU384 of NumericLiteral; pub type u96 = core::internal::BoundedInt<0, 79228162514264337593543950335>; pub extern type RangeCheck96; diff --git a/corelib/src/test/circuit_test.cairo b/corelib/src/test/circuit_test.cairo index 8bfdf48f28f..79967a146da 100644 --- a/corelib/src/test/circuit_test.cairo +++ b/corelib/src/test/circuit_test.cairo @@ -13,6 +13,12 @@ fn test_u96() { assert_eq!(a, 0x123); } +#[test] +fn test_u384() { + let a: u384 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + assert_eq!(a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); +} + #[test] fn test_try_into_u96() { assert_eq!(0x123_felt252.try_into(), Option::::Some(0x123)); diff --git a/crates/cairo-lang-semantic/src/corelib.rs b/crates/cairo-lang-semantic/src/corelib.rs index 15be1c7cbfe..1f5f148374e 100644 --- a/crates/cairo-lang-semantic/src/corelib.rs +++ b/crates/cairo-lang-semantic/src/corelib.rs @@ -860,10 +860,16 @@ pub fn validate_literal( value.to_i64().is_none() } else if ty == get_core_ty_by_name(db, "i128".into(), vec![]) { value.to_i128().is_none() + } else if ty == get_core_ty_by_name(db, "u384".into(), vec![]) { + value.is_negative() || value.bits() > 384 } else { return Err(LiteralError::InvalidTypeForLiteral(ty)); }; - if is_out_of_range { Err(LiteralError::OutOfRange(ty)) } else { Ok(()) } + if is_out_of_range { + Err(LiteralError::OutOfRange(ty)) + } else { + Ok(()) + } } /// Returns the type if the inner value of a `NonZero` type, if it is wrapped in one. diff --git a/crates/cairo-lang-semantic/src/items/constant.rs b/crates/cairo-lang-semantic/src/items/constant.rs index 58b8da11c5e..40d6ac74d8e 100644 --- a/crates/cairo-lang-semantic/src/items/constant.rs +++ b/crates/cairo-lang-semantic/src/items/constant.rs @@ -389,10 +389,9 @@ pub fn value_as_const_value( validate_literal(db.upcast(), ty, value.clone())?; let get_basic_const_value = |ty| { let u256_ty = get_core_ty_by_name(db.upcast(), "u256".into(), vec![]); + let u384_ty = get_core_ty_by_name(db.upcast(), "u384".into(), vec![]); - if ty != u256_ty { - ConstValue::Int(value.clone(), ty) - } else { + if ty == u256_ty { let u128_ty = get_core_ty_by_name(db.upcast(), "u128".into(), vec![]); let mask128 = BigInt::from(u128::MAX); let low = value & mask128; @@ -401,6 +400,21 @@ pub fn value_as_const_value( vec![(ConstValue::Int(low, u128_ty)), (ConstValue::Int(high, u128_ty))], ty, ) + } else if ty == u384_ty { + let u96_ty = get_core_ty_by_name(db.upcast(), "u96".into(), vec![]); + let mask96 = BigInt::from(2).pow(96) - 1; + + ConstValue::Struct( + vec![ + (ConstValue::Int(value & &mask96, u96_ty)), + (ConstValue::Int((value >> 96) & &mask96, u96_ty)), + (ConstValue::Int((value >> 192) & &mask96, u96_ty)), + (ConstValue::Int((value >> 288) & &mask96, u96_ty)), + ], + ty, + ) + } else { + ConstValue::Int(value.clone(), ty) } };