use super::*;
use console::program::FinalizeType;
impl<N: Network> RegistersStore<N> for FinalizeRegisters<N> {
#[inline]
fn store(
&mut self,
stack: &(impl StackMatches<N> + StackProgram<N>),
register: &Register<N>,
stack_value: Value<N>,
) -> Result<()> {
match (register, stack_value) {
(Register::Locator(locator), stack_value) => {
match self.last_register {
None => ensure!(*locator == 0, "Out-of-order write operation at '{register}'"),
Some(last) => ensure!(*locator > last, "Out-of-order write operation at '{register}'"),
};
ensure!(!self.registers.contains_key(locator), "Cannot write to occupied register '{register}'");
match (self.finalize_types.get_type(stack, register), &stack_value) {
(Ok(FinalizeType::Plaintext(plaintext_type)), Value::Plaintext(plaintext_value)) => {
stack.matches_plaintext(plaintext_value, &plaintext_type)?
}
(Ok(FinalizeType::Future(locator)), Value::Future(future)) => {
stack.matches_future(future, &locator)?
}
(Ok(finalize_type), stack_value) => bail!(
"Attempted to store a '{stack_value}' value in a register '{register}' of type '{finalize_type}' in a finalize scope",
),
(Err(error), _) => bail!("Register '{register}' is missing a type definition: {error}"),
};
match self.registers.insert(*locator, stack_value) {
Some(..) => bail!("Attempted to write to register '{register}' again"),
None => {
self.last_register = Some(*locator);
Ok(())
}
}
}
(Register::Access(..), _) => bail!("Cannot store to a register access: '{register}'"),
}
}
}