diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 94ba5756ba..7bbedc0479 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -9,7 +9,7 @@ use crate::{ }; use leo_ast::LeoParser; use leo_inputs::LeoInputsParser; -use leo_types::{InputValue, Inputs, MainInputs, Program}; +use leo_types::{Inputs, MainInputs, Program}; use snarkos_errors::gadgets::SynthesisError; use snarkos_models::{ @@ -70,6 +70,34 @@ impl> Compiler { self.program_inputs.set_main_inputs(program_inputs); } + fn load_program(&mut self) -> Result { + // Load the program syntax tree from the file path + Ok(LeoParser::load_file(&self.main_file_path)?) + } + + pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> { + // Parse the program syntax tree + let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?; + + // Build program from syntax tree + let package_name = self.package_name.clone(); + + self.program = Program::from(syntax_tree, package_name); + self.imported_programs = ImportParser::parse(&self.program)?; + + log::debug!("Program parsing complete\n{:#?}", self.program); + + Ok(()) + } + + pub fn parse_inputs(&mut self, inputs_string: &str) -> Result<(), CompilerError> { + let syntax_tree = LeoInputsParser::parse_file(&inputs_string)?; + + self.program_inputs.parse(syntax_tree)?; + + Ok(()) + } + pub fn checksum(&self) -> Result { // Read in the main file as string let unparsed_file = fs::read_to_string(&self.main_file_path) @@ -101,41 +129,13 @@ impl> Compiler { generate_test_constraints::(cs, self.program, self.program_inputs, &self.imported_programs) } - fn load_program(&mut self) -> Result { - // Load the program syntax tree from the file path - Ok(LeoParser::load_file(&self.main_file_path)?) - } - - pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> { - // Parse the program syntax tree - let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?; - - // Build program from syntax tree - let package_name = self.package_name.clone(); - - self.program = Program::from(syntax_tree, package_name); - self.imported_programs = ImportParser::parse(&self.program)?; - - log::debug!("Program parsing complete\n{:#?}", self.program); - - Ok(()) - } - - pub fn parse_inputs(&mut self, inputs_string: &str) -> Result<(), CompilerError> { - let syntax_tree = LeoInputsParser::parse_file(&inputs_string)?; - - self.program_inputs.parse(syntax_tree)?; - - Ok(()) - } - pub fn to_bytes(&self) -> Result, CompilerError> { Ok(bincode::serialize(&self.program)?) } pub fn from_bytes(bytes: &[u8]) -> Result { let program: Program = bincode::deserialize(bytes)?; - let mut program_inputs = Inputs::new(); + let program_inputs = Inputs::new(); Ok(Self { package_name: program.name.clone(), diff --git a/compiler/src/errors/function.rs b/compiler/src/errors/function.rs index 60c694ace4..1a4dae5865 100644 --- a/compiler/src/errors/function.rs +++ b/compiler/src/errors/function.rs @@ -78,4 +78,10 @@ impl FunctionError { Self::new_from_span(message, span) } + + pub fn input_not_found(expected: String, span: Span) -> Self { + let message = format!("main function input {} not found", expected); + + Self::new_from_span(message, span) + } } diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index 5c524dd408..98c6743760 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -39,28 +39,77 @@ impl> ConstrainedProgram { // Store input values as new variables in resolved program for (input_model, input_expression) in function.inputs.clone().iter().zip(inputs.into_iter()) { - if let Input::FunctionInput(input_model) = input_model { - // First evaluate input expression - let mut input_value = self.enforce_input( - cs, - scope.clone(), - caller_scope.clone(), - function_name.clone(), - vec![input_model.type_.clone()], - input_expression, - )?; + let (name, value) = match input_model { + Input::FunctionInput(input_model) => { + // First evaluate input expression + let mut input_value = self.enforce_input( + cs, + scope.clone(), + caller_scope.clone(), + function_name.clone(), + vec![input_model.type_.clone()], + input_expression, + )?; - if input_model.mutable { - input_value = ConstrainedValue::Mutable(Box::new(input_value)) + if input_model.mutable { + input_value = ConstrainedValue::Mutable(Box::new(input_value)) + } + + (input_model.identifier.name.clone(), input_value) } + Input::Registers(identifier) => { + let input_value = self.enforce_input( + cs, + scope.clone(), + caller_scope.clone(), + function_name.clone(), + vec![], + input_expression, + )?; - // Store input as variable with {function_name}_{input_name} - let input_program_identifier = new_scope(function_name.clone(), input_model.identifier.name.clone()); - self.store(input_program_identifier, input_value); - } else { - println!("function input model {}", input_model); - println!("function input option {}", input_expression) - } + (identifier.name.clone(), input_value) + } + Input::Record(identifier) => { + let input_value = self.enforce_input( + cs, + scope.clone(), + caller_scope.clone(), + function_name.clone(), + vec![], + input_expression, + )?; + + (identifier.name.clone(), input_value) + } + Input::State(identifier) => { + let input_value = self.enforce_input( + cs, + scope.clone(), + caller_scope.clone(), + function_name.clone(), + vec![], + input_expression, + )?; + + (identifier.name.clone(), input_value) + } + Input::StateLeaf(identifier) => { + let input_value = self.enforce_input( + cs, + scope.clone(), + caller_scope.clone(), + function_name.clone(), + vec![], + input_expression, + )?; + + (identifier.name.clone(), input_value) + } + }; + + // Store input as variable with {function_name}_{input_name} + let input_program_identifier = new_scope(function_name.clone(), name); + self.store(input_program_identifier, value); } // Evaluate every statement in the function and save all potential results diff --git a/compiler/src/function/input/mod.rs b/compiler/src/function/input/mod.rs index 27a55172fc..a00b16e4f7 100644 --- a/compiler/src/function/input/mod.rs +++ b/compiler/src/function/input/mod.rs @@ -8,3 +8,6 @@ pub use self::input::*; pub mod main_input; pub use self::main_input::*; + +pub mod section; +pub use self::section::*; diff --git a/compiler/src/function/input/section.rs b/compiler/src/function/input/section.rs new file mode 100644 index 0000000000..34a5824418 --- /dev/null +++ b/compiler/src/function/input/section.rs @@ -0,0 +1,37 @@ +use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType}; + +use leo_types::{Identifier, InputValue, Parameter}; +use snarkos_models::{ + curves::{Field, PrimeField}, + gadgets::r1cs::ConstraintSystem, +}; +use std::collections::HashMap; + +impl> ConstrainedProgram { + pub fn allocate_input_section>( + &mut self, + cs: &mut CS, + identifier: Identifier, + section: HashMap>, + ) -> Result, FunctionError> { + let mut members = vec![]; + + // Store each section definition as a circuit member value + for (parameter, option) in section.into_iter() { + let member_name = parameter.variable.clone(); + let member_value = self.allocate_main_function_input( + cs, + parameter.type_, + parameter.variable.name, + option, + parameter.span, + )?; + let member = ConstrainedCircuitMember(member_name, member_value); + + members.push(member) + } + + // Return section as circuit expression + Ok(ConstrainedValue::CircuitExpression(identifier, members)) + } +} diff --git a/compiler/src/function/main_function.rs b/compiler/src/function/main_function.rs index 3dd08b5d8d..ee1261bbd5 100644 --- a/compiler/src/function/main_function.rs +++ b/compiler/src/function/main_function.rs @@ -30,12 +30,13 @@ impl> ConstrainedProgram { // Iterate over main function inputs and allocate new passed-by variable values let mut input_variables = vec![]; - let mut seen = 0; - for (i, input_model) in function.inputs.clone().into_iter().enumerate() { - match input_model { + for input_model in function.inputs.clone().into_iter() { + let (identifier, value) = match input_model { Input::FunctionInput(input_model) => { let name = input_model.identifier.name.clone(); - let input_option = inputs.get(&name); + let input_option = inputs + .get(&name) + .ok_or(FunctionError::input_not_found(name.clone(), function.span.clone()))?; let input_value = self.allocate_main_function_input( cs, input_model.type_, @@ -44,25 +45,41 @@ impl> ConstrainedProgram { function.span.clone(), )?; - // Store a new variable for every allocated main function input - let input_name = new_scope(function_name.clone(), input_model.identifier.name.clone()); - self.store(input_name.clone(), input_value); + (input_model.identifier, input_value) + } + Input::Registers(identifier) => { + let section = inputs.get_registers(); + let value = self.allocate_input_section(cs, identifier.clone(), section)?; - input_variables.push(Expression::Identifier(input_model.identifier)); + (identifier, value) } - Input::Registers => { - seen += 1; + Input::Record(identifier) => { + let section = inputs.get_record(); + let value = self.allocate_input_section(cs, identifier.clone(), section)?; + + (identifier, value) } - Input::Record => { - seen += 1; + Input::State(identifier) => { + let section = inputs.get_state(); + let value = self.allocate_input_section(cs, identifier.clone(), section)?; + + (identifier, value) } - Input::State => { - seen += 1; + Input::StateLeaf(identifier) => { + let section = inputs.get_state_leaf(); + let value = self.allocate_input_section(cs, identifier.clone(), section)?; + + (identifier, value) } - Input::StateLeaf => { - seen += 1; - } - } + }; + + // Store input as variable with {function_name}_{identifier_name} + let input_name = new_scope(function_name.clone(), identifier.name.clone()); + + // Store a new variable for every allocated main function input + self.store(input_name, value); + + input_variables.push(Expression::Identifier(identifier)); } self.enforce_function(cs, scope, function_name, function, input_variables) diff --git a/leo/commands/prove.rs b/leo/commands/prove.rs index 2b8db08cec..9a84284f74 100644 --- a/leo/commands/prove.rs +++ b/leo/commands/prove.rs @@ -3,7 +3,7 @@ use crate::{ cli_types::*, commands::SetupCommand, errors::CLIError, - files::{InputsFile, Manifest, ProofFile}, + files::{Manifest, ProofFile}, }; use snarkos_algorithms::snark::{create_random_proof, PreparedVerifyingKey, Proof}; @@ -34,7 +34,7 @@ impl CLI for ProveCommand { #[cfg_attr(tarpaulin, skip)] fn output(options: Self::Options) -> Result { - let (mut program, parameters, prepared_verifying_key) = SetupCommand::output(options)?; + let (program, parameters, prepared_verifying_key) = SetupCommand::output(options)?; // Get the package name let path = current_dir()?; @@ -42,10 +42,6 @@ impl CLI for ProveCommand { log::info!("Proving..."); - // Fetch main program inputs here - // let inputs_string = InputsFile::new(&package_name).read_from(&path)?; - // program.parse_inputs(&inputs_string)?; - // Start the timer let start = Instant::now(); diff --git a/types/src/common/identifier.rs b/types/src/common/identifier.rs index cd152b5ccd..799596fca6 100644 --- a/types/src/common/identifier.rs +++ b/types/src/common/identifier.rs @@ -1,5 +1,6 @@ use crate::Span; use leo_ast::common::Identifier as AstIdentifier; +use leo_inputs::common::Identifier as InputsAstIdentifier; use serde::{Deserialize, Serialize}; use std::fmt; @@ -26,6 +27,15 @@ impl<'ast> From> for Identifier { } } +impl<'ast> From> for Identifier { + fn from(identifier: InputsAstIdentifier<'ast>) -> Self { + Self { + name: identifier.value, + span: Span::from(identifier.span), + } + } +} + impl fmt::Display for Identifier { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.name) diff --git a/types/src/expression.rs b/types/src/expression.rs index e0ef19abcc..dcfd5b34df 100644 --- a/types/src/expression.rs +++ b/types/src/expression.rs @@ -17,6 +17,7 @@ use leo_ast::{ }; use leo_ast::values::AddressValue; +use leo_inputs::values::NumberValue; use serde::{Deserialize, Serialize}; use std::fmt; @@ -103,7 +104,7 @@ impl Expression { } impl<'ast> Expression { - pub(crate) fn get_count(count: Value<'ast>) -> usize { + pub(crate) fn get_count_from_value(count: Value<'ast>) -> usize { match count { Value::Integer(integer) => integer .number @@ -114,6 +115,10 @@ impl<'ast> Expression { size => unimplemented!("Array size should be an integer {}", size), } } + + pub(crate) fn get_count_from_number(number: NumberValue<'ast>) -> usize { + number.value.parse::().expect("Unable to read array size") + } } impl<'ast> fmt::Display for Expression { @@ -398,7 +403,7 @@ impl<'ast> From> for Expression { impl<'ast> From> for Expression { fn from(array: ArrayInitializerExpression<'ast>) -> Self { - let count = Expression::get_count(array.count); + let count = Expression::get_count_from_value(array.count); let expression = Box::new(SpreadOrExpression::from(*array.expression)); Expression::Array(vec![expression; count], Span::from(array.span)) diff --git a/types/src/functions/inputs/input.rs b/types/src/functions/inputs/input.rs index 7f46b1fcc4..621b093436 100644 --- a/types/src/functions/inputs/input.rs +++ b/types/src/functions/inputs/input.rs @@ -1,26 +1,59 @@ -use crate::FunctionInput; +use crate::{FunctionInput, Identifier, Span}; use leo_ast::functions::inputs::Input as AstInput; use serde::{Deserialize, Serialize}; use std::fmt; +const RECORD_VARIABLE_NAME: &str = "record"; +const REGISTERS_VARIABLE_NAME: &str = "registers"; +const STATE_VARIABLE_NAME: &str = "state"; +const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf"; + #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum Input { FunctionInput(FunctionInput), - Record, - Registers, - State, - StateLeaf, + Record(Identifier), + Registers(Identifier), + State(Identifier), + StateLeaf(Identifier), } impl<'ast> From> for Input { fn from(input: AstInput<'ast>) -> Self { match input { AstInput::FunctionInput(function_input) => Input::FunctionInput(FunctionInput::from(function_input)), - AstInput::Record(_) => Input::Record, - AstInput::Registers(_) => Input::Registers, - AstInput::State(_) => Input::State, - AstInput::StateLeaf(_) => Input::StateLeaf, + AstInput::Record(record) => { + let id = Identifier { + name: RECORD_VARIABLE_NAME.to_string(), + span: Span::from(record.span), + }; + + Input::Record(id) + } + AstInput::Registers(registers) => { + let id = Identifier { + name: REGISTERS_VARIABLE_NAME.to_string(), + span: Span::from(registers.span), + }; + + Input::Registers(id) + } + AstInput::State(state) => { + let id = Identifier { + name: STATE_VARIABLE_NAME.to_string(), + span: Span::from(state.span), + }; + + Input::State(id) + } + AstInput::StateLeaf(state_leaf) => { + let id = Identifier { + name: STATE_LEAF_VARIABLE_NAME.to_string(), + span: Span::from(state_leaf.span), + }; + + Input::StateLeaf(id) + } } } } @@ -29,10 +62,10 @@ impl Input { fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Input::FunctionInput(function_input) => write!(f, "{}", function_input), - Input::Record => write!(f, "record"), - Input::Registers => write!(f, "registers"), - Input::State => write!(f, "state"), - Input::StateLeaf => write!(f, "state_leaf"), + Input::Record(id) => write!(f, "{}", id), + Input::Registers(id) => write!(f, "{}", id), + Input::State(id) => write!(f, "{}", id), + Input::StateLeaf(id) => write!(f, "{}", id), } } } diff --git a/types/src/inputs/inputs.rs b/types/src/inputs/inputs.rs index c48fa8d83d..8d31add380 100644 --- a/types/src/inputs/inputs.rs +++ b/types/src/inputs/inputs.rs @@ -1,8 +1,9 @@ -use crate::{Input, InputValue, MainInputs, ProgramInputs, ProgramState}; +use crate::{InputValue, MainInputs, Parameter, ProgramInputs, ProgramState}; use leo_inputs::{ files::{File, TableOrSection}, InputParserError, }; +use std::collections::HashMap; #[derive(Clone, PartialEq, Eq)] pub struct Inputs { @@ -55,7 +56,27 @@ impl Inputs { } /// Returns the main function input value with the given `name` - pub fn get(&self, name: &String) -> Option { + pub fn get(&self, name: &String) -> Option> { self.inputs.get(name) } + + /// Returns the runtime register input values + pub fn get_registers(&self) -> HashMap> { + self.inputs.get_registers() + } + + /// Returns the runtime record input values + pub fn get_record(&self) -> HashMap> { + self.state.get_record() + } + + /// Returns the runtime state input values + pub fn get_state(&self) -> HashMap> { + self.state.get_state() + } + + /// Returns the runtime state leaf input values + pub fn get_state_leaf(&self) -> HashMap> { + self.state.get_state_leaf() + } } diff --git a/types/src/inputs/macros.rs b/types/src/inputs/macros.rs index 9c497d9088..eda9be1049 100644 --- a/types/src/inputs/macros.rs +++ b/types/src/inputs/macros.rs @@ -6,7 +6,7 @@ macro_rules! input_section_impl { #[derive(Clone, PartialEq, Eq)] pub struct $name { is_present: bool, - values: HashMap>, + values: HashMap>, } impl $name { @@ -23,14 +23,14 @@ macro_rules! input_section_impl { let is_present = self.is_present; let mut values = self.values.clone(); - values.iter_mut().for_each(|(_name, value)| { + values.iter_mut().for_each(|(_parameter, value)| { *value = None; }); Self { is_present, values } } - /// Returns `true` if the `$name` variable is passed as input to the main function + /// Returns `true` if the main function contains the `$name` variable. pub fn is_present(&self) -> bool { self.is_present } @@ -41,14 +41,19 @@ macro_rules! input_section_impl { self.is_present = true; for definition in definitions { - let name = definition.parameter.variable.value; - let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?; + let value = InputValue::from_expression(definition.parameter.type_.clone(), definition.expression)?; + let parameter = Parameter::from(definition.parameter); - self.values.insert(name, Some(value)); + self.values.insert(parameter, Some(value)); } Ok(()) } + + /// Returns this section's hashmap of values + pub fn values(&self) -> HashMap> { + self.values.clone() + } } )*) } diff --git a/types/src/inputs/mod.rs b/types/src/inputs/mod.rs index 40ac427004..79244864c6 100644 --- a/types/src/inputs/mod.rs +++ b/types/src/inputs/mod.rs @@ -8,6 +8,9 @@ pub use inputs::*; pub mod input_value; pub use input_value::*; +pub mod parameters; +pub use parameters::*; + pub mod program_inputs; pub use program_inputs::*; diff --git a/types/src/inputs/parameters/mod.rs b/types/src/inputs/parameters/mod.rs new file mode 100644 index 0000000000..cf55dbc6dd --- /dev/null +++ b/types/src/inputs/parameters/mod.rs @@ -0,0 +1,2 @@ +pub mod parameter; +pub use parameter::*; diff --git a/types/src/inputs/parameters/parameter.rs b/types/src/inputs/parameters/parameter.rs new file mode 100644 index 0000000000..f5ad9880fa --- /dev/null +++ b/types/src/inputs/parameters/parameter.rs @@ -0,0 +1,19 @@ +use crate::{Identifier, Span, Type}; +use leo_inputs::parameters::Parameter as AstParameter; + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct Parameter { + pub variable: Identifier, + pub type_: Type, + pub span: Span, +} + +impl<'ast> From> for Parameter { + fn from(parameter: AstParameter<'ast>) -> Self { + Self { + variable: Identifier::from(parameter.variable), + type_: Type::from(parameter.type_), + span: Span::from(parameter.span), + } + } +} diff --git a/types/src/inputs/program_inputs/main_inputs.rs b/types/src/inputs/program_inputs/main_inputs.rs index 5e982608a7..089978bfef 100644 --- a/types/src/inputs/program_inputs/main_inputs.rs +++ b/types/src/inputs/program_inputs/main_inputs.rs @@ -1,4 +1,4 @@ -use crate::{Input, InputValue}; +use crate::InputValue; use leo_inputs::{definitions::Definition, InputParserError}; use std::collections::HashMap; @@ -12,10 +12,6 @@ impl MainInputs { Self { inputs: HashMap::new() } } - pub fn len(&self) -> usize { - self.inputs.len() - } - /// Returns an empty version of this struct with `None` values. /// Called during constraint synthesis to provide private inputs. pub fn empty(&self) -> Self { @@ -28,6 +24,10 @@ impl MainInputs { Self { inputs } } + pub fn len(&self) -> usize { + self.inputs.len() + } + /// Parses main input definitions and stores them in `self`. pub fn parse(&mut self, definitions: Vec) -> Result<(), InputParserError> { for definition in definitions { @@ -40,8 +40,8 @@ impl MainInputs { Ok(()) } - /// Returns main function input at `index` - pub fn get(&self, name: &String) -> Option { - self.inputs.get(name).unwrap().clone() + /// Returns an `Option` of the main function input at `name` + pub fn get(&self, name: &String) -> Option> { + self.inputs.get(name).map(|input| input.clone()) } } diff --git a/types/src/inputs/program_inputs/program_inputs.rs b/types/src/inputs/program_inputs/program_inputs.rs index f3eeaa0a04..776b84fecc 100644 --- a/types/src/inputs/program_inputs/program_inputs.rs +++ b/types/src/inputs/program_inputs/program_inputs.rs @@ -1,8 +1,9 @@ -use crate::{Input, InputValue, MainInputs, Registers}; +use crate::{InputValue, MainInputs, Parameter, Registers}; use leo_inputs::{ sections::{Header, Section}, InputParserError, }; +use std::collections::HashMap; #[derive(Clone, PartialEq, Eq)] pub struct ProgramInputs { @@ -50,7 +51,13 @@ impl ProgramInputs { } } - pub fn get(&self, name: &String) -> Option { + /// Returns the main function input value with the given `name` + pub fn get(&self, name: &String) -> Option> { self.main.get(name) } + + /// Returns the runtime register input values + pub fn get_registers(&self) -> HashMap> { + self.registers.values() + } } diff --git a/types/src/inputs/program_inputs/registers.rs b/types/src/inputs/program_inputs/registers.rs index 4726ec6c9e..32e1d1b328 100644 --- a/types/src/inputs/program_inputs/registers.rs +++ b/types/src/inputs/program_inputs/registers.rs @@ -1,4 +1,4 @@ -use crate::{Input, InputValue}; +use crate::{InputValue, Parameter}; use leo_inputs::{definitions::Definition, InputParserError}; use std::collections::HashMap; diff --git a/types/src/inputs/program_state/private_state/private_state.rs b/types/src/inputs/program_state/private_state/private_state.rs index bf2f37c786..746640edc7 100644 --- a/types/src/inputs/program_state/private_state/private_state.rs +++ b/types/src/inputs/program_state/private_state/private_state.rs @@ -1,8 +1,9 @@ -use crate::{Input, Record, StateLeaf}; +use crate::{InputValue, Parameter, Record, StateLeaf}; use leo_inputs::{ sections::{Header, Section}, InputParserError, }; +use std::collections::HashMap; #[derive(Clone, PartialEq, Eq)] pub struct PrivateState { @@ -55,4 +56,14 @@ impl PrivateState { Ok(()) } + + /// Returns the runtime record input values + pub fn get_record(&self) -> HashMap> { + self.record.values() + } + + /// Returns the runtime state leaf input values + pub fn get_state_leaf(&self) -> HashMap> { + self.state_leaf.values() + } } diff --git a/types/src/inputs/program_state/private_state/record.rs b/types/src/inputs/program_state/private_state/record.rs index 5f4a61c661..fa08deca91 100644 --- a/types/src/inputs/program_state/private_state/record.rs +++ b/types/src/inputs/program_state/private_state/record.rs @@ -1,4 +1,4 @@ -use crate::{Input, InputValue}; +use crate::{InputValue, Parameter}; use leo_inputs::{definitions::Definition, InputParserError}; use std::collections::HashMap; diff --git a/types/src/inputs/program_state/private_state/state_leaf.rs b/types/src/inputs/program_state/private_state/state_leaf.rs index 30b40a6842..fa79aa6d68 100644 --- a/types/src/inputs/program_state/private_state/state_leaf.rs +++ b/types/src/inputs/program_state/private_state/state_leaf.rs @@ -1,4 +1,4 @@ -use crate::{Input, InputValue}; +use crate::{InputValue, Parameter}; use leo_inputs::{definitions::Definition, InputParserError}; use std::collections::HashMap; diff --git a/types/src/inputs/program_state/program_state.rs b/types/src/inputs/program_state/program_state.rs index ce37bc0c6b..f786f8f59d 100644 --- a/types/src/inputs/program_state/program_state.rs +++ b/types/src/inputs/program_state/program_state.rs @@ -1,9 +1,11 @@ -use crate::{Input, PrivateState, PublicState}; +use crate::{InputValue, Parameter, PrivateState, PublicState}; use leo_inputs::{ tables::{Table, Visibility}, InputParserError, }; +use std::collections::HashMap; + #[derive(Clone, PartialEq, Eq)] pub struct ProgramState { public: PublicState, @@ -38,4 +40,19 @@ impl ProgramState { Visibility::Public(_public) => self.public.parse(table.sections), } } + + /// Returns the runtime record input values + pub fn get_record(&self) -> HashMap> { + self.private.get_record() + } + + /// Returns the runtime state input values + pub fn get_state(&self) -> HashMap> { + self.public.get_state() + } + + /// Returns the runtime state leaf input values + pub fn get_state_leaf(&self) -> HashMap> { + self.private.get_state_leaf() + } } diff --git a/types/src/inputs/program_state/public_state/public_state.rs b/types/src/inputs/program_state/public_state/public_state.rs index e3bc7c2066..3a81edb274 100644 --- a/types/src/inputs/program_state/public_state/public_state.rs +++ b/types/src/inputs/program_state/public_state/public_state.rs @@ -1,9 +1,11 @@ -use crate::{Input, State}; +use crate::{InputValue, Parameter, State}; use leo_inputs::{ sections::{Header, Section}, InputParserError, }; +use std::collections::HashMap; + #[derive(Clone, PartialEq, Eq)] pub struct PublicState { state: State, @@ -14,10 +16,6 @@ impl PublicState { Self { state: State::new() } } - pub fn len(&self) -> usize { - if self.state.is_present() { 1usize } else { 0usize } - } - /// Returns an empty version of this struct with `None` values. /// Called during constraint synthesis to provide private inputs. pub fn empty(&self) -> Self { @@ -26,6 +24,11 @@ impl PublicState { Self { state } } + pub fn len(&self) -> usize { + if self.state.is_present() { 1usize } else { 0usize } + } + + /// Parse all inputs included in a file and store them in `self`. pub fn parse(&mut self, sections: Vec
) -> Result<(), InputParserError> { for section in sections { match section.header { @@ -36,4 +39,9 @@ impl PublicState { Ok(()) } + + /// Returns the runtime state input values + pub fn get_state(&self) -> HashMap> { + self.state.values() + } } diff --git a/types/src/inputs/program_state/public_state/state.rs b/types/src/inputs/program_state/public_state/state.rs index 6e1fe7a2ae..eb5d40c21d 100644 --- a/types/src/inputs/program_state/public_state/state.rs +++ b/types/src/inputs/program_state/public_state/state.rs @@ -1,4 +1,4 @@ -use crate::{Input, InputValue}; +use crate::{InputValue, Parameter}; use leo_inputs::{definitions::Definition, InputParserError}; use std::collections::HashMap; diff --git a/types/src/types/integer_type.rs b/types/src/types/integer_type.rs index 01736f4647..65aed392e5 100644 --- a/types/src/types/integer_type.rs +++ b/types/src/types/integer_type.rs @@ -1,10 +1,11 @@ use leo_ast::types::IntegerType as AstIntegerType; +use leo_inputs::types::IntegerType as InputsAstIntegerType; use serde::{Deserialize, Serialize}; use std::fmt; /// Explicit integer type -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum IntegerType { U8, U16, @@ -37,6 +38,24 @@ impl From for IntegerType { } } +impl From for IntegerType { + fn from(integer_type: InputsAstIntegerType) -> Self { + match integer_type { + InputsAstIntegerType::U8Type(_type) => IntegerType::U8, + InputsAstIntegerType::U16Type(_type) => IntegerType::U16, + InputsAstIntegerType::U32Type(_type) => IntegerType::U32, + InputsAstIntegerType::U64Type(_type) => IntegerType::U64, + InputsAstIntegerType::U128Type(_type) => IntegerType::U128, + + InputsAstIntegerType::I8Type(_type) => IntegerType::I8, + InputsAstIntegerType::I16Type(_type) => IntegerType::I16, + InputsAstIntegerType::I32Type(_type) => IntegerType::I32, + InputsAstIntegerType::I64Type(_type) => IntegerType::I64, + InputsAstIntegerType::I128Type(_type) => IntegerType::I128, + } + } +} + impl fmt::Display for IntegerType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/types/src/types/type_.rs b/types/src/types/type_.rs index 8c4711a4b3..7bd1680057 100644 --- a/types/src/types/type_.rs +++ b/types/src/types/type_.rs @@ -1,11 +1,12 @@ use crate::{Expression, Identifier, IntegerType}; use leo_ast::types::{ArrayType, CircuitType, DataType, Type as AstType}; +use leo_inputs::types::{ArrayType as InputsArrayType, DataType as InputsDataType, Type as InputsAstType}; use serde::{Deserialize, Serialize}; use std::fmt; /// Explicit type used for defining a variable or expression type -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Type { // Data types Address, @@ -50,13 +51,13 @@ impl From for Type { } } -impl<'ast> From> for Type { - fn from(array_type: ArrayType<'ast>) -> Self { +impl<'ast> From> for Type { + fn from(array_type: InputsArrayType<'ast>) -> Self { let element_type = Box::new(Type::from(array_type._type)); let dimensions = array_type .dimensions .into_iter() - .map(|row| Expression::get_count(row)) + .map(|row| Expression::get_count_from_number(row)) .collect(); Type::Array(element_type, dimensions) @@ -70,16 +71,52 @@ impl<'ast> From> for Type { } impl<'ast> From> for Type { - fn from(_type: AstType<'ast>) -> Self { - match _type { - AstType::Basic(_type) => Type::from(_type), - AstType::Array(_type) => Type::from(_type), - AstType::Circuit(_type) => Type::from(_type), + fn from(type_: AstType<'ast>) -> Self { + match type_ { + AstType::Basic(type_) => Type::from(type_), + AstType::Array(type_) => Type::from(type_), + AstType::Circuit(type_) => Type::from(type_), AstType::SelfType(_type) => Type::SelfType, } } } +/// inputs pest ast -> Explicit Type + +impl From for Type { + fn from(data_type: InputsDataType) -> Self { + match data_type { + InputsDataType::Address(_type) => Type::Address, + InputsDataType::Boolean(_type) => Type::Boolean, + InputsDataType::Field(_type) => Type::Field, + InputsDataType::Group(_type) => Type::Group, + InputsDataType::Integer(type_) => Type::IntegerType(IntegerType::from(type_)), + } + } +} + +impl<'ast> From> for Type { + fn from(array_type: ArrayType<'ast>) -> Self { + let element_type = Box::new(Type::from(array_type._type)); + let dimensions = array_type + .dimensions + .into_iter() + .map(|row| Expression::get_count_from_value(row)) + .collect(); + + Type::Array(element_type, dimensions) + } +} + +impl<'ast> From> for Type { + fn from(type_: InputsAstType<'ast>) -> Self { + match type_ { + InputsAstType::Basic(type_) => Type::from(type_), + InputsAstType::Array(type_) => Type::from(type_), + } + } +} + impl Type { pub fn outer_dimension(&self, dimensions: &Vec) -> Self { let type_ = self.clone();