cairo_vm/hint_processor/builtin_hint_processor/
memset_utils.rs1use crate::stdlib::{any::Any, collections::HashMap, prelude::*};
2
3use crate::Felt252;
4use crate::{
5 hint_processor::{
6 builtin_hint_processor::hint_utils::{
7 get_integer_from_var_name, insert_value_from_var_name,
8 },
9 hint_processor_definition::HintReference,
10 },
11 serde::deserialize_program::ApTracking,
12 types::exec_scope::ExecutionScopes,
13 vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
14};
15
16pub fn memset_enter_scope(
19 vm: &mut VirtualMachine,
20 exec_scopes: &mut ExecutionScopes,
21 ids_data: &HashMap<String, HintReference>,
22 ap_tracking: &ApTracking,
23) -> Result<(), HintError> {
24 let n: Box<dyn Any> = Box::new(get_integer_from_var_name("n", vm, ids_data, ap_tracking)?);
25 exec_scopes.enter_scope(HashMap::from([(String::from("n"), n)]));
26 Ok(())
27}
28
29pub fn memset_step_loop(
36 vm: &mut VirtualMachine,
37 exec_scopes: &mut ExecutionScopes,
38 ids_data: &HashMap<String, HintReference>,
39 ap_tracking: &ApTracking,
40 i_name: &'static str,
41) -> Result<(), HintError> {
42 let n = exec_scopes.get_mut_ref::<Felt252>("n")?;
44 *n -= Felt252::ONE;
46 let flag = Felt252::from((*n > Felt252::ZERO) as u8);
49 insert_value_from_var_name(i_name, flag, vm, ids_data, ap_tracking)?;
50 Ok(())
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use crate::types::relocatable::Relocatable;
59 use crate::{
60 any_box,
61 hint_processor::{
62 builtin_hint_processor::builtin_hint_processor_definition::{
63 BuiltinHintProcessor, HintProcessorData,
64 },
65 hint_processor_definition::HintProcessorLogic,
66 },
67 types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable},
68 utils::test_utils::*,
69 vm::errors::memory_errors::MemoryError,
70 };
71 use assert_matches::assert_matches;
72
73 #[cfg(target_arch = "wasm32")]
74 use wasm_bindgen_test::*;
75
76 #[test]
77 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
78 fn memset_enter_scope_valid() {
79 let hint_code = "vm_enter_scope({'n': ids.n})";
80 let mut vm = vm!();
81 vm.run_context.fp = 2;
83 vm.segments = segments![((1, 1), 5)];
85 let ids_data = ids_data!["n"];
86 assert!(run_hint!(vm, ids_data, hint_code).is_ok());
87 }
88
89 #[test]
90 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
91 fn memset_enter_scope_invalid() {
92 let hint_code = "vm_enter_scope({'n': ids.n})";
93 let mut vm = vm!();
94 vm.run_context.fp = 2;
96 vm.segments = segments![((1, 1), (1, 0))];
99 let ids_data = ids_data!["n"];
100 assert_matches!(
101 run_hint!(vm, ids_data, hint_code),
102 Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "n"
103 );
104 }
105
106 #[test]
107 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
108 fn memset_continue_loop_valid_continue_loop_equal_1() {
109 let hint_code = "n -= 1\nids.continue_loop = 1 if n > 0 else 0";
110 let mut vm = vm!();
111 vm.run_context.fp = 1;
113 let mut exec_scopes = scope![("n", Felt252::ONE)];
115 vm.segments = segments![((1, 1), 5)];
118 let ids_data = ids_data!["continue_loop"];
119 assert!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes).is_ok());
120 check_memory![vm.segments.memory, ((1, 0), 0)];
122 }
123
124 #[test]
125 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
126 fn memset_continue_loop_valid_continue_loop_equal_5() {
127 let hint_code = "n -= 1\nids.continue_loop = 1 if n > 0 else 0";
128 let mut vm = vm!();
129 vm.run_context.fp = 1;
131 let mut exec_scopes = scope![("n", Felt252::from(5))];
133 vm.segments = segments![((1, 2), 5)];
136 let ids_data = ids_data!["continue_loop"];
137 assert!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes).is_ok());
138
139 check_memory![vm.segments.memory, ((1, 0), 1)];
141 }
142
143 #[test]
144 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
145 fn memset_continue_loop_variable_not_in_scope_error() {
146 let hint_code = "n -= 1\nids.continue_loop = 1 if n > 0 else 0";
147 let mut vm = vm!();
148 vm.run_context.fp = 3;
150
151 vm.segments = segments![((1, 2), 5)];
158 let ids_data = ids_data!["continue_loop"];
159 assert_matches!(
160 run_hint!(vm, ids_data, hint_code),
161 Err(HintError::VariableNotInScopeError(bx)) if bx.as_ref() == "n"
162 );
163 }
164
165 #[test]
166 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
167 fn memset_continue_loop_insert_error() {
168 let hint_code = "n -= 1\nids.continue_loop = 1 if n > 0 else 0";
169 let mut vm = vm!();
170 vm.run_context.fp = 1;
172 let mut exec_scopes = scope![("n", Felt252::ONE)];
174 vm.segments = segments![((1, 0), 5)];
177 let ids_data = ids_data!["continue_loop"];
178 assert_matches!(
179 run_hint!(vm, ids_data, hint_code, &mut exec_scopes),
180 Err(HintError::Memory(
181 MemoryError::InconsistentMemory(bx)
182 )) if *bx == (Relocatable::from((1, 0)),
183 MaybeRelocatable::from(Felt252::from(5)),
184 MaybeRelocatable::from(Felt252::ZERO))
185 );
186 }
187}