Skip to main content

leo_ast/
lib.rs

1// Copyright (C) 2019-2026 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
17//! The abstract syntax tree (ast) for a Leo program.
18//!
19//! This module contains the [`Ast`] type, a wrapper around the [`Program`] type.
20//! The [`Ast`] type is intended to be parsed and modified by different passes
21//! of the Leo compiler. The Leo compiler can generate a set of R1CS constraints from any [`Ast`].
22
23#![allow(ambiguous_glob_reexports)]
24
25#[cfg(target_arch = "wasm32")]
26extern crate self as snarkvm;
27
28// Preserve this crate's existing `snarkvm::...` imports on WASM without pulling
29// in the full native-oriented `snarkvm` dependency graph.
30#[cfg(target_arch = "wasm32")]
31mod snarkvm_wasm;
32#[cfg(target_arch = "wasm32")]
33#[doc(hidden)]
34pub use snarkvm_wasm::{console, prelude, synthesizer};
35
36mod errors;
37
38mod composite;
39pub use self::composite::*;
40
41pub mod common;
42pub use self::common::*;
43
44pub mod constructor;
45pub use self::constructor::*;
46
47mod expressions;
48pub use self::expressions::*;
49
50mod functions;
51pub use self::functions::*;
52
53mod interface;
54pub use self::interface::*;
55
56mod indent_display;
57use indent_display::*;
58
59pub mod const_eval;
60
61mod library;
62pub use self::library::*;
63
64mod mapping;
65pub use self::mapping::*;
66
67mod module;
68pub use self::module::*;
69
70mod passes;
71pub use self::passes::*;
72
73mod program;
74pub use self::program::*;
75
76mod statement;
77pub use self::statement::*;
78
79mod storage;
80pub use self::storage::*;
81
82mod types;
83pub use self::types::*;
84
85mod stub;
86pub use self::stub::*;
87
88pub use common::node::*;
89
90/// The abstract syntax tree (AST) for a Leo program.
91///
92/// The [`Ast`] type represents a Leo program as a series of recursive data types.
93/// These data types form a tree that begins from either a [`Program`] or [`Library`] root.
94// Ast is a single root value, not stored in collections; boxing would add unnecessary indirection.
95#[allow(clippy::large_enum_variant)]
96#[derive(Clone, Debug, Eq, PartialEq)]
97pub enum Ast {
98    Program(Program),
99    Library(Library),
100}
101
102impl std::fmt::Display for Ast {
103    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104        match self {
105            Ast::Program(program) => write!(f, "{}", program),
106            Ast::Library(library) => write!(f, "{}", library),
107        }
108    }
109}
110
111// The "default" AST is somewhat arbitrary here. Mostly, this is implicitly used when writing
112// something like `let ast = std::mem::take(&mut state.ast);`
113impl Default for Ast {
114    fn default() -> Self {
115        Ast::Program(Program::default())
116    }
117}
118
119impl Ast {
120    pub fn map(self, program_fn: impl FnOnce(Program) -> Program, library_fn: impl FnOnce(Library) -> Library) -> Self {
121        match self {
122            Ast::Program(p) => Ast::Program(program_fn(p)),
123            Ast::Library(l) => Ast::Library(library_fn(l)),
124        }
125    }
126
127    pub fn try_map<E>(
128        self,
129        program_fn: impl FnOnce(Program) -> Result<Program, E>,
130        library_fn: impl FnOnce(Library) -> Result<Library, E>,
131    ) -> Result<Self, E> {
132        match self {
133            Ast::Program(p) => Ok(Ast::Program(program_fn(p)?)),
134            Ast::Library(l) => Ok(Ast::Library(library_fn(l)?)),
135        }
136    }
137
138    pub fn visit(&self, program_fn: impl FnOnce(&Program), library_fn: impl FnOnce(&Library)) {
139        match self {
140            Ast::Program(p) => program_fn(p),
141            Ast::Library(l) => library_fn(l),
142        }
143    }
144}