mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 02:31:44 +03:00
Add documentation for renamed modules
This commit is contained in:
parent
5a46cb5bb0
commit
61f4189483
@ -14,6 +14,13 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! The pest abstract syntax tree (ast) for a Leo program.
|
||||
//!
|
||||
//! This module contains the [`LeoAst`] type, a wrapper around the [`File`] type.
|
||||
//! The [`LeoAst`] type is the datatype generated by the pest parser using grammar from `leo.pest`.
|
||||
//! The [`LeoAst`] type is intended to be parsed into a [`LeoCoreAst`]. It should not be parsed by
|
||||
//! any other pass of the compiler.
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
@ -47,6 +54,12 @@ pub(crate) use span::*;
|
||||
use from_pest::FromPest;
|
||||
use std::{fs, path::Path};
|
||||
|
||||
/// The pest abstract syntax tree (ast) for a Leo program.
|
||||
///
|
||||
/// The [`LeoAst`] type represents a Leo program as a series of recursive data types.
|
||||
/// These data types form a tree that begins from a [`File`] type root.
|
||||
///
|
||||
/// A new [`LeoAst`] can be created from a `*.leo` file at a [`Path`].
|
||||
pub struct LeoAst<'ast> {
|
||||
ast: files::File<'ast>,
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
/// Stores information to compile a Leo program.
|
||||
#[derive(Clone)]
|
||||
pub struct Compiler<F: Field + PrimeField, G: GroupType<F>> {
|
||||
package_name: String,
|
||||
@ -76,9 +77,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
///
|
||||
/// Parses program files.
|
||||
/// Returns a new `Compiler` from the given main file path.
|
||||
///
|
||||
/// Returns a compiler struct that stores the typed program abstract syntax trees (ast).
|
||||
/// Parses and stores a program from the main file path.
|
||||
/// Parses and stores all imported programs.
|
||||
/// Performs type inference checking on the program and imported programs.
|
||||
///
|
||||
pub fn parse_program_without_input(
|
||||
package_name: String,
|
||||
@ -93,9 +96,12 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
///
|
||||
/// Parses input, state, and program files.
|
||||
/// Returns a new `Compiler` from the given main file path.
|
||||
///
|
||||
/// Returns a compiler struct that stores the typed input and typed program abstract syntax trees (ast).
|
||||
/// Parses and stores program input from from the input file path and state file path
|
||||
/// Parses and stores a program from the main file path.
|
||||
/// Parses and stores all imported programs.
|
||||
/// Performs type inference checking on the program, imported programs, and program input.
|
||||
///
|
||||
pub fn parse_program_with_input(
|
||||
package_name: String,
|
||||
@ -116,9 +122,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
///
|
||||
/// Parse the input and state files.
|
||||
/// Parses and stores program input from from the input file path and state file path
|
||||
///
|
||||
/// Stores a typed ast of all input variables to the program.
|
||||
/// Calls `set_path()` on compiler errors with the given input file path or state file path
|
||||
///
|
||||
pub fn parse_input(
|
||||
&mut self,
|
||||
@ -153,7 +159,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
///
|
||||
/// Runs program parser and program checker consecutively.
|
||||
/// Runs program parser and type inference checker consecutively.
|
||||
///
|
||||
pub(crate) fn parse_and_check_program(&mut self) -> Result<(), CompilerError> {
|
||||
self.parse_program()?;
|
||||
@ -162,23 +168,28 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
///
|
||||
/// Parses the Leo program file, constructs a syntax tree, and generates a program.
|
||||
/// Parses and stores the main program file, constructs a syntax tree, and generates a program.
|
||||
///
|
||||
/// Parses and stores all programs imported by the main program file.
|
||||
///
|
||||
pub(crate) fn parse_program(&mut self) -> Result<(), CompilerError> {
|
||||
// Load the program file.
|
||||
let program_string = LeoAst::load_file(&self.main_file_path)?;
|
||||
|
||||
// Use the parser to construct the abstract syntax tree.
|
||||
let ast = LeoAst::new(&self.main_file_path, &program_string).map_err(|mut e| {
|
||||
// Use the parser to construct the pest abstract syntax tree (ast).
|
||||
let pest_ast = LeoAst::new(&self.main_file_path, &program_string).map_err(|mut e| {
|
||||
e.set_path(&self.main_file_path);
|
||||
|
||||
e
|
||||
})?;
|
||||
|
||||
// Use the typed parser to construct the typed syntax tree.
|
||||
let typed_tree = LeoCoreAst::new(&self.package_name, &ast);
|
||||
// Construct the core ast from the pest ast.
|
||||
let core_ast = LeoCoreAst::new(&self.package_name, &pest_ast);
|
||||
|
||||
self.program = typed_tree.into_repr();
|
||||
// Store the main program file.
|
||||
self.program = core_ast.into_repr();
|
||||
|
||||
// Parse and store all programs imported by the main program file.
|
||||
self.imported_programs = ImportParser::parse(&self.program)?;
|
||||
|
||||
tracing::debug!("Program parsing complete\n{:#?}", self.program);
|
||||
@ -215,7 +226,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
///
|
||||
/// Parses the Leo program string, constructs a syntax tree, and generates a program.
|
||||
/// Equivalent to parse_and_check_program but uses the given program_string instead of a main
|
||||
/// file path.
|
||||
///
|
||||
/// Used for testing only.
|
||||
///
|
||||
#[deprecated(note = "Please use the 'parse_program' method instead.")]
|
||||
@ -230,10 +243,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
// Derive the package name.
|
||||
let package_name = &self.package_name;
|
||||
|
||||
// Use the typed parser to construct the typed syntax tree.
|
||||
let typed_tree = LeoCoreAst::new(package_name, &ast);
|
||||
// Construct the core ast from the pest ast.
|
||||
let core_ast = LeoCoreAst::new(package_name, &ast);
|
||||
|
||||
self.program = typed_tree.into_repr();
|
||||
// Store the main program file.
|
||||
self.program = core_ast.into_repr();
|
||||
|
||||
// Parse and store all programs imported by the main program file.
|
||||
self.imported_programs = ImportParser::parse(&self.program)?;
|
||||
|
||||
// Create a new symbol table from the program, imported programs, and program input.
|
||||
@ -248,14 +264,16 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
///
|
||||
/// Manually sets main function input
|
||||
/// Manually sets main function input.
|
||||
///
|
||||
/// Used for testing only.
|
||||
///
|
||||
pub fn set_main_input(&mut self, input: MainInput) {
|
||||
self.program_input.set_main_input(input);
|
||||
}
|
||||
|
||||
///
|
||||
/// Verifies the input to the program
|
||||
/// Verifies the input to the program.
|
||||
///
|
||||
pub fn verify_local_data_commitment(
|
||||
&self,
|
||||
@ -297,7 +315,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
)
|
||||
}
|
||||
|
||||
///
|
||||
/// Synthesizes the circuit for test functions with program input.
|
||||
///
|
||||
pub fn compile_test_constraints(self, input_pairs: InputPairs) -> Result<(u32, u32), CompilerError> {
|
||||
generate_test_constraints::<F, G>(
|
||||
self.program,
|
||||
@ -308,7 +328,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Calls the internal generate_constraints method with arguments
|
||||
///
|
||||
/// Calls the internal generate_constraints method with arguments.
|
||||
///
|
||||
pub fn generate_constraints_helper<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
@ -324,7 +346,9 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
///
|
||||
/// Synthesizes the circuit with program input.
|
||||
///
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
|
||||
let output_directory = self.output_directory.clone();
|
||||
let package_name = self.package_name.clone();
|
||||
|
@ -14,8 +14,11 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! A typed syntax tree is represented as a `Program` and consists of import, circuit, and function definitions.
|
||||
//! Each defined type consists of typed statements and expressions.
|
||||
//! The core abstract syntax tree (ast) for a Leo program.
|
||||
//!
|
||||
//! This module contains the [`LeoCoreAst`] type, a wrapper around the [`Program`] type.
|
||||
//! The [`LeoCoreAst`] type is intended to be parsed and modified by different passes
|
||||
//! of the Leo compiler. The Leo compiler can generate a set of R1CS constraints from any [`LeoCoreAst`].
|
||||
|
||||
pub mod annotation;
|
||||
pub use self::annotation::*;
|
||||
@ -58,32 +61,38 @@ pub use self::types::*;
|
||||
|
||||
use leo_ast::LeoAst;
|
||||
|
||||
/// The core abstract syntax tree (ast) for a Leo program.
|
||||
///
|
||||
/// The [`LeoCoreAst`] type represents a Leo program as a series of recursive data types.
|
||||
/// These data types form a tree that begins from a [`Program`] type root.
|
||||
///
|
||||
/// A new [`LeoCoreAst`] can be created from a [`LeoAst`] generated by the pest parser in the `ast` module.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct LeoCoreAst {
|
||||
typed_ast: Program,
|
||||
core_ast: Program,
|
||||
}
|
||||
|
||||
impl LeoCoreAst {
|
||||
/// Creates a new core syntax tree from a given program name and abstract syntax tree.
|
||||
pub fn new<'ast>(program_name: &str, ast: &LeoAst<'ast>) -> Self {
|
||||
Self {
|
||||
typed_ast: Program::from(program_name, ast.as_repr()),
|
||||
core_ast: Program::from(program_name, ast.as_repr()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the inner program syntax tree representation.
|
||||
pub fn into_repr(self) -> Program {
|
||||
self.typed_ast
|
||||
self.core_ast
|
||||
}
|
||||
|
||||
/// Serializes the core syntax tree into a JSON string.
|
||||
pub fn to_json_string(&self) -> Result<String, serde_json::Error> {
|
||||
Ok(serde_json::to_string_pretty(&self.typed_ast)?)
|
||||
Ok(serde_json::to_string_pretty(&self.core_ast)?)
|
||||
}
|
||||
|
||||
/// Deserializes the JSON string into a core syntax tree.
|
||||
pub fn from_json_string(json: &str) -> Result<Self, serde_json::Error> {
|
||||
let typed_ast: Program = serde_json::from_str(json)?;
|
||||
Ok(Self { typed_ast })
|
||||
Ok(Self { core_ast: typed_ast })
|
||||
}
|
||||
}
|
||||
|
@ -23,16 +23,16 @@ fn to_leo_core_tree(filepath: &Path) -> Result<String, ParserError> {
|
||||
let program_filepath = filepath.to_path_buf();
|
||||
let program_string = LeoAst::load_file(&program_filepath)?;
|
||||
|
||||
// Parses the Leo file and constructs an abstract syntax tree.
|
||||
// Parses the Leo file and constructs a pest ast.
|
||||
let ast = LeoAst::new(&program_filepath, &program_string)?;
|
||||
|
||||
// Parse the abstract core tree and constructs a typed core tree.
|
||||
let typed_ast = LeoCoreAst::new("leo_core_tree", &ast);
|
||||
// Parse the pest ast and constructs a core ast.
|
||||
let core_ast = LeoCoreAst::new("leo_core_tree", &ast);
|
||||
|
||||
// Serializes the typed core tree into JSON format.
|
||||
let serialized_typed_tree = LeoCoreAst::to_json_string(&typed_ast)?;
|
||||
// Serializes the core tree into JSON format.
|
||||
let serialized_core_ast = LeoCoreAst::to_json_string(&core_ast)?;
|
||||
|
||||
Ok(serialized_typed_tree)
|
||||
Ok(serialized_core_ast)
|
||||
}
|
||||
|
||||
fn main() -> Result<(), ParserError> {
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! A typed Leo program consists of import, circuit, and function definitions.
|
||||
//! A Leo program consists of import, circuit, and function definitions.
|
||||
//! Each defined type consists of typed statements and expressions.
|
||||
|
||||
use crate::{load_annotation, Circuit, Function, FunctionInput, Identifier, ImportStatement, TestFunction};
|
||||
|
@ -21,74 +21,74 @@ use leo_core_ast::Program;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn to_typed_ast(program_filepath: &Path) -> LeoCoreAst {
|
||||
fn to_core_ast(program_filepath: &Path) -> LeoCoreAst {
|
||||
// Loads the Leo code as a string from the given file path.
|
||||
let program_string = LeoAst::load_file(program_filepath).unwrap();
|
||||
|
||||
// Parses the Leo file and constructs an abstract syntax tree.
|
||||
// Parses the Leo file and constructs a pest ast.
|
||||
let ast = LeoAst::new(&program_filepath, &program_string).unwrap();
|
||||
|
||||
// Parse the abstract syntax tree and constructs a typed syntax tree.
|
||||
// Parses the pest ast and constructs a core ast.
|
||||
LeoCoreAst::new("leo_core_tree", &ast)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "ci_skip"))]
|
||||
fn test_serialize() {
|
||||
// Construct a typed syntax tree from the given test file.
|
||||
let typed_ast = {
|
||||
// Construct a core ast from the given test file.
|
||||
let core_ast = {
|
||||
let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
program_filepath.push("tests/serialization/main.leo");
|
||||
|
||||
to_typed_ast(&program_filepath)
|
||||
to_core_ast(&program_filepath)
|
||||
};
|
||||
|
||||
// Serializes the typed syntax tree into JSON format.
|
||||
let serialized_typed_ast: Program =
|
||||
serde_json::from_value(serde_json::to_value(typed_ast.into_repr()).unwrap()).unwrap();
|
||||
// Serializes the core ast into JSON format.
|
||||
let serialized_core_ast: Program =
|
||||
serde_json::from_value(serde_json::to_value(core_ast.into_repr()).unwrap()).unwrap();
|
||||
|
||||
// Load the expected typed syntax tree.
|
||||
let expected: Program = serde_json::from_str(include_str!("expected_typed_ast.json")).unwrap();
|
||||
// Load the expected core ast.
|
||||
let expected: Program = serde_json::from_str(include_str!("expected_core_ast.json")).unwrap();
|
||||
|
||||
assert_eq!(expected, serialized_typed_ast);
|
||||
assert_eq!(expected, serialized_core_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(feature = "ci_skip"))]
|
||||
fn test_deserialize() {
|
||||
// Load the expected typed syntax tree.
|
||||
let expected_typed_ast = {
|
||||
// Load the expected core ast.
|
||||
let expected_core_ast = {
|
||||
let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
program_filepath.push("tests/serialization/main.leo");
|
||||
|
||||
to_typed_ast(&program_filepath)
|
||||
to_core_ast(&program_filepath)
|
||||
};
|
||||
|
||||
// Construct a typed syntax tree by deserializing a typed syntax tree JSON file.
|
||||
let serialized_typed_ast = include_str!("expected_typed_ast.json");
|
||||
let typed_ast = LeoCoreAst::from_json_string(serialized_typed_ast).unwrap();
|
||||
// Construct a core ast by deserializing a core ast JSON file.
|
||||
let serialized_typed_ast = include_str!("expected_core_ast.json");
|
||||
let core_ast = LeoCoreAst::from_json_string(serialized_typed_ast).unwrap();
|
||||
|
||||
assert_eq!(expected_typed_ast, typed_ast);
|
||||
assert_eq!(expected_core_ast, core_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_deserialize_serialize() {
|
||||
// Construct a typed syntax tree from the given test file.
|
||||
let typed_ast = {
|
||||
// Construct a core ast from the given test file.
|
||||
let core_ast = {
|
||||
let mut program_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
program_filepath.push("tests/serialization/main.leo");
|
||||
|
||||
to_typed_ast(&program_filepath)
|
||||
to_core_ast(&program_filepath)
|
||||
};
|
||||
|
||||
// Serializes the typed syntax tree into JSON format.
|
||||
let serialized_typed_ast = typed_ast.to_json_string().unwrap();
|
||||
// Serializes the core ast into JSON format.
|
||||
let serialized_core_ast = core_ast.to_json_string().unwrap();
|
||||
|
||||
// Deserializes the typed syntax tree into a LeoTypedAst.
|
||||
let typed_ast = LeoCoreAst::from_json_string(&serialized_typed_ast).unwrap();
|
||||
// Deserializes the serialized core ast into a LeoCoreAst.
|
||||
let core_ast = LeoCoreAst::from_json_string(&serialized_core_ast).unwrap();
|
||||
|
||||
// Reserializes the typed syntax tree into JSON format.
|
||||
let reserialized_typed_ast = typed_ast.to_json_string().unwrap();
|
||||
// Reserializes the core ast into JSON format.
|
||||
let reserialized_core_ast = core_ast.to_json_string().unwrap();
|
||||
|
||||
assert_eq!(serialized_typed_ast, reserialized_typed_ast);
|
||||
assert_eq!(serialized_core_ast, reserialized_core_ast);
|
||||
}
|
||||
|
@ -14,6 +14,11 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! The symbol table for a Leo program.
|
||||
//!
|
||||
//! This module contains the [`SymbolTable`] type, an abstract data type that tracks the current
|
||||
//! bindings for functions and circuits in a Leo program.
|
||||
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
|
@ -27,12 +27,11 @@ pub const REGISTERS_VARIABLE_NAME: &str = "registers";
|
||||
pub const STATE_VARIABLE_NAME: &str = "state";
|
||||
pub const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf";
|
||||
|
||||
/// A abstract data type that tracks the current bindings for functions and circuits.
|
||||
/// The symbol table for a Leo program.
|
||||
///
|
||||
/// A symbol table has access to all function and circuit names in its
|
||||
/// parent's symbol table.
|
||||
/// A symbol table has access to all function and circuit names in its parent's symbol table.
|
||||
/// A symbol table cannot access names in its child's symbol table.
|
||||
/// Children cannot access names in another sibling's symbol table.
|
||||
/// A child symbol table cannot access names in another sibling's symbol table.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct SymbolTable {
|
||||
/// Maps name -> parameter type.
|
||||
|
@ -14,6 +14,11 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! A type inference check for a Leo program.
|
||||
//!
|
||||
//! This module contains the [`TypeInference`] type, which stores information needed to run a type
|
||||
//! inference check over a program.
|
||||
|
||||
#[macro_use]
|
||||
extern crate thiserror;
|
||||
|
||||
|
@ -18,7 +18,11 @@ use crate::{Frame, Scope, TypeInferenceError};
|
||||
use leo_core_ast::{Circuit, CircuitMember, Function, Program};
|
||||
use leo_symbol_table::SymbolTable;
|
||||
|
||||
/// Stores information need to run a type inference check over a program.
|
||||
/// A type inference check for a Leo program.
|
||||
///
|
||||
/// A [`TypeInference`] type stores a stack of frames. A new frame is created for every
|
||||
/// function. Frames store type assertions that assert an expression is a type.
|
||||
/// Calling the `check()` method on a [`TypeInference`] checks that all type assertions are satisfied.
|
||||
pub struct TypeInference {
|
||||
table: SymbolTable,
|
||||
frames: Vec<Frame>,
|
||||
|
Loading…
Reference in New Issue
Block a user