mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-23 18:21:38 +03:00
merge testnet3
This commit is contained in:
commit
b2890f393a
757
Cargo.lock
generated
757
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
11
Cargo.toml
@ -58,7 +58,8 @@ rev = "51633e2"
|
||||
version = "0.3.65"
|
||||
|
||||
[dependencies.clap]
|
||||
version = "3.1"
|
||||
version = "3.2.1"
|
||||
features = ["derive", "env"]
|
||||
|
||||
[dependencies.color-backtrace]
|
||||
version = "0.5.1"
|
||||
@ -79,9 +80,6 @@ features = ["serde"]
|
||||
[dependencies.lazy_static]
|
||||
version = "1.4.0"
|
||||
|
||||
[dependencies.notify]
|
||||
version = "4.0.17"
|
||||
|
||||
[dependencies.rand]
|
||||
version = "0.8"
|
||||
|
||||
@ -89,7 +87,7 @@ version = "0.8"
|
||||
version = "0.6.3"
|
||||
|
||||
[dependencies.reqwest]
|
||||
version = "0.11.10"
|
||||
version = "0.11.11"
|
||||
features = [ "blocking", "json", "multipart" ]
|
||||
|
||||
[dependencies.self_update]
|
||||
@ -103,9 +101,6 @@ features = [ "derive" ]
|
||||
[dependencies.serde_json]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.structopt]
|
||||
version = "0.3"
|
||||
|
||||
[dependencies.sys-info]
|
||||
version = "0.9.1"
|
||||
|
||||
|
@ -22,7 +22,7 @@ use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum ParamMode {
|
||||
Constant,
|
||||
Const,
|
||||
Private,
|
||||
Public,
|
||||
}
|
||||
@ -32,7 +32,7 @@ impl fmt::Display for ParamMode {
|
||||
use ParamMode::*;
|
||||
|
||||
match self {
|
||||
Constant => write!(f, "constant"),
|
||||
Const => write!(f, "const"),
|
||||
Private => write!(f, "private"),
|
||||
Public => write!(f, "public"),
|
||||
}
|
||||
|
@ -46,6 +46,15 @@ impl InputAst {
|
||||
Ok(serde_json::to_value(&self).map_err(|e| AstError::failed_to_convert_ast_to_json_value(&e))?)
|
||||
}
|
||||
|
||||
/// Serializes the input into a JSON file.
|
||||
pub fn to_json_file(&self, mut path: std::path::PathBuf, file_name: &str) -> Result<()> {
|
||||
path.push(file_name);
|
||||
let file = std::fs::File::create(&path).map_err(|e| AstError::failed_to_create_ast_json_file(&path, &e))?;
|
||||
let writer = std::io::BufWriter::new(file);
|
||||
Ok(serde_json::to_writer_pretty(writer, &self)
|
||||
.map_err(|e| AstError::failed_to_write_ast_to_json_file(&path, &e))?)
|
||||
}
|
||||
|
||||
/// Serializes the `Input` into a JSON value and removes keys from object mappings before writing to a file.
|
||||
pub fn to_json_file_without_keys(
|
||||
&self,
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "leo-compiler"
|
||||
version = "1.5.3"
|
||||
authors = [ "The Aleo Team <hello@aleo.org>" ]
|
||||
authors = ["The Aleo Team <hello@aleo.org>"]
|
||||
description = "Compiler of the Leo programming language"
|
||||
homepage = "https://aleo.org"
|
||||
repository = "https://github.com/AleoHQ/leo"
|
||||
@ -10,10 +10,10 @@ keywords = [
|
||||
"cryptography",
|
||||
"leo",
|
||||
"programming-language",
|
||||
"zero-knowledge"
|
||||
"zero-knowledge",
|
||||
]
|
||||
categories = [ "cryptography::cryptocurrencies", "web-programming" ]
|
||||
include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ]
|
||||
categories = ["cryptography::cryptocurrencies", "web-programming"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE.md"]
|
||||
license = "GPL-3.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.56.1"
|
||||
@ -52,7 +52,6 @@ features = ["derive"]
|
||||
[dev-dependencies.serde_yaml]
|
||||
version = "0.8.24"
|
||||
|
||||
|
||||
[features]
|
||||
default = [ ]
|
||||
ci_skip = [ "leo-ast/ci_skip" ]
|
||||
default = []
|
||||
ci_skip = ["leo-ast/ci_skip"]
|
||||
|
176
compiler/compiler/src/compiler.rs
Normal file
176
compiler/compiler/src/compiler.rs
Normal file
@ -0,0 +1,176 @@
|
||||
// Copyright (C) 2019-2021 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// 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 compiler for Leo programs.
|
||||
//!
|
||||
//! The [`Compiler`] type compiles Leo programs into R1CS circuits.
|
||||
use leo_ast::Program;
|
||||
pub use leo_ast::{Ast, InputAst};
|
||||
use leo_errors::emitter::Handler;
|
||||
use leo_errors::{CompilerError, Result};
|
||||
pub use leo_passes::SymbolTable;
|
||||
use leo_passes::*;
|
||||
use leo_span::source_map::FileName;
|
||||
use leo_span::symbol::with_session_globals;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::OutputOptions;
|
||||
|
||||
/// The primary entry point of the Leo compiler.
|
||||
#[derive(Clone)]
|
||||
pub struct Compiler<'a> {
|
||||
/// The handler is used for error and warning emissions.
|
||||
handler: &'a Handler,
|
||||
/// The path to the main leo file.
|
||||
main_file_path: PathBuf,
|
||||
/// The path to where the compiler outputs all generated files.
|
||||
output_directory: PathBuf,
|
||||
/// The AST for the program.
|
||||
pub ast: Ast,
|
||||
/// The input ast for the program if it exists.
|
||||
pub input_ast: Option<InputAst>,
|
||||
/// Compiler options on some optional output files.
|
||||
output_options: OutputOptions,
|
||||
}
|
||||
|
||||
impl<'a> Compiler<'a> {
|
||||
///
|
||||
/// Returns a new Leo compiler.
|
||||
///
|
||||
pub fn new(
|
||||
handler: &'a Handler,
|
||||
main_file_path: PathBuf,
|
||||
output_directory: PathBuf,
|
||||
output_options: Option<OutputOptions>,
|
||||
) -> Self {
|
||||
Self {
|
||||
handler,
|
||||
main_file_path,
|
||||
output_directory,
|
||||
ast: Ast::new(Program::new("Initial".to_string())),
|
||||
input_ast: None,
|
||||
output_options: output_options.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a SHA256 checksum of the program file.
|
||||
///
|
||||
pub fn checksum(&self) -> Result<String> {
|
||||
// Read in the main file as string
|
||||
let unparsed_file = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(self.main_file_path.clone(), e))?;
|
||||
|
||||
// Hash the file contents
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(unparsed_file.as_bytes());
|
||||
let hash = hasher.finalize();
|
||||
|
||||
Ok(format!("{:x}", hash))
|
||||
}
|
||||
|
||||
// Parses and stores a program file content from a string, constructs a syntax tree, and generates a program.
|
||||
pub fn parse_program_from_string(&mut self, program_string: &str, name: FileName) -> Result<()> {
|
||||
// Register the source (`program_string`) in the source map.
|
||||
let prg_sf = with_session_globals(|s| s.source_map.new_source(program_string, name));
|
||||
|
||||
// Use the parser to construct the abstract syntax tree (ast).
|
||||
let ast: leo_ast::Ast = leo_parser::parse_ast(self.handler, &prg_sf.src, prg_sf.start_pos)?;
|
||||
|
||||
if self.output_options.ast_initial {
|
||||
// Write the AST snapshot post parsing.
|
||||
if self.output_options.spans_enabled {
|
||||
ast.to_json_file(self.output_directory.clone(), "initial_ast.json")?;
|
||||
} else {
|
||||
ast.to_json_file_without_keys(self.output_directory.clone(), "initial_ast.json", &["span"])?;
|
||||
}
|
||||
}
|
||||
|
||||
self.ast = ast;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses and stores the main program file, constructs a syntax tree, and generates a program.
|
||||
pub fn parse_program(&mut self) -> Result<()> {
|
||||
// Load the program file.
|
||||
let program_string = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(&self.main_file_path, e))?;
|
||||
|
||||
self.parse_program_from_string(&program_string, FileName::Real(self.main_file_path.clone()))
|
||||
}
|
||||
|
||||
/// Parses and stores the input file, constructs a syntax tree, and generates a program input.
|
||||
pub fn parse_input(&mut self, input_file_path: PathBuf) -> Result<()> {
|
||||
if input_file_path.exists() {
|
||||
// Load the input file into the source map.
|
||||
let input_sf = with_session_globals(|s| s.source_map.load_file(&input_file_path))
|
||||
.map_err(|e| CompilerError::file_read_error(&input_file_path, e))?;
|
||||
|
||||
// Parse and serialize it.
|
||||
let input_ast = leo_parser::parse_input(self.handler, &input_sf.src, input_sf.start_pos)?;
|
||||
if self.output_options.ast_initial {
|
||||
// Write the input AST snapshot post parsing.
|
||||
if self.output_options.spans_enabled {
|
||||
input_ast.to_json_file(self.output_directory.clone(), "initial_input_ast.json")?;
|
||||
} else {
|
||||
input_ast.to_json_file_without_keys(
|
||||
self.output_directory.clone(),
|
||||
"initial_input_ast.json",
|
||||
&["span"],
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
self.input_ast = Some(input_ast);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
/// Runs the symbol table pass.
|
||||
///
|
||||
pub fn symbol_table_pass(&self) -> Result<SymbolTable<'_>> {
|
||||
CreateSymbolTable::do_pass((&self.ast, self.handler))
|
||||
}
|
||||
|
||||
///
|
||||
/// Runs the type checker pass.
|
||||
///
|
||||
pub fn type_checker_pass(&'a self, symbol_table: &mut SymbolTable<'_>) -> Result<()> {
|
||||
TypeChecker::do_pass((&self.ast, &mut symbol_table.clone(), self.handler))
|
||||
}
|
||||
|
||||
///
|
||||
/// Runs the compiler stages.
|
||||
///
|
||||
pub fn compiler_stages(&self) -> Result<SymbolTable<'_>> {
|
||||
let mut st = self.symbol_table_pass()?;
|
||||
self.type_checker_pass(&mut st)?;
|
||||
Ok(st)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a compiled Leo program.
|
||||
///
|
||||
pub fn compile(&mut self) -> Result<SymbolTable<'_>> {
|
||||
self.parse_program()?;
|
||||
self.compiler_stages()
|
||||
}
|
||||
}
|
@ -14,125 +14,15 @@
|
||||
// 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 compiler for Leo programs.
|
||||
//!
|
||||
//! The [`Compiler`] type compiles Leo programs into R1CS circuits.
|
||||
|
||||
#![allow(clippy::module_inception)]
|
||||
#![allow(clippy::upper_case_acronyms)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
mod compiler;
|
||||
pub use compiler::*;
|
||||
|
||||
mod options;
|
||||
pub use options::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
use leo_ast::Program;
|
||||
pub use leo_ast::{Ast, InputAst};
|
||||
use leo_errors::emitter::Handler;
|
||||
use leo_errors::{CompilerError, Result};
|
||||
pub use leo_passes::SymbolTable;
|
||||
use leo_passes::*;
|
||||
use leo_span::source_map::FileName;
|
||||
use leo_span::symbol::with_session_globals;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone)]
|
||||
/// The primary entry point of the Leo compiler.
|
||||
pub struct Compiler<'a> {
|
||||
handler: &'a Handler,
|
||||
main_file_path: PathBuf,
|
||||
output_directory: PathBuf,
|
||||
pub ast: Ast,
|
||||
pub input_ast: Option<InputAst>,
|
||||
}
|
||||
|
||||
impl<'a> Compiler<'a> {
|
||||
///
|
||||
/// Returns a new Leo compiler.
|
||||
///
|
||||
pub fn new(handler: &'a Handler, main_file_path: PathBuf, output_directory: PathBuf) -> Self {
|
||||
Self {
|
||||
handler,
|
||||
main_file_path,
|
||||
output_directory,
|
||||
ast: Ast::new(Program::new("Initial".to_string())),
|
||||
input_ast: None,
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a SHA256 checksum of the program file.
|
||||
///
|
||||
pub fn checksum(&self) -> Result<String> {
|
||||
// Read in the main file as string
|
||||
let unparsed_file = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(self.main_file_path.clone(), e))?;
|
||||
|
||||
// Hash the file contents
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(unparsed_file.as_bytes());
|
||||
let hash = hasher.finalize();
|
||||
|
||||
Ok(format!("{:x}", hash))
|
||||
}
|
||||
|
||||
// Parses and stores a program file content from a string, constructs a syntax tree, and generates a program.
|
||||
pub fn parse_program_from_string(&mut self, program_string: &str, name: FileName) -> Result<()> {
|
||||
// Register the source (`program_string`) in the source map.
|
||||
let prg_sf = with_session_globals(|s| s.source_map.new_source(program_string, name));
|
||||
|
||||
// Use the parser to construct the abstract syntax tree (ast).
|
||||
let ast: leo_ast::Ast = leo_parser::parse_ast(self.handler, &prg_sf.src, prg_sf.start_pos)?;
|
||||
// Write the AST snapshot post parsing.
|
||||
ast.to_json_file_without_keys(self.output_directory.clone(), "initial_ast.json", &["span"])?;
|
||||
|
||||
self.ast = ast;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Parses and stores the main program file, constructs a syntax tree, and generates a program.
|
||||
pub fn parse_program(&mut self) -> Result<()> {
|
||||
// Load the program file.
|
||||
let program_string = fs::read_to_string(&self.main_file_path)
|
||||
.map_err(|e| CompilerError::file_read_error(&self.main_file_path, e))?;
|
||||
|
||||
self.parse_program_from_string(&program_string, FileName::Real(self.main_file_path.clone()))
|
||||
}
|
||||
|
||||
/// Parses and stores the input file, constructs a syntax tree, and generates a program input.
|
||||
pub fn parse_input(&mut self, input_file_path: PathBuf) -> Result<()> {
|
||||
if input_file_path.exists() {
|
||||
// Load the input file into the source map.
|
||||
let input_sf = with_session_globals(|s| s.source_map.load_file(&input_file_path))
|
||||
.map_err(|e| CompilerError::file_read_error(&input_file_path, e))?;
|
||||
|
||||
// Parse and serialize it.
|
||||
let input_ast = leo_parser::parse_input(self.handler, &input_sf.src, input_sf.start_pos)?;
|
||||
input_ast.to_json_file_without_keys(self.output_directory.clone(), "inital_input_ast.json", &["span"])?;
|
||||
|
||||
self.input_ast = Some(input_ast);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
/// Runs the compiler stages.
|
||||
///
|
||||
fn compiler_stages(&self) -> Result<SymbolTable<'_>> {
|
||||
let symbol_table = CreateSymbolTable::do_pass((&self.ast, self.handler))?;
|
||||
|
||||
TypeChecker::do_pass((&self.ast, &mut symbol_table.clone(), self.handler))?;
|
||||
|
||||
Ok(symbol_table)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a compiled Leo program.
|
||||
///
|
||||
pub fn compile(&self) -> Result<SymbolTable<'_>> {
|
||||
self.compiler_stages()
|
||||
}
|
||||
}
|
||||
|
25
compiler/compiler/src/options.rs
Normal file
25
compiler/compiler/src/options.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2019-2021 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// 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/>.
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct OutputOptions {
|
||||
/// Whether spans are enabled in the output ASTs.
|
||||
pub spans_enabled: bool,
|
||||
/// If enabled writes the AST after parsing.
|
||||
pub ast_initial: bool,
|
||||
/// If enabled writes the input AST after parsing.
|
||||
pub input_ast_initial: bool,
|
||||
}
|
@ -21,7 +21,7 @@ use std::{
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::Compiler;
|
||||
use crate::{Compiler, OutputOptions};
|
||||
|
||||
use leo_errors::{
|
||||
emitter::{Buffer, Emitter, Handler},
|
||||
@ -40,7 +40,16 @@ fn new_compiler(handler: &Handler, main_file_path: PathBuf) -> Compiler<'_> {
|
||||
let output_dir = PathBuf::from("/tmp/output/");
|
||||
fs::create_dir_all(output_dir.clone()).unwrap();
|
||||
|
||||
Compiler::new(handler, main_file_path, output_dir)
|
||||
Compiler::new(
|
||||
handler,
|
||||
main_file_path,
|
||||
output_dir,
|
||||
Some(OutputOptions {
|
||||
spans_enabled: false,
|
||||
input_ast_initial: true,
|
||||
ast_initial: true,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_program<'a>(
|
||||
@ -123,8 +132,10 @@ fn collect_all_inputs(test: &Test) -> Result<Vec<PathBuf>, String> {
|
||||
Ok(list)
|
||||
}
|
||||
|
||||
fn compile_and_process<'a>(parsed: &'a mut Compiler<'a>) -> Result<SymbolTable<'a>, LeoError> {
|
||||
parsed.compiler_stages()
|
||||
fn compile_and_process<'a>(parsed: &'a mut Compiler<'a>) -> Result<SymbolTable<'_>, LeoError> {
|
||||
let mut st = parsed.symbol_table_pass()?;
|
||||
parsed.type_checker_pass(&mut st)?;
|
||||
Ok(st)
|
||||
}
|
||||
|
||||
// Errors used in this module.
|
||||
@ -194,7 +205,7 @@ fn run_test(test: Test, handler: &Handler, err_buf: &BufferEmitter) -> Result<Va
|
||||
for input in inputs {
|
||||
let mut parsed = parsed.clone();
|
||||
handler.extend_if_error(parsed.parse_input(input))?;
|
||||
let initial_input_ast = hash_file("/tmp/output/inital_input_ast.json");
|
||||
let initial_input_ast = hash_file("/tmp/output/initial_input_ast.json");
|
||||
|
||||
output_items.push(OutputItem { initial_input_ast });
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user