impl leo run

This commit is contained in:
collin 2022-07-12 14:44:20 -07:00
parent dcd6501262
commit fa28678a26
9 changed files with 63 additions and 91 deletions

View File

@ -19,11 +19,10 @@ use crate::{normalize_json_value, remove_key_from_json};
use super::*;
use leo_errors::{AstError, Result};
/// Input data which includes [`ProgramInput`] and [`ProgramState`].
/// Input data which includes [`ProgramInput`].
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Input {
pub program_input: ProgramInput,
pub program_state: ProgramState,
}
impl Input {
@ -34,13 +33,26 @@ impl Input {
}
/// A raw unprocessed input or state file data. Used for future conversion
/// into [`ProgramInput`] or [`ProgramState`].
/// into [`ProgramInput`].
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct InputAst {
pub sections: Vec<Section>,
}
impl InputAst {
/// Returns all values of the input AST for execution with `leo run`.
pub fn values(&self) -> Vec<String> {
self.sections
.iter()
.flat_map(|section| {
section
.definitions
.iter()
.map(|definition| definition.value.to_string())
})
.collect::<Vec<_>>()
}
/// Serializes the `Input` into a JSON Value.
pub fn to_json_value(&self) -> Result<serde_json::Value> {
Ok(serde_json::to_value(&self).map_err(|e| AstError::failed_to_convert_ast_to_json_value(&e))?)

View File

@ -26,9 +26,6 @@ pub use input_value::*;
pub mod program_input;
pub use program_input::*;
pub mod program_state;
pub use program_state::*;
pub mod section;
pub use section::*;

View File

@ -20,24 +20,17 @@ use super::*;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ProgramInput {
pub main: Definitions,
pub registers: Definitions,
}
impl TryFrom<InputAst> for ProgramInput {
type Error = LeoError;
fn try_from(input: InputAst) -> Result<Self> {
let mut main = IndexMap::new();
let mut registers = IndexMap::new();
for section in input.sections {
let target = match section.name {
sym::main => &mut main,
sym::registers => &mut registers,
_ => {
return Err(
InputError::unexpected_section(&["main", "registers"], section.name, section.span).into(),
)
}
_ => return Err(InputError::unexpected_section(&["main"], section.name, section.span).into()),
};
for definition in section.definitions {
@ -48,6 +41,6 @@ impl TryFrom<InputAst> for ProgramInput {
}
}
Ok(ProgramInput { main, registers })
Ok(ProgramInput { main })
}
}

View File

@ -1,50 +0,0 @@
// Copyright (C) 2019-2022 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use super::*;
/// Processed Program state.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ProgramState {
pub state: Definitions,
}
impl TryFrom<InputAst> for ProgramState {
type Error = LeoError;
fn try_from(input: InputAst) -> Result<Self> {
let mut state = IndexMap::new();
for section in input.sections {
if matches!(section.name, sym::state | sym::record | sym::state_leaf) {
for definition in section.definitions {
state.insert(
definition.name.name,
InputValue::try_from((definition.type_, definition.value))?,
);
}
} else {
return Err(InputError::unexpected_section(
&["state", "record", "state_leaf"],
section.name,
section.span,
)
.into());
}
}
Ok(ProgramState { state })
}
}

View File

@ -30,7 +30,7 @@ pub(crate) use tokenizer::*;
pub mod parser;
pub use parser::*;
use leo_ast::{Ast, Input, ProgramInput, ProgramState};
use leo_ast::{Ast, Input, ProgramInput};
use leo_errors::emitter::Handler;
use leo_errors::Result;
@ -46,8 +46,5 @@ pub fn parse_ast(handler: &Handler, source: &str, start_pos: BytePos) -> Result<
pub fn parse_program_inputs(handler: &Handler, input_string: &str, start_pos: BytePos) -> Result<Input> {
let program_input: ProgramInput = parser::parse_input(handler, input_string, start_pos)?.try_into()?;
Ok(Input {
program_input,
program_state: ProgramState::default(),
})
Ok(Input { program_input })
}

View File

@ -16,7 +16,7 @@
use super::*;
use crate::{commands::Command, context::Context};
use leo_compiler::{Ast, Compiler, InputAst, OutputOptions};
use leo_compiler::{Compiler, InputAst, OutputOptions};
use leo_errors::{CliError, Result};
use leo_package::{
inputs::InputFile,
@ -75,7 +75,7 @@ pub struct Build {
impl Command for Build {
type Input = ();
type Output = (Option<InputAst>, Ast, bool);
type Output = Option<InputAst>;
fn log_span(&self) -> Span {
tracing::span!(tracing::Level::INFO, "Build")
@ -89,8 +89,8 @@ impl Command for Build {
// Get the package path.
let path = context.dir()?;
// Get the package name.
let package_name = context.program_name()?;
// Get the program name.
let program_name = context.program_name()?;
// Sanitize the package path to the root directory.
let mut package_path = path.clone();
@ -115,7 +115,7 @@ impl Command for Build {
main_file_path.push(MAIN_FILENAME);
// Load the input file at `package_name.in`
let input_path = InputFile::new(&package_name).setup_file_path(&path);
let input_path = InputFile::new(&program_name).setup_file_path(&path);
// Create the outputs directory
OutputsDirectory::create(&package_path)?;
@ -128,7 +128,7 @@ impl Command for Build {
// Create a new instance of the Leo compiler.
let mut program = Compiler::new(
package_name.to_string(),
program_name.to_string(),
String::from("aleo"),
&handler,
main_file_path,
@ -163,7 +163,7 @@ impl Command for Build {
}
// If a checksum file exists, check if it differs from the new checksum
let checksum_file = ChecksumFile::new(&package_name);
let checksum_file = ChecksumFile::new(&program_name);
let checksum_differs = if checksum_file.exists_at(&package_path) {
let previous_checksum = checksum_file.read_from(&package_path)?;
program_checksum != previous_checksum
@ -182,6 +182,6 @@ impl Command for Build {
tracing::info!("Complete");
Ok((program.input_ast, program.ast, checksum_differs))
Ok(program.input_ast)
}
}

View File

@ -39,6 +39,7 @@ use std::time::Instant;
use tracing::span::Span;
pub(crate) type Network = snarkvm::prelude::Testnet3;
pub(crate) const ALEO_CLI_COMMAND: &str = "aleo";
/// Base trait for the Leo CLI, see methods and their documentation for details.
pub trait Command {

View File

@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::commands::ALEO_CLI_COMMAND;
use crate::{commands::Command, context::Context};
use leo_errors::{PackageError, Result};
use leo_package::package::Package;
@ -43,8 +44,11 @@ impl Command for New {
}
fn apply(self, _context: Context, _: Self::Input) -> Result<Self::Output> {
tracing::info!("Starting...");
// Call the `aleo new` command from the Aleo SDK.
let command = AleoNew::try_parse_from(&["aleo", &self.name]).expect("Failed to parse `aleo new` command");
let command =
AleoNew::try_parse_from(&[ALEO_CLI_COMMAND, &self.name]).expect("Failed to parse `aleo new` command");
let result = command.parse().expect("Failed to create a new Aleo project");
// Derive the program directory path.
@ -54,9 +58,9 @@ impl Command for New {
// Initialize the Leo package in the directory created by `aleo new`.
Package::initialize(&self.name, &path)?;
// todo: modify the readme file to build with `leo build`.
// todo: modify the readme file to recommend building with `leo build`.
// Log success.
// Log the output of the `aleo new` command.
tracing::info!("{}", result);
Ok(())

View File

@ -15,10 +15,14 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use super::build::BuildOptions;
use crate::{commands::Command, context::Context};
use crate::commands::ALEO_CLI_COMMAND;
use crate::{
commands::{Build, Command},
context::Context,
};
use leo_errors::Result;
// use aleo::commands::CLI as AleoCLI;
use aleo::commands::Run as AleoRun;
use clap::StructOpt;
use tracing::span::Span;
@ -34,25 +38,39 @@ pub struct Run {
}
impl Command for Run {
type Input = ();
type Input = <Build as Command>::Output;
type Output = ();
fn log_span(&self) -> Span {
tracing::span!(tracing::Level::INFO, "Executing")
}
fn prelude(&self, _context: Context) -> Result<Self::Input> {
Ok(()) // todo: call aleo build here?
fn prelude(&self, context: Context) -> Result<Self::Input> {
(Build {
compiler_options: self.compiler_options.clone(),
})
.execute(context)
}
fn apply(self, _context: Context, _input: Self::Input) -> Result<Self::Output> {
fn apply(self, _context: Context, input: Self::Input) -> Result<Self::Output> {
// Compose the `aleo run` command.
let mut arguments = vec![ALEO_CLI_COMMAND.to_string(), "main".to_string()];
// Get the input values.
let mut values = match input {
Some(input_ast) => input_ast.values(),
None => Vec::new(),
};
arguments.append(&mut values);
tracing::info!("Starting...");
// Execute the aleo program.
// let cli = AleoCLI::parse_from(&["aleo", "run", "main"]);
// Call the `aleo run` command from the Aleo SDK.
let command = AleoRun::try_parse_from(&arguments).expect("Failed to parse aleo run command");
let res = command.parse().expect("Failed to execute Aleo project.");
// Log the verifier output
// tracing::info!("Result: {}", res);
// Log the output of the `aleo run` command.
tracing::info!("{}", res);
Ok(())
}