From 0a49dd1ec3db2fa286a81afa37075322f650925d Mon Sep 17 00:00:00 2001 From: howardwu Date: Thu, 23 Apr 2020 18:52:43 -0700 Subject: [PATCH 01/16] Adds compiler module --- Cargo.lock | 18 ++++-- Cargo.toml | 2 +- benchmark/Cargo.toml | 4 -- compiler/Cargo.toml | 17 ++++++ compiler/simple.leo | 4 ++ compiler/simple_import.leo | 4 ++ compiler/src/lib.rs | 0 compiler/src/main.rs | 111 +++++++++++++++++++++++++++++++++++++ 8 files changed, 151 insertions(+), 9 deletions(-) create mode 100644 compiler/Cargo.toml create mode 100644 compiler/simple.leo create mode 100644 compiler/simple_import.leo create mode 100644 compiler/src/lib.rs create mode 100644 compiler/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index cf0444284d..ec4fb87a42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -609,11 +609,21 @@ name = "leo-benchmark" version = "0.1.0" dependencies = [ "from-pest", - "lazy_static", "leo-program", - "pest", - "pest-ast", - "pest_derive", + "rand 0.7.3", + "snarkos-algorithms", + "snarkos-curves", + "snarkos-errors", + "snarkos-gadgets", + "snarkos-models", +] + +[[package]] +name = "leo-compiler" +version = "0.1.0" +dependencies = [ + "from-pest", + "leo-program", "rand 0.7.3", "snarkos-algorithms", "snarkos-curves", diff --git a/Cargo.toml b/Cargo.toml index cd660f70e7..57626b0002 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ name = "leo" path = "benchmark/src/main.rs" [workspace] -members = [ "benchmark", "program" ] +members = [ "benchmark", "compiler", "program" ] [dependencies] snarkos-algorithms = { path = "../snarkOS/algorithms", version = "0.8.0" } diff --git a/benchmark/Cargo.toml b/benchmark/Cargo.toml index b415248975..bd5a8fb8a2 100644 --- a/benchmark/Cargo.toml +++ b/benchmark/Cargo.toml @@ -14,8 +14,4 @@ snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0" } snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" } from-pest = { version = "0.3.1" } -lazy_static = { version = "1.3.0" } -pest = { version = "2.0" } -pest-ast = { version = "0.3.3" } -pest_derive = { version = "2.0" } rand = { version = "0.7" } diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml new file mode 100644 index 0000000000..63a514c6cf --- /dev/null +++ b/compiler/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "leo-compiler" +version = "0.1.0" +authors = ["The Aleo Team "] +edition = "2018" + +[dependencies] +leo-program = { path = "../program", version = "0.1.0" } + +snarkos-algorithms = { path = "../../snarkOS/algorithms", version = "0.8.0" } +snarkos-curves = { path = "../../snarkOS/curves", version = "0.8.0" } +snarkos-errors = { path = "../../snarkOS/errors", version = "0.8.0" } +snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0" } +snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" } + +from-pest = { version = "0.3.1" } +rand = { version = "0.7" } diff --git a/compiler/simple.leo b/compiler/simple.leo new file mode 100644 index 0000000000..847c630eb2 --- /dev/null +++ b/compiler/simple.leo @@ -0,0 +1,4 @@ +function main() -> (u32) { + a = 1 + 1 + return a +} \ No newline at end of file diff --git a/compiler/simple_import.leo b/compiler/simple_import.leo new file mode 100644 index 0000000000..667fa6871c --- /dev/null +++ b/compiler/simple_import.leo @@ -0,0 +1,4 @@ +struct Point { + u32 x + u32 y +} \ No newline at end of file diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/compiler/src/main.rs b/compiler/src/main.rs new file mode 100644 index 0000000000..baea1f03d1 --- /dev/null +++ b/compiler/src/main.rs @@ -0,0 +1,111 @@ +use leo_program::{self, ast}; + +use snarkos_algorithms::snark::{ + create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, +}; +use snarkos_curves::bls12_377::{Bls12_377, Fr}; +use snarkos_errors::gadgets::SynthesisError; +use snarkos_models::{ + curves::{Field, PrimeField}, + gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem}, +}; + +use from_pest::FromPest; +use rand::thread_rng; +use std::{ + fs, + marker::PhantomData, + time::{Duration, Instant}, +}; + +pub struct Benchmark { + _engine: PhantomData, +} + +impl Benchmark { + pub fn new() -> Self { + Self { + _engine: PhantomData, + } + } +} + +impl ConstraintSynthesizer for Benchmark { + fn generate_constraints>( + self, + cs: &mut CS, + ) -> Result<(), SynthesisError> { + // Read in file as string + let unparsed_file = fs::read_to_string("simple.leo").expect("cannot read file"); + + // Parse the file using leo.pest + let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse"); + + // Build the abstract syntax tree + let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); + // println!("{:#?}", syntax_tree); + + let program = leo_program::Program::<'_, F>::from(syntax_tree); + println!(" compiled: {:#?}", program); + + let program = program.name("simple".into()); + leo_program::ResolvedProgram::generate_constraints(cs, program); + + Ok(()) + } +} + +fn main() { + let mut setup = Duration::new(0, 0); + let mut proving = Duration::new(0, 0); + let mut verifying = Duration::new(0, 0); + + let rng = &mut thread_rng(); + + let start = Instant::now(); + + let params = { + let circuit = Benchmark::::new(); + generate_random_parameters::(circuit, rng).unwrap() + }; + + let prepared_verifying_key = prepare_verifying_key::(¶ms.vk); + + setup += start.elapsed(); + + let start = Instant::now(); + let proof = { + let c = Benchmark::new(); + create_random_proof(c, ¶ms, rng).unwrap() + }; + + proving += start.elapsed(); + + // let _inputs: Vec<_> = [1u32; 1].to_vec(); + + let start = Instant::now(); + + let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap(); + + verifying += start.elapsed(); + + println!(" "); + println!(" Setup time : {:?} milliseconds", setup.as_millis()); + println!(" Prover time : {:?} milliseconds", proving.as_millis()); + println!( + " Verifier time : {:?} milliseconds", + verifying.as_millis() + ); + println!(" Verifier output : {}", is_success); + println!(" "); + + // let mut cs = TestConstraintSystem::::new(); + // + // println!("\n satisfied: {:?}", cs.is_satisfied()); + // + // println!( + // "\n number of constraints for input: {}", + // cs.num_constraints() + // ); + // +} From 8c5be763ff1cea5890e7b713b626d4f507ca4a93 Mon Sep 17 00:00:00 2001 From: howardwu Date: Thu, 23 Apr 2020 23:57:05 -0700 Subject: [PATCH 02/16] Compiler wip --- Cargo.lock | 125 ++++++++++++++++++++---- Cargo.toml | 18 ++-- compiler/Cargo.toml | 17 ---- compiler/src/lib.rs | 0 compiler/src/main.rs | 111 --------------------- hello_world/Leo.toml | 6 ++ leo/commands/cli.rs | 68 +++++++++++++ leo/commands/cli_types.rs | 12 +++ leo/commands/mod.rs | 6 ++ leo/commands/new/mod.rs | 2 + leo/commands/new/new.rs | 66 +++++++++++++ leo/errors/cli.rs | 31 ++++++ leo/errors/commands/mod.rs | 2 + leo/errors/commands/new.rs | 27 ++++++ leo/errors/manifest.rs | 24 +++++ leo/errors/mod.rs | 8 ++ leo/lib.rs | 6 ++ leo/main.rs | 143 ++++++++++++++++++++++++++++ leo/manifest.rs | 87 +++++++++++++++++ {compiler => leo}/simple.leo | 0 {compiler => leo}/simple_import.leo | 0 21 files changed, 606 insertions(+), 153 deletions(-) delete mode 100644 compiler/Cargo.toml delete mode 100644 compiler/src/lib.rs delete mode 100644 compiler/src/main.rs create mode 100644 hello_world/Leo.toml create mode 100644 leo/commands/cli.rs create mode 100644 leo/commands/cli_types.rs create mode 100644 leo/commands/mod.rs create mode 100644 leo/commands/new/mod.rs create mode 100644 leo/commands/new/new.rs create mode 100644 leo/errors/cli.rs create mode 100644 leo/errors/commands/mod.rs create mode 100644 leo/errors/commands/new.rs create mode 100644 leo/errors/manifest.rs create mode 100644 leo/errors/mod.rs create mode 100644 leo/lib.rs create mode 100644 leo/main.rs create mode 100644 leo/manifest.rs rename {compiler => leo}/simple.leo (100%) rename {compiler => leo}/simple_import.leo (100%) diff --git a/Cargo.lock b/Cargo.lock index ec4fb87a42..123be2b395 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,6 +233,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "colored" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -507,6 +518,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.8" @@ -591,17 +611,21 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" name = "leo" version = "0.1.0" dependencies = [ + "clap", + "colored", + "failure", "from-pest", - "lazy_static", - "pest", - "pest-ast", - "pest_derive", "rand 0.7.3", + "rand_core 0.5.1", + "serde", + "serde_json", "snarkos-algorithms", "snarkos-curves", "snarkos-errors", "snarkos-gadgets", "snarkos-models", + "structopt", + "toml", ] [[package]] @@ -618,20 +642,6 @@ dependencies = [ "snarkos-models", ] -[[package]] -name = "leo-compiler" -version = "0.1.0" -dependencies = [ - "from-pest", - "leo-program", - "rand 0.7.3", - "snarkos-algorithms", - "snarkos-curves", - "snarkos-errors", - "snarkos-gadgets", - "snarkos-models", -] - [[package]] name = "leo-program" version = "0.1.0" @@ -807,6 +817,32 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +[[package]] +name = "proc-macro-error" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.9", + "quote 1.0.3", + "syn 1.0.16", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" +dependencies = [ + "proc-macro2 1.0.9", + "quote 1.0.3", + "syn 1.0.16", + "syn-mid", + "version_check", +] + [[package]] name = "proc-macro2" version = "0.4.30" @@ -1159,6 +1195,9 @@ name = "serde" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_derive" @@ -1312,6 +1351,30 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "structopt" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863246aaf5ddd0d6928dfeb1a9ca65f505599e4e1b399935ef7e75107516b4ef" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d239ca4b13aee7a2142e6795cbd69e457665ff8037aed33b3effdc430d2f927a" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2 1.0.9", + "quote 1.0.3", + "syn 1.0.16", +] + [[package]] name = "subtle" version = "1.0.0" @@ -1340,6 +1403,17 @@ dependencies = [ "unicode-xid 0.2.0", ] +[[package]] +name = "syn-mid" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" +dependencies = [ + "proc-macro2 1.0.9", + "quote 1.0.3", + "syn 1.0.16", +] + [[package]] name = "synstructure" version = "0.12.3" @@ -1388,6 +1462,15 @@ dependencies = [ "crunchy 0.2.2", ] +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + [[package]] name = "typenum" version = "1.11.2" @@ -1412,6 +1495,12 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + [[package]] name = "unicode-width" version = "0.1.7" diff --git a/Cargo.toml b/Cargo.toml index 57626b0002..4d7760d007 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,14 +6,14 @@ edition = "2018" [lib] name = "leo" -path = "program/src/lib.rs" +path = "leo/lib.rs" [[bin]] name = "leo" -path = "benchmark/src/main.rs" +path = "leo/main.rs" [workspace] -members = [ "benchmark", "compiler", "program" ] +members = [ "benchmark", "program" ] [dependencies] snarkos-algorithms = { path = "../snarkOS/algorithms", version = "0.8.0" } @@ -22,9 +22,13 @@ snarkos-errors = { path = "../snarkOS/errors", version = "0.8.0" } snarkos-gadgets = { path = "../snarkOS/gadgets", version = "0.8.0" } snarkos-models = { path = "../snarkOS/models", version = "0.8.0" } +clap = { version = "2.33.0" } +colored = { version = "1.9" } +failure = { version = "0.1.5" } from-pest = { version = "0.3.1" } -lazy_static = { version = "1.3.0" } -pest = { version = "2.0" } -pest-ast = { version = "0.3.3" } -pest_derive = { version = "2.0" } rand = { version = "0.7" } +rand_core = { version = "0.5.1" } +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0" } +structopt = { version = "0.3.14" } +toml = { version = "0.5" } diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml deleted file mode 100644 index 63a514c6cf..0000000000 --- a/compiler/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "leo-compiler" -version = "0.1.0" -authors = ["The Aleo Team "] -edition = "2018" - -[dependencies] -leo-program = { path = "../program", version = "0.1.0" } - -snarkos-algorithms = { path = "../../snarkOS/algorithms", version = "0.8.0" } -snarkos-curves = { path = "../../snarkOS/curves", version = "0.8.0" } -snarkos-errors = { path = "../../snarkOS/errors", version = "0.8.0" } -snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0" } -snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" } - -from-pest = { version = "0.3.1" } -rand = { version = "0.7" } diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/compiler/src/main.rs b/compiler/src/main.rs deleted file mode 100644 index baea1f03d1..0000000000 --- a/compiler/src/main.rs +++ /dev/null @@ -1,111 +0,0 @@ -use leo_program::{self, ast}; - -use snarkos_algorithms::snark::{ - create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, -}; -use snarkos_curves::bls12_377::{Bls12_377, Fr}; -use snarkos_errors::gadgets::SynthesisError; -use snarkos_models::{ - curves::{Field, PrimeField}, - gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem}, -}; - -use from_pest::FromPest; -use rand::thread_rng; -use std::{ - fs, - marker::PhantomData, - time::{Duration, Instant}, -}; - -pub struct Benchmark { - _engine: PhantomData, -} - -impl Benchmark { - pub fn new() -> Self { - Self { - _engine: PhantomData, - } - } -} - -impl ConstraintSynthesizer for Benchmark { - fn generate_constraints>( - self, - cs: &mut CS, - ) -> Result<(), SynthesisError> { - // Read in file as string - let unparsed_file = fs::read_to_string("simple.leo").expect("cannot read file"); - - // Parse the file using leo.pest - let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse"); - - // Build the abstract syntax tree - let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); - // println!("{:#?}", syntax_tree); - - let program = leo_program::Program::<'_, F>::from(syntax_tree); - println!(" compiled: {:#?}", program); - - let program = program.name("simple".into()); - leo_program::ResolvedProgram::generate_constraints(cs, program); - - Ok(()) - } -} - -fn main() { - let mut setup = Duration::new(0, 0); - let mut proving = Duration::new(0, 0); - let mut verifying = Duration::new(0, 0); - - let rng = &mut thread_rng(); - - let start = Instant::now(); - - let params = { - let circuit = Benchmark::::new(); - generate_random_parameters::(circuit, rng).unwrap() - }; - - let prepared_verifying_key = prepare_verifying_key::(¶ms.vk); - - setup += start.elapsed(); - - let start = Instant::now(); - let proof = { - let c = Benchmark::new(); - create_random_proof(c, ¶ms, rng).unwrap() - }; - - proving += start.elapsed(); - - // let _inputs: Vec<_> = [1u32; 1].to_vec(); - - let start = Instant::now(); - - let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap(); - - verifying += start.elapsed(); - - println!(" "); - println!(" Setup time : {:?} milliseconds", setup.as_millis()); - println!(" Prover time : {:?} milliseconds", proving.as_millis()); - println!( - " Verifier time : {:?} milliseconds", - verifying.as_millis() - ); - println!(" Verifier output : {}", is_success); - println!(" "); - - // let mut cs = TestConstraintSystem::::new(); - // - // println!("\n satisfied: {:?}", cs.is_satisfied()); - // - // println!( - // "\n number of constraints for input: {}", - // cs.num_constraints() - // ); - // -} diff --git a/hello_world/Leo.toml b/hello_world/Leo.toml new file mode 100644 index 0000000000..936e861ed0 --- /dev/null +++ b/hello_world/Leo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello_world" +version = "0.1.0" +authors = "Satoshi Nakamoto" +license = "Apache/MIT" + diff --git a/leo/commands/cli.rs b/leo/commands/cli.rs new file mode 100644 index 0000000000..df9b988909 --- /dev/null +++ b/leo/commands/cli.rs @@ -0,0 +1,68 @@ +use crate::commands::cli_types::*; +use crate::errors::CLIError; + +use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; + +pub trait CLI { + type Options; + + const NAME: NameType; + const ABOUT: AboutType; + const FLAGS: &'static [FlagType]; + const OPTIONS: &'static [OptionType]; + const SUBCOMMANDS: &'static [SubCommandType]; + + #[cfg_attr(tarpaulin, skip)] + fn new<'a, 'b>() -> App<'a, 'b> { + let flags = &Self::FLAGS + .iter() + .map(|a| Arg::from_usage(a).global(true)) + .collect::>>(); + let options = &Self::OPTIONS + .iter() + .map(|a| match a.2.len() > 0 { + true => Arg::from_usage(a.0) + .conflicts_with_all(a.1) + .possible_values(a.2) + .requires_all(a.3), + false => Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3), + }) + .collect::>>(); + let subcommands = Self::SUBCOMMANDS + .iter() + .map(|s| { + SubCommand::with_name(s.0) + .about(s.1) + .args( + &s.2.iter() + .map(|a| match a.2.len() > 0 { + true => Arg::from_usage(a.0) + .conflicts_with_all(a.1) + .possible_values(a.2) + .requires_all(a.3), + false => Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3), + }) + .collect::>>(), + ) + .settings(s.3) + }) + .collect::>>(); + + SubCommand::with_name(Self::NAME) + .about(Self::ABOUT) + .settings(&[ + AppSettings::ColoredHelp, + AppSettings::DisableHelpSubcommand, + AppSettings::DisableVersion, + ]) + .args(flags) + .args(options) + .subcommands(subcommands) + } + + #[cfg_attr(tarpaulin, skip)] + fn parse(arguments: &ArgMatches) -> Result; + + #[cfg_attr(tarpaulin, skip)] + fn output(&mut self, options: Self::Options) -> Result<(), CLIError>; +} diff --git a/leo/commands/cli_types.rs b/leo/commands/cli_types.rs new file mode 100644 index 0000000000..41df6786d2 --- /dev/null +++ b/leo/commands/cli_types.rs @@ -0,0 +1,12 @@ +use clap::AppSettings; + +pub type NameType = &'static str; +pub type AboutType = &'static str; +pub type FlagType = &'static str; +pub type OptionType = ( + &'static str, + &'static [&'static str], + &'static [&'static str], + &'static [&'static str], +); +pub type SubCommandType = (NameType, AboutType, &'static [OptionType], &'static [AppSettings]); diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs new file mode 100644 index 0000000000..7bb1ce1ed0 --- /dev/null +++ b/leo/commands/mod.rs @@ -0,0 +1,6 @@ +#[cfg_attr(tarpaulin, skip)] +pub mod cli; +pub mod cli_types; + +pub mod new; +pub use self::new::*; diff --git a/leo/commands/new/mod.rs b/leo/commands/new/mod.rs new file mode 100644 index 0000000000..cbfcd90e50 --- /dev/null +++ b/leo/commands/new/mod.rs @@ -0,0 +1,2 @@ +pub mod new; +pub use self::new::*; diff --git a/leo/commands/new/new.rs b/leo/commands/new/new.rs new file mode 100644 index 0000000000..183361ecf7 --- /dev/null +++ b/leo/commands/new/new.rs @@ -0,0 +1,66 @@ +use crate::commands::{cli::*, cli_types::*}; +use crate::errors::{CLIError, ManifestError, NewError}; +use crate::manifest::Manifest; + +use clap::{ArgMatches, Values}; +use colored::*; +use rand::{rngs::StdRng, Rng}; +use rand_core::SeedableRng; +use serde::{Deserialize, Serialize}; +use serde_json::from_str; +use std::{fmt, fmt::Display, fs, str::FromStr}; +use std::path::PathBuf; +use structopt::StructOpt; + +#[derive(Debug, StructOpt)] +pub struct NewCommand { + #[structopt(parse(from_os_str))] + path: PathBuf, +} + +impl CLI for NewCommand { + type Options = (); + + const NAME: NameType = "new"; + const ABOUT: AboutType = "Creates a new Leo package (include -h for more options)"; + const FLAGS: &'static [FlagType] = &[]; + const OPTIONS: &'static [OptionType] = &[]; + const SUBCOMMANDS: &'static [SubCommandType] = &[]; + + #[cfg_attr(tarpaulin, skip)] + fn parse(arguments: &ArgMatches) -> Result { + let mut options = (); + // options.parse(arguments, &["count", "format", "json", "network"]); + // + // match arguments.subcommand() { + // ("hd", Some(arguments)) => { + // options.subcommand = Some("hd".into()); + // options.parse(arguments, &["count", "json", "network"]); + // options.parse(arguments, &["derivation", "language", "password", "word count"]); + // } + // _ => {} + // }; + + Ok(options) + } + + #[cfg_attr(tarpaulin, skip)] + fn output(&mut self, options: Self::Options) -> Result<(), CLIError> { + let package_name = self.path + .file_stem() + .ok_or_else(|| NewError::ProjectNameInvalid(self.path.as_os_str().to_owned()))? + .to_string_lossy() + .to_string(); + + if self.path.exists() { + return Err(NewError::DirectoryAlreadyExists(self.path.as_os_str().to_owned()).into()); + } + fs::create_dir_all(&self.path).map_err(|error| { + NewError::CreatingRootDirectory(self.path.as_os_str().to_owned(), error) + })?; + + Manifest::new(&package_name).write_to(&self.path).map_err(NewError::ManifestError)?; + + Ok(()) + } +} diff --git a/leo/errors/cli.rs b/leo/errors/cli.rs new file mode 100644 index 0000000000..af8eecf728 --- /dev/null +++ b/leo/errors/cli.rs @@ -0,0 +1,31 @@ +use crate::errors::{ManifestError, NewError}; + +#[derive(Debug, Fail)] +pub enum CLIError { + #[fail(display = "{}: {}", _0, _1)] + Crate(&'static str, String), + + #[fail(display = "{}", _0)] + ManifestError(ManifestError), + + #[fail(display = "{}", _0)] + NewError(NewError), +} + +impl From for CLIError { + fn from(error: ManifestError) -> Self { + CLIError::ManifestError(error) + } +} + +impl From for CLIError { + fn from(error: NewError) -> Self { + CLIError::NewError(error) + } +} + +impl From for CLIError { + fn from(error: serde_json::error::Error) -> Self { + CLIError::Crate("serde_json", format!("{:?}", error)) + } +} diff --git a/leo/errors/commands/mod.rs b/leo/errors/commands/mod.rs new file mode 100644 index 0000000000..cbfcd90e50 --- /dev/null +++ b/leo/errors/commands/mod.rs @@ -0,0 +1,2 @@ +pub mod new; +pub use self::new::*; diff --git a/leo/errors/commands/new.rs b/leo/errors/commands/new.rs new file mode 100644 index 0000000000..6be242b583 --- /dev/null +++ b/leo/errors/commands/new.rs @@ -0,0 +1,27 @@ +use crate::errors::ManifestError; + +use std::ffi::OsString; +use std::io; + +#[derive(Debug, Fail)] +pub enum NewError { + + #[fail(display = "root directory {:?} creating: {}", _0, _1)] + CreatingRootDirectory(OsString, io::Error), + + #[fail(display = "directory {:?} already exists", _0)] + DirectoryAlreadyExists(OsString), + + #[fail(display = "{}", _0)] + ManifestError(ManifestError), + + #[fail(display = "package name is missing - {:?}", _0)] + ProjectNameInvalid(OsString), + +} + +impl From for NewError { + fn from(error: ManifestError) -> Self { + NewError::ManifestError(error) + } +} diff --git a/leo/errors/manifest.rs b/leo/errors/manifest.rs new file mode 100644 index 0000000000..b62184b4c1 --- /dev/null +++ b/leo/errors/manifest.rs @@ -0,0 +1,24 @@ +use std::io; + +#[derive(Debug, Fail)] +pub enum ManifestError { + + #[fail(display = "`{}` creating: {}", _0, _1)] + Creating(&'static str, io::Error), + + #[fail(display = "`{}` metadata: {}", _0, _1)] + Metadata(&'static str, io::Error), + + #[fail(display = "`{}` opening: {}", _0, _1)] + Opening(&'static str, io::Error), + + #[fail(display = "`{}` parsing: {}", _0, _1)] + Parsing(&'static str, toml::de::Error), + + #[fail(display = "`{}` reading: {}", _0, _1)] + Reading(&'static str, io::Error), + + #[fail(display = "`{}` writing: {}", _0, _1)] + Writing(&'static str, io::Error), + +} diff --git a/leo/errors/mod.rs b/leo/errors/mod.rs new file mode 100644 index 0000000000..48cc961b38 --- /dev/null +++ b/leo/errors/mod.rs @@ -0,0 +1,8 @@ +pub mod cli; +pub use self::cli::*; + +pub mod commands; +pub use self::commands::*; + +pub mod manifest; +pub use self::manifest::*; diff --git a/leo/lib.rs b/leo/lib.rs new file mode 100644 index 0000000000..3ef9fb50aa --- /dev/null +++ b/leo/lib.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate failure; + +pub mod commands; +pub mod errors; +pub mod manifest; diff --git a/leo/main.rs b/leo/main.rs new file mode 100644 index 0000000000..086b87575f --- /dev/null +++ b/leo/main.rs @@ -0,0 +1,143 @@ +// use leo_program::{self, ast}; +// +// use snarkos_algorithms::snark::{ +// create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, +// }; +// use snarkos_curves::bls12_377::{Bls12_377, Fr}; +// use snarkos_errors::gadgets::SynthesisError; +// use snarkos_models::{ +// curves::{Field, PrimeField}, +// gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem}, +// }; +// +// use from_pest::FromPest; +// use rand::thread_rng; +// use std::{ +// fs, +// marker::PhantomData, +// time::{Duration, Instant}, +// }; +// +// pub struct Benchmark { +// _engine: PhantomData, +// } +// +// impl Benchmark { +// pub fn new() -> Self { +// Self { +// _engine: PhantomData, +// } +// } +// } +// +// impl ConstraintSynthesizer for Benchmark { +// fn generate_constraints>( +// self, +// cs: &mut CS, +// ) -> Result<(), SynthesisError> { +// // Read in file as string +// let unparsed_file = fs::read_to_string("simple.leo").expect("cannot read file"); +// +// // Parse the file using leo.pest +// let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse"); +// +// // Build the abstract syntax tree +// let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); +// // println!("{:#?}", syntax_tree); +// +// let program = leo_program::Program::<'_, F>::from(syntax_tree); +// println!(" compiled: {:#?}", program); +// +// let program = program.name("simple".into()); +// leo_program::ResolvedProgram::generate_constraints(cs, program); +// +// Ok(()) +// } +// } +// +// fn main() { +// let mut setup = Duration::new(0, 0); +// let mut proving = Duration::new(0, 0); +// let mut verifying = Duration::new(0, 0); +// +// let rng = &mut thread_rng(); +// +// let start = Instant::now(); +// +// let params = { +// let circuit = Benchmark::::new(); +// generate_random_parameters::(circuit, rng).unwrap() +// }; +// +// let prepared_verifying_key = prepare_verifying_key::(¶ms.vk); +// +// setup += start.elapsed(); +// +// let start = Instant::now(); +// let proof = { +// let c = Benchmark::new(); +// create_random_proof(c, ¶ms, rng).unwrap() +// }; +// +// proving += start.elapsed(); +// +// // let _inputs: Vec<_> = [1u32; 1].to_vec(); +// +// let start = Instant::now(); +// +// let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap(); +// +// verifying += start.elapsed(); +// +// println!(" "); +// println!(" Setup time : {:?} milliseconds", setup.as_millis()); +// println!(" Prover time : {:?} milliseconds", proving.as_millis()); +// println!( +// " Verifier time : {:?} milliseconds", +// verifying.as_millis() +// ); +// println!(" Verifier output : {}", is_success); +// println!(" "); +// +// // let mut cs = TestConstraintSystem::::new(); +// // +// // println!("\n satisfied: {:?}", cs.is_satisfied()); +// // +// // println!( +// // "\n number of constraints for input: {}", +// // cs.num_constraints() +// // ); +// // +// } + +use leo::commands::{cli::*, NewCommand}; +use leo::errors::CLIError; + +use clap::{App, AppSettings}; + +#[cfg_attr(tarpaulin, skip)] +fn main() -> Result<(), CLIError> { + let arguments = App::new("leo") + .version("v0.1.0") + .about("Leo compiler and package manager") + .author("The Aleo Team ") + .settings(&[ + AppSettings::ColoredHelp, + AppSettings::DisableHelpSubcommand, + AppSettings::DisableVersion, + AppSettings::SubcommandRequiredElseHelp, + ]) + .subcommands(vec![ + NewCommand::new(), + ]) + .set_term_width(0) + .get_matches(); + + + match arguments.subcommand() { + // ("new", Some(arguments)) => { + // NewCommand::().output(NewCommand::parse(arguments)?) + // }, + _ => unreachable!(), + } +} \ No newline at end of file diff --git a/leo/manifest.rs b/leo/manifest.rs new file mode 100644 index 0000000000..5e92322c0e --- /dev/null +++ b/leo/manifest.rs @@ -0,0 +1,87 @@ +use crate::errors::ManifestError; + +use failure::Fail; +use serde::Deserialize; +use std::convert::TryFrom; +use std::fs::File; +use std::io::Read; +use std::io::Write; +use std::path::PathBuf; + +pub static FILE_NAME_DEFAULT: &str = "Leo.toml"; + +#[derive(Deserialize)] +pub struct Package { + pub name: String, + pub version: String, +} + +#[derive(Deserialize)] +pub struct Manifest { + pub package: Package, +} + +impl Manifest { + pub fn new(package_name: &str) -> Self { + Self { + package: Package { + name: package_name.to_owned(), + version: "0.1.0".to_owned(), + }, + } + } + + pub fn exists_at(path: &PathBuf) -> bool { + let mut path = path.to_owned(); + if path.is_dir() { + path.push(PathBuf::from(FILE_NAME_DEFAULT)); + } + path.exists() + } + + pub fn write_to(self, path: &PathBuf) -> Result<(), ManifestError> { + let mut path = path.to_owned(); + if path.is_dir() { + path.push(PathBuf::from(FILE_NAME_DEFAULT)); + } + + let mut file = + File::create(&path).map_err(|error| ManifestError::Creating(FILE_NAME_DEFAULT, error))?; + file.write_all(self.template().as_bytes()) + .map_err(|error| ManifestError::Writing(FILE_NAME_DEFAULT, error)) + } + + fn template(&self) -> String { + format!( + r#"[package] +name = "{}" +version = "0.1.0" +"#, + self.package.name + ) + } +} + +impl TryFrom<&PathBuf> for Manifest { + type Error = ManifestError; + + fn try_from(path: &PathBuf) -> Result { + let mut path = path.to_owned(); + if path.is_dir() { + path.push(PathBuf::from(FILE_NAME_DEFAULT)); + } + + let mut file = + File::open(path).map_err(|error| ManifestError::Opening(FILE_NAME_DEFAULT, error))?; + let size = file + .metadata() + .map_err(|error| ManifestError::Metadata(FILE_NAME_DEFAULT, error))? + .len() as usize; + + let mut buffer = String::with_capacity(size); + file.read_to_string(&mut buffer) + .map_err(|error| ManifestError::Reading(FILE_NAME_DEFAULT, error))?; + + Ok(toml::from_str(&buffer).map_err(|error| ManifestError::Parsing(FILE_NAME_DEFAULT, error))?) + } +} diff --git a/compiler/simple.leo b/leo/simple.leo similarity index 100% rename from compiler/simple.leo rename to leo/simple.leo diff --git a/compiler/simple_import.leo b/leo/simple_import.leo similarity index 100% rename from compiler/simple_import.leo rename to leo/simple_import.leo From 93b47602dd4720ddc5d181018b9543596e9f4bb7 Mon Sep 17 00:00:00 2001 From: howardwu Date: Fri, 24 Apr 2020 21:15:33 -0700 Subject: [PATCH 03/16] Rename from new to init --- leo/commands/{new/new.rs => init/init.rs} | 6 +++--- leo/commands/init/mod.rs | 2 ++ leo/commands/mod.rs | 4 ++-- leo/commands/new/mod.rs | 2 -- leo/main.rs | 20 ++++++++++---------- 5 files changed, 17 insertions(+), 17 deletions(-) rename leo/commands/{new/new.rs => init/init.rs} (96%) create mode 100644 leo/commands/init/mod.rs delete mode 100644 leo/commands/new/mod.rs diff --git a/leo/commands/new/new.rs b/leo/commands/init/init.rs similarity index 96% rename from leo/commands/new/new.rs rename to leo/commands/init/init.rs index 183361ecf7..6505eeb710 100644 --- a/leo/commands/new/new.rs +++ b/leo/commands/init/init.rs @@ -13,15 +13,15 @@ use std::path::PathBuf; use structopt::StructOpt; #[derive(Debug, StructOpt)] -pub struct NewCommand { +pub struct InitCommand { #[structopt(parse(from_os_str))] path: PathBuf, } -impl CLI for NewCommand { +impl CLI for InitCommand { type Options = (); - const NAME: NameType = "new"; + const NAME: NameType = "init"; const ABOUT: AboutType = "Creates a new Leo package (include -h for more options)"; const FLAGS: &'static [FlagType] = &[]; const OPTIONS: &'static [OptionType] = &[]; diff --git a/leo/commands/init/mod.rs b/leo/commands/init/mod.rs new file mode 100644 index 0000000000..2d5b8771e7 --- /dev/null +++ b/leo/commands/init/mod.rs @@ -0,0 +1,2 @@ +pub mod init; +pub use self::init::*; diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs index 7bb1ce1ed0..dda8b56111 100644 --- a/leo/commands/mod.rs +++ b/leo/commands/mod.rs @@ -2,5 +2,5 @@ pub mod cli; pub mod cli_types; -pub mod new; -pub use self::new::*; +pub mod init; +pub use self::init::*; diff --git a/leo/commands/new/mod.rs b/leo/commands/new/mod.rs deleted file mode 100644 index cbfcd90e50..0000000000 --- a/leo/commands/new/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod new; -pub use self::new::*; diff --git a/leo/main.rs b/leo/main.rs index 086b87575f..a04b94bb1c 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -23,7 +23,7 @@ // } // // impl Benchmark { -// pub fn new() -> Self { +// pub fn init() -> Self { // Self { // _engine: PhantomData, // } @@ -56,16 +56,16 @@ // } // // fn main() { -// let mut setup = Duration::new(0, 0); -// let mut proving = Duration::new(0, 0); -// let mut verifying = Duration::new(0, 0); +// let mut setup = Duration::init(0, 0); +// let mut proving = Duration::init(0, 0); +// let mut verifying = Duration::init(0, 0); // // let rng = &mut thread_rng(); // // let start = Instant::now(); // // let params = { -// let circuit = Benchmark::::new(); +// let circuit = Benchmark::::init(); // generate_random_parameters::(circuit, rng).unwrap() // }; // @@ -75,7 +75,7 @@ // // let start = Instant::now(); // let proof = { -// let c = Benchmark::new(); +// let c = Benchmark::init(); // create_random_proof(c, ¶ms, rng).unwrap() // }; // @@ -99,7 +99,7 @@ // println!(" Verifier output : {}", is_success); // println!(" "); // -// // let mut cs = TestConstraintSystem::::new(); +// // let mut cs = TestConstraintSystem::::init(); // // // // println!("\n satisfied: {:?}", cs.is_satisfied()); // // @@ -110,7 +110,7 @@ // // // } -use leo::commands::{cli::*, NewCommand}; +use leo::commands::{cli::*, InitCommand}; use leo::errors::CLIError; use clap::{App, AppSettings}; @@ -128,14 +128,14 @@ fn main() -> Result<(), CLIError> { AppSettings::SubcommandRequiredElseHelp, ]) .subcommands(vec![ - NewCommand::new(), + InitCommand::new(), ]) .set_term_width(0) .get_matches(); match arguments.subcommand() { - // ("new", Some(arguments)) => { + // ("init", Some(arguments)) => { // NewCommand::().output(NewCommand::parse(arguments)?) // }, _ => unreachable!(), From 83065845dfdd119807cf59a1112fe1720e7f2bf1 Mon Sep 17 00:00:00 2001 From: howardwu Date: Fri, 24 Apr 2020 23:56:26 -0700 Subject: [PATCH 04/16] Complete command --- leo/{commands => }/cli.rs | 4 +- leo/{commands => }/cli_types.rs | 0 leo/commands/init.rs | 63 +++++++++++++++++++++++ leo/commands/init/init.rs | 66 ------------------------- leo/commands/init/mod.rs | 2 - leo/commands/mod.rs | 4 -- leo/directories/mod.rs | 2 + leo/directories/source.rs | 61 +++++++++++++++++++++++ leo/errors/cli.rs | 27 +++++++--- leo/errors/commands/{new.rs => init.rs} | 13 +++-- leo/errors/commands/mod.rs | 4 +- leo/errors/directory/mod.rs | 2 + leo/errors/directory/source.rs | 27 ++++++++++ leo/errors/mod.rs | 3 ++ leo/lib.rs | 4 ++ leo/main.rs | 8 +-- leo/manifest.rs | 1 - 17 files changed, 199 insertions(+), 92 deletions(-) rename leo/{commands => }/cli.rs (95%) rename leo/{commands => }/cli_types.rs (100%) create mode 100644 leo/commands/init.rs delete mode 100644 leo/commands/init/init.rs delete mode 100644 leo/commands/init/mod.rs create mode 100644 leo/directories/mod.rs create mode 100644 leo/directories/source.rs rename leo/errors/commands/{new.rs => init.rs} (58%) create mode 100644 leo/errors/directory/mod.rs create mode 100644 leo/errors/directory/source.rs diff --git a/leo/commands/cli.rs b/leo/cli.rs similarity index 95% rename from leo/commands/cli.rs rename to leo/cli.rs index df9b988909..4de644a0a9 100644 --- a/leo/commands/cli.rs +++ b/leo/cli.rs @@ -1,4 +1,4 @@ -use crate::commands::cli_types::*; +use crate::cli_types::*; use crate::errors::CLIError; use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; @@ -64,5 +64,5 @@ pub trait CLI { fn parse(arguments: &ArgMatches) -> Result; #[cfg_attr(tarpaulin, skip)] - fn output(&mut self, options: Self::Options) -> Result<(), CLIError>; + fn output(options: Self::Options) -> Result<(), CLIError>; } diff --git a/leo/commands/cli_types.rs b/leo/cli_types.rs similarity index 100% rename from leo/commands/cli_types.rs rename to leo/cli_types.rs diff --git a/leo/commands/init.rs b/leo/commands/init.rs new file mode 100644 index 0000000000..5b7a5be6f9 --- /dev/null +++ b/leo/commands/init.rs @@ -0,0 +1,63 @@ +use crate::{cli::*, cli_types::*}; +use crate::directories::SourceDirectory; +use crate::errors::{CLIError, InitError}; +use crate::manifest::Manifest; + +use clap::ArgMatches; +use std::env::current_dir; + +#[derive(Debug)] +pub struct InitCommand; + +impl CLI for InitCommand { + type Options = Option; + + const NAME: NameType = "init"; + const ABOUT: AboutType = "Creates a new Leo package (include -h for more options)"; + const FLAGS: &'static [FlagType] = &[]; + const OPTIONS: &'static [OptionType] = &[]; + const SUBCOMMANDS: &'static [SubCommandType] = &[]; + + #[cfg_attr(tarpaulin, skip)] + fn parse(_arguments: &ArgMatches) -> Result { + Ok(None) + } + + #[cfg_attr(tarpaulin, skip)] + fn output(options: Self::Options) -> Result<(), CLIError> { + let name = options; + let path = current_dir()?; + + // Derive the package name + let package_name = match name { + Some(name) => name, + None => path + .file_stem() + .ok_or_else(|| InitError::ProjectNameInvalid(path.as_os_str().to_owned()))? + .to_string_lossy() + .to_string(), + }; + + // Verify the directory exists + if !path.exists() { + return Err(InitError::DirectoryDoesNotExist(path.as_os_str().to_owned()).into()); + } + + // Verify a manifest file does not already exist + if Manifest::exists_at(&path) { + return Err(InitError::PackageAlreadyExists(path.as_os_str().to_owned()).into()); + } + Manifest::new(&package_name).write_to(&path)?; + + // Create the source directory + SourceDirectory::create(&path)?; + + // if !MainFile::exists_at(&path) { + // MainFile::new(&package_name) + // .write_to(&path) + // .map_err(Error::MainFile)?; + // } + + Ok(()) + } +} diff --git a/leo/commands/init/init.rs b/leo/commands/init/init.rs deleted file mode 100644 index 6505eeb710..0000000000 --- a/leo/commands/init/init.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::commands::{cli::*, cli_types::*}; -use crate::errors::{CLIError, ManifestError, NewError}; -use crate::manifest::Manifest; - -use clap::{ArgMatches, Values}; -use colored::*; -use rand::{rngs::StdRng, Rng}; -use rand_core::SeedableRng; -use serde::{Deserialize, Serialize}; -use serde_json::from_str; -use std::{fmt, fmt::Display, fs, str::FromStr}; -use std::path::PathBuf; -use structopt::StructOpt; - -#[derive(Debug, StructOpt)] -pub struct InitCommand { - #[structopt(parse(from_os_str))] - path: PathBuf, -} - -impl CLI for InitCommand { - type Options = (); - - const NAME: NameType = "init"; - const ABOUT: AboutType = "Creates a new Leo package (include -h for more options)"; - const FLAGS: &'static [FlagType] = &[]; - const OPTIONS: &'static [OptionType] = &[]; - const SUBCOMMANDS: &'static [SubCommandType] = &[]; - - #[cfg_attr(tarpaulin, skip)] - fn parse(arguments: &ArgMatches) -> Result { - let mut options = (); - // options.parse(arguments, &["count", "format", "json", "network"]); - // - // match arguments.subcommand() { - // ("hd", Some(arguments)) => { - // options.subcommand = Some("hd".into()); - // options.parse(arguments, &["count", "json", "network"]); - // options.parse(arguments, &["derivation", "language", "password", "word count"]); - // } - // _ => {} - // }; - - Ok(options) - } - - #[cfg_attr(tarpaulin, skip)] - fn output(&mut self, options: Self::Options) -> Result<(), CLIError> { - let package_name = self.path - .file_stem() - .ok_or_else(|| NewError::ProjectNameInvalid(self.path.as_os_str().to_owned()))? - .to_string_lossy() - .to_string(); - - if self.path.exists() { - return Err(NewError::DirectoryAlreadyExists(self.path.as_os_str().to_owned()).into()); - } - fs::create_dir_all(&self.path).map_err(|error| { - NewError::CreatingRootDirectory(self.path.as_os_str().to_owned(), error) - })?; - - Manifest::new(&package_name).write_to(&self.path).map_err(NewError::ManifestError)?; - - Ok(()) - } -} diff --git a/leo/commands/init/mod.rs b/leo/commands/init/mod.rs deleted file mode 100644 index 2d5b8771e7..0000000000 --- a/leo/commands/init/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod init; -pub use self::init::*; diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs index dda8b56111..2d5b8771e7 100644 --- a/leo/commands/mod.rs +++ b/leo/commands/mod.rs @@ -1,6 +1,2 @@ -#[cfg_attr(tarpaulin, skip)] -pub mod cli; -pub mod cli_types; - pub mod init; pub use self::init::*; diff --git a/leo/directories/mod.rs b/leo/directories/mod.rs new file mode 100644 index 0000000000..6dd9d696d3 --- /dev/null +++ b/leo/directories/mod.rs @@ -0,0 +1,2 @@ +pub mod source; +pub use self::source::*; diff --git a/leo/directories/source.rs b/leo/directories/source.rs new file mode 100644 index 0000000000..e3c2c07436 --- /dev/null +++ b/leo/directories/source.rs @@ -0,0 +1,61 @@ +use crate::errors::SourceDirectoryError; + +use std::fs; +use std::path::PathBuf; + +pub(self) static DIRECTORY_NAME_DEFAULT: &str = "src/"; + +static SOURCE_FILE_EXTENSION_DEFAULT: &str = "leo"; + +pub struct SourceDirectory; + +impl SourceDirectory { + /// Creates a directory at the provided path with the default directory name. + pub fn create(path: &PathBuf) -> Result<(), SourceDirectoryError> { + let mut path = path.to_owned(); + if path.is_dir() && !path.ends_with(DIRECTORY_NAME_DEFAULT) { + path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT)); + } + + fs::create_dir_all(&path).map_err(SourceDirectoryError::Creating) + } + + /// Returns a list of files in the source directory. + pub fn files(path: &PathBuf) -> Result, SourceDirectoryError> { + let mut path = path.to_owned(); + path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT)); + let directory = fs::read_dir(&path).map_err(SourceDirectoryError::Reading)?; + + let mut file_paths = Vec::new(); + for file_entry in directory.into_iter() { + let file_entry = file_entry.map_err(SourceDirectoryError::GettingFileEntry)?; + let file_path = file_entry.path(); + + // Verify that the entry is structured as a valid file + let file_type = file_entry + .file_type() + .map_err(|error| SourceDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?; + if !file_type.is_file() { + return Err(SourceDirectoryError::InvalidFileType( + file_path.as_os_str().to_owned(), + file_type, + )); + } + + // Verify that the file has the default file extension + let file_extension = file_path + .extension() + .ok_or_else(|| SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?; + if file_extension != SOURCE_FILE_EXTENSION_DEFAULT { + return Err(SourceDirectoryError::InvalidFileExtension( + file_path.as_os_str().to_owned(), + file_extension.to_owned(), + )); + } + + file_paths.push(file_path); + } + + Ok(file_paths) + } +} diff --git a/leo/errors/cli.rs b/leo/errors/cli.rs index af8eecf728..a40e3785b5 100644 --- a/leo/errors/cli.rs +++ b/leo/errors/cli.rs @@ -1,4 +1,4 @@ -use crate::errors::{ManifestError, NewError}; +use crate::errors::{ManifestError, InitError, SourceDirectoryError}; #[derive(Debug, Fail)] pub enum CLIError { @@ -9,7 +9,10 @@ pub enum CLIError { ManifestError(ManifestError), #[fail(display = "{}", _0)] - NewError(NewError), + InitError(InitError), + + #[fail(display = "{}", _0)] + SourceDirectoryError(SourceDirectoryError), } impl From for CLIError { @@ -18,14 +21,26 @@ impl From for CLIError { } } -impl From for CLIError { - fn from(error: NewError) -> Self { - CLIError::NewError(error) +impl From for CLIError { + fn from(error: InitError) -> Self { + CLIError::InitError(error) + } +} + +impl From for CLIError { + fn from(error: SourceDirectoryError) -> Self { + CLIError::SourceDirectoryError(error) } } impl From for CLIError { fn from(error: serde_json::error::Error) -> Self { - CLIError::Crate("serde_json", format!("{:?}", error)) + CLIError::Crate("serde_json", format!("{}", error)) + } +} + +impl From for CLIError { + fn from(error: std::io::Error) -> Self { + CLIError::Crate("std::io", format!("{}", error)) } } diff --git a/leo/errors/commands/new.rs b/leo/errors/commands/init.rs similarity index 58% rename from leo/errors/commands/new.rs rename to leo/errors/commands/init.rs index 6be242b583..d721c5a80f 100644 --- a/leo/errors/commands/new.rs +++ b/leo/errors/commands/init.rs @@ -4,24 +4,27 @@ use std::ffi::OsString; use std::io; #[derive(Debug, Fail)] -pub enum NewError { +pub enum InitError { #[fail(display = "root directory {:?} creating: {}", _0, _1)] CreatingRootDirectory(OsString, io::Error), - #[fail(display = "directory {:?} already exists", _0)] - DirectoryAlreadyExists(OsString), + #[fail(display = "directory {:?} does not exist", _0)] + DirectoryDoesNotExist(OsString), #[fail(display = "{}", _0)] ManifestError(ManifestError), + #[fail(display = "package at path {:?} already exists", _0)] + PackageAlreadyExists(OsString), + #[fail(display = "package name is missing - {:?}", _0)] ProjectNameInvalid(OsString), } -impl From for NewError { +impl From for InitError { fn from(error: ManifestError) -> Self { - NewError::ManifestError(error) + InitError::ManifestError(error) } } diff --git a/leo/errors/commands/mod.rs b/leo/errors/commands/mod.rs index cbfcd90e50..2d5b8771e7 100644 --- a/leo/errors/commands/mod.rs +++ b/leo/errors/commands/mod.rs @@ -1,2 +1,2 @@ -pub mod new; -pub use self::new::*; +pub mod init; +pub use self::init::*; diff --git a/leo/errors/directory/mod.rs b/leo/errors/directory/mod.rs new file mode 100644 index 0000000000..6dd9d696d3 --- /dev/null +++ b/leo/errors/directory/mod.rs @@ -0,0 +1,2 @@ +pub mod source; +pub use self::source::*; diff --git a/leo/errors/directory/source.rs b/leo/errors/directory/source.rs new file mode 100644 index 0000000000..2ac823ad3b --- /dev/null +++ b/leo/errors/directory/source.rs @@ -0,0 +1,27 @@ +use std::{ffi::OsString, fs::FileType, io}; + +#[derive(Debug, Fail)] +pub enum SourceDirectoryError { + + #[fail(display = "creating: {}", _0)] + Creating(io::Error), + + #[fail(display = "file entry getting: {}", _0)] + GettingFileEntry(io::Error), + + #[fail(display = "file {:?} extension getting", _0)] + GettingFileExtension(OsString), + + #[fail(display = "file {:?} type getting: {}", _0, _1)] + GettingFileType(OsString, io::Error), + + #[fail(display = "invalid file {:?} extension: {:?}", _0, _1)] + InvalidFileExtension(OsString, OsString), + + #[fail(display = "invalid file {:?} type: {:?}", _0, _1)] + InvalidFileType(OsString, FileType), + + #[fail(display = "reading: {}", _0)] + Reading(io::Error), + +} diff --git a/leo/errors/mod.rs b/leo/errors/mod.rs index 48cc961b38..3eec4a7fe6 100644 --- a/leo/errors/mod.rs +++ b/leo/errors/mod.rs @@ -4,5 +4,8 @@ pub use self::cli::*; pub mod commands; pub use self::commands::*; +pub mod directory; +pub use self::directory::*; + pub mod manifest; pub use self::manifest::*; diff --git a/leo/lib.rs b/leo/lib.rs index 3ef9fb50aa..942ef4ddff 100644 --- a/leo/lib.rs +++ b/leo/lib.rs @@ -1,6 +1,10 @@ #[macro_use] extern crate failure; +#[cfg_attr(tarpaulin, skip)] +pub mod cli; +pub mod cli_types; pub mod commands; +pub mod directories; pub mod errors; pub mod manifest; diff --git a/leo/main.rs b/leo/main.rs index a04b94bb1c..bf3e8110d2 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -110,7 +110,7 @@ // // // } -use leo::commands::{cli::*, InitCommand}; +use leo::{cli::*, commands::*}; use leo::errors::CLIError; use clap::{App, AppSettings}; @@ -135,9 +135,9 @@ fn main() -> Result<(), CLIError> { match arguments.subcommand() { - // ("init", Some(arguments)) => { - // NewCommand::().output(NewCommand::parse(arguments)?) - // }, + ("init", Some(arguments)) => { + InitCommand::output(InitCommand::parse(arguments)?) + }, _ => unreachable!(), } } \ No newline at end of file diff --git a/leo/manifest.rs b/leo/manifest.rs index 5e92322c0e..61e885d853 100644 --- a/leo/manifest.rs +++ b/leo/manifest.rs @@ -1,6 +1,5 @@ use crate::errors::ManifestError; -use failure::Fail; use serde::Deserialize; use std::convert::TryFrom; use std::fs::File; From fb4e5ee8e133876ab88169f603422cf1b81e7d52 Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 00:19:20 -0700 Subject: [PATCH 05/16] Adds main function with --- leo/commands/init.rs | 10 +++---- leo/directories/source.rs | 2 +- leo/errors/cli.rs | 27 ++++++++++++------ leo/errors/files/main.rs | 9 ++++++ leo/errors/files/mod.rs | 2 ++ leo/errors/mod.rs | 3 ++ leo/files/main.rs | 59 +++++++++++++++++++++++++++++++++++++++ leo/files/mod.rs | 2 ++ leo/lib.rs | 1 + 9 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 leo/errors/files/main.rs create mode 100644 leo/errors/files/mod.rs create mode 100644 leo/files/main.rs create mode 100644 leo/files/mod.rs diff --git a/leo/commands/init.rs b/leo/commands/init.rs index 5b7a5be6f9..27014b8d0c 100644 --- a/leo/commands/init.rs +++ b/leo/commands/init.rs @@ -1,6 +1,7 @@ use crate::{cli::*, cli_types::*}; use crate::directories::SourceDirectory; use crate::errors::{CLIError, InitError}; +use crate::files::MainFile; use crate::manifest::Manifest; use clap::ArgMatches; @@ -52,11 +53,10 @@ impl CLI for InitCommand { // Create the source directory SourceDirectory::create(&path)?; - // if !MainFile::exists_at(&path) { - // MainFile::new(&package_name) - // .write_to(&path) - // .map_err(Error::MainFile)?; - // } + // Create the main file in the source directory + if !MainFile::exists_at(&path) { + MainFile::new(&package_name).write_to(&path)?; + } Ok(()) } diff --git a/leo/directories/source.rs b/leo/directories/source.rs index e3c2c07436..94fe516e3c 100644 --- a/leo/directories/source.rs +++ b/leo/directories/source.rs @@ -3,7 +3,7 @@ use crate::errors::SourceDirectoryError; use std::fs; use std::path::PathBuf; -pub(self) static DIRECTORY_NAME_DEFAULT: &str = "src/"; +pub(crate) static DIRECTORY_NAME_DEFAULT: &str = "src/"; static SOURCE_FILE_EXTENSION_DEFAULT: &str = "leo"; diff --git a/leo/errors/cli.rs b/leo/errors/cli.rs index a40e3785b5..81cfe8b92b 100644 --- a/leo/errors/cli.rs +++ b/leo/errors/cli.rs @@ -1,4 +1,4 @@ -use crate::errors::{ManifestError, InitError, SourceDirectoryError}; +use crate::errors::{InitError, MainFileError, ManifestError, SourceDirectoryError}; #[derive(Debug, Fail)] pub enum CLIError { @@ -6,27 +6,36 @@ pub enum CLIError { Crate(&'static str, String), #[fail(display = "{}", _0)] - ManifestError(ManifestError), + InitError(InitError), #[fail(display = "{}", _0)] - InitError(InitError), + MainFileError(MainFileError), + + #[fail(display = "{}", _0)] + ManifestError(ManifestError), #[fail(display = "{}", _0)] SourceDirectoryError(SourceDirectoryError), } -impl From for CLIError { - fn from(error: ManifestError) -> Self { - CLIError::ManifestError(error) - } -} - impl From for CLIError { fn from(error: InitError) -> Self { CLIError::InitError(error) } } +impl From for CLIError { + fn from(error: MainFileError) -> Self { + CLIError::MainFileError(error) + } +} + +impl From for CLIError { + fn from(error: ManifestError) -> Self { + CLIError::ManifestError(error) + } +} + impl From for CLIError { fn from(error: SourceDirectoryError) -> Self { CLIError::SourceDirectoryError(error) diff --git a/leo/errors/files/main.rs b/leo/errors/files/main.rs new file mode 100644 index 0000000000..915a7bf014 --- /dev/null +++ b/leo/errors/files/main.rs @@ -0,0 +1,9 @@ +use std::io; + +#[derive(Debug, Fail)] +pub enum MainFileError { + #[fail(display = "creating: {}", _0)] + Creating(io::Error), + #[fail(display = "writing: {}", _0)] + Writing(io::Error), +} diff --git a/leo/errors/files/mod.rs b/leo/errors/files/mod.rs new file mode 100644 index 0000000000..959a903935 --- /dev/null +++ b/leo/errors/files/mod.rs @@ -0,0 +1,2 @@ +pub mod main; +pub use self::main::*; diff --git a/leo/errors/mod.rs b/leo/errors/mod.rs index 3eec4a7fe6..d642b7be32 100644 --- a/leo/errors/mod.rs +++ b/leo/errors/mod.rs @@ -7,5 +7,8 @@ pub use self::commands::*; pub mod directory; pub use self::directory::*; +pub mod files; +pub use self::files::*; + pub mod manifest; pub use self::manifest::*; diff --git a/leo/files/main.rs b/leo/files/main.rs new file mode 100644 index 0000000000..9aba8768ef --- /dev/null +++ b/leo/files/main.rs @@ -0,0 +1,59 @@ +//! The `main.leo` file. + +use crate::directories::source::DIRECTORY_NAME_DEFAULT; +use crate::errors::MainFileError; + +use serde::Deserialize; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +pub static FILE_NAME_DEFAULT: &str = "main.leo"; + +#[derive(Deserialize)] +pub struct MainFile { + pub package_name: String, +} + +impl MainFile { + pub fn new(package_name: &str) -> Self { + Self { package_name: package_name.to_string() } + } + + pub fn exists_at(path: &PathBuf) -> bool { + let mut path = path.to_owned(); + if path.is_dir() { + if !path.ends_with(DIRECTORY_NAME_DEFAULT) { + path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT)); + } + path.push(PathBuf::from(FILE_NAME_DEFAULT)); + } + path.exists() + } + + pub fn write_to(self, path: &PathBuf) -> Result<(), MainFileError> { + let mut path = path.to_owned(); + if path.is_dir() { + if !path.ends_with(DIRECTORY_NAME_DEFAULT) { + path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT)); + } + path.push(PathBuf::from(FILE_NAME_DEFAULT)); + } + + let mut file = File::create(&path).map_err(MainFileError::Creating)?; + file.write_all(self.template().as_bytes()) + .map_err(MainFileError::Writing) + } + + fn template(&self) -> String { + format!( + r#"// The '{}' main function. +function main() -> (u32) {{ + a = 1 + 1 + return a +}} +"#, + self.package_name + ) + } +} \ No newline at end of file diff --git a/leo/files/mod.rs b/leo/files/mod.rs new file mode 100644 index 0000000000..959a903935 --- /dev/null +++ b/leo/files/mod.rs @@ -0,0 +1,2 @@ +pub mod main; +pub use self::main::*; diff --git a/leo/lib.rs b/leo/lib.rs index 942ef4ddff..9342eecad8 100644 --- a/leo/lib.rs +++ b/leo/lib.rs @@ -7,4 +7,5 @@ pub mod cli_types; pub mod commands; pub mod directories; pub mod errors; +pub mod files; pub mod manifest; From 2f1e5acec4be2a3a5e0ae3e2e53acf9964163358 Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 00:25:35 -0700 Subject: [PATCH 06/16] Cleanup --- leo/errors/cli.rs | 2 ++ leo/errors/files/main.rs | 12 ++++++++++++ leo/files/main.rs | 5 ++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/leo/errors/cli.rs b/leo/errors/cli.rs index 81cfe8b92b..fb3c38655b 100644 --- a/leo/errors/cli.rs +++ b/leo/errors/cli.rs @@ -2,6 +2,7 @@ use crate::errors::{InitError, MainFileError, ManifestError, SourceDirectoryErro #[derive(Debug, Fail)] pub enum CLIError { + #[fail(display = "{}: {}", _0, _1)] Crate(&'static str, String), @@ -16,6 +17,7 @@ pub enum CLIError { #[fail(display = "{}", _0)] SourceDirectoryError(SourceDirectoryError), + } impl From for CLIError { diff --git a/leo/errors/files/main.rs b/leo/errors/files/main.rs index 915a7bf014..e7c5a48de3 100644 --- a/leo/errors/files/main.rs +++ b/leo/errors/files/main.rs @@ -2,8 +2,20 @@ use std::io; #[derive(Debug, Fail)] pub enum MainFileError { + + #[fail(display = "{}: {}", _0, _1)] + Crate(&'static str, String), + #[fail(display = "creating: {}", _0)] Creating(io::Error), + #[fail(display = "writing: {}", _0)] Writing(io::Error), + +} + +impl From for MainFileError { + fn from(error: std::io::Error) -> Self { + MainFileError::Crate("std::io", format!("{}", error)) + } } diff --git a/leo/files/main.rs b/leo/files/main.rs index 9aba8768ef..a1c225205d 100644 --- a/leo/files/main.rs +++ b/leo/files/main.rs @@ -40,9 +40,8 @@ impl MainFile { path.push(PathBuf::from(FILE_NAME_DEFAULT)); } - let mut file = File::create(&path).map_err(MainFileError::Creating)?; - file.write_all(self.template().as_bytes()) - .map_err(MainFileError::Writing) + let mut file = File::create(&path)?; + Ok(file.write_all(self.template().as_bytes())?) } fn template(&self) -> String { From dcb5f542a804674f91ec3f60515bc10507eb4753 Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 00:35:11 -0700 Subject: [PATCH 07/16] Adds input directory to --- leo/commands/init.rs | 5 ++- leo/directories/inputs.rs | 61 ++++++++++++++++++++++++++++++++++ leo/directories/mod.rs | 3 ++ leo/directories/source.rs | 12 +++---- leo/errors/cli.rs | 11 +++++- leo/errors/directory/inputs.rs | 27 +++++++++++++++ leo/errors/directory/mod.rs | 3 ++ leo/files/main.rs | 10 +++--- 8 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 leo/directories/inputs.rs create mode 100644 leo/errors/directory/inputs.rs diff --git a/leo/commands/init.rs b/leo/commands/init.rs index 27014b8d0c..7050757856 100644 --- a/leo/commands/init.rs +++ b/leo/commands/init.rs @@ -1,5 +1,5 @@ use crate::{cli::*, cli_types::*}; -use crate::directories::SourceDirectory; +use crate::directories::{InputsDirectory, SourceDirectory}; use crate::errors::{CLIError, InitError}; use crate::files::MainFile; use crate::manifest::Manifest; @@ -53,6 +53,9 @@ impl CLI for InitCommand { // Create the source directory SourceDirectory::create(&path)?; + // Create the inputs directory + InputsDirectory::create(&path)?; + // Create the main file in the source directory if !MainFile::exists_at(&path) { MainFile::new(&package_name).write_to(&path)?; diff --git a/leo/directories/inputs.rs b/leo/directories/inputs.rs new file mode 100644 index 0000000000..0982527c76 --- /dev/null +++ b/leo/directories/inputs.rs @@ -0,0 +1,61 @@ +use crate::errors::InputsDirectoryError; + +use std::fs; +use std::path::PathBuf; + +pub(crate) static INPUTS_DIRECTORY_NAME: &str = "inputs/"; + +static INPUTS_FILE_EXTENSION: &str = "leo.in"; + +pub struct InputsDirectory; + +impl InputsDirectory { + /// Creates a directory at the provided path with the default directory name. + pub fn create(path: &PathBuf) -> Result<(), InputsDirectoryError> { + let mut path = path.to_owned(); + if path.is_dir() && !path.ends_with(INPUTS_DIRECTORY_NAME) { + path.push(PathBuf::from(INPUTS_DIRECTORY_NAME)); + } + + fs::create_dir_all(&path).map_err(InputsDirectoryError::Creating) + } + + /// Returns a list of files in the source directory. + pub fn files(path: &PathBuf) -> Result, InputsDirectoryError> { + let mut path = path.to_owned(); + path.push(PathBuf::from(INPUTS_DIRECTORY_NAME)); + let directory = fs::read_dir(&path).map_err(InputsDirectoryError::Reading)?; + + let mut file_paths = Vec::new(); + for file_entry in directory.into_iter() { + let file_entry = file_entry.map_err(InputsDirectoryError::GettingFileEntry)?; + let file_path = file_entry.path(); + + // Verify that the entry is structured as a valid file + let file_type = file_entry + .file_type() + .map_err(|error| InputsDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?; + if !file_type.is_file() { + return Err(InputsDirectoryError::InvalidFileType( + file_path.as_os_str().to_owned(), + file_type, + )); + } + + // Verify that the file has the default file extension + let file_extension = file_path + .extension() + .ok_or_else(|| InputsDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?; + if file_extension != INPUTS_FILE_EXTENSION { + return Err(InputsDirectoryError::InvalidFileExtension( + file_path.as_os_str().to_owned(), + file_extension.to_owned(), + )); + } + + file_paths.push(file_path); + } + + Ok(file_paths) + } +} diff --git a/leo/directories/mod.rs b/leo/directories/mod.rs index 6dd9d696d3..cbc68327b5 100644 --- a/leo/directories/mod.rs +++ b/leo/directories/mod.rs @@ -1,2 +1,5 @@ +pub mod inputs; +pub use self::inputs::*; + pub mod source; pub use self::source::*; diff --git a/leo/directories/source.rs b/leo/directories/source.rs index 94fe516e3c..eb9bb78c37 100644 --- a/leo/directories/source.rs +++ b/leo/directories/source.rs @@ -3,9 +3,9 @@ use crate::errors::SourceDirectoryError; use std::fs; use std::path::PathBuf; -pub(crate) static DIRECTORY_NAME_DEFAULT: &str = "src/"; +pub(crate) static SOURCE_DIRECTORY_NAME: &str = "src/"; -static SOURCE_FILE_EXTENSION_DEFAULT: &str = "leo"; +static SOURCE_FILE_EXTENSION: &str = "leo"; pub struct SourceDirectory; @@ -13,8 +13,8 @@ impl SourceDirectory { /// Creates a directory at the provided path with the default directory name. pub fn create(path: &PathBuf) -> Result<(), SourceDirectoryError> { let mut path = path.to_owned(); - if path.is_dir() && !path.ends_with(DIRECTORY_NAME_DEFAULT) { - path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT)); + if path.is_dir() && !path.ends_with(SOURCE_DIRECTORY_NAME) { + path.push(PathBuf::from(SOURCE_DIRECTORY_NAME)); } fs::create_dir_all(&path).map_err(SourceDirectoryError::Creating) @@ -23,7 +23,7 @@ impl SourceDirectory { /// Returns a list of files in the source directory. pub fn files(path: &PathBuf) -> Result, SourceDirectoryError> { let mut path = path.to_owned(); - path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT)); + path.push(PathBuf::from(SOURCE_DIRECTORY_NAME)); let directory = fs::read_dir(&path).map_err(SourceDirectoryError::Reading)?; let mut file_paths = Vec::new(); @@ -46,7 +46,7 @@ impl SourceDirectory { let file_extension = file_path .extension() .ok_or_else(|| SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?; - if file_extension != SOURCE_FILE_EXTENSION_DEFAULT { + if file_extension != SOURCE_FILE_EXTENSION { return Err(SourceDirectoryError::InvalidFileExtension( file_path.as_os_str().to_owned(), file_extension.to_owned(), diff --git a/leo/errors/cli.rs b/leo/errors/cli.rs index fb3c38655b..9dccf1ffdd 100644 --- a/leo/errors/cli.rs +++ b/leo/errors/cli.rs @@ -1,4 +1,4 @@ -use crate::errors::{InitError, MainFileError, ManifestError, SourceDirectoryError}; +use crate::errors::{InitError, InputsDirectoryError, MainFileError, ManifestError, SourceDirectoryError}; #[derive(Debug, Fail)] pub enum CLIError { @@ -9,6 +9,9 @@ pub enum CLIError { #[fail(display = "{}", _0)] InitError(InitError), + #[fail(display = "{}", _0)] + InputsDirectoryError(InputsDirectoryError), + #[fail(display = "{}", _0)] MainFileError(MainFileError), @@ -26,6 +29,12 @@ impl From for CLIError { } } +impl From for CLIError { + fn from(error: InputsDirectoryError) -> Self { + CLIError::InputsDirectoryError(error) + } +} + impl From for CLIError { fn from(error: MainFileError) -> Self { CLIError::MainFileError(error) diff --git a/leo/errors/directory/inputs.rs b/leo/errors/directory/inputs.rs new file mode 100644 index 0000000000..e13479e456 --- /dev/null +++ b/leo/errors/directory/inputs.rs @@ -0,0 +1,27 @@ +use std::{ffi::OsString, fs::FileType, io}; + +#[derive(Debug, Fail)] +pub enum InputsDirectoryError { + + #[fail(display = "creating: {}", _0)] + Creating(io::Error), + + #[fail(display = "file entry getting: {}", _0)] + GettingFileEntry(io::Error), + + #[fail(display = "file {:?} extension getting", _0)] + GettingFileExtension(OsString), + + #[fail(display = "file {:?} type getting: {}", _0, _1)] + GettingFileType(OsString, io::Error), + + #[fail(display = "invalid file {:?} extension: {:?}", _0, _1)] + InvalidFileExtension(OsString, OsString), + + #[fail(display = "invalid file {:?} type: {:?}", _0, _1)] + InvalidFileType(OsString, FileType), + + #[fail(display = "reading: {}", _0)] + Reading(io::Error), + +} diff --git a/leo/errors/directory/mod.rs b/leo/errors/directory/mod.rs index 6dd9d696d3..cbc68327b5 100644 --- a/leo/errors/directory/mod.rs +++ b/leo/errors/directory/mod.rs @@ -1,2 +1,5 @@ +pub mod inputs; +pub use self::inputs::*; + pub mod source; pub use self::source::*; diff --git a/leo/files/main.rs b/leo/files/main.rs index a1c225205d..0cf73879de 100644 --- a/leo/files/main.rs +++ b/leo/files/main.rs @@ -1,6 +1,6 @@ //! The `main.leo` file. -use crate::directories::source::DIRECTORY_NAME_DEFAULT; +use crate::directories::source::SOURCE_DIRECTORY_NAME; use crate::errors::MainFileError; use serde::Deserialize; @@ -23,8 +23,8 @@ impl MainFile { pub fn exists_at(path: &PathBuf) -> bool { let mut path = path.to_owned(); if path.is_dir() { - if !path.ends_with(DIRECTORY_NAME_DEFAULT) { - path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT)); + if !path.ends_with(SOURCE_DIRECTORY_NAME) { + path.push(PathBuf::from(SOURCE_DIRECTORY_NAME)); } path.push(PathBuf::from(FILE_NAME_DEFAULT)); } @@ -34,8 +34,8 @@ impl MainFile { pub fn write_to(self, path: &PathBuf) -> Result<(), MainFileError> { let mut path = path.to_owned(); if path.is_dir() { - if !path.ends_with(DIRECTORY_NAME_DEFAULT) { - path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT)); + if !path.ends_with(SOURCE_DIRECTORY_NAME) { + path.push(PathBuf::from(SOURCE_DIRECTORY_NAME)); } path.push(PathBuf::from(FILE_NAME_DEFAULT)); } From 18768bbec72e1d256c6e584db4fd1126c5ee0b47 Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 01:47:10 -0700 Subject: [PATCH 08/16] Adds command --- Cargo.lock | 3 + Cargo.toml | 4 + leo/commands/init.rs | 3 +- leo/commands/mod.rs | 3 + leo/commands/run.rs | 135 ++++++++++++++++++++++++++++++++ leo/compiler.rs | 50 ++++++++++++ leo/directories/mod.rs | 3 + leo/directories/outputs.rs | 34 ++++++++ leo/errors/cli.rs | 20 ++++- leo/errors/commands/mod.rs | 3 + leo/errors/commands/run.rs | 33 ++++++++ leo/errors/directory/mod.rs | 3 + leo/errors/directory/outputs.rs | 30 +++++++ leo/files/main.rs | 6 +- leo/lib.rs | 2 + leo/logger.rs | 45 +++++++++++ leo/main.rs | 10 ++- leo/simple.leo | 4 - leo/simple_import.leo | 4 - 19 files changed, 378 insertions(+), 17 deletions(-) create mode 100644 leo/commands/run.rs create mode 100644 leo/compiler.rs create mode 100644 leo/directories/outputs.rs create mode 100644 leo/errors/commands/run.rs create mode 100644 leo/errors/directory/outputs.rs create mode 100644 leo/logger.rs delete mode 100644 leo/simple.leo delete mode 100644 leo/simple_import.leo diff --git a/Cargo.lock b/Cargo.lock index 123be2b395..9913b156ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -613,8 +613,11 @@ version = "0.1.0" dependencies = [ "clap", "colored", + "env_logger", "failure", "from-pest", + "leo-program", + "log", "rand 0.7.3", "rand_core 0.5.1", "serde", diff --git a/Cargo.toml b/Cargo.toml index 4d7760d007..7afe57dd86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,8 @@ path = "leo/main.rs" members = [ "benchmark", "program" ] [dependencies] +leo-program = { path = "./program", version = "0.1.0" } + snarkos-algorithms = { path = "../snarkOS/algorithms", version = "0.8.0" } snarkos-curves = { path = "../snarkOS/curves", version = "0.8.0" } snarkos-errors = { path = "../snarkOS/errors", version = "0.8.0" } @@ -24,8 +26,10 @@ snarkos-models = { path = "../snarkOS/models", version = "0.8.0" } clap = { version = "2.33.0" } colored = { version = "1.9" } +env_logger = { version = "0.7" } failure = { version = "0.1.5" } from-pest = { version = "0.3.1" } +log = { version = "0.4" } rand = { version = "0.7" } rand_core = { version = "0.5.1" } serde = { version = "1.0", features = ["derive"] } diff --git a/leo/commands/init.rs b/leo/commands/init.rs index 7050757856..6089c7007a 100644 --- a/leo/commands/init.rs +++ b/leo/commands/init.rs @@ -56,8 +56,9 @@ impl CLI for InitCommand { // Create the inputs directory InputsDirectory::create(&path)?; - // Create the main file in the source directory + // Verify the main file does not exist if !MainFile::exists_at(&path) { + // Create the main file in the source directory MainFile::new(&package_name).write_to(&path)?; } diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs index 2d5b8771e7..b8ba748f1e 100644 --- a/leo/commands/mod.rs +++ b/leo/commands/mod.rs @@ -1,2 +1,5 @@ pub mod init; pub use self::init::*; + +pub mod run; +pub use self::run::*; diff --git a/leo/commands/run.rs b/leo/commands/run.rs new file mode 100644 index 0000000000..6d0e205acc --- /dev/null +++ b/leo/commands/run.rs @@ -0,0 +1,135 @@ +use crate::{cli::*, cli_types::*}; +use crate::compiler::Compiler; +use crate::directories::{OutputsDirectory, source::SOURCE_DIRECTORY_NAME}; +use crate::errors::{CLIError, RunError}; +use crate::files::{MainFile, MAIN_FILE_NAME}; +use crate::manifest::Manifest; + +use snarkos_curves::bls12_377::Fr; + +use clap::ArgMatches; +use std::convert::TryFrom; +use std::env::current_dir; +use std::path::PathBuf; + +#[derive(Debug)] +pub struct RunCommand; + +impl CLI for RunCommand { + type Options = (); + + const NAME: NameType = "run"; + const ABOUT: AboutType = "Run a program with inputs (include -h for more options)"; + const FLAGS: &'static [FlagType] = &[]; + const OPTIONS: &'static [OptionType] = &[]; + const SUBCOMMANDS: &'static [SubCommandType] = &[]; + + #[cfg_attr(tarpaulin, skip)] + fn parse(_arguments: &ArgMatches) -> Result { + Ok(()) + } + + #[cfg_attr(tarpaulin, skip)] + fn output(_options: Self::Options) -> Result<(), CLIError> { + let path = current_dir()?; + let _manifest = Manifest::try_from(&path)?; + + // Sanitize the package path to the root directory + let mut package_path = path.clone(); + if package_path.is_file() { + package_path.pop(); + } + + // Verify the main file exists + if !MainFile::exists_at(&package_path) { + return Err(RunError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into()); + } + + // Create the outputs directory + OutputsDirectory::create(&package_path)?; + + // Construct the path to the main file in the source directory + let mut main_file_path = package_path.clone(); + main_file_path.push(SOURCE_DIRECTORY_NAME); + main_file_path.push(MAIN_FILE_NAME); + + log::debug!("Compiling program located in {:?}", main_file_path); + + fn run(main_file_path: PathBuf) { + + use snarkos_algorithms::snark::{create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof}; + use snarkos_curves::bls12_377::Bls12_377; + + use rand::thread_rng; + use std::time::{Duration, Instant}; + + let mut setup = Duration::new(0, 0); + let mut proving = Duration::new(0, 0); + let mut verifying = Duration::new(0, 0); + + let rng = &mut thread_rng(); + + let start = Instant::now(); + + let params = { + let circuit = Compiler::::init(main_file_path.clone()); + generate_random_parameters::(circuit, rng).unwrap() + }; + + let prepared_verifying_key = prepare_verifying_key::(¶ms.vk); + + setup += start.elapsed(); + + let start = Instant::now(); + let proof = { + let circuit = Compiler::::init(main_file_path); + create_random_proof(circuit, ¶ms, rng).unwrap() + }; + + proving += start.elapsed(); + + // let _inputs: Vec<_> = [1u32; 1].to_vec(); + + let start = Instant::now(); + + let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap(); + + verifying += start.elapsed(); + + println!(" "); + println!(" Setup time : {:?} milliseconds", setup.as_millis()); + println!(" Prover time : {:?} milliseconds", proving.as_millis()); + println!( + " Verifier time : {:?} milliseconds", + verifying.as_millis() + ); + println!(" Verifier output : {}", is_success); + println!(" "); + } + + run(main_file_path); + + // let source_files = SourceDirectory::files(&package_path)?; + // BuildDirectory::create(&circuit_path).map_err(Error::BuildDirectory)?; + // DataDirectory::create(&circuit_path).map_err(Error::DataDirectory)?; + + // Compiler::build( + // self.verbosity, + // &self.witness, + // &self.public_data, + // &self.circuit, + // &source_file_paths, + // ) + // .map_err(Error::Compiler)?; + // + // VirtualMachine::run( + // self.verbosity, + // &self.circuit, + // &self.witness, + // &self.public_data, + // ) + // .map_err(Error::VirtualMachine)?; + + Ok(()) + } +} diff --git a/leo/compiler.rs b/leo/compiler.rs new file mode 100644 index 0000000000..a8d1c2baab --- /dev/null +++ b/leo/compiler.rs @@ -0,0 +1,50 @@ +use leo_program::{self, ast}; + +use snarkos_errors::gadgets::SynthesisError; +use snarkos_models::{ + curves::{Field, PrimeField}, + gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem}, +}; + +use from_pest::FromPest; +use std::{ + fs, + marker::PhantomData, + path::PathBuf, +}; + +pub struct Compiler { + main_file_path: PathBuf, + _engine: PhantomData, +} + +impl Compiler { + pub fn init(main_file_path: PathBuf) -> Self { + Self { main_file_path, _engine: PhantomData } + } +} + +impl ConstraintSynthesizer for Compiler { + fn generate_constraints>( + self, + cs: &mut CS, + ) -> Result<(), SynthesisError> { + // Read in the main file as string + let unparsed_file = fs::read_to_string(&self.main_file_path).expect("cannot read file"); + + // Parse the file using leo.pest + let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse"); + + // Build the abstract syntax tree + let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); + // println!("{:#?}", syntax_tree); + + let program = leo_program::Program::<'_, F>::from(syntax_tree); + println!(" compiled: {:#?}", program); + + let program = program.name("simple".into()); + leo_program::ResolvedProgram::generate_constraints(cs, program); + + Ok(()) + } +} \ No newline at end of file diff --git a/leo/directories/mod.rs b/leo/directories/mod.rs index cbc68327b5..31f99c6104 100644 --- a/leo/directories/mod.rs +++ b/leo/directories/mod.rs @@ -1,5 +1,8 @@ pub mod inputs; pub use self::inputs::*; +pub mod outputs; +pub use self::outputs::*; + pub mod source; pub use self::source::*; diff --git a/leo/directories/outputs.rs b/leo/directories/outputs.rs new file mode 100644 index 0000000000..eaf1d4928d --- /dev/null +++ b/leo/directories/outputs.rs @@ -0,0 +1,34 @@ +use crate::errors::OutputsDirectoryError; + +use std::fs; +use std::path::PathBuf; + +pub(crate) static OUTPUTS_DIRECTORY_NAME: &str = "outputs/"; + +pub struct OutputsDirectory; + +impl OutputsDirectory { + /// Creates a directory at the provided path with the default directory name. + pub fn create(path: &PathBuf) -> Result<(), OutputsDirectoryError> { + let mut path = path.to_owned(); + if path.is_dir() && !path.ends_with(OUTPUTS_DIRECTORY_NAME) { + path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME)); + } + + fs::create_dir_all(&path).map_err(OutputsDirectoryError::Creating) + } + + /// Removes the directory at the provided path. + pub fn remove(path: &PathBuf) -> Result<(), OutputsDirectoryError> { + let mut path = path.to_owned(); + if path.is_dir() && !path.ends_with(OUTPUTS_DIRECTORY_NAME) { + path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME)); + } + + if path.exists() { + fs::remove_dir_all(&path).map_err(OutputsDirectoryError::Removing)?; + } + + Ok(()) + } +} diff --git a/leo/errors/cli.rs b/leo/errors/cli.rs index 9dccf1ffdd..b37af25e75 100644 --- a/leo/errors/cli.rs +++ b/leo/errors/cli.rs @@ -1,4 +1,4 @@ -use crate::errors::{InitError, InputsDirectoryError, MainFileError, ManifestError, SourceDirectoryError}; +use crate::errors::{InitError, InputsDirectoryError, MainFileError, ManifestError, OutputsDirectoryError, RunError, SourceDirectoryError}; #[derive(Debug, Fail)] pub enum CLIError { @@ -18,6 +18,12 @@ pub enum CLIError { #[fail(display = "{}", _0)] ManifestError(ManifestError), + #[fail(display = "{}", _0)] + OutputsDirectoryError(OutputsDirectoryError), + + #[fail(display = "{}", _0)] + RunError(RunError), + #[fail(display = "{}", _0)] SourceDirectoryError(SourceDirectoryError), @@ -47,6 +53,18 @@ impl From for CLIError { } } +impl From for CLIError { + fn from(error: OutputsDirectoryError) -> Self { + CLIError::OutputsDirectoryError(error) + } +} + +impl From for CLIError { + fn from(error: RunError) -> Self { + CLIError::RunError(error) + } +} + impl From for CLIError { fn from(error: SourceDirectoryError) -> Self { CLIError::SourceDirectoryError(error) diff --git a/leo/errors/commands/mod.rs b/leo/errors/commands/mod.rs index 2d5b8771e7..b8ba748f1e 100644 --- a/leo/errors/commands/mod.rs +++ b/leo/errors/commands/mod.rs @@ -1,2 +1,5 @@ pub mod init; pub use self::init::*; + +pub mod run; +pub use self::run::*; diff --git a/leo/errors/commands/run.rs b/leo/errors/commands/run.rs new file mode 100644 index 0000000000..7d2c8e8696 --- /dev/null +++ b/leo/errors/commands/run.rs @@ -0,0 +1,33 @@ +use crate::errors::ManifestError; + +use std::ffi::OsString; +use std::io; + +#[derive(Debug, Fail)] +pub enum RunError { + + #[fail(display = "root directory {:?} creating: {}", _0, _1)] + CreatingRootDirectory(OsString, io::Error), + + #[fail(display = "directory {:?} does not exist", _0)] + DirectoryDoesNotExist(OsString), + + #[fail(display = "main file {:?} does not exist", _0)] + MainFileDoesNotExist(OsString), + + #[fail(display = "{}", _0)] + ManifestError(ManifestError), + + #[fail(display = "package at path {:?} already exists", _0)] + PackageAlreadyExists(OsString), + + #[fail(display = "package name is missing - {:?}", _0)] + ProjectNameInvalid(OsString), + +} + +impl From for RunError { + fn from(error: ManifestError) -> Self { + RunError::ManifestError(error) + } +} diff --git a/leo/errors/directory/mod.rs b/leo/errors/directory/mod.rs index cbc68327b5..31f99c6104 100644 --- a/leo/errors/directory/mod.rs +++ b/leo/errors/directory/mod.rs @@ -1,5 +1,8 @@ pub mod inputs; pub use self::inputs::*; +pub mod outputs; +pub use self::outputs::*; + pub mod source; pub use self::source::*; diff --git a/leo/errors/directory/outputs.rs b/leo/errors/directory/outputs.rs new file mode 100644 index 0000000000..87c61db1f0 --- /dev/null +++ b/leo/errors/directory/outputs.rs @@ -0,0 +1,30 @@ +use std::{ffi::OsString, fs::FileType, io}; + +#[derive(Debug, Fail)] +pub enum OutputsDirectoryError { + + #[fail(display = "creating: {}", _0)] + Creating(io::Error), + + #[fail(display = "file entry getting: {}", _0)] + GettingFileEntry(io::Error), + + #[fail(display = "file {:?} extension getting", _0)] + GettingFileExtension(OsString), + + #[fail(display = "file {:?} type getting: {}", _0, _1)] + GettingFileType(OsString, io::Error), + + #[fail(display = "invalid file {:?} extension: {:?}", _0, _1)] + InvalidFileExtension(OsString, OsString), + + #[fail(display = "invalid file {:?} type: {:?}", _0, _1)] + InvalidFileType(OsString, FileType), + + #[fail(display = "reading: {}", _0)] + Reading(io::Error), + + #[fail(display = "removing: {}", _0)] + Removing(io::Error), + +} diff --git a/leo/files/main.rs b/leo/files/main.rs index 0cf73879de..8862d66b51 100644 --- a/leo/files/main.rs +++ b/leo/files/main.rs @@ -8,7 +8,7 @@ use std::fs::File; use std::io::Write; use std::path::PathBuf; -pub static FILE_NAME_DEFAULT: &str = "main.leo"; +pub static MAIN_FILE_NAME: &str = "main.leo"; #[derive(Deserialize)] pub struct MainFile { @@ -26,7 +26,7 @@ impl MainFile { if !path.ends_with(SOURCE_DIRECTORY_NAME) { path.push(PathBuf::from(SOURCE_DIRECTORY_NAME)); } - path.push(PathBuf::from(FILE_NAME_DEFAULT)); + path.push(PathBuf::from(MAIN_FILE_NAME)); } path.exists() } @@ -37,7 +37,7 @@ impl MainFile { if !path.ends_with(SOURCE_DIRECTORY_NAME) { path.push(PathBuf::from(SOURCE_DIRECTORY_NAME)); } - path.push(PathBuf::from(FILE_NAME_DEFAULT)); + path.push(PathBuf::from(MAIN_FILE_NAME)); } let mut file = File::create(&path)?; diff --git a/leo/lib.rs b/leo/lib.rs index 9342eecad8..84a0ef6202 100644 --- a/leo/lib.rs +++ b/leo/lib.rs @@ -5,7 +5,9 @@ extern crate failure; pub mod cli; pub mod cli_types; pub mod commands; +pub mod compiler; pub mod directories; pub mod errors; pub mod files; +pub mod logger; pub mod manifest; diff --git a/leo/logger.rs b/leo/logger.rs new file mode 100644 index 0000000000..e2ac5c3175 --- /dev/null +++ b/leo/logger.rs @@ -0,0 +1,45 @@ +use colored::Colorize; +use std::io::Write; + +const LEVEL_NAME_LENGTH: usize = 10; + +#[allow(dead_code)] +fn level_string(level: log::Level) -> colored::ColoredString { + match level { + log::Level::Error => "ERROR".bold().red(), + log::Level::Warn => "WARN".bold().yellow(), + log::Level::Info => "INFO".bold().blue(), + log::Level::Debug => "DEBUG".bold().magenta(), + log::Level::Trace => "TRACE".bold(), + } +} + +/// Initialize logger with custom format and verbosity. +/// +/// # Arguments +/// +/// * `verbosity` - Verbosity level. 0 for `Warn`, 1 for `Info`, 2 for `Debug`, more for `Trace` +pub fn init_logger(app_name: &'static str, verbosity: usize) { + env_logger::builder() + .filter_level(match verbosity { + 0 => log::LevelFilter::Warn, + 1 => log::LevelFilter::Info, + 2 => log::LevelFilter::Debug, + _ => log::LevelFilter::Trace, + }) + .format(move |buf, record| { + let mut padding = String::from("\n"); + for _ in 0..(app_name.len() + LEVEL_NAME_LENGTH + 4) { + padding.push(' '); + } + + writeln!( + buf, + "[{:>5} {:>5}] {}", + level_string(record.level()), + app_name, + record.args().to_string().replace("\n", &padding) + ) + }) + .init(); +} diff --git a/leo/main.rs b/leo/main.rs index bf3e8110d2..615de0adde 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -110,13 +110,15 @@ // // // } -use leo::{cli::*, commands::*}; +use leo::{cli::*, commands::*, logger}; use leo::errors::CLIError; use clap::{App, AppSettings}; #[cfg_attr(tarpaulin, skip)] fn main() -> Result<(), CLIError> { + logger::init_logger("leo", 3); + let arguments = App::new("leo") .version("v0.1.0") .about("Leo compiler and package manager") @@ -129,15 +131,15 @@ fn main() -> Result<(), CLIError> { ]) .subcommands(vec![ InitCommand::new(), + RunCommand::new(), ]) .set_term_width(0) .get_matches(); match arguments.subcommand() { - ("init", Some(arguments)) => { - InitCommand::output(InitCommand::parse(arguments)?) - }, + ("init", Some(arguments)) => InitCommand::output(InitCommand::parse(arguments)?), + ("run", Some(arguments)) => RunCommand::output(RunCommand::parse(arguments)?), _ => unreachable!(), } } \ No newline at end of file diff --git a/leo/simple.leo b/leo/simple.leo deleted file mode 100644 index 847c630eb2..0000000000 --- a/leo/simple.leo +++ /dev/null @@ -1,4 +0,0 @@ -function main() -> (u32) { - a = 1 + 1 - return a -} \ No newline at end of file diff --git a/leo/simple_import.leo b/leo/simple_import.leo deleted file mode 100644 index 667fa6871c..0000000000 --- a/leo/simple_import.leo +++ /dev/null @@ -1,4 +0,0 @@ -struct Point { - u32 x - u32 y -} \ No newline at end of file From b85aa8f547731d74158cbf1eac8883d071e8d67a Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 16:02:31 -0700 Subject: [PATCH 09/16] Adds command to Leo --- leo/cli.rs | 9 +++++ leo/cli_types.rs | 12 ++++++ leo/commands/init.rs | 5 ++- leo/commands/mod.rs | 3 ++ leo/commands/new.rs | 76 ++++++++++++++++++++++++++++++++++++++ leo/commands/run.rs | 3 +- leo/errors/cli.rs | 11 +++++- leo/errors/commands/mod.rs | 3 ++ leo/errors/commands/new.rs | 30 +++++++++++++++ leo/main.rs | 4 +- 10 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 leo/commands/new.rs create mode 100644 leo/errors/commands/new.rs diff --git a/leo/cli.rs b/leo/cli.rs index 4de644a0a9..e51f635f1d 100644 --- a/leo/cli.rs +++ b/leo/cli.rs @@ -8,12 +8,20 @@ pub trait CLI { const NAME: NameType; const ABOUT: AboutType; + const ARGUMENTS: &'static [ArgumentType]; const FLAGS: &'static [FlagType]; const OPTIONS: &'static [OptionType]; const SUBCOMMANDS: &'static [SubCommandType]; #[cfg_attr(tarpaulin, skip)] fn new<'a, 'b>() -> App<'a, 'b> { + let arguments = &Self::ARGUMENTS + .iter() + .map(|a| Arg::with_name(a.0) + .help(a.1) + .required(a.2) + .index(a.3)) + .collect::>>(); let flags = &Self::FLAGS .iter() .map(|a| Arg::from_usage(a).global(true)) @@ -55,6 +63,7 @@ pub trait CLI { AppSettings::DisableHelpSubcommand, AppSettings::DisableVersion, ]) + .args(arguments) .args(flags) .args(options) .subcommands(subcommands) diff --git a/leo/cli_types.rs b/leo/cli_types.rs index 41df6786d2..ef33d69cb9 100644 --- a/leo/cli_types.rs +++ b/leo/cli_types.rs @@ -1,12 +1,24 @@ use clap::AppSettings; pub type NameType = &'static str; + pub type AboutType = &'static str; + +pub type DescriptionType = &'static str; + +pub type RequiredType = bool; + +pub type IndexType = u64; + +pub type ArgumentType = (NameType, DescriptionType, RequiredType, IndexType); + pub type FlagType = &'static str; + pub type OptionType = ( &'static str, &'static [&'static str], &'static [&'static str], &'static [&'static str], ); + pub type SubCommandType = (NameType, AboutType, &'static [OptionType], &'static [AppSettings]); diff --git a/leo/commands/init.rs b/leo/commands/init.rs index 6089c7007a..3c6b82ec91 100644 --- a/leo/commands/init.rs +++ b/leo/commands/init.rs @@ -14,7 +14,8 @@ impl CLI for InitCommand { type Options = Option; const NAME: NameType = "init"; - const ABOUT: AboutType = "Creates a new Leo package (include -h for more options)"; + const ABOUT: AboutType = "Creates a new Leo package in an existing directory"; + const ARGUMENTS: &'static [ArgumentType] = &[]; const FLAGS: &'static [FlagType] = &[]; const OPTIONS: &'static [OptionType] = &[]; const SUBCOMMANDS: &'static [SubCommandType] = &[]; @@ -48,6 +49,8 @@ impl CLI for InitCommand { if Manifest::exists_at(&path) { return Err(InitError::PackageAlreadyExists(path.as_os_str().to_owned()).into()); } + + // Create the manifest file Manifest::new(&package_name).write_to(&path)?; // Create the source directory diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs index b8ba748f1e..634e0b58fc 100644 --- a/leo/commands/mod.rs +++ b/leo/commands/mod.rs @@ -1,5 +1,8 @@ pub mod init; pub use self::init::*; +pub mod new; +pub use self::new::*; + pub mod run; pub use self::run::*; diff --git a/leo/commands/new.rs b/leo/commands/new.rs new file mode 100644 index 0000000000..c38199489a --- /dev/null +++ b/leo/commands/new.rs @@ -0,0 +1,76 @@ +use crate::{cli::*, cli_types::*}; +use crate::directories::{InputsDirectory, SourceDirectory}; +use crate::errors::{CLIError, NewError}; +use crate::files::MainFile; +use crate::manifest::Manifest; + +use clap::ArgMatches; +use std::env::current_dir; +use std::fs; + +#[derive(Debug)] +pub struct NewCommand; + +impl CLI for NewCommand { + type Options = Option; + + const NAME: NameType = "new"; + const ABOUT: AboutType = "Creates a new Leo package"; + const ARGUMENTS: &'static [ArgumentType] = &[ + // (name, description, required, index) + ("NAME", "Sets the resulting package name, defaults to the directory name", true, 1u64) + ]; + const FLAGS: &'static [FlagType] = &[]; + const OPTIONS: &'static [OptionType] = &[]; + const SUBCOMMANDS: &'static [SubCommandType] = &[]; + + #[cfg_attr(tarpaulin, skip)] + fn parse(arguments: &ArgMatches) -> Result { + match arguments.value_of("NAME") { + Some(name) => Ok(Some(name.to_string())), + None => Ok(None) + } + } + + #[cfg_attr(tarpaulin, skip)] + fn output(options: Self::Options) -> Result<(), CLIError> { + let mut path = current_dir()?; + + // Derive the package name + let package_name = match options { + Some(name) => name, + None => path + .file_stem() + .ok_or_else(|| NewError::ProjectNameInvalid(path.as_os_str().to_owned()))? + .to_string_lossy() + .to_string(), + }; + + // Derive the package directory path + path.push(&package_name); + + // Verify the package directory path does not exist yet + if path.exists() { + return Err(NewError::DirectoryAlreadyExists(path.as_os_str().to_owned()).into()); + } + + // Create the package directory + fs::create_dir_all(&path).map_err(|error| { + NewError::CreatingRootDirectory(path.as_os_str().to_owned(), error) + })?; + + // Create the manifest file + Manifest::new(&package_name).write_to(&path)?; + + // Create the source directory + SourceDirectory::create(&path)?; + + // Create the inputs directory + InputsDirectory::create(&path)?; + + // Create the main file in the source directory + MainFile::new(&package_name).write_to(&path)?; + + Ok(()) + } +} diff --git a/leo/commands/run.rs b/leo/commands/run.rs index 6d0e205acc..aee82267fc 100644 --- a/leo/commands/run.rs +++ b/leo/commands/run.rs @@ -19,7 +19,8 @@ impl CLI for RunCommand { type Options = (); const NAME: NameType = "run"; - const ABOUT: AboutType = "Run a program with inputs (include -h for more options)"; + const ABOUT: AboutType = "Run a program with inputs"; + const ARGUMENTS: &'static [ArgumentType] = &[]; const FLAGS: &'static [FlagType] = &[]; const OPTIONS: &'static [OptionType] = &[]; const SUBCOMMANDS: &'static [SubCommandType] = &[]; diff --git a/leo/errors/cli.rs b/leo/errors/cli.rs index b37af25e75..734389254e 100644 --- a/leo/errors/cli.rs +++ b/leo/errors/cli.rs @@ -1,4 +1,4 @@ -use crate::errors::{InitError, InputsDirectoryError, MainFileError, ManifestError, OutputsDirectoryError, RunError, SourceDirectoryError}; +use crate::errors::*; #[derive(Debug, Fail)] pub enum CLIError { @@ -18,6 +18,9 @@ pub enum CLIError { #[fail(display = "{}", _0)] ManifestError(ManifestError), + #[fail(display = "{}", _0)] + NewError(NewError), + #[fail(display = "{}", _0)] OutputsDirectoryError(OutputsDirectoryError), @@ -53,6 +56,12 @@ impl From for CLIError { } } +impl From for CLIError { + fn from(error: NewError) -> Self { + CLIError::NewError(error) + } +} + impl From for CLIError { fn from(error: OutputsDirectoryError) -> Self { CLIError::OutputsDirectoryError(error) diff --git a/leo/errors/commands/mod.rs b/leo/errors/commands/mod.rs index b8ba748f1e..634e0b58fc 100644 --- a/leo/errors/commands/mod.rs +++ b/leo/errors/commands/mod.rs @@ -1,5 +1,8 @@ pub mod init; pub use self::init::*; +pub mod new; +pub use self::new::*; + pub mod run; pub use self::run::*; diff --git a/leo/errors/commands/new.rs b/leo/errors/commands/new.rs new file mode 100644 index 0000000000..f06d18de4e --- /dev/null +++ b/leo/errors/commands/new.rs @@ -0,0 +1,30 @@ +use crate::errors::ManifestError; + +use std::ffi::OsString; +use std::io; + +#[derive(Debug, Fail)] +pub enum NewError { + + #[fail(display = "root directory {:?} creating: {}", _0, _1)] + CreatingRootDirectory(OsString, io::Error), + + #[fail(display = "directory {:?} already exists", _0)] + DirectoryAlreadyExists(OsString), + + #[fail(display = "{}", _0)] + ManifestError(ManifestError), + + #[fail(display = "package at path {:?} already exists", _0)] + PackageAlreadyExists(OsString), + + #[fail(display = "package name is missing - {:?}", _0)] + ProjectNameInvalid(OsString), + +} + +impl From for NewError { + fn from(error: ManifestError) -> Self { + NewError::ManifestError(error) + } +} diff --git a/leo/main.rs b/leo/main.rs index 615de0adde..04d8515def 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -129,7 +129,8 @@ fn main() -> Result<(), CLIError> { AppSettings::DisableVersion, AppSettings::SubcommandRequiredElseHelp, ]) - .subcommands(vec![ + .subcommands(vec![ // TODO (howardwu): Print subcommands in non-alphabetical order, instead print as ordered here. + NewCommand::new(), InitCommand::new(), RunCommand::new(), ]) @@ -138,6 +139,7 @@ fn main() -> Result<(), CLIError> { match arguments.subcommand() { + ("new", Some(arguments)) => NewCommand::output(NewCommand::parse(arguments)?), ("init", Some(arguments)) => InitCommand::output(InitCommand::parse(arguments)?), ("run", Some(arguments)) => RunCommand::output(RunCommand::parse(arguments)?), _ => unreachable!(), From 108789a52f6db63f58f9371c3ab49ca83dfd4b7c Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 17:18:49 -0700 Subject: [PATCH 10/16] Move compiled program output to info logging --- leo/compiler.rs | 4 ++-- leo/main.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/leo/compiler.rs b/leo/compiler.rs index a8d1c2baab..d7243f91a3 100644 --- a/leo/compiler.rs +++ b/leo/compiler.rs @@ -37,10 +37,10 @@ impl ConstraintSynthesizer for Compiler { // Build the abstract syntax tree let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); - // println!("{:#?}", syntax_tree); + log::debug!("{:#?}", syntax_tree); let program = leo_program::Program::<'_, F>::from(syntax_tree); - println!(" compiled: {:#?}", program); + log::info!(" compiled: {:#?}", program); let program = program.name("simple".into()); leo_program::ResolvedProgram::generate_constraints(cs, program); diff --git a/leo/main.rs b/leo/main.rs index 04d8515def..b1a509cdba 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -117,7 +117,7 @@ use clap::{App, AppSettings}; #[cfg_attr(tarpaulin, skip)] fn main() -> Result<(), CLIError> { - logger::init_logger("leo", 3); + logger::init_logger("leo", 1); let arguments = App::new("leo") .version("v0.1.0") From c5fdbb85e088604003b0d46ee199bcbf20fd6f8b Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 17:19:48 -0700 Subject: [PATCH 11/16] Cleanup main.rs --- leo/main.rs | 115 +--------------------------------------------------- 1 file changed, 2 insertions(+), 113 deletions(-) diff --git a/leo/main.rs b/leo/main.rs index b1a509cdba..2d4aaa1e41 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -1,115 +1,3 @@ -// use leo_program::{self, ast}; -// -// use snarkos_algorithms::snark::{ -// create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, -// }; -// use snarkos_curves::bls12_377::{Bls12_377, Fr}; -// use snarkos_errors::gadgets::SynthesisError; -// use snarkos_models::{ -// curves::{Field, PrimeField}, -// gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem}, -// }; -// -// use from_pest::FromPest; -// use rand::thread_rng; -// use std::{ -// fs, -// marker::PhantomData, -// time::{Duration, Instant}, -// }; -// -// pub struct Benchmark { -// _engine: PhantomData, -// } -// -// impl Benchmark { -// pub fn init() -> Self { -// Self { -// _engine: PhantomData, -// } -// } -// } -// -// impl ConstraintSynthesizer for Benchmark { -// fn generate_constraints>( -// self, -// cs: &mut CS, -// ) -> Result<(), SynthesisError> { -// // Read in file as string -// let unparsed_file = fs::read_to_string("simple.leo").expect("cannot read file"); -// -// // Parse the file using leo.pest -// let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse"); -// -// // Build the abstract syntax tree -// let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); -// // println!("{:#?}", syntax_tree); -// -// let program = leo_program::Program::<'_, F>::from(syntax_tree); -// println!(" compiled: {:#?}", program); -// -// let program = program.name("simple".into()); -// leo_program::ResolvedProgram::generate_constraints(cs, program); -// -// Ok(()) -// } -// } -// -// fn main() { -// let mut setup = Duration::init(0, 0); -// let mut proving = Duration::init(0, 0); -// let mut verifying = Duration::init(0, 0); -// -// let rng = &mut thread_rng(); -// -// let start = Instant::now(); -// -// let params = { -// let circuit = Benchmark::::init(); -// generate_random_parameters::(circuit, rng).unwrap() -// }; -// -// let prepared_verifying_key = prepare_verifying_key::(¶ms.vk); -// -// setup += start.elapsed(); -// -// let start = Instant::now(); -// let proof = { -// let c = Benchmark::init(); -// create_random_proof(c, ¶ms, rng).unwrap() -// }; -// -// proving += start.elapsed(); -// -// // let _inputs: Vec<_> = [1u32; 1].to_vec(); -// -// let start = Instant::now(); -// -// let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap(); -// -// verifying += start.elapsed(); -// -// println!(" "); -// println!(" Setup time : {:?} milliseconds", setup.as_millis()); -// println!(" Prover time : {:?} milliseconds", proving.as_millis()); -// println!( -// " Verifier time : {:?} milliseconds", -// verifying.as_millis() -// ); -// println!(" Verifier output : {}", is_success); -// println!(" "); -// -// // let mut cs = TestConstraintSystem::::init(); -// // -// // println!("\n satisfied: {:?}", cs.is_satisfied()); -// // -// // println!( -// // "\n number of constraints for input: {}", -// // cs.num_constraints() -// // ); -// // -// } - use leo::{cli::*, commands::*, logger}; use leo::errors::CLIError; @@ -129,7 +17,8 @@ fn main() -> Result<(), CLIError> { AppSettings::DisableVersion, AppSettings::SubcommandRequiredElseHelp, ]) - .subcommands(vec![ // TODO (howardwu): Print subcommands in non-alphabetical order, instead print as ordered here. + // TODO (howardwu): Print subcommands in non-alphabetical order, instead print as ordered here. + .subcommands(vec![ NewCommand::new(), InitCommand::new(), RunCommand::new(), From 9daeb358baefe4f0a75a9eb0a34dc0576e6dad3c Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 17:40:02 -0700 Subject: [PATCH 12/16] Add command to Leo --- leo/commands/build.rs | 63 ++++++++++++++++++++++++++++++++++++ leo/commands/mod.rs | 3 ++ leo/commands/run.rs | 2 +- leo/errors/cli.rs | 9 ++++++ leo/errors/commands/build.rs | 20 ++++++++++++ leo/errors/commands/mod.rs | 3 ++ leo/errors/commands/run.rs | 13 -------- leo/main.rs | 4 ++- 8 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 leo/commands/build.rs create mode 100644 leo/errors/commands/build.rs diff --git a/leo/commands/build.rs b/leo/commands/build.rs new file mode 100644 index 0000000000..daaf741a2f --- /dev/null +++ b/leo/commands/build.rs @@ -0,0 +1,63 @@ +use crate::{cli::*, cli_types::*}; +use crate::compiler::Compiler; +use crate::directories::{OutputsDirectory, source::SOURCE_DIRECTORY_NAME}; +use crate::errors::{CLIError, BuildError}; +use crate::files::{MainFile, MAIN_FILE_NAME}; +use crate::manifest::Manifest; + +use snarkos_curves::bls12_377::Fr; + +use clap::ArgMatches; +use std::convert::TryFrom; +use std::env::current_dir; + +#[derive(Debug)] +pub struct BuildCommand; + +impl CLI for BuildCommand { + type Options = (); + + const NAME: NameType = "build"; + const ABOUT: AboutType = "Compile the current package"; + const ARGUMENTS: &'static [ArgumentType] = &[]; + const FLAGS: &'static [FlagType] = &[]; + const OPTIONS: &'static [OptionType] = &[]; + const SUBCOMMANDS: &'static [SubCommandType] = &[]; + + #[cfg_attr(tarpaulin, skip)] + fn parse(_arguments: &ArgMatches) -> Result { + Ok(()) + } + + #[cfg_attr(tarpaulin, skip)] + fn output(_options: Self::Options) -> Result<(), CLIError> { + let path = current_dir()?; + let _manifest = Manifest::try_from(&path)?; + + // Sanitize the package path to the root directory + let mut package_path = path.clone(); + if package_path.is_file() { + package_path.pop(); + } + + // Verify the main file exists + if !MainFile::exists_at(&package_path) { + return Err(BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into()); + } + + // Create the outputs directory + OutputsDirectory::create(&package_path)?; + + // Construct the path to the main file in the source directory + let mut main_file_path = package_path.clone(); + main_file_path.push(SOURCE_DIRECTORY_NAME); + main_file_path.push(MAIN_FILE_NAME); + + log::info!("Compiling program located in {:?}", main_file_path); + + // Compile from the main file path + let _circuit = Compiler::::init(main_file_path); + + Ok(()) + } +} diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs index 634e0b58fc..968a4b6e24 100644 --- a/leo/commands/mod.rs +++ b/leo/commands/mod.rs @@ -1,3 +1,6 @@ +pub mod build; +pub use self::build::*; + pub mod init; pub use self::init::*; diff --git a/leo/commands/run.rs b/leo/commands/run.rs index aee82267fc..610427f09f 100644 --- a/leo/commands/run.rs +++ b/leo/commands/run.rs @@ -54,7 +54,7 @@ impl CLI for RunCommand { main_file_path.push(SOURCE_DIRECTORY_NAME); main_file_path.push(MAIN_FILE_NAME); - log::debug!("Compiling program located in {:?}", main_file_path); + log::info!("Compiling program located in {:?}", main_file_path); fn run(main_file_path: PathBuf) { diff --git a/leo/errors/cli.rs b/leo/errors/cli.rs index 734389254e..f8a31d7cd6 100644 --- a/leo/errors/cli.rs +++ b/leo/errors/cli.rs @@ -3,6 +3,9 @@ use crate::errors::*; #[derive(Debug, Fail)] pub enum CLIError { + #[fail(display = "{}", _0)] + BuildError(BuildError), + #[fail(display = "{}: {}", _0, _1)] Crate(&'static str, String), @@ -32,6 +35,12 @@ pub enum CLIError { } +impl From for CLIError { + fn from(error: BuildError) -> Self { + CLIError::BuildError(error) + } +} + impl From for CLIError { fn from(error: InitError) -> Self { CLIError::InitError(error) diff --git a/leo/errors/commands/build.rs b/leo/errors/commands/build.rs new file mode 100644 index 0000000000..f74f995c33 --- /dev/null +++ b/leo/errors/commands/build.rs @@ -0,0 +1,20 @@ +use crate::errors::ManifestError; + +use std::ffi::OsString; + +#[derive(Debug, Fail)] +pub enum BuildError { + + #[fail(display = "main file {:?} does not exist", _0)] + MainFileDoesNotExist(OsString), + + #[fail(display = "{}", _0)] + ManifestError(ManifestError), + +} + +impl From for BuildError { + fn from(error: ManifestError) -> Self { + BuildError::ManifestError(error) + } +} diff --git a/leo/errors/commands/mod.rs b/leo/errors/commands/mod.rs index 634e0b58fc..968a4b6e24 100644 --- a/leo/errors/commands/mod.rs +++ b/leo/errors/commands/mod.rs @@ -1,3 +1,6 @@ +pub mod build; +pub use self::build::*; + pub mod init; pub use self::init::*; diff --git a/leo/errors/commands/run.rs b/leo/errors/commands/run.rs index 7d2c8e8696..5c16d35933 100644 --- a/leo/errors/commands/run.rs +++ b/leo/errors/commands/run.rs @@ -1,29 +1,16 @@ use crate::errors::ManifestError; use std::ffi::OsString; -use std::io; #[derive(Debug, Fail)] pub enum RunError { - #[fail(display = "root directory {:?} creating: {}", _0, _1)] - CreatingRootDirectory(OsString, io::Error), - - #[fail(display = "directory {:?} does not exist", _0)] - DirectoryDoesNotExist(OsString), - #[fail(display = "main file {:?} does not exist", _0)] MainFileDoesNotExist(OsString), #[fail(display = "{}", _0)] ManifestError(ManifestError), - #[fail(display = "package at path {:?} already exists", _0)] - PackageAlreadyExists(OsString), - - #[fail(display = "package name is missing - {:?}", _0)] - ProjectNameInvalid(OsString), - } impl From for RunError { diff --git a/leo/main.rs b/leo/main.rs index 2d4aaa1e41..57b60346c4 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -21,6 +21,7 @@ fn main() -> Result<(), CLIError> { .subcommands(vec![ NewCommand::new(), InitCommand::new(), + BuildCommand::new(), RunCommand::new(), ]) .set_term_width(0) @@ -30,7 +31,8 @@ fn main() -> Result<(), CLIError> { match arguments.subcommand() { ("new", Some(arguments)) => NewCommand::output(NewCommand::parse(arguments)?), ("init", Some(arguments)) => InitCommand::output(InitCommand::parse(arguments)?), + ("build", Some(arguments)) => BuildCommand::output(BuildCommand::parse(arguments)?), ("run", Some(arguments)) => RunCommand::output(RunCommand::parse(arguments)?), _ => unreachable!(), } -} \ No newline at end of file +} From a72e4ce4a3331e295c8d26fb34dce331a554e725 Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 18:11:49 -0700 Subject: [PATCH 13/16] Optimize implementation to use subcommands --- leo/cli.rs | 3 ++- leo/commands/build.rs | 7 +++--- leo/commands/init.rs | 3 ++- leo/commands/new.rs | 3 ++- leo/commands/run.rs | 50 ++++++++----------------------------------- leo/compiler.rs | 1 + leo/main.rs | 18 +++++++++++----- 7 files changed, 33 insertions(+), 52 deletions(-) diff --git a/leo/cli.rs b/leo/cli.rs index e51f635f1d..5ba8367697 100644 --- a/leo/cli.rs +++ b/leo/cli.rs @@ -5,6 +5,7 @@ use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; pub trait CLI { type Options; + type Output; const NAME: NameType; const ABOUT: AboutType; @@ -73,5 +74,5 @@ pub trait CLI { fn parse(arguments: &ArgMatches) -> Result; #[cfg_attr(tarpaulin, skip)] - fn output(options: Self::Options) -> Result<(), CLIError>; + fn output(options: Self::Options) -> Result; } diff --git a/leo/commands/build.rs b/leo/commands/build.rs index daaf741a2f..80f5baa0b0 100644 --- a/leo/commands/build.rs +++ b/leo/commands/build.rs @@ -16,6 +16,7 @@ pub struct BuildCommand; impl CLI for BuildCommand { type Options = (); + type Output = Compiler; const NAME: NameType = "build"; const ABOUT: AboutType = "Compile the current package"; @@ -30,7 +31,7 @@ impl CLI for BuildCommand { } #[cfg_attr(tarpaulin, skip)] - fn output(_options: Self::Options) -> Result<(), CLIError> { + fn output(_options: Self::Options) -> Result { let path = current_dir()?; let _manifest = Manifest::try_from(&path)?; @@ -56,8 +57,8 @@ impl CLI for BuildCommand { log::info!("Compiling program located in {:?}", main_file_path); // Compile from the main file path - let _circuit = Compiler::::init(main_file_path); + let circuit = Compiler::::init(main_file_path); - Ok(()) + Ok(circuit) } } diff --git a/leo/commands/init.rs b/leo/commands/init.rs index 3c6b82ec91..5ccfc1bb0e 100644 --- a/leo/commands/init.rs +++ b/leo/commands/init.rs @@ -12,6 +12,7 @@ pub struct InitCommand; impl CLI for InitCommand { type Options = Option; + type Output = (); const NAME: NameType = "init"; const ABOUT: AboutType = "Creates a new Leo package in an existing directory"; @@ -26,7 +27,7 @@ impl CLI for InitCommand { } #[cfg_attr(tarpaulin, skip)] - fn output(options: Self::Options) -> Result<(), CLIError> { + fn output(options: Self::Options) -> Result { let name = options; let path = current_dir()?; diff --git a/leo/commands/new.rs b/leo/commands/new.rs index c38199489a..7878c7c735 100644 --- a/leo/commands/new.rs +++ b/leo/commands/new.rs @@ -13,6 +13,7 @@ pub struct NewCommand; impl CLI for NewCommand { type Options = Option; + type Output = (); const NAME: NameType = "new"; const ABOUT: AboutType = "Creates a new Leo package"; @@ -33,7 +34,7 @@ impl CLI for NewCommand { } #[cfg_attr(tarpaulin, skip)] - fn output(options: Self::Options) -> Result<(), CLIError> { + fn output(options: Self::Options) -> Result { let mut path = current_dir()?; // Derive the package name diff --git a/leo/commands/run.rs b/leo/commands/run.rs index 610427f09f..30c24a108a 100644 --- a/leo/commands/run.rs +++ b/leo/commands/run.rs @@ -1,22 +1,18 @@ use crate::{cli::*, cli_types::*}; +use crate::commands::BuildCommand; use crate::compiler::Compiler; -use crate::directories::{OutputsDirectory, source::SOURCE_DIRECTORY_NAME}; -use crate::errors::{CLIError, RunError}; -use crate::files::{MainFile, MAIN_FILE_NAME}; -use crate::manifest::Manifest; +use crate::errors::CLIError; use snarkos_curves::bls12_377::Fr; use clap::ArgMatches; -use std::convert::TryFrom; -use std::env::current_dir; -use std::path::PathBuf; #[derive(Debug)] pub struct RunCommand; impl CLI for RunCommand { type Options = (); + type Output = (); const NAME: NameType = "run"; const ABOUT: AboutType = "Run a program with inputs"; @@ -31,32 +27,10 @@ impl CLI for RunCommand { } #[cfg_attr(tarpaulin, skip)] - fn output(_options: Self::Options) -> Result<(), CLIError> { - let path = current_dir()?; - let _manifest = Manifest::try_from(&path)?; + fn output(options: Self::Options) -> Result<(), CLIError> { + let circuit = BuildCommand::output(options)?; - // Sanitize the package path to the root directory - let mut package_path = path.clone(); - if package_path.is_file() { - package_path.pop(); - } - - // Verify the main file exists - if !MainFile::exists_at(&package_path) { - return Err(RunError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into()); - } - - // Create the outputs directory - OutputsDirectory::create(&package_path)?; - - // Construct the path to the main file in the source directory - let mut main_file_path = package_path.clone(); - main_file_path.push(SOURCE_DIRECTORY_NAME); - main_file_path.push(MAIN_FILE_NAME); - - log::info!("Compiling program located in {:?}", main_file_path); - - fn run(main_file_path: PathBuf) { + fn run(circuit: Compiler) { use snarkos_algorithms::snark::{create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof}; use snarkos_curves::bls12_377::Bls12_377; @@ -72,20 +46,14 @@ impl CLI for RunCommand { let start = Instant::now(); - let params = { - let circuit = Compiler::::init(main_file_path.clone()); - generate_random_parameters::(circuit, rng).unwrap() - }; + let params = generate_random_parameters::(circuit.clone(), rng).unwrap(); let prepared_verifying_key = prepare_verifying_key::(¶ms.vk); setup += start.elapsed(); let start = Instant::now(); - let proof = { - let circuit = Compiler::::init(main_file_path); - create_random_proof(circuit, ¶ms, rng).unwrap() - }; + let proof = create_random_proof(circuit, ¶ms, rng).unwrap(); proving += start.elapsed(); @@ -108,7 +76,7 @@ impl CLI for RunCommand { println!(" "); } - run(main_file_path); + run(circuit); // let source_files = SourceDirectory::files(&package_path)?; // BuildDirectory::create(&circuit_path).map_err(Error::BuildDirectory)?; diff --git a/leo/compiler.rs b/leo/compiler.rs index d7243f91a3..ed91868252 100644 --- a/leo/compiler.rs +++ b/leo/compiler.rs @@ -13,6 +13,7 @@ use std::{ path::PathBuf, }; +#[derive(Clone)] pub struct Compiler { main_file_path: PathBuf, _engine: PhantomData, diff --git a/leo/main.rs b/leo/main.rs index 57b60346c4..958e21735e 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -27,12 +27,20 @@ fn main() -> Result<(), CLIError> { .set_term_width(0) .get_matches(); - match arguments.subcommand() { - ("new", Some(arguments)) => NewCommand::output(NewCommand::parse(arguments)?), - ("init", Some(arguments)) => InitCommand::output(InitCommand::parse(arguments)?), - ("build", Some(arguments)) => BuildCommand::output(BuildCommand::parse(arguments)?), - ("run", Some(arguments)) => RunCommand::output(RunCommand::parse(arguments)?), + ("new", Some(arguments)) => { + NewCommand::output(NewCommand::parse(arguments)?) + }, + ("init", Some(arguments)) => { + InitCommand::output(InitCommand::parse(arguments)?) + }, + ("build", Some(arguments)) => { + BuildCommand::output(BuildCommand::parse(arguments)?)?; + Ok(()) + }, + ("run", Some(arguments)) => { + RunCommand::output(RunCommand::parse(arguments)?) + }, _ => unreachable!(), } } From 9f60cf3393e89dd3d26a93e9ed0906df1e72bd5c Mon Sep 17 00:00:00 2001 From: howardwu Date: Sat, 25 Apr 2020 18:25:36 -0700 Subject: [PATCH 14/16] Adds command --- leo/commands/mod.rs | 3 ++ leo/commands/run.rs | 87 ++++++++++++------------------------------- leo/commands/setup.rs | 50 +++++++++++++++++++++++++ leo/main.rs | 15 ++++---- 4 files changed, 83 insertions(+), 72 deletions(-) create mode 100644 leo/commands/setup.rs diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs index 968a4b6e24..9a7bff1df7 100644 --- a/leo/commands/mod.rs +++ b/leo/commands/mod.rs @@ -9,3 +9,6 @@ pub use self::new::*; pub mod run; pub use self::run::*; + +pub mod setup; +pub use self::setup::*; diff --git a/leo/commands/run.rs b/leo/commands/run.rs index 30c24a108a..840a2b4ffb 100644 --- a/leo/commands/run.rs +++ b/leo/commands/run.rs @@ -1,11 +1,12 @@ use crate::{cli::*, cli_types::*}; -use crate::commands::BuildCommand; -use crate::compiler::Compiler; +use crate::commands::SetupCommand; use crate::errors::CLIError; -use snarkos_curves::bls12_377::Fr; +use snarkos_algorithms::snark::{create_random_proof, verify_proof}; use clap::ArgMatches; +use rand::thread_rng; +use std::time::{Duration, Instant}; #[derive(Debug)] pub struct RunCommand; @@ -28,76 +29,34 @@ impl CLI for RunCommand { #[cfg_attr(tarpaulin, skip)] fn output(options: Self::Options) -> Result<(), CLIError> { - let circuit = BuildCommand::output(options)?; + let (circuit, parameters, prepared_verifying_key) = SetupCommand::output(options)?; - fn run(circuit: Compiler) { + let rng = &mut thread_rng(); - use snarkos_algorithms::snark::{create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof}; - use snarkos_curves::bls12_377::Bls12_377; + let mut proving = Duration::new(0, 0); + let mut verifying = Duration::new(0, 0); - use rand::thread_rng; - use std::time::{Duration, Instant}; + let start = Instant::now(); + let proof = create_random_proof(circuit, ¶meters, rng).unwrap(); - let mut setup = Duration::new(0, 0); - let mut proving = Duration::new(0, 0); - let mut verifying = Duration::new(0, 0); + proving += start.elapsed(); - let rng = &mut thread_rng(); + // let _inputs: Vec<_> = [1u32; 1].to_vec(); - let start = Instant::now(); + let start = Instant::now(); - let params = generate_random_parameters::(circuit.clone(), rng).unwrap(); + let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap(); - let prepared_verifying_key = prepare_verifying_key::(¶ms.vk); + verifying += start.elapsed(); - setup += start.elapsed(); - - let start = Instant::now(); - let proof = create_random_proof(circuit, ¶ms, rng).unwrap(); - - proving += start.elapsed(); - - // let _inputs: Vec<_> = [1u32; 1].to_vec(); - - let start = Instant::now(); - - let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap(); - - verifying += start.elapsed(); - - println!(" "); - println!(" Setup time : {:?} milliseconds", setup.as_millis()); - println!(" Prover time : {:?} milliseconds", proving.as_millis()); - println!( - " Verifier time : {:?} milliseconds", - verifying.as_millis() - ); - println!(" Verifier output : {}", is_success); - println!(" "); - } - - run(circuit); - - // let source_files = SourceDirectory::files(&package_path)?; - // BuildDirectory::create(&circuit_path).map_err(Error::BuildDirectory)?; - // DataDirectory::create(&circuit_path).map_err(Error::DataDirectory)?; - - // Compiler::build( - // self.verbosity, - // &self.witness, - // &self.public_data, - // &self.circuit, - // &source_file_paths, - // ) - // .map_err(Error::Compiler)?; - // - // VirtualMachine::run( - // self.verbosity, - // &self.circuit, - // &self.witness, - // &self.public_data, - // ) - // .map_err(Error::VirtualMachine)?; + println!(" "); + println!(" Prover time : {:?} milliseconds", proving.as_millis()); + println!( + " Verifier time : {:?} milliseconds", + verifying.as_millis() + ); + println!(" Verifier output : {}", is_success); + println!(" "); Ok(()) } diff --git a/leo/commands/setup.rs b/leo/commands/setup.rs new file mode 100644 index 0000000000..506f85ce71 --- /dev/null +++ b/leo/commands/setup.rs @@ -0,0 +1,50 @@ +use crate::{cli::*, cli_types::*}; +use crate::commands::BuildCommand; +use crate::compiler::Compiler; +use crate::errors::CLIError; + +use snarkos_algorithms::snark::{generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey}; +use snarkos_curves::bls12_377::{Bls12_377, Fr}; + +use clap::ArgMatches; +use rand::thread_rng; +use std::time::Instant; + +#[derive(Debug)] +pub struct SetupCommand; + +impl CLI for SetupCommand { + type Options = (); + type Output = (Compiler, Parameters, PreparedVerifyingKey); + + const NAME: NameType = "setup"; + const ABOUT: AboutType = "Run a program setup"; + const ARGUMENTS: &'static [ArgumentType] = &[]; + const FLAGS: &'static [FlagType] = &[]; + const OPTIONS: &'static [OptionType] = &[]; + const SUBCOMMANDS: &'static [SubCommandType] = &[]; + + #[cfg_attr(tarpaulin, skip)] + fn parse(_arguments: &ArgMatches) -> Result { + Ok(()) + } + + #[cfg_attr(tarpaulin, skip)] + fn output(options: Self::Options) -> Result { + let circuit = BuildCommand::output(options)?; + + let start = Instant::now(); + + let rng = &mut thread_rng(); + let parameters = generate_random_parameters::(circuit.clone(), rng).unwrap(); + let prepared_verifying_key = prepare_verifying_key::(¶meters.vk); + + let finish = start.elapsed(); + + println!(" "); + println!(" Setup time : {:?} milliseconds", finish.as_millis()); + println!(" "); + + Ok((circuit, parameters, prepared_verifying_key)) + } +} diff --git a/leo/main.rs b/leo/main.rs index 958e21735e..1f322217e7 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -22,25 +22,24 @@ fn main() -> Result<(), CLIError> { NewCommand::new(), InitCommand::new(), BuildCommand::new(), + SetupCommand::new(), RunCommand::new(), ]) .set_term_width(0) .get_matches(); match arguments.subcommand() { - ("new", Some(arguments)) => { - NewCommand::output(NewCommand::parse(arguments)?) - }, - ("init", Some(arguments)) => { - InitCommand::output(InitCommand::parse(arguments)?) - }, + ("new", Some(arguments)) => NewCommand::output(NewCommand::parse(arguments)?), + ("init", Some(arguments)) => InitCommand::output(InitCommand::parse(arguments)?), ("build", Some(arguments)) => { BuildCommand::output(BuildCommand::parse(arguments)?)?; Ok(()) }, - ("run", Some(arguments)) => { - RunCommand::output(RunCommand::parse(arguments)?) + ("setup", Some(arguments)) => { + SetupCommand::output(SetupCommand::parse(arguments)?)?; + Ok(()) }, + ("run", Some(arguments)) => RunCommand::output(RunCommand::parse(arguments)?), _ => unreachable!(), } } From 026b59a67a8613700cd1131e6176baefcaeab70c Mon Sep 17 00:00:00 2001 From: howardwu Date: Sun, 26 Apr 2020 22:34:15 -0700 Subject: [PATCH 15/16] Rename program to compiler --- Cargo.lock | 6 +++--- Cargo.toml | 4 ++-- benchmark/Cargo.toml | 2 +- {program => compiler}/Cargo.toml | 2 +- {program => compiler}/README.md | 0 {program => compiler}/src/ast.rs | 0 {program => compiler}/src/constraints/boolean.rs | 0 {program => compiler}/src/constraints/constraints.rs | 0 {program => compiler}/src/constraints/expression.rs | 0 {program => compiler}/src/constraints/field_element.rs | 0 {program => compiler}/src/constraints/integer.rs | 0 {program => compiler}/src/constraints/mod.rs | 0 {program => compiler}/src/constraints/resolved_program.rs | 0 {program => compiler}/src/constraints/resolved_value.rs | 0 {program => compiler}/src/constraints/statement.rs | 0 {program => compiler}/src/imports.rs | 0 {program => compiler}/src/leo.pest | 0 {program => compiler}/src/lib.rs | 0 {program => compiler}/src/types.rs | 0 {program => compiler}/src/types_display.rs | 0 {program => compiler}/src/types_from.rs | 0 hello_world/Leo.toml | 6 ------ leo/compiler.rs | 6 +++--- 23 files changed, 10 insertions(+), 16 deletions(-) rename {program => compiler}/Cargo.toml (96%) rename {program => compiler}/README.md (100%) rename {program => compiler}/src/ast.rs (100%) rename {program => compiler}/src/constraints/boolean.rs (100%) rename {program => compiler}/src/constraints/constraints.rs (100%) rename {program => compiler}/src/constraints/expression.rs (100%) rename {program => compiler}/src/constraints/field_element.rs (100%) rename {program => compiler}/src/constraints/integer.rs (100%) rename {program => compiler}/src/constraints/mod.rs (100%) rename {program => compiler}/src/constraints/resolved_program.rs (100%) rename {program => compiler}/src/constraints/resolved_value.rs (100%) rename {program => compiler}/src/constraints/statement.rs (100%) rename {program => compiler}/src/imports.rs (100%) rename {program => compiler}/src/leo.pest (100%) rename {program => compiler}/src/lib.rs (100%) rename {program => compiler}/src/types.rs (100%) rename {program => compiler}/src/types_display.rs (100%) rename {program => compiler}/src/types_from.rs (100%) delete mode 100644 hello_world/Leo.toml diff --git a/Cargo.lock b/Cargo.lock index 9913b156ec..5556ed3788 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -616,7 +616,7 @@ dependencies = [ "env_logger", "failure", "from-pest", - "leo-program", + "leo-compiler", "log", "rand 0.7.3", "rand_core 0.5.1", @@ -636,7 +636,7 @@ name = "leo-benchmark" version = "0.1.0" dependencies = [ "from-pest", - "leo-program", + "leo-compiler", "rand 0.7.3", "snarkos-algorithms", "snarkos-curves", @@ -646,7 +646,7 @@ dependencies = [ ] [[package]] -name = "leo-program" +name = "leo-compiler" version = "0.1.0" dependencies = [ "from-pest", diff --git a/Cargo.toml b/Cargo.toml index 7afe57dd86..55047cccab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,10 +13,10 @@ name = "leo" path = "leo/main.rs" [workspace] -members = [ "benchmark", "program" ] +members = [ "benchmark", "compiler" ] [dependencies] -leo-program = { path = "./program", version = "0.1.0" } +leo-compiler = { path = "compiler", version = "0.1.0" } snarkos-algorithms = { path = "../snarkOS/algorithms", version = "0.8.0" } snarkos-curves = { path = "../snarkOS/curves", version = "0.8.0" } diff --git a/benchmark/Cargo.toml b/benchmark/Cargo.toml index bd5a8fb8a2..89857c2b2f 100644 --- a/benchmark/Cargo.toml +++ b/benchmark/Cargo.toml @@ -5,7 +5,7 @@ authors = ["The Aleo Team "] edition = "2018" [dependencies] -leo-program = { path = "../program", version = "0.1.0" } +leo-compiler = { path = "../compiler", version = "0.1.0" } snarkos-algorithms = { path = "../../snarkOS/algorithms", version = "0.8.0" } snarkos-curves = { path = "../../snarkOS/curves", version = "0.8.0" } diff --git a/program/Cargo.toml b/compiler/Cargo.toml similarity index 96% rename from program/Cargo.toml rename to compiler/Cargo.toml index edf6119c79..68ab501c4d 100644 --- a/program/Cargo.toml +++ b/compiler/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "leo-program" +name = "leo-compiler" version = "0.1.0" authors = ["The Aleo Team "] edition = "2018" diff --git a/program/README.md b/compiler/README.md similarity index 100% rename from program/README.md rename to compiler/README.md diff --git a/program/src/ast.rs b/compiler/src/ast.rs similarity index 100% rename from program/src/ast.rs rename to compiler/src/ast.rs diff --git a/program/src/constraints/boolean.rs b/compiler/src/constraints/boolean.rs similarity index 100% rename from program/src/constraints/boolean.rs rename to compiler/src/constraints/boolean.rs diff --git a/program/src/constraints/constraints.rs b/compiler/src/constraints/constraints.rs similarity index 100% rename from program/src/constraints/constraints.rs rename to compiler/src/constraints/constraints.rs diff --git a/program/src/constraints/expression.rs b/compiler/src/constraints/expression.rs similarity index 100% rename from program/src/constraints/expression.rs rename to compiler/src/constraints/expression.rs diff --git a/program/src/constraints/field_element.rs b/compiler/src/constraints/field_element.rs similarity index 100% rename from program/src/constraints/field_element.rs rename to compiler/src/constraints/field_element.rs diff --git a/program/src/constraints/integer.rs b/compiler/src/constraints/integer.rs similarity index 100% rename from program/src/constraints/integer.rs rename to compiler/src/constraints/integer.rs diff --git a/program/src/constraints/mod.rs b/compiler/src/constraints/mod.rs similarity index 100% rename from program/src/constraints/mod.rs rename to compiler/src/constraints/mod.rs diff --git a/program/src/constraints/resolved_program.rs b/compiler/src/constraints/resolved_program.rs similarity index 100% rename from program/src/constraints/resolved_program.rs rename to compiler/src/constraints/resolved_program.rs diff --git a/program/src/constraints/resolved_value.rs b/compiler/src/constraints/resolved_value.rs similarity index 100% rename from program/src/constraints/resolved_value.rs rename to compiler/src/constraints/resolved_value.rs diff --git a/program/src/constraints/statement.rs b/compiler/src/constraints/statement.rs similarity index 100% rename from program/src/constraints/statement.rs rename to compiler/src/constraints/statement.rs diff --git a/program/src/imports.rs b/compiler/src/imports.rs similarity index 100% rename from program/src/imports.rs rename to compiler/src/imports.rs diff --git a/program/src/leo.pest b/compiler/src/leo.pest similarity index 100% rename from program/src/leo.pest rename to compiler/src/leo.pest diff --git a/program/src/lib.rs b/compiler/src/lib.rs similarity index 100% rename from program/src/lib.rs rename to compiler/src/lib.rs diff --git a/program/src/types.rs b/compiler/src/types.rs similarity index 100% rename from program/src/types.rs rename to compiler/src/types.rs diff --git a/program/src/types_display.rs b/compiler/src/types_display.rs similarity index 100% rename from program/src/types_display.rs rename to compiler/src/types_display.rs diff --git a/program/src/types_from.rs b/compiler/src/types_from.rs similarity index 100% rename from program/src/types_from.rs rename to compiler/src/types_from.rs diff --git a/hello_world/Leo.toml b/hello_world/Leo.toml deleted file mode 100644 index 936e861ed0..0000000000 --- a/hello_world/Leo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "hello_world" -version = "0.1.0" -authors = "Satoshi Nakamoto" -license = "Apache/MIT" - diff --git a/leo/compiler.rs b/leo/compiler.rs index ed91868252..1441db540c 100644 --- a/leo/compiler.rs +++ b/leo/compiler.rs @@ -1,4 +1,4 @@ -use leo_program::{self, ast}; +use leo_compiler::{self, ast}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ @@ -40,11 +40,11 @@ impl ConstraintSynthesizer for Compiler { let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); log::debug!("{:#?}", syntax_tree); - let program = leo_program::Program::<'_, F>::from(syntax_tree); + let program = leo_compiler::Program::<'_, F>::from(syntax_tree); log::info!(" compiled: {:#?}", program); let program = program.name("simple".into()); - leo_program::ResolvedProgram::generate_constraints(cs, program); + leo_compiler::ResolvedProgram::generate_constraints(cs, program); Ok(()) } From d1158708152dc450979fa3829c3d29a333ce8aba Mon Sep 17 00:00:00 2001 From: howardwu Date: Sun, 26 Apr 2020 22:37:08 -0700 Subject: [PATCH 16/16] Moves compiler.rs to leo-compiler module --- Cargo.lock | 1 + compiler/Cargo.toml | 1 + {leo => compiler/src}/compiler.rs | 6 +++--- compiler/src/lib.rs | 2 ++ leo/commands/build.rs | 2 +- leo/commands/setup.rs | 2 +- leo/lib.rs | 1 - 7 files changed, 9 insertions(+), 6 deletions(-) rename {leo => compiler/src}/compiler.rs (87%) diff --git a/Cargo.lock b/Cargo.lock index 5556ed3788..a354c85b5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -651,6 +651,7 @@ version = "0.1.0" dependencies = [ "from-pest", "lazy_static", + "log", "pest", "pest-ast", "pest_derive", diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 68ab501c4d..eee6323fbc 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -13,6 +13,7 @@ snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" } from-pest = { version = "0.3.1" } lazy_static = { version = "1.3.0" } +log = { version = "0.4" } pest = { version = "2.0" } pest-ast = { version = "0.3.3" } pest_derive = { version = "2.0" } diff --git a/leo/compiler.rs b/compiler/src/compiler.rs similarity index 87% rename from leo/compiler.rs rename to compiler/src/compiler.rs index 1441db540c..14f95ffa5c 100644 --- a/leo/compiler.rs +++ b/compiler/src/compiler.rs @@ -1,4 +1,4 @@ -use leo_compiler::{self, ast}; +use crate::{ast, Program, ResolvedProgram}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ @@ -40,11 +40,11 @@ impl ConstraintSynthesizer for Compiler { let syntax_tree = ast::File::from_pest(&mut file).expect("infallible"); log::debug!("{:#?}", syntax_tree); - let program = leo_compiler::Program::<'_, F>::from(syntax_tree); + let program = Program::<'_, F>::from(syntax_tree); log::info!(" compiled: {:#?}", program); let program = program.name("simple".into()); - leo_compiler::ResolvedProgram::generate_constraints(cs, program); + ResolvedProgram::generate_constraints(cs, program); Ok(()) } diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 33b53b3b98..86ef52e8bb 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -10,6 +10,8 @@ extern crate pest_derive; pub mod ast; +pub mod compiler; + pub mod constraints; pub use self::constraints::*; diff --git a/leo/commands/build.rs b/leo/commands/build.rs index 80f5baa0b0..873ab5833b 100644 --- a/leo/commands/build.rs +++ b/leo/commands/build.rs @@ -1,9 +1,9 @@ use crate::{cli::*, cli_types::*}; -use crate::compiler::Compiler; use crate::directories::{OutputsDirectory, source::SOURCE_DIRECTORY_NAME}; use crate::errors::{CLIError, BuildError}; use crate::files::{MainFile, MAIN_FILE_NAME}; use crate::manifest::Manifest; +use leo_compiler::compiler::Compiler; use snarkos_curves::bls12_377::Fr; diff --git a/leo/commands/setup.rs b/leo/commands/setup.rs index 506f85ce71..36f2ca2367 100644 --- a/leo/commands/setup.rs +++ b/leo/commands/setup.rs @@ -1,7 +1,7 @@ use crate::{cli::*, cli_types::*}; use crate::commands::BuildCommand; -use crate::compiler::Compiler; use crate::errors::CLIError; +use leo_compiler::compiler::Compiler; use snarkos_algorithms::snark::{generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey}; use snarkos_curves::bls12_377::{Bls12_377, Fr}; diff --git a/leo/lib.rs b/leo/lib.rs index 84a0ef6202..55d29c86db 100644 --- a/leo/lib.rs +++ b/leo/lib.rs @@ -5,7 +5,6 @@ extern crate failure; pub mod cli; pub mod cli_types; pub mod commands; -pub mod compiler; pub mod directories; pub mod errors; pub mod files;