Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Add get next dict key #424

Merged
merged 12 commits into from
Apr 27, 2023
48 changes: 46 additions & 2 deletions crates/cairo-1-hint-processor/src/hint_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use num_integer::Integer;
use num_traits::identities::Zero;
use std::{collections::HashMap, ops::Mul};

use crate::dict_manager::DictManagerExecScope;
use crate::dict_manager::{DictManagerExecScope, DictSquashExecScope};

/// HintProcessor for Cairo 1 compiler hints.
struct Cairo1HintProcessor {}
Expand Down Expand Up @@ -202,6 +202,27 @@ impl Cairo1HintProcessor {
.map_err(HintError::from)
}

fn dict_read(
&self,
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
dict_ptr: &ResOperand,
key: &ResOperand,
value_dst: &CellRef,
) -> Result<(), HintError> {
let (dict_base, dict_offset) = extract_buffer(dict_ptr);
let dict_address = get_ptr(vm, dict_base, &dict_offset)?;
let key = res_operand_get_val(vm, key)?;
let dict_manager_exec_scope = exec_scopes
.get_mut_ref::<DictManagerExecScope>("dict_manager_exec_scope")
.expect("Trying to read from a dict while dict manager was not initialized.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this expect and use an error type (HintError)

let value = dict_manager_exec_scope
.get_from_tracker(dict_address, &key)
.unwrap_or_else(|| DictManagerExecScope::DICT_DEFAULT_VALUE.into());
vm.insert_value(cell_ref_to_relocatable(value_dst, vm), value)
.map_err(HintError::from)
}

fn div_mod(
&self,
vm: &mut VirtualMachine,
Expand Down Expand Up @@ -347,6 +368,23 @@ impl Cairo1HintProcessor {
Ok(())
}

fn get_next_dict_key(
&self,
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
next_key: &CellRef,
) -> Result<(), HintError> {
let dict_squash_exec_scope: &mut DictSquashExecScope =
exec_scopes.get_mut_ref("dict_squash_exec_scope")?;
dict_squash_exec_scope.pop_current_key();
if let Some(current_key) = dict_squash_exec_scope.current_key() {
return vm
.insert_value(cell_ref_to_relocatable(next_key, vm), current_key)
.map_err(HintError::from);
}
Err(HintError::KeyNotFound)
}

fn assert_le_is_second_excluded(
&self,
vm: &mut VirtualMachine,
Expand Down Expand Up @@ -387,15 +425,21 @@ impl HintProcessor for Cairo1HintProcessor {
} => self.get_segment_arena_index(vm, exec_scopes, dict_end_ptr, dict_index),
Hint::AllocSegment { dst } => self.alloc_segment(vm, dst),
Hint::TestLessThan { lhs, rhs, dst } => self.test_less_than(vm, lhs, rhs, dst),
Hint::GetNextDictKey { next_key } => self.get_next_dict_key(vm, exec_scopes, next_key),
Hint::AssertLeFindSmallArcs {
range_check_ptr,
a,
b,
} => self.assert_le_find_small_arcs(vm, exec_scopes, range_check_ptr, a, b),
Hint::SquareRoot { value, dst } => self.square_root(vm, value, dst),
Hint::TestLessThanOrEqual { lhs, rhs, dst } => {
self.test_less_than_or_equal(vm, lhs, rhs, dst)
}
Hint::Felt252DictRead {
dict_ptr,
key,
value_dst,
} => self.dict_read(vm, exec_scopes, dict_ptr, key, value_dst),
Hint::SquareRoot { value, dst } => self.square_root(vm, value, dst),
Hint::DivMod {
lhs,
rhs,
Expand Down