cairo_lang_sierra/extensions/modules/int/
mod.rs1use std::marker::PhantomData;
2
3use num_bigint::BigInt;
4
5use super::felt252::Felt252Type;
6use super::try_from_felt252::{TryFromFelt252, TryFromFelt252Libfunc};
7use super::utils::reinterpret_cast_signature;
8use crate::extensions::lib_func::{
9 BranchSignature, DeferredOutputKind, LibfuncSignature, OutputVarInfo, ParamSignature,
10 SierraApChange, SignatureSpecializationContext, SpecializationContext,
11};
12use crate::extensions::{
13 NamedLibfunc, NamedType, NoGenericArgsGenericLibfunc, NoGenericArgsGenericType,
14 OutputVarReferenceInfo, SignatureBasedConcreteLibfunc, SpecializationError,
15};
16use crate::ids::GenericTypeId;
17use crate::program::GenericArg;
18
19pub mod signed;
20pub mod signed128;
21pub mod unsigned;
22pub mod unsigned128;
23pub mod unsigned256;
24pub mod unsigned512;
25
26#[derive(Copy, Clone, Debug, PartialEq, Eq)]
28pub enum IntOperator {
29 OverflowingAdd,
30 OverflowingSub,
31}
32
33pub struct IntOperationConcreteLibfunc {
34 pub operator: IntOperator,
35 pub signature: LibfuncSignature,
36}
37impl SignatureBasedConcreteLibfunc for IntOperationConcreteLibfunc {
38 fn signature(&self) -> &LibfuncSignature {
39 &self.signature
40 }
41}
42
43pub trait IntTraits: Default {
45 type IntType: TryFrom<BigInt> + Into<BigInt> + Copy;
47 const IS_SMALL: bool;
50 const GENERIC_TYPE_ID: GenericTypeId;
52 const CONST: &'static str;
54 const EQUAL: &'static str;
56 const TO_FELT252: &'static str;
58 const TRY_FROM_FELT252: &'static str;
60}
61
62pub trait IntMulTraits: IntTraits {
64 const WIDE_MUL: &'static str;
66 const WIDE_MUL_RES_TYPE_ID: GenericTypeId;
68}
69
70#[derive(Default)]
71pub struct IntType<TIntTraits: IntTraits> {
72 _phantom: PhantomData<TIntTraits>,
73}
74impl<TIntTraits: IntTraits> NoGenericArgsGenericType for IntType<TIntTraits> {
75 const ID: GenericTypeId = TIntTraits::GENERIC_TYPE_ID;
76 const STORABLE: bool = true;
77 const DUPLICATABLE: bool = true;
78 const DROPPABLE: bool = true;
79 const ZERO_SIZED: bool = false;
80}
81
82#[derive(Default)]
84pub struct IntConstLibfunc<TIntTraits: IntTraits> {
85 _phantom: PhantomData<TIntTraits>,
86}
87impl<TIntTraits: IntTraits> NamedLibfunc for IntConstLibfunc<TIntTraits> {
88 const STR_ID: &'static str = TIntTraits::CONST;
89 type Concrete = IntConstConcreteLibfunc<TIntTraits>;
90
91 fn specialize_signature(
92 &self,
93 context: &dyn SignatureSpecializationContext,
94 _args: &[GenericArg],
95 ) -> Result<LibfuncSignature, SpecializationError> {
96 Ok(LibfuncSignature::new_non_branch(
97 vec![],
98 vec![OutputVarInfo {
99 ty: context.get_concrete_type(TIntTraits::GENERIC_TYPE_ID, &[])?,
100 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Const),
101 }],
102 SierraApChange::Known { new_vars_only: true },
103 ))
104 }
105
106 fn specialize(
107 &self,
108 context: &dyn SpecializationContext,
109 args: &[GenericArg],
110 ) -> Result<Self::Concrete, SpecializationError> {
111 match args {
112 [GenericArg::Value(c)] => Ok(Self::Concrete {
113 c: TIntTraits::IntType::try_from(c.clone())
114 .map_err(|_| SpecializationError::UnsupportedGenericArg)?,
115 signature: <Self as NamedLibfunc>::specialize_signature(
116 self,
117 context.upcast(),
118 args,
119 )?,
120 }),
121 _ => Err(SpecializationError::UnsupportedGenericArg),
122 }
123 }
124}
125
126pub struct IntConstConcreteLibfunc<TIntTraits: IntTraits> {
127 pub c: TIntTraits::IntType,
128 pub signature: LibfuncSignature,
129}
130impl<TIntTraits: IntTraits> SignatureBasedConcreteLibfunc for IntConstConcreteLibfunc<TIntTraits> {
131 fn signature(&self) -> &LibfuncSignature {
132 &self.signature
133 }
134}
135
136#[derive(Default)]
138pub struct IntEqualLibfunc<TIntTraits: IntTraits> {
139 _phantom: PhantomData<TIntTraits>,
140}
141impl<TIntTraits: IntTraits> NoGenericArgsGenericLibfunc for IntEqualLibfunc<TIntTraits> {
142 const STR_ID: &'static str = TIntTraits::EQUAL;
143
144 fn specialize_signature(
145 &self,
146 context: &dyn SignatureSpecializationContext,
147 ) -> Result<LibfuncSignature, SpecializationError> {
148 let ty = context.get_concrete_type(TIntTraits::GENERIC_TYPE_ID, &[])?;
149 let param_signatures =
150 vec![ParamSignature::new(ty.clone()), ParamSignature::new(ty).with_allow_const()];
151 let branch_signatures = (0..2)
152 .map(|_| BranchSignature {
153 vars: vec![],
154 ap_change: SierraApChange::Known { new_vars_only: false },
155 })
156 .collect();
157 Ok(LibfuncSignature { param_signatures, branch_signatures, fallthrough: Some(0) })
158 }
159}
160
161#[derive(Default)]
163pub struct IntToFelt252Libfunc<TIntTraits: IntTraits> {
164 _phantom: PhantomData<TIntTraits>,
165}
166impl<TIntTraits: IntTraits> NoGenericArgsGenericLibfunc for IntToFelt252Libfunc<TIntTraits> {
167 const STR_ID: &'static str = TIntTraits::TO_FELT252;
168
169 fn specialize_signature(
170 &self,
171 context: &dyn SignatureSpecializationContext,
172 ) -> Result<LibfuncSignature, SpecializationError> {
173 Ok(reinterpret_cast_signature(
174 context.get_concrete_type(TIntTraits::GENERIC_TYPE_ID, &[])?,
175 context.get_concrete_type(Felt252Type::id(), &[])?,
176 ))
177 }
178}
179
180#[derive(Default)]
182pub struct IntFromFelt252Trait<TIntTraits: IntTraits> {
183 _phantom: PhantomData<TIntTraits>,
184}
185impl<TIntTraits: IntTraits> TryFromFelt252 for IntFromFelt252Trait<TIntTraits> {
186 const STR_ID: &'static str = TIntTraits::TRY_FROM_FELT252;
187 const GENERIC_TYPE_ID: GenericTypeId = TIntTraits::GENERIC_TYPE_ID;
188}
189
190pub type IntFromFelt252Libfunc<T> = TryFromFelt252Libfunc<IntFromFelt252Trait<T>>;
191#[derive(Default)]
193pub struct IntWideMulLibfunc<TIntMulTraits: IntMulTraits> {
194 _phantom: PhantomData<TIntMulTraits>,
195}
196impl<TIntMulTraits: IntMulTraits> NoGenericArgsGenericLibfunc for IntWideMulLibfunc<TIntMulTraits> {
197 const STR_ID: &'static str = TIntMulTraits::WIDE_MUL;
198
199 fn specialize_signature(
200 &self,
201 context: &dyn SignatureSpecializationContext,
202 ) -> Result<LibfuncSignature, SpecializationError> {
203 let ty = context.get_concrete_type(TIntMulTraits::GENERIC_TYPE_ID, &[])?;
204 Ok(LibfuncSignature::new_non_branch_ex(
205 vec![ParamSignature::new(ty.clone()), ParamSignature::new(ty).with_allow_const()],
206 vec![OutputVarInfo {
207 ty: context.get_concrete_type(TIntMulTraits::WIDE_MUL_RES_TYPE_ID, &[])?,
208 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
209 }],
210 SierraApChange::Known { new_vars_only: true },
211 ))
212 }
213}