leo_passes/code_generation/
mod.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 std::fmt::Display;
18
19use crate::Pass;
20
21use itertools::Itertools;
22use leo_ast::{Literal, Mode, ProgramId};
23use leo_errors::Result;
24
25mod expression;
26
27mod program;
28
29mod statement;
30
31mod type_;
32
33mod visitor;
34use snarkvm::{
35    prelude::{ArrayType, LiteralType, Network, PlaintextType},
36    synthesizer::program::{CommitVariant, DeserializeVariant, ECDSAVerifyVariant, HashVariant, SerializeVariant},
37};
38use visitor::*;
39
40pub struct CodeGenerating;
41
42impl Pass for CodeGenerating {
43    type Input = ();
44    type Output = AleoProgram;
45
46    const NAME: &str = "CodeGenerating";
47
48    fn do_pass(_input: Self::Input, state: &mut crate::CompilerState) -> Result<Self::Output> {
49        let mut visitor = CodeGeneratingVisitor {
50            state,
51            next_register: 0,
52            current_function: None,
53            variable_mapping: Default::default(),
54            composite_mapping: Default::default(),
55            global_mapping: Default::default(),
56            variant: None,
57            program: &state.ast.ast,
58            program_id: None,
59            finalize_caller: None,
60            next_label: 0,
61            conditional_depth: 0,
62            internal_record_inputs: Default::default(),
63        };
64        let code = visitor.visit_program(visitor.state.ast.as_repr());
65        Ok(code)
66    }
67}
68
69#[derive(Debug)]
70pub struct AleoProgram {
71    imports: Vec<String>,
72    program_id: ProgramId,
73    data_types: Vec<AleoDatatype>, // order matters
74    mappings: Vec<AleoMapping>,
75    functions: Vec<AleoFunctional>,
76    constructor: Option<AleoConstructor>,
77}
78
79impl Display for AleoProgram {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        self.imports
82            .iter()
83            .map(|program_name| format!("import {program_name}.aleo;"))
84            .chain(std::iter::once(format!("program {};\n", self.program_id)))
85            .chain(self.data_types.iter().map(ToString::to_string))
86            .chain(self.mappings.iter().map(ToString::to_string))
87            .chain(self.functions.iter().map(ToString::to_string))
88            .chain(self.constructor.iter().map(ToString::to_string))
89            .join("\n")
90            .fmt(f)
91    }
92}
93
94#[derive(Debug)]
95pub enum AleoDatatype {
96    Struct(AleoStruct),
97    Record(AleoRecord),
98}
99
100impl Display for AleoDatatype {
101    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102        match self {
103            Self::Struct(s) => s.fmt(f),
104            Self::Record(r) => r.fmt(f),
105        }
106    }
107}
108
109#[derive(Debug)]
110pub struct AleoStruct {
111    name: String,
112    fields: Vec<(String, AleoType)>,
113}
114impl Display for AleoStruct {
115    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116        writeln!(f, "struct {}:", self.name)?;
117        for (id, ty) in self.fields.iter() {
118            writeln!(f, "    {id} as {ty};")?;
119        }
120        Ok(())
121    }
122}
123
124#[derive(Debug)]
125pub struct AleoRecord {
126    name: String,
127    fields: Vec<(String, AleoType, AleoVisibility)>,
128}
129impl Display for AleoRecord {
130    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131        writeln!(f, "record {}:", self.name)?;
132        for (id, ty, mode) in self.fields.iter() {
133            writeln!(f, "    {id} as {ty}.{mode};")?;
134        }
135        Ok(())
136    }
137}
138
139#[derive(Debug)]
140pub enum AleoVisibility {
141    Constant,
142    Public,
143    Private,
144}
145impl AleoVisibility {
146    fn maybe_from(mode: Mode) -> Option<Self> {
147        match mode {
148            Mode::None => None,
149            Mode::Constant => Some(Self::Constant),
150            Mode::Private => Some(Self::Private),
151            Mode::Public => Some(Self::Public),
152        }
153    }
154}
155
156impl Display for AleoVisibility {
157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158        write!(f, "{}", match self {
159            Self::Constant => "constant",
160            Self::Public => "public",
161            Self::Private => "private",
162        })
163    }
164}
165
166#[derive(Debug)]
167pub struct AleoMapping {
168    name: String,
169    key_type: AleoType,
170    key_visibility: Option<AleoVisibility>,
171    value_type: AleoType,
172    value_visibility: Option<AleoVisibility>,
173}
174impl Display for AleoMapping {
175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176        writeln!(f, "mapping {}:", self.name)?;
177        if let Some(key_viz) = &self.key_visibility {
178            writeln!(f, "    key as {}.{};", self.key_type, key_viz)?;
179        } else {
180            writeln!(f, "    key as {};", self.key_type)?;
181        }
182        if let Some(value_viz) = &self.value_visibility {
183            writeln!(f, "    value as {}.{};", self.value_type, value_viz)?;
184        } else {
185            writeln!(f, "    value as {};", self.value_type)?;
186        }
187        Ok(())
188    }
189}
190
191#[derive(Debug)]
192pub struct AleoClosure {
193    name: String,
194    inputs: Vec<AleoInput>,
195    statements: Vec<AleoStmt>,
196}
197impl Display for AleoClosure {
198    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
199        writeln!(f, "closure {}:", self.name)?;
200        for input in &self.inputs {
201            write!(f, "{}", input)?;
202        }
203        for stm in &self.statements {
204            write!(f, "{}", stm)?;
205        }
206        Ok(())
207    }
208}
209
210#[derive(Debug)]
211pub enum AleoFunctional {
212    Closure(AleoClosure),
213    Function(AleoFunction),
214    Finalize(AleoFinalize),
215}
216impl AleoFunctional {
217    pub fn as_closure(self) -> AleoClosure {
218        if let Self::Closure(c) = self { c } else { panic!("this is not a closure") }
219    }
220
221    pub fn as_function(self) -> AleoFunction {
222        if let Self::Function(c) = self { c } else { panic!("this is not a function") }
223    }
224
225    pub fn as_function_ref_mut(&mut self) -> &mut AleoFunction {
226        if let Self::Function(c) = self { c } else { panic!("this is not a function") }
227    }
228
229    pub fn as_finalize(self) -> AleoFinalize {
230        if let Self::Finalize(c) = self { c } else { panic!("this is not a finalize") }
231    }
232}
233impl Display for AleoFunctional {
234    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235        match self {
236            Self::Closure(c) => c.fmt(f),
237            Self::Function(fun) => fun.fmt(f),
238            Self::Finalize(fin) => fin.fmt(f),
239        }
240    }
241}
242
243#[derive(Debug)]
244pub struct AleoFunction {
245    name: String,
246    inputs: Vec<AleoInput>,
247    statements: Vec<AleoStmt>,
248    finalize: Option<AleoFinalize>,
249}
250impl Display for AleoFunction {
251    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
252        writeln!(f, "function {}:", self.name)?;
253        for input in &self.inputs {
254            write!(f, "{}", input)?;
255        }
256        for stm in &self.statements {
257            write!(f, "{}", stm)?;
258        }
259        if let Some(finalize) = &self.finalize {
260            write!(f, "\n{}", finalize)?;
261        }
262        Ok(())
263    }
264}
265
266#[derive(Debug)]
267pub struct AleoFinalize {
268    caller_name: String,
269    inputs: Vec<AleoInput>,
270    statements: Vec<AleoStmt>,
271}
272impl Display for AleoFinalize {
273    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
274        writeln!(f, "finalize {}:", self.caller_name)?;
275        for input in &self.inputs {
276            write!(f, "{}", input)?;
277        }
278        for stm in &self.statements {
279            write!(f, "{}", stm)?;
280        }
281        Ok(())
282    }
283}
284
285#[derive(Debug)]
286pub struct AleoInput {
287    register: AleoReg,
288    type_: AleoType,
289    visibility: Option<AleoVisibility>,
290}
291impl Display for AleoInput {
292    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
293        if let Some(visibility) = &self.visibility {
294            writeln!(f, "    input {} as {}.{};", self.register, self.type_, visibility)
295        } else {
296            writeln!(f, "    input {} as {};", self.register, self.type_)
297        }
298    }
299}
300
301#[derive(Debug)]
302pub struct AleoConstructor {
303    statements: Vec<AleoStmt>,
304    // FIXME: remove later, needed for the exact same behavior as previous codegen
305    is_custom: bool,
306}
307impl Display for AleoConstructor {
308    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
309        writeln!(f, "constructor:")?;
310        for stm in &self.statements {
311            write!(f, "{}", stm)?;
312        }
313        if self.is_custom {
314            writeln!(f)?;
315        }
316        Ok(())
317    }
318}
319
320#[derive(Hash, Eq, PartialEq, Clone, Debug)]
321pub enum AleoExpr {
322    Bool(bool),
323    Reg(AleoReg),
324    Tuple(Vec<AleoExpr>),
325    ArrayAccess(Box<AleoExpr>, Box<AleoExpr>),
326    U32(u32),
327    U16(u16),
328    Literal(Literal),
329    MemberAccess(Box<AleoExpr>, String),
330    RawName(String),
331}
332impl Display for AleoExpr {
333    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
334        match self {
335            Self::Bool(boolean) => write!(f, "{boolean}"),
336            Self::Reg(reg) => write!(f, "{reg}"),
337            Self::Tuple(regs) => write!(f, "{}", regs.iter().map(|reg| reg.to_string()).join(" ")),
338            Self::U32(val) => write!(f, "{val}u32"),
339            Self::U16(val) => write!(f, "{val}u16"),
340            Self::ArrayAccess(array, index) => write!(f, "{array}[{index}]"),
341            Self::MemberAccess(comp, member) => write!(f, "{comp}.{member}"),
342            Self::RawName(n) => write!(f, "{n}"),
343            Self::Literal(l) => write!(f, "{}", l.display_decimal()),
344        }
345    }
346}
347
348#[derive(Debug)]
349pub enum AleoStmt {
350    Output(AleoExpr, AleoType, Option<AleoVisibility>),
351    AssertEq(AleoExpr, AleoExpr),
352    AssertNeq(AleoExpr, AleoExpr),
353    Cast(AleoExpr, AleoReg, AleoType),
354    Abs(AleoExpr, AleoReg),
355    AbsW(AleoExpr, AleoReg),
356    Double(AleoExpr, AleoReg),
357    Inv(AleoExpr, AleoReg),
358    Not(AleoExpr, AleoReg),
359    Neg(AleoExpr, AleoReg),
360    Square(AleoExpr, AleoReg),
361    Sqrt(AleoExpr, AleoReg),
362    Ternary(AleoExpr, AleoExpr, AleoExpr, AleoReg),
363    Commit(CommitVariant, AleoExpr, AleoExpr, AleoReg, AleoType),
364    Hash(HashVariant, AleoExpr, AleoReg, AleoType),
365    Get(AleoExpr, AleoExpr, AleoReg),
366    GetOrUse(AleoExpr, AleoExpr, AleoExpr, AleoReg),
367    Set(AleoExpr, AleoExpr, AleoExpr),
368    Remove(AleoExpr, AleoExpr),
369    Contains(AleoExpr, AleoExpr, AleoReg),
370    RandChacha(AleoReg, AleoType),
371    SignVerify(AleoExpr, AleoExpr, AleoExpr, AleoReg),
372    EcdsaVerify(ECDSAVerifyVariant, AleoExpr, AleoExpr, AleoExpr, AleoReg),
373    Await(AleoExpr),
374    Serialize(SerializeVariant, AleoExpr, AleoType, AleoReg, AleoType),
375    Deserialize(DeserializeVariant, AleoExpr, AleoType, AleoReg, AleoType),
376    Call(String, Vec<AleoExpr>, Vec<AleoReg>),
377    Async(String, Vec<AleoExpr>, Vec<AleoReg>),
378    BranchEq(AleoExpr, AleoExpr, String),
379    Position(String),
380    Add(AleoExpr, AleoExpr, AleoReg),
381    AddWrapped(AleoExpr, AleoExpr, AleoReg),
382    And(AleoExpr, AleoExpr, AleoReg),
383    Div(AleoExpr, AleoExpr, AleoReg),
384    DivWrapped(AleoExpr, AleoExpr, AleoReg),
385    Eq(AleoExpr, AleoExpr, AleoReg),
386    Gte(AleoExpr, AleoExpr, AleoReg),
387    Gt(AleoExpr, AleoExpr, AleoReg),
388    Lte(AleoExpr, AleoExpr, AleoReg),
389    Lt(AleoExpr, AleoExpr, AleoReg),
390    Mod(AleoExpr, AleoExpr, AleoReg),
391    Mul(AleoExpr, AleoExpr, AleoReg),
392    MulWrapped(AleoExpr, AleoExpr, AleoReg),
393    Nand(AleoExpr, AleoExpr, AleoReg),
394    Neq(AleoExpr, AleoExpr, AleoReg),
395    Nor(AleoExpr, AleoExpr, AleoReg),
396    Or(AleoExpr, AleoExpr, AleoReg),
397    Pow(AleoExpr, AleoExpr, AleoReg),
398    PowWrapped(AleoExpr, AleoExpr, AleoReg),
399    Rem(AleoExpr, AleoExpr, AleoReg),
400    RemWrapped(AleoExpr, AleoExpr, AleoReg),
401    Shl(AleoExpr, AleoExpr, AleoReg),
402    ShlWrapped(AleoExpr, AleoExpr, AleoReg),
403    Shr(AleoExpr, AleoExpr, AleoReg),
404    ShrWrapped(AleoExpr, AleoExpr, AleoReg),
405    Sub(AleoExpr, AleoExpr, AleoReg),
406    SubWrapped(AleoExpr, AleoExpr, AleoReg),
407    Xor(AleoExpr, AleoExpr, AleoReg),
408}
409impl Display for AleoStmt {
410    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
411        match self {
412            Self::Output(arg, type_, viz) => {
413                if let Some(viz) = &viz {
414                    writeln!(f, "    output {} as {}.{};", arg, type_, viz)
415                } else {
416                    writeln!(f, "    output {} as {};", arg, type_)
417                }
418            }
419            Self::AssertEq(left, right) => writeln!(f, "    assert.eq {left} {right};"),
420            Self::AssertNeq(left, right) => writeln!(f, "    assert.neq {left} {right};"),
421            Self::Cast(operands, dest, type_) => {
422                writeln!(f, "    cast {operands} into {dest} as {type_};")
423            }
424            Self::Abs(op, dest) => writeln!(f, "    abs {op} into {dest};"),
425            Self::AbsW(op, dest) => writeln!(f, "    abs.w {op} into {dest};"),
426            Self::Double(op, dest) => writeln!(f, "    double {op} into {dest};"),
427            Self::Inv(op, dest) => writeln!(f, "    inv {op} into {dest};"),
428            Self::Not(op, dest) => writeln!(f, "    not {op} into {dest};"),
429            Self::Neg(op, dest) => writeln!(f, "    neg {op} into {dest};"),
430            Self::Square(op, dest) => writeln!(f, "    square {op} into {dest};"),
431            Self::Sqrt(op, dest) => writeln!(f, "    sqrt {op} into {dest};"),
432            Self::Ternary(cond, if_true, if_false, dest) => {
433                writeln!(f, "    ternary {cond} {if_true} {if_false} into {dest};")
434            }
435            Self::Commit(variant, arg0, arg1, dest, type_) => {
436                writeln!(
437                    f,
438                    "    {} {arg0} {arg1} into {dest} as {type_};",
439                    CommitVariant::opcode(variant.clone() as u8)
440                )
441            }
442            Self::Hash(variant, arg0, dest, type_) => {
443                writeln!(f, "    {} {arg0} into {dest} as {type_};", variant.opcode())
444            }
445            Self::Get(mapping, key, dest) => writeln!(f, "    get {mapping}[{key}] into {dest};"),
446            Self::GetOrUse(mapping, key, default, dest) => {
447                writeln!(f, "    get.or_use {mapping}[{key}] {default} into {dest};")
448            }
449            Self::Set(value, mapping, key) => writeln!(f, "    set {value} into {mapping}[{key}];"),
450            Self::Remove(mapping, key) => writeln!(f, "    remove {mapping}[{key}];"),
451            Self::Contains(mapping, key, dest) => writeln!(f, "    contains {mapping}[{key}] into {dest};"),
452            Self::RandChacha(dest, type_) => writeln!(f, "    rand.chacha into {dest} as {type_};"),
453            Self::SignVerify(arg0, arg1, arg2, dest) => {
454                writeln!(f, "    sign.verify {arg0} {arg1} {arg2} into {dest};")
455            }
456            Self::EcdsaVerify(variant, arg0, arg1, arg2, dest) => {
457                writeln!(f, "    {} {arg0} {arg1} {arg2} into {dest};", variant.opcode())
458            }
459            Self::Await(exp) => writeln!(f, "    await {exp};"),
460            Self::Serialize(variant, input, input_ty, dest, dest_ty) => {
461                writeln!(
462                    f,
463                    "    {} {input} ({input_ty}) into {dest} ({dest_ty});",
464                    SerializeVariant::opcode(variant.clone() as u8),
465                )
466            }
467            Self::Deserialize(variant, input, input_ty, dest, dest_ty) => {
468                writeln!(
469                    f,
470                    "    {} {input} ({input_ty}) into {dest} ({dest_ty});",
471                    DeserializeVariant::opcode(variant.clone() as u8),
472                )
473            }
474            Self::Call(id, inputs, dests) => {
475                write!(f, "    call {id}")?;
476                if !inputs.is_empty() {
477                    write!(f, " {}", inputs.iter().map(|input| input.to_string()).join(" "))?;
478                }
479                if !dests.is_empty() {
480                    write!(f, " into {}", dests.iter().map(|input| input.to_string()).join(" "))?;
481                }
482                writeln!(f, ";")
483            }
484            Self::Async(id, inputs, dests) => {
485                write!(f, "    async {id}")?;
486                if !inputs.is_empty() {
487                    write!(f, " {}", inputs.iter().map(|input| input.to_string()).join(" "))?;
488                }
489                if !dests.is_empty() {
490                    write!(f, " into {}", dests.iter().map(|input| input.to_string()).join(" "))?;
491                }
492                writeln!(f, ";")
493            }
494            Self::BranchEq(arg0, arg1, label) => {
495                writeln!(f, "    branch.eq {arg0} {arg1} to {label};")
496            }
497            Self::Position(label) => writeln!(f, "    position {label};"),
498            Self::Add(arg0, arg1, dest) => writeln!(f, "    add {arg0} {arg1} into {dest};"),
499            Self::AddWrapped(arg0, arg1, dest) => writeln!(f, "    add.w {arg0} {arg1} into {dest};"),
500            Self::And(arg0, arg1, dest) => writeln!(f, "    and {arg0} {arg1} into {dest};"),
501            Self::Div(arg0, arg1, dest) => writeln!(f, "    div {arg0} {arg1} into {dest};"),
502            Self::DivWrapped(arg0, arg1, dest) => writeln!(f, "    div.w {arg0} {arg1} into {dest};"),
503            Self::Eq(arg0, arg1, dest) => writeln!(f, "    is.eq {arg0} {arg1} into {dest};"),
504            Self::Gte(arg0, arg1, dest) => writeln!(f, "    gte {arg0} {arg1} into {dest};"),
505            Self::Gt(arg0, arg1, dest) => writeln!(f, "    gt {arg0} {arg1} into {dest};"),
506            Self::Lte(arg0, arg1, dest) => writeln!(f, "    lte {arg0} {arg1} into {dest};"),
507            Self::Lt(arg0, arg1, dest) => writeln!(f, "    lt {arg0} {arg1} into {dest};"),
508            Self::Mod(arg0, arg1, dest) => writeln!(f, "    mod {arg0} {arg1} into {dest};"),
509            Self::Mul(arg0, arg1, dest) => writeln!(f, "    mul {arg0} {arg1} into {dest};"),
510            Self::MulWrapped(arg0, arg1, dest) => writeln!(f, "    mul.w {arg0} {arg1} into {dest};"),
511            Self::Nand(arg0, arg1, dest) => writeln!(f, "    nand {arg0} {arg1} into {dest};"),
512            Self::Neq(arg0, arg1, dest) => writeln!(f, "    is.neq {arg0} {arg1} into {dest};"),
513            Self::Nor(arg0, arg1, dest) => writeln!(f, "    nor {arg0} {arg1} into {dest};"),
514            Self::Or(arg0, arg1, dest) => writeln!(f, "    or {arg0} {arg1} into {dest};"),
515            Self::Pow(arg0, arg1, dest) => writeln!(f, "    pow {arg0} {arg1} into {dest};"),
516            Self::PowWrapped(arg0, arg1, dest) => writeln!(f, "    pow.w {arg0} {arg1} into {dest};"),
517            Self::Rem(arg0, arg1, dest) => writeln!(f, "    rem {arg0} {arg1} into {dest};"),
518            Self::RemWrapped(arg0, arg1, dest) => writeln!(f, "    rem.w {arg0} {arg1} into {dest};"),
519            Self::Shl(arg0, arg1, dest) => writeln!(f, "    shl {arg0} {arg1} into {dest};"),
520            Self::ShlWrapped(arg0, arg1, dest) => writeln!(f, "    shl.w {arg0} {arg1} into {dest};"),
521            Self::Shr(arg0, arg1, dest) => writeln!(f, "    shr {arg0} {arg1} into {dest};"),
522            Self::ShrWrapped(arg0, arg1, dest) => writeln!(f, "    shr.w {arg0} {arg1} into {dest};"),
523            Self::Sub(arg0, arg1, dest) => writeln!(f, "    sub {arg0} {arg1} into {dest};"),
524            Self::SubWrapped(arg0, arg1, dest) => writeln!(f, "    sub.w {arg0} {arg1} into {dest};"),
525            Self::Xor(arg0, arg1, dest) => writeln!(f, "    xor {arg0} {arg1} into {dest};"),
526        }
527    }
528}
529
530#[derive(Debug)]
531pub enum AleoType {
532    Future { name: String, program: String },
533    Record { name: String, program: Option<String> },
534    Ident { name: String },
535    Array { inner: Box<AleoType>, len: u32 },
536    GroupX,
537    GroupY,
538    Address,
539    Boolean,
540    Field,
541    Group,
542    I8,
543    I16,
544    I32,
545    I64,
546    I128,
547    U8,
548    U16,
549    U32,
550    U64,
551    U128,
552    Scalar,
553    Signature,
554    String,
555}
556impl Display for AleoType {
557    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
558        match self {
559            Self::Future { name, program } => write!(f, "{program}.aleo/{name}.future"),
560            Self::Record { name, program: Some(program_name) } => write!(f, "{program_name}.aleo/{name}.record"),
561            Self::Record { name, program: None } => write!(f, "{name}.record"),
562            Self::GroupX => write!(f, "group.x"),
563            Self::GroupY => write!(f, "group.y"),
564            Self::Ident { name } => write!(f, "{name}"),
565            Self::Address => write!(f, "address"),
566            Self::Boolean => write!(f, "boolean"),
567            Self::Field => write!(f, "field"),
568            Self::Group => write!(f, "group"),
569            Self::I8 => write!(f, "i8"),
570            Self::I16 => write!(f, "i16"),
571            Self::I32 => write!(f, "i32"),
572            Self::I64 => write!(f, "i64"),
573            Self::I128 => write!(f, "i128"),
574            Self::U8 => write!(f, "u8"),
575            Self::U16 => write!(f, "u16"),
576            Self::U32 => write!(f, "u32"),
577            Self::U64 => write!(f, "u64"),
578            Self::U128 => write!(f, "u128"),
579            Self::Scalar => write!(f, "scalar"),
580            Self::Signature => write!(f, "signature"),
581            Self::String => write!(f, "string"),
582            Self::Array { inner, len } => write!(f, "[{inner}; {len}u32]"),
583        }
584    }
585}
586impl<N: Network> From<PlaintextType<N>> for AleoType {
587    fn from(value: PlaintextType<N>) -> Self {
588        match value {
589            PlaintextType::Literal(lit) => lit.into(),
590            PlaintextType::Struct(id) => Self::Ident { name: id.to_string() },
591            PlaintextType::Array(arr) => arr.into(),
592        }
593    }
594}
595impl From<LiteralType> for AleoType {
596    fn from(value: LiteralType) -> Self {
597        match value {
598            LiteralType::Address => Self::Address,
599            LiteralType::Boolean => Self::Boolean,
600            LiteralType::Field => Self::Field,
601            LiteralType::Group => Self::Group,
602            LiteralType::I8 => Self::I8,
603            LiteralType::I16 => Self::I16,
604            LiteralType::I32 => Self::I32,
605            LiteralType::I64 => Self::I64,
606            LiteralType::I128 => Self::I128,
607            LiteralType::U8 => Self::U8,
608            LiteralType::U16 => Self::U16,
609            LiteralType::U32 => Self::U32,
610            LiteralType::U64 => Self::U64,
611            LiteralType::U128 => Self::U128,
612            LiteralType::Scalar => Self::Scalar,
613            LiteralType::Signature => Self::Signature,
614            LiteralType::String => Self::String,
615        }
616    }
617}
618impl<N: Network> From<ArrayType<N>> for AleoType {
619    fn from(value: ArrayType<N>) -> Self {
620        Self::Array { len: **value.length(), inner: Box::new(AleoType::from(value.next_element_type().clone())) }
621    }
622}
623
624#[derive(Hash, Eq, PartialEq, Clone, Debug)]
625pub enum AleoReg {
626    Self_,
627    Block,
628    Network,
629    R(u64),
630}
631impl Display for AleoReg {
632    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
633        match self {
634            Self::Self_ => write!(f, "self"),
635            Self::Block => write!(f, "block"),
636            Self::Network => write!(f, "network"),
637            Self::R(n) => write!(f, "r{n}"),
638        }
639    }
640}