1use super::*;
18
19use leo_ast::{IntegerType, Type};
20use leo_span::Symbol;
21
22use snarkvm::prelude::{
23 Address as SvmAddressParam,
24 Boolean as SvmBooleanParam,
25 Cast,
26 Field as SvmFieldParam,
27 FromBits as _,
28 Group as SvmGroupParam,
29 Identifier as SvmIdentifierParam,
30 Literal,
31 Plaintext,
32 Scalar as SvmScalarParam,
33 TestnetV0,
35 ToBits,
36 integers::Integer as SvmIntegerParam,
37};
38
39use indexmap::IndexMap;
40use std::{
41 fmt,
42 hash::{Hash, Hasher},
43 str::FromStr as _,
44};
45
46pub type SvmAddress = SvmAddressParam<TestnetV0>;
47type SvmBoolean = SvmBooleanParam<TestnetV0>;
48type SvmField = SvmFieldParam<TestnetV0>;
49type SvmGroup = SvmGroupParam<TestnetV0>;
50type SvmIdentifier = SvmIdentifierParam<TestnetV0>;
51type SvmInteger<I> = SvmIntegerParam<TestnetV0, I>;
52type SvmScalar = SvmScalarParam<TestnetV0>;
53#[derive(Clone, Debug, Eq, PartialEq)]
56pub struct StructContents {
57 pub name: Symbol,
58 pub contents: IndexMap<Symbol, Value>,
59}
60
61impl Hash for StructContents {
62 fn hash<H: Hasher>(&self, state: &mut H) {
63 self.name.hash(state);
64 for (_symbol, value) in self.contents.iter() {
65 value.hash(state);
66 }
67 }
68}
69
70#[derive(Clone, Debug, Eq, PartialEq, Hash)]
71pub struct AsyncExecution {
72 pub function: GlobalId,
73 pub arguments: Vec<Value>,
74}
75
76#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
77pub struct Future(pub Vec<AsyncExecution>);
78
79impl fmt::Display for Future {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 write!(f, "Future")?;
82 if !self.0.is_empty() {
83 write!(f, " with calls to ")?;
84 let mut names = self.0.iter().map(|async_ex| async_ex.function).peekable();
85 while let Some(name) = names.next() {
86 write!(f, "{name}")?;
87 if names.peek().is_some() {
88 write!(f, ", ")?;
89 }
90 }
91 }
92 Ok(())
93 }
94}
95
96#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
100pub enum Value {
101 #[default]
102 Unit,
103 Bool(bool),
104 U8(u8),
105 U16(u16),
106 U32(u32),
107 U64(u64),
108 U128(u128),
109 I8(i8),
110 I16(i16),
111 I32(i32),
112 I64(i64),
113 I128(i128),
114 Group(SvmGroup),
115 Field(SvmField),
116 Scalar(SvmScalar),
117 Array(Vec<Value>),
118 Tuple(Vec<Value>),
120 Address(SvmAddress),
121 Future(Future),
122 Struct(StructContents),
123 }
125
126impl fmt::Display for Value {
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128 use Value::*;
129 match self {
130 Unit => write!(f, "()"),
131
132 Bool(x) => write!(f, "{x}"),
133 U8(x) => write!(f, "{x}u8"),
134 U16(x) => write!(f, "{x}u16"),
135 U32(x) => write!(f, "{x}u32"),
136 U64(x) => write!(f, "{x}u64"),
137 U128(x) => write!(f, "{x}u128"),
138 I8(x) => write!(f, "{x}i8"),
139 I16(x) => write!(f, "{x}i16"),
140 I32(x) => write!(f, "{x}i32"),
141 I64(x) => write!(f, "{x}i64"),
142 I128(x) => write!(f, "{x}i128"),
143 Group(x) => write!(f, "{x}"),
144 Field(x) => write!(f, "{x}"),
145 Scalar(x) => write!(f, "{x}"),
146 Array(x) => {
147 write!(f, "[")?;
148 let mut iter = x.iter().peekable();
149 while let Some(value) = iter.next() {
150 write!(f, "{value}")?;
151 if iter.peek().is_some() {
152 write!(f, ", ")?;
153 }
154 }
155 write!(f, "]")
156 }
157 Struct(StructContents { name, contents }) => {
158 write!(f, "{name} {{")?;
159 let mut iter = contents.iter().peekable();
160 while let Some((member_name, value)) = iter.next() {
161 write!(f, "{member_name}: {value}")?;
162 if iter.peek().is_some() {
163 write!(f, ", ")?;
164 }
165 }
166 write!(f, "}}")
167 }
168 Tuple(x) => {
169 write!(f, "(")?;
170 let mut iter = x.iter().peekable();
171 while let Some(value) = iter.next() {
172 write!(f, "{value}")?;
173 if iter.peek().is_some() {
174 write!(f, ", ")?;
175 }
176 }
177 write!(f, ")")
178 }
179 Address(x) => write!(f, "{x}"),
180 Future(future) => write!(f, "{future}"),
181 }
184 }
185}
186
187impl ToBits for Value {
188 fn write_bits_le(&self, vec: &mut Vec<bool>) {
189 use Value::*;
190
191 let plaintext: Plaintext<TestnetV0> = match self {
192 Bool(x) => Literal::Boolean(SvmBoolean::new(*x)).into(),
193 U8(x) => Literal::U8(SvmInteger::new(*x)).into(),
194 U16(x) => Literal::U16(SvmInteger::new(*x)).into(),
195 U32(x) => Literal::U32(SvmInteger::new(*x)).into(),
196 U64(x) => Literal::U64(SvmInteger::new(*x)).into(),
197 U128(x) => Literal::U128(SvmInteger::new(*x)).into(),
198 I8(x) => Literal::I8(SvmInteger::new(*x)).into(),
199 I16(x) => Literal::I16(SvmInteger::new(*x)).into(),
200 I32(x) => Literal::I32(SvmInteger::new(*x)).into(),
201 I64(x) => Literal::I64(SvmInteger::new(*x)).into(),
202 I128(x) => Literal::I128(SvmInteger::new(*x)).into(),
203 Group(x) => Literal::Group(*x).into(),
204 Field(x) => Literal::Field(*x).into(),
205 Scalar(x) => Literal::Scalar(*x).into(),
206 Address(x) => Literal::Address(*x).into(),
207 Struct(StructContents { name: _, contents }) => {
208 (contents.len() as u8).write_bits_le(vec);
209 for (name, value) in contents.iter() {
210 let name_s = name.to_string();
211 let identifier = SvmIdentifier::from_str(&name_s).expect("identifier should parse");
212 identifier.size_in_bits().write_bits_le(vec);
213 identifier.write_bits_le(vec);
214 let value_bits = value.to_bits_le();
215 (value_bits.len() as u16).write_bits_le(vec);
216 vec.extend_from_slice(&value_bits);
217 }
218 return;
219 }
220
221 Array(array) => {
222 for element in array.iter() {
223 let bits = element.to_bits_le();
224 (bits.len() as u16).write_bits_le(vec);
225 vec.extend_from_slice(&bits);
226 }
227 return;
228 }
229 _ => tc_fail!(),
230 };
231
232 plaintext.write_bits_le(vec);
233 }
234
235 fn write_bits_be(&self, _vec: &mut Vec<bool>) {
236 todo!()
237 }
238}
239
240impl Value {
241 pub fn to_fields(&self) -> Vec<SvmField> {
242 let mut bits = self.to_bits_le();
243 bits.push(true);
244 bits.chunks(SvmField::SIZE_IN_DATA_BITS)
245 .map(|bits| SvmField::from_bits_le(bits).expect("conversion should work"))
246 .collect()
247 }
248
249 pub fn gte(&self, rhs: &Self) -> Result<bool> {
250 rhs.gt(self).map(|v| !v)
251 }
252
253 pub fn lte(&self, rhs: &Self) -> Result<bool> {
254 rhs.lt(self).map(|v| !v)
255 }
256
257 pub fn lt(&self, rhs: &Self) -> Result<bool> {
258 use Value::*;
259 Ok(match (self, rhs) {
260 (U8(x), U8(y)) => x < y,
261 (U16(x), U16(y)) => x < y,
262 (U32(x), U32(y)) => x < y,
263 (U64(x), U64(y)) => x < y,
264 (U128(x), U128(y)) => x < y,
265 (I8(x), I8(y)) => x < y,
266 (I16(x), I16(y)) => x < y,
267 (I32(x), I32(y)) => x < y,
268 (I64(x), I64(y)) => x < y,
269 (I128(x), I128(y)) => x < y,
270 (Field(x), Field(y)) => x < y,
271 (a, b) => halt_no_span!("Type failure: {a} < {b}"),
272 })
273 }
274
275 pub fn gt(&self, rhs: &Self) -> Result<bool> {
276 use Value::*;
277 Ok(match (self, rhs) {
278 (U8(x), U8(y)) => x > y,
279 (U16(x), U16(y)) => x > y,
280 (U32(x), U32(y)) => x > y,
281 (U64(x), U64(y)) => x > y,
282 (U128(x), U128(y)) => x > y,
283 (I8(x), I8(y)) => x > y,
284 (I16(x), I16(y)) => x > y,
285 (I32(x), I32(y)) => x > y,
286 (I64(x), I64(y)) => x > y,
287 (I128(x), I128(y)) => x > y,
288 (Field(x), Field(y)) => x > y,
289 (a, b) => halt_no_span!("Type failure: {a} > {b}"),
290 })
291 }
292
293 pub fn neq(&self, rhs: &Self) -> Result<bool> {
294 self.eq(rhs).map(|v| !v)
295 }
296
297 pub fn eq(&self, rhs: &Self) -> Result<bool> {
303 use Value::*;
304 Ok(match (self, rhs) {
305 (Unit, Unit) => true,
306 (Bool(x), Bool(y)) => x == y,
307 (U8(x), U8(y)) => x == y,
308 (U16(x), U16(y)) => x == y,
309 (U32(x), U32(y)) => x == y,
310 (U64(x), U64(y)) => x == y,
311 (U128(x), U128(y)) => x == y,
312 (I8(x), I8(y)) => x == y,
313 (I16(x), I16(y)) => x == y,
314 (I32(x), I32(y)) => x == y,
315 (I64(x), I64(y)) => x == y,
316 (I128(x), I128(y)) => x == y,
317 (Field(x), Field(y)) => x == y,
318 (Group(x), Group(y)) => x == y,
319 (Array(x), Array(y)) => {
320 if x.len() != y.len() {
321 return Ok(false);
322 }
323 for (lhs, rhs) in x.iter().zip(y.iter()) {
324 match lhs.eq(rhs) {
325 Ok(true) => {}
326 Ok(false) => return Ok(false),
327 Err(e) => return Err(e),
328 }
329 }
330 true
331 }
332 (a, b) => halt_no_span!("Type failure: {a} == {b}"),
333 })
334 }
335
336 pub fn inc_wrapping(&self) -> Self {
337 match self {
338 Value::U8(x) => Value::U8(x.wrapping_add(1)),
339 Value::U16(x) => Value::U16(x.wrapping_add(1)),
340 Value::U32(x) => Value::U32(x.wrapping_add(1)),
341 Value::U64(x) => Value::U64(x.wrapping_add(1)),
342 Value::U128(x) => Value::U128(x.wrapping_add(1)),
343 Value::I8(x) => Value::I8(x.wrapping_add(1)),
344 Value::I16(x) => Value::I16(x.wrapping_add(1)),
345 Value::I32(x) => Value::I32(x.wrapping_add(1)),
346 Value::I64(x) => Value::I64(x.wrapping_add(1)),
347 Value::I128(x) => Value::I128(x.wrapping_add(1)),
348 _ => tc_fail!(),
349 }
350 }
351
352 pub fn generator() -> Self {
354 Value::Group(SvmGroup::generator())
355 }
356
357 pub fn simple_shl(&self, shift: u32) -> Self {
360 match self {
361 Value::U8(x) => Value::U8(x << shift),
362 Value::U16(x) => Value::U16(x << shift),
363 Value::U32(x) => Value::U32(x << shift),
364 Value::U64(x) => Value::U64(x << shift),
365 Value::U128(x) => Value::U128(x << shift),
366 Value::I8(x) => Value::I8(x << shift),
367 Value::I16(x) => Value::I16(x << shift),
368 Value::I32(x) => Value::I32(x << shift),
369 Value::I64(x) => Value::I64(x << shift),
370 Value::I128(x) => Value::I128(x << shift),
371 _ => tc_fail!(),
372 }
373 }
374
375 pub fn simple_shr(&self, shift: u32) -> Self {
376 match self {
377 Value::U8(x) => Value::U8(x >> shift),
378 Value::U16(x) => Value::U16(x >> shift),
379 Value::U32(x) => Value::U32(x >> shift),
380 Value::U64(x) => Value::U64(x >> shift),
381 Value::U128(x) => Value::U128(x >> shift),
382 Value::I8(x) => Value::I8(x >> shift),
383 Value::I16(x) => Value::I16(x >> shift),
384 Value::I32(x) => Value::I32(x >> shift),
385 Value::I64(x) => Value::I64(x >> shift),
386 Value::I128(x) => Value::I128(x >> shift),
387 _ => tc_fail!(),
388 }
389 }
390
391 pub fn cast(&self, cast_type: &Type) -> Option<Value> {
393 match self {
394 Value::Bool(b) => really_cast(SvmBoolean::new(*b), cast_type),
395 Value::U8(x) => really_cast(SvmInteger::new(*x), cast_type),
396 Value::U16(x) => really_cast(SvmInteger::new(*x), cast_type),
397 Value::U32(x) => really_cast(SvmInteger::new(*x), cast_type),
398 Value::U64(x) => really_cast(SvmInteger::new(*x), cast_type),
399 Value::U128(x) => really_cast(SvmInteger::new(*x), cast_type),
400 Value::I8(x) => really_cast(SvmInteger::new(*x), cast_type),
401 Value::I16(x) => really_cast(SvmInteger::new(*x), cast_type),
402 Value::I32(x) => really_cast(SvmInteger::new(*x), cast_type),
403 Value::I64(x) => really_cast(SvmInteger::new(*x), cast_type),
404 Value::I128(x) => really_cast(SvmInteger::new(*x), cast_type),
405 Value::Group(g) => really_cast(g.to_x_coordinate(), cast_type),
406 Value::Field(f) => really_cast(*f, cast_type),
407 Value::Scalar(s) => really_cast(*s, cast_type),
408 Value::Address(a) => really_cast(a.to_group().to_x_coordinate(), cast_type),
409 _ => None,
410 }
411 }
412}
413
414fn really_cast<C>(c: C, cast_type: &Type) -> Option<Value>
415where
416 C: Cast<SvmAddress>
417 + Cast<SvmField>
418 + Cast<SvmAddress>
419 + Cast<SvmGroup>
420 + Cast<SvmBoolean>
421 + Cast<SvmScalar>
422 + Cast<SvmInteger<u8>>
423 + Cast<SvmInteger<u16>>
424 + Cast<SvmInteger<u32>>
425 + Cast<SvmInteger<u64>>
426 + Cast<SvmInteger<u128>>
427 + Cast<SvmInteger<i8>>
428 + Cast<SvmInteger<i16>>
429 + Cast<SvmInteger<i32>>
430 + Cast<SvmInteger<i64>>
431 + Cast<SvmInteger<i128>>,
432{
433 use Type::*;
434
435 let value = match cast_type {
436 Address => Value::Address(c.cast().ok()?),
437 Boolean => Value::Bool({
438 let b: SvmBoolean = c.cast().ok()?;
439 *b
440 }),
441 Field => Value::Field(c.cast().ok()?),
442 Group => Value::Group(c.cast().ok()?),
443 Integer(IntegerType::U8) => Value::U8({
444 let i: SvmInteger<u8> = c.cast().ok()?;
445 *i
446 }),
447 Integer(IntegerType::U16) => Value::U16({
448 let i: SvmInteger<u16> = c.cast().ok()?;
449 *i
450 }),
451 Integer(IntegerType::U32) => Value::U32({
452 let i: SvmInteger<u32> = c.cast().ok()?;
453 *i
454 }),
455 Integer(IntegerType::U64) => Value::U64({
456 let i: SvmInteger<u64> = c.cast().ok()?;
457 *i
458 }),
459 Integer(IntegerType::U128) => Value::U128({
460 let i: SvmInteger<u128> = c.cast().ok()?;
461 *i
462 }),
463 Integer(IntegerType::I8) => Value::I8({
464 let i: SvmInteger<i8> = c.cast().ok()?;
465 *i
466 }),
467 Integer(IntegerType::I16) => Value::I16({
468 let i: SvmInteger<i16> = c.cast().ok()?;
469 *i
470 }),
471 Integer(IntegerType::I32) => Value::I32({
472 let i: SvmInteger<i32> = c.cast().ok()?;
473 *i
474 }),
475 Integer(IntegerType::I64) => Value::I64({
476 let i: SvmInteger<i64> = c.cast().ok()?;
477 *i
478 }),
479 Integer(IntegerType::I128) => Value::I128({
480 let i: SvmInteger<i128> = c.cast().ok()?;
481 *i
482 }),
483 Scalar => Value::Scalar(c.cast().ok()?),
484
485 _ => tc_fail!(),
486 };
487 Some(value)
488}