cairo_lang_sierra/extensions/modules/
boolean.rs

1use super::get_bool_type;
2use crate::define_libfunc_hierarchy;
3use crate::extensions::felt252::Felt252Type;
4use crate::extensions::lib_func::{
5    DeferredOutputKind, LibfuncSignature, OutputVarInfo, ParamSignature, SierraApChange,
6    SignatureSpecializationContext,
7};
8use crate::extensions::{
9    NamedType, NoGenericArgsGenericLibfunc, OutputVarReferenceInfo, SpecializationError,
10};
11
12define_libfunc_hierarchy! {
13    pub enum BoolLibfunc {
14        And(BoolAndLibfunc),
15        Not(BoolNotLibfunc),
16        Xor(BoolXorLibfunc),
17        Or(BoolOrLibfunc),
18        ToFelt252(BoolToFelt252Libfunc),
19    }, BoolConcreteLibfunc
20}
21
22/// Libfunc for converting a bool into a felt252.
23#[derive(Default)]
24pub struct BoolToFelt252Libfunc {}
25impl NoGenericArgsGenericLibfunc for BoolToFelt252Libfunc {
26    const STR_ID: &'static str = "bool_to_felt252";
27
28    fn specialize_signature(
29        &self,
30        context: &dyn SignatureSpecializationContext,
31    ) -> Result<LibfuncSignature, SpecializationError> {
32        Ok(LibfuncSignature::new_non_branch_ex(
33            vec![ParamSignature {
34                ty: get_bool_type(context)?,
35                allow_deferred: true,
36                allow_add_const: true,
37                allow_const: true,
38            }],
39            vec![OutputVarInfo {
40                ty: context.get_concrete_type(Felt252Type::id(), &[])?,
41                ref_info: OutputVarReferenceInfo::SameAsParam { param_idx: 0 },
42            }],
43            SierraApChange::Known { new_vars_only: true },
44        ))
45    }
46}
47
48/// Utility for common boolean libfunc signature definitions.
49fn boolean_libfunc_signature(
50    context: &dyn SignatureSpecializationContext,
51    new_vars_only: bool,
52    is_unary: bool,
53) -> Result<LibfuncSignature, SpecializationError> {
54    let bool_type = get_bool_type(context)?;
55    Ok(LibfuncSignature::new_non_branch(
56        if is_unary { vec![bool_type.clone()] } else { vec![bool_type.clone(), bool_type.clone()] },
57        vec![OutputVarInfo {
58            ty: bool_type,
59            ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
60        }],
61        SierraApChange::Known { new_vars_only },
62    ))
63}
64
65/// Libfunc for boolean AND.
66#[derive(Default)]
67pub struct BoolAndLibfunc {}
68impl NoGenericArgsGenericLibfunc for BoolAndLibfunc {
69    const STR_ID: &'static str = "bool_and_impl";
70
71    fn specialize_signature(
72        &self,
73        context: &dyn SignatureSpecializationContext,
74    ) -> Result<LibfuncSignature, SpecializationError> {
75        boolean_libfunc_signature(context, true, false)
76    }
77}
78
79/// Libfunc for boolean NOT.
80#[derive(Default)]
81pub struct BoolNotLibfunc {}
82impl NoGenericArgsGenericLibfunc for BoolNotLibfunc {
83    const STR_ID: &'static str = "bool_not_impl";
84
85    fn specialize_signature(
86        &self,
87        context: &dyn SignatureSpecializationContext,
88    ) -> Result<LibfuncSignature, SpecializationError> {
89        boolean_libfunc_signature(context, false, true)
90    }
91}
92
93/// Libfunc for boolean XOR.
94#[derive(Default)]
95pub struct BoolXorLibfunc {}
96impl NoGenericArgsGenericLibfunc for BoolXorLibfunc {
97    const STR_ID: &'static str = "bool_xor_impl";
98
99    fn specialize_signature(
100        &self,
101        context: &dyn SignatureSpecializationContext,
102    ) -> Result<LibfuncSignature, SpecializationError> {
103        boolean_libfunc_signature(context, false, false)
104    }
105}
106
107/// Libfunc for boolean OR.
108#[derive(Default)]
109pub struct BoolOrLibfunc {}
110impl NoGenericArgsGenericLibfunc for BoolOrLibfunc {
111    const STR_ID: &'static str = "bool_or_impl";
112
113    fn specialize_signature(
114        &self,
115        context: &dyn SignatureSpecializationContext,
116    ) -> Result<LibfuncSignature, SpecializationError> {
117        boolean_libfunc_signature(context, false, false)
118    }
119}