1use crate::{Opcode, Operand, Operation, RegistersCircuit, RegistersTrait, StackTrait};
17use console::{
18 network::prelude::*,
19 program::{Literal, LiteralType, PlaintextType, Register, RegisterType},
20};
21
22use core::marker::PhantomData;
23
24pub type UnaryLiteral<N, O> = Literals<N, O, 1>;
26pub type BinaryLiteral<N, O> = Literals<N, O, 2>;
28pub type TernaryLiteral<N, O> = Literals<N, O, 3>;
30
31#[derive(Clone, PartialEq, Eq, Hash)]
32pub struct Literals<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize> {
33 operands: Vec<Operand<N>>,
35 destination: Register<N>,
37 _phantom: PhantomData<O>,
39}
40
41impl<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize>
42 Literals<N, O, NUM_OPERANDS>
43{
44 #[inline]
46 pub const fn opcode() -> Opcode {
47 O::OPCODE
48 }
49
50 #[inline]
52 pub fn operands(&self) -> &[Operand<N>] {
53 &self.operands
54 }
55
56 #[inline]
58 pub fn destinations(&self) -> Vec<Register<N>> {
59 vec![self.destination.clone()]
60 }
61}
62
63impl<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize>
64 Literals<N, O, NUM_OPERANDS>
65{
66 pub fn evaluate(&self, stack: &impl StackTrait<N>, registers: &mut impl RegistersTrait<N>) -> Result<()> {
68 if self.operands.len() != NUM_OPERANDS {
70 bail!("Instruction '{}' expects {NUM_OPERANDS} operands, found {} operands", O::OPCODE, self.operands.len())
71 }
72
73 let inputs: Vec<_> =
75 self.operands.iter().map(|operand| registers.load_literal(stack, operand)).try_collect()?;
76 let input_types: Vec<_> =
78 inputs.iter().map(|input| RegisterType::Plaintext(PlaintextType::from(input.to_type()))).collect();
79
80 let inputs: [Literal<N>; NUM_OPERANDS] =
82 inputs.try_into().map_err(|_| anyhow!("Failed to prepare operands in evaluate"))?;
83
84 let output = O::evaluate(&inputs)?;
86
87 let output_type = RegisterType::Plaintext(PlaintextType::from(output.to_type()));
89
90 let expected_types = self.output_types(stack, &input_types)?;
92 ensure!(expected_types.len() == 1, "Expected 1 output type, found {}", expected_types.len());
94 ensure!(expected_types[0] == output_type, "Expected output type '{}', found {output_type}", expected_types[0]);
96
97 registers.store_literal(stack, &self.destination, output)
99 }
100
101 pub fn execute<A: circuit::Aleo<Network = N>>(
103 &self,
104 stack: &impl StackTrait<N>,
105 registers: &mut impl RegistersCircuit<N, A>,
106 ) -> Result<()> {
107 if self.operands.len() != NUM_OPERANDS {
109 bail!("Instruction '{}' expects {NUM_OPERANDS} operands, found {} operands", O::OPCODE, self.operands.len())
110 }
111
112 let inputs: Vec<_> =
114 self.operands.iter().map(|operand| registers.load_literal_circuit(stack, operand)).try_collect()?;
115 let input_types: Vec<_> =
117 inputs.iter().map(|input| RegisterType::Plaintext(PlaintextType::from(input.to_type()))).collect();
118
119 let output = O::execute(&inputs.try_into().map_err(|_| anyhow!("Failed to prepare operands in execute"))?)?;
121 let output_type = RegisterType::Plaintext(PlaintextType::from(output.to_type()));
123
124 let expected_types = self.output_types(stack, &input_types)?;
126 ensure!(expected_types.len() == 1, "Expected 1 output type, found {}", expected_types.len());
128 ensure!(expected_types[0] == output_type, "Expected output type '{}', found {output_type}", expected_types[0]);
130
131 registers.store_literal_circuit(stack, &self.destination, output)
133 }
134
135 #[inline]
137 pub fn finalize(&self, stack: &impl StackTrait<N>, registers: &mut impl RegistersTrait<N>) -> Result<()> {
138 self.evaluate(stack, registers)
139 }
140
141 pub fn output_types(
143 &self,
144 _stack: &impl StackTrait<N>,
145 input_types: &[RegisterType<N>],
146 ) -> Result<Vec<RegisterType<N>>> {
147 if input_types.len() != NUM_OPERANDS {
149 bail!("Instruction '{}' expects {NUM_OPERANDS} inputs, found {} inputs", O::OPCODE, input_types.len())
150 }
151 if self.operands.len() != NUM_OPERANDS {
153 bail!("Instruction '{}' expects {NUM_OPERANDS} operands, found {} operands", O::OPCODE, self.operands.len())
154 }
155
156 let input_types = input_types
158 .iter()
159 .map(|input_type| match input_type {
160 RegisterType::Plaintext(PlaintextType::Literal(literal_type)) => Ok(*literal_type),
161 RegisterType::Plaintext(PlaintextType::Struct(..))
162 | RegisterType::Plaintext(PlaintextType::Array(..))
163 | RegisterType::Record(..)
164 | RegisterType::ExternalRecord(..)
165 | RegisterType::Future(..) => bail!("Expected literal type, found '{input_type}'"),
166 })
167 .collect::<Result<Vec<_>>>()?;
168
169 let output = O::output_type(&input_types.try_into().map_err(|_| anyhow!("Failed to prepare operand types"))?)?;
171
172 Ok(vec![RegisterType::Plaintext(PlaintextType::Literal(output))])
174 }
175}
176
177impl<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize> Parser
178 for Literals<N, O, NUM_OPERANDS>
179{
180 fn parse(string: &str) -> ParserResult<Self> {
182 let (string, _) = tag(*O::OPCODE)(string)?;
184 let (string, _) = Sanitizer::parse_whitespaces(string)?;
186
187 if NUM_OPERANDS > N::MAX_OPERANDS {
189 return map_res(fail, |_: ParserResult<Self>| {
190 Err(format!("The number of operands must be <= {}", N::MAX_OPERANDS))
191 })(string);
192 }
193
194 let mut operands = Vec::with_capacity(NUM_OPERANDS);
196 let mut string_tracker = string;
198 for _ in 0..NUM_OPERANDS {
200 let (string, operand) = Operand::parse(string_tracker)?;
202 let (string, _) = Sanitizer::parse_whitespaces(string)?;
204 operands.push(operand);
206 string_tracker = string;
208 }
209 let string = string_tracker;
211
212 let (string, _) = tag("into")(string)?;
214 let (string, _) = Sanitizer::parse_whitespaces(string)?;
216 let (string, destination) = Register::parse(string)?;
218
219 Ok((string, Self { operands, destination, _phantom: PhantomData }))
220 }
221}
222
223impl<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize> FromStr
224 for Literals<N, O, NUM_OPERANDS>
225{
226 type Err = Error;
227
228 fn from_str(string: &str) -> Result<Self> {
230 match Self::parse(string) {
231 Ok((remainder, object)) => {
232 ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
234 Ok(object)
236 }
237 Err(error) => bail!("Failed to parse string. {error}"),
238 }
239 }
240}
241
242impl<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize> Debug
243 for Literals<N, O, NUM_OPERANDS>
244{
245 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
247 Display::fmt(self, f)
248 }
249}
250
251impl<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize> Display
252 for Literals<N, O, NUM_OPERANDS>
253{
254 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
256 if NUM_OPERANDS > N::MAX_OPERANDS {
258 return Err(fmt::Error);
259 }
260 if self.operands.len() > NUM_OPERANDS {
262 return Err(fmt::Error);
263 }
264 write!(f, "{} ", O::OPCODE)?;
266 self.operands.iter().try_for_each(|operand| write!(f, "{operand} "))?;
267 write!(f, "into {}", self.destination)
268 }
269}
270
271impl<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize> FromBytes
272 for Literals<N, O, NUM_OPERANDS>
273{
274 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
276 if NUM_OPERANDS > N::MAX_OPERANDS {
278 return Err(error(format!("The number of operands must be <= {}", N::MAX_OPERANDS)));
279 }
280
281 let mut operands = Vec::with_capacity(NUM_OPERANDS);
283 for _ in 0..NUM_OPERANDS {
285 operands.push(Operand::read_le(&mut reader)?);
286 }
287
288 let destination = Register::read_le(&mut reader)?;
290 Ok(Self { operands, destination, _phantom: PhantomData })
292 }
293}
294
295impl<N: Network, O: Operation<N, Literal<N>, LiteralType, NUM_OPERANDS>, const NUM_OPERANDS: usize> ToBytes
296 for Literals<N, O, NUM_OPERANDS>
297{
298 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
300 if NUM_OPERANDS > N::MAX_OPERANDS {
302 return Err(error(format!("The number of operands must be <= {}", N::MAX_OPERANDS)));
303 }
304 if self.operands.len() > NUM_OPERANDS {
306 return Err(error(format!("The number of operands must be {NUM_OPERANDS}")));
307 }
308 self.operands.iter().try_for_each(|operand| operand.write_le(&mut writer))?;
310 self.destination.write_le(&mut writer)
312 }
313}