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
25mod composite;
26pub use self::composite::*;
27
28pub mod common;
29pub use self::common::*;
30
31pub mod constructor;
32pub use self::constructor::*;
33
34mod expressions;
35pub use self::expressions::*;
36
37mod functions;
38pub use self::functions::*;
39
40mod interface;
41pub use self::interface::*;
42
43mod indent_display;
44use indent_display::*;
45
46pub mod const_eval;
47
48mod library;
49pub use self::library::*;
50
51mod mapping;
52pub use self::mapping::*;
53
54mod module;
55pub use self::module::*;
56
57mod passes;
58pub use self::passes::*;
59
60mod program;
61pub use self::program::*;
62
63mod statement;
64pub use self::statement::*;
65
66mod storage;
67pub use self::storage::*;
68
69mod types;
70pub use self::types::*;
71
72mod stub;
73pub use self::stub::*;
74
75pub use common::node::*;
76
77/// The abstract syntax tree (AST) for a Leo program.
78///
79/// The [`Ast`] type represents a Leo program as a series of recursive data types.
80/// These data types form a tree that begins from either a [`Program`] or [`Library`] root.
81// Ast is a single root value, not stored in collections; boxing would add unnecessary indirection.
82#[allow(clippy::large_enum_variant)]
83#[derive(Clone, Debug, Eq, PartialEq)]
84pub enum Ast {
85    Program(Program),
86    Library(Library),
87}
88
89impl std::fmt::Display for Ast {
90    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91        match self {
92            Ast::Program(program) => write!(f, "{}", program),
93            Ast::Library(library) => write!(f, "{}", library),
94        }
95    }
96}
97
98// The "default" AST is somewhat arbitrary here. Mostly, this is implicitly used when writing
99// something like `let ast = std::mem::take(&mut state.ast);`
100impl Default for Ast {
101    fn default() -> Self {
102        Ast::Program(Program::default())
103    }
104}
105
106impl Ast {
107    pub fn map(self, program_fn: impl FnOnce(Program) -> Program, library_fn: impl FnOnce(Library) -> Library) -> Self {
108        match self {
109            Ast::Program(p) => Ast::Program(program_fn(p)),
110            Ast::Library(l) => Ast::Library(library_fn(l)),
111        }
112    }
113
114    pub fn try_map<E>(
115        self,
116        program_fn: impl FnOnce(Program) -> Result<Program, E>,
117        library_fn: impl FnOnce(Library) -> Result<Library, E>,
118    ) -> Result<Self, E> {
119        match self {
120            Ast::Program(p) => Ok(Ast::Program(program_fn(p)?)),
121            Ast::Library(l) => Ok(Ast::Library(library_fn(l)?)),
122        }
123    }
124
125    pub fn visit(&self, program_fn: impl FnOnce(&Program), library_fn: impl FnOnce(&Library)) {
126        match self {
127            Ast::Program(p) => program_fn(p),
128            Ast::Library(l) => library_fn(l),
129        }
130    }
131}