leo_grammar/
lib.rs

1// Copyright (C) 2019-2020 Aleo Systems 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 pest abstract syntax tree (ast) for a Leo program.
18//!
19//! This module contains the [`Grammar`] type, a wrapper around the [`File`] type in this module.
20//! The [`Grammar`] type is the datatype generated by the pest parser using grammar from `leo.pest`.
21//! The [`Grammar`] type is intended to be parsed into a [`Ast`]. It should not be parsed by
22//! any other pass of the compiler.
23
24#[macro_use]
25extern crate lazy_static;
26#[macro_use]
27extern crate pest_derive;
28#[macro_use]
29extern crate thiserror;
30
31pub mod ast;
32
33pub mod access;
34pub mod annotations;
35pub mod circuits;
36pub mod common;
37pub mod console;
38pub mod definitions;
39pub mod expressions;
40pub mod files;
41pub mod functions;
42pub mod imports;
43pub mod operations;
44pub mod statements;
45pub mod types;
46pub mod values;
47
48pub mod errors;
49pub use errors::*;
50
51pub(crate) mod span;
52pub(crate) use span::*;
53
54use from_pest::FromPest;
55use std::{fs, path::Path};
56
57/// The pest abstract syntax tree (ast) for a Leo program.
58///
59/// The [`Grammar`] type represents a Leo program as a series of recursive data types.
60/// These data types form a tree that begins from a [`File`] type root.
61///
62/// A new [`Grammar`] type can be created from a `*.leo` file at a [`Path`].
63/// A [`Grammar`] type can be used to create a new [`Ast`] type.
64pub struct Grammar<'ast> {
65    ast: files::File<'ast>,
66}
67
68impl<'ast> Grammar<'ast> {
69    /// Creates a new abstract syntax tree given the file path.
70    pub fn new(file_path: &'ast Path, program_string: &'ast str) -> Result<Self, ParserError> {
71        // TODO (howardwu): Turn this check back on after fixing the testing module.
72        // assert_eq!(program_string, fs::read_to_string(file_path).map_err(|_| ParserError::FileReadError(file_path.clone()))?);
73
74        // Parse the file using leo.pest
75        let file = &mut ast::parse(&program_string)
76            .map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?;
77
78        // Builds the abstract syntax tree using pest derivation.
79        let ast = files::File::<'ast>::from_pest(file).map_err(|_| ParserError::SyntaxTreeError)?;
80        tracing::debug!("{:#?}", ast);
81
82        Ok(Self { ast })
83    }
84
85    // TODO (howardwu): Remove this in favor of a dedicated file loader to verify checksums
86    //  and maintain a global cache of program strings during the compilation process.
87    /// Loads the Leo code as a string from the given file path.
88    pub fn load_file(file_path: &'ast Path) -> Result<String, ParserError> {
89        Ok(fs::read_to_string(file_path).map_err(|_| ParserError::FileReadError(file_path.to_owned()))?)
90    }
91
92    /// Returns a reference to the inner abstract syntax tree representation.
93    pub fn as_repr(&self) -> &files::File<'ast> {
94        &self.ast
95    }
96
97    /// Serializes the abstract syntax tree into a JSON string.
98    pub fn to_json_string(&self) -> Result<String, ParserError> {
99        Ok(serde_json::to_string_pretty(&self.ast)?)
100    }
101}