use super::*;
impl<N: Network, A: circuit::Aleo<Network = N>> Registers<N, A> {
#[inline]
pub fn load_literal(&self, stack: &Stack<N>, operand: &Operand<N>) -> Result<Literal<N>> {
match self.load(stack, operand)? {
Value::Plaintext(Plaintext::Literal(literal, ..)) => Ok(literal),
Value::Plaintext(Plaintext::Interface(..)) => bail!("Operand must be a literal"),
Value::Record(..) => bail!("Operand must be a literal"),
}
}
#[inline]
pub fn load(&self, stack: &Stack<N>, operand: &Operand<N>) -> Result<Value<N>> {
let register = match operand {
Operand::Literal(literal) => return Ok(Value::Plaintext(Plaintext::from(literal))),
Operand::Register(register) => register,
Operand::ProgramID(program_id) => {
return Ok(Value::Plaintext(Plaintext::from(Literal::Address(program_id.to_address()?))));
}
Operand::Caller => return Ok(Value::Plaintext(Plaintext::from(Literal::Address(self.caller()?)))),
};
let stack_value =
self.console_registers.get(®ister.locator()).ok_or_else(|| anyhow!("'{register}' does not exist"))?;
let stack_value = match register {
Register::Locator(..) => stack_value.clone(),
Register::Member(_, ref path) => {
match stack_value {
Value::Plaintext(plaintext) => Value::Plaintext(plaintext.find(path)?),
Value::Record(record) => match record.find(path)? {
Entry::Constant(plaintext) | Entry::Public(plaintext) | Entry::Private(plaintext) => {
Value::Plaintext(plaintext)
}
},
}
}
};
match self.register_types.get_type(stack, register) {
Ok(register_type) => stack.matches_register_type(&stack_value, ®ister_type)?,
Err(error) => bail!("Register '{register}' is not a member of the function: {error}"),
};
Ok(stack_value)
}
}
impl<N: Network, A: circuit::Aleo<Network = N>> Registers<N, A> {
#[inline]
pub fn load_literal_circuit(&self, stack: &Stack<N>, operand: &Operand<N>) -> Result<circuit::program::Literal<A>> {
match self.load_circuit(stack, operand)? {
circuit::Value::Plaintext(circuit::Plaintext::Literal(literal, ..)) => Ok(literal),
circuit::Value::Plaintext(circuit::Plaintext::Interface(..)) => bail!("Operand must be a literal"),
circuit::Value::Record(..) => bail!("Operand must be a literal"),
}
}
#[inline]
pub fn load_circuit(&self, stack: &Stack<N>, operand: &Operand<N>) -> Result<circuit::Value<A>> {
use circuit::Inject;
let register = match operand {
Operand::Literal(literal) => {
return Ok(circuit::Value::Plaintext(circuit::Plaintext::from(circuit::Literal::constant(
literal.clone(),
))));
}
Operand::Register(register) => register,
Operand::ProgramID(program_id) => {
return Ok(circuit::Value::Plaintext(circuit::Plaintext::from(circuit::Literal::constant(
Literal::Address(program_id.to_address()?),
))));
}
Operand::Caller => {
return Ok(circuit::Value::Plaintext(circuit::Plaintext::from(circuit::Literal::Address(
self.caller_circuit()?,
))));
}
};
let circuit_value =
self.circuit_registers.get(®ister.locator()).ok_or_else(|| anyhow!("'{register}' does not exist"))?;
let circuit_value = match register {
Register::Locator(..) => circuit_value.clone(),
Register::Member(_, ref path) => {
let path = path.iter().map(|member| circuit::Identifier::constant(*member)).collect::<Vec<_>>();
match circuit_value {
circuit::Value::Plaintext(plaintext) => circuit::Value::Plaintext(plaintext.find(&path)?),
circuit::Value::Record(record) => match record.find(&path)? {
circuit::Entry::Constant(plaintext)
| circuit::Entry::Public(plaintext)
| circuit::Entry::Private(plaintext) => circuit::Value::Plaintext(plaintext),
},
}
}
};
match self.register_types.get_type(stack, register) {
Ok(register_type) => {
stack.matches_register_type(&circuit::Eject::eject_value(&circuit_value), ®ister_type)?
}
Err(error) => bail!("Register '{register}' is not a member of the function: {error}"),
};
Ok(circuit_value)
}
}