leo_ast/interpreter_value/
value.rs

1// Copyright (C) 2019-2025 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17use leo_span::Symbol;
18use snarkvm::prelude::{
19    Address as SvmAddressParam,
20    Boolean as SvmBooleanParam,
21    Field as SvmFieldParam,
22    Group as SvmGroupParam,
23    Identifier as SvmIdentifierParam,
24    Scalar as SvmScalarParam,
25    // Signature as SvmSignatureParam,
26    TestnetV0,
27    integers::Integer as SvmIntegerParam,
28};
29
30use std::{
31    fmt,
32    hash::{Hash, Hasher},
33};
34
35use indexmap::IndexMap;
36
37pub type SvmAddress = SvmAddressParam<TestnetV0>;
38pub type SvmBoolean = SvmBooleanParam<TestnetV0>;
39pub type SvmField = SvmFieldParam<TestnetV0>;
40pub type SvmGroup = SvmGroupParam<TestnetV0>;
41pub type SvmIdentifier = SvmIdentifierParam<TestnetV0>;
42pub type SvmInteger<I> = SvmIntegerParam<TestnetV0, I>;
43pub type SvmScalar = SvmScalarParam<TestnetV0>;
44
45/// Global values - such as mappings, functions, etc -
46/// are identified by program and name.
47#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
48pub struct GlobalId {
49    pub program: Symbol,
50    pub name: Symbol,
51}
52
53impl fmt::Display for GlobalId {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        write!(f, "{}.aleo/{}", self.program, self.name)
56    }
57}
58
59#[derive(Clone, Debug, Eq, PartialEq)]
60pub struct StructContents {
61    pub name: Symbol,
62    pub contents: IndexMap<Symbol, Value>,
63}
64
65impl Hash for StructContents {
66    fn hash<H: Hasher>(&self, state: &mut H) {
67        self.name.hash(state);
68        for (_symbol, value) in self.contents.iter() {
69            value.hash(state);
70        }
71    }
72}
73
74#[derive(Clone, Debug, Eq, PartialEq, Hash)]
75pub struct AsyncExecution {
76    pub function: GlobalId,
77    pub arguments: Vec<Value>,
78}
79
80#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
81pub struct Future(pub Vec<AsyncExecution>);
82
83impl fmt::Display for Future {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        write!(f, "Future")?;
86        if !self.0.is_empty() {
87            write!(f, " with calls to ")?;
88            let mut names = self.0.iter().map(|async_ex| async_ex.function).peekable();
89            while let Some(name) = names.next() {
90                write!(f, "{name}")?;
91                if names.peek().is_some() {
92                    write!(f, ", ")?;
93                }
94            }
95        }
96        Ok(())
97    }
98}
99
100/// A Leo value of any type.
101///
102/// Mappings and functions aren't considered values.
103#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
104pub enum Value {
105    #[default]
106    Unit,
107    Bool(bool),
108    U8(u8),
109    U16(u16),
110    U32(u32),
111    U64(u64),
112    U128(u128),
113    I8(i8),
114    I16(i16),
115    I32(i32),
116    I64(i64),
117    I128(i128),
118    Group(SvmGroup),
119    Field(SvmField),
120    Scalar(SvmScalar),
121    Array(Vec<Value>),
122    Repeat(Box<Value>, Box<Value>),
123    // Signature(Box<SvmSignature>),
124    Tuple(Vec<Value>),
125    Address(SvmAddress),
126    Future(Future),
127    Struct(StructContents),
128    // String(()),
129}
130
131impl fmt::Display for Value {
132    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133        use Value::*;
134        match self {
135            Unit => write!(f, "()"),
136
137            Bool(x) => write!(f, "{x}"),
138            U8(x) => write!(f, "{x}u8"),
139            U16(x) => write!(f, "{x}u16"),
140            U32(x) => write!(f, "{x}u32"),
141            U64(x) => write!(f, "{x}u64"),
142            U128(x) => write!(f, "{x}u128"),
143            I8(x) => write!(f, "{x}i8"),
144            I16(x) => write!(f, "{x}i16"),
145            I32(x) => write!(f, "{x}i32"),
146            I64(x) => write!(f, "{x}i64"),
147            I128(x) => write!(f, "{x}i128"),
148            Group(x) => write!(f, "{x}"),
149            Field(x) => write!(f, "{x}"),
150            Scalar(x) => write!(f, "{x}"),
151            Array(x) => {
152                write!(f, "[")?;
153                let mut iter = x.iter().peekable();
154                while let Some(value) = iter.next() {
155                    write!(f, "{value}")?;
156                    if iter.peek().is_some() {
157                        write!(f, ", ")?;
158                    }
159                }
160                write!(f, "]")
161            }
162            Repeat(expr, count) => write!(f, "[{expr}; {count}]"),
163            Struct(StructContents { name, contents }) => {
164                write!(f, "{name} {{")?;
165                let mut iter = contents.iter().peekable();
166                while let Some((member_name, value)) = iter.next() {
167                    write!(f, "{member_name}: {value}")?;
168                    if iter.peek().is_some() {
169                        write!(f, ", ")?;
170                    }
171                }
172                write!(f, "}}")
173            }
174            Tuple(x) => {
175                write!(f, "(")?;
176                let mut iter = x.iter().peekable();
177                while let Some(value) = iter.next() {
178                    write!(f, "{value}")?;
179                    if iter.peek().is_some() {
180                        write!(f, ", ")?;
181                    }
182                }
183                write!(f, ")")
184            }
185            Address(x) => write!(f, "{x}"),
186            Future(future) => write!(f, "{future}"),
187            // Signature(x) => write!(f, "{x}"),
188            // String(_) => todo!(),
189        }
190    }
191}