From d5ac5e6709fab257a2212e36a6311788addbd033 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 28 Jul 2020 21:22:31 -0700 Subject: [PATCH] use input section macro in leo types --- compiler/src/compiler.rs | 4 +- types/src/inputs/inputs.rs | 10 +++- types/src/inputs/macros.rs | 54 +++++++++++++++++ types/src/inputs/mod.rs | 4 ++ .../src/inputs/program_inputs/main_inputs.rs | 41 +++---------- .../inputs/program_inputs/program_inputs.rs | 7 ++- types/src/inputs/program_inputs/registers.rs | 58 +----------------- .../private_state/private_state.rs | 7 ++- .../program_state/private_state/record.rs | 59 +----------------- .../program_state/private_state/state_leaf.rs | 58 +----------------- .../src/inputs/program_state/program_state.rs | 7 ++- .../public_state/public_state.rs | 4 +- .../program_state/public_state/state.rs | 60 +------------------ 13 files changed, 94 insertions(+), 279 deletions(-) create mode 100644 types/src/inputs/macros.rs diff --git a/compiler/src/compiler.rs b/compiler/src/compiler.rs index 12bf8eca60..94ba5756ba 100644 --- a/compiler/src/compiler.rs +++ b/compiler/src/compiler.rs @@ -52,7 +52,7 @@ impl> Compiler { let mut compiler = Self::new(package_name); compiler.set_path(main_file_path); - // Generate the inputs file abstract syntax tree + // Generate the inputs file abstract syntax tree and store definitions compiler.parse_inputs(inputs_string)?; // Generate the program abstract syntax tree and assemble the program @@ -124,7 +124,7 @@ impl> Compiler { pub fn parse_inputs(&mut self, inputs_string: &str) -> Result<(), CompilerError> { let syntax_tree = LeoInputsParser::parse_file(&inputs_string)?; - self.program_inputs.parse_file(syntax_tree)?; + self.program_inputs.parse(syntax_tree)?; Ok(()) } diff --git a/types/src/inputs/inputs.rs b/types/src/inputs/inputs.rs index f3a5e7b216..c48fa8d83d 100644 --- a/types/src/inputs/inputs.rs +++ b/types/src/inputs/inputs.rs @@ -27,22 +27,26 @@ impl Inputs { Self { inputs, state } } + /// Returns the number of input variables to pass into the `main` program function pub fn len(&self) -> usize { self.inputs.len() + self.state.len() } + /// Manually set the input variables to the `main` program function pub fn set_main_inputs(&mut self, inputs: MainInputs) { self.inputs.main = inputs; } - pub fn parse_file(&mut self, file: File) -> Result<(), InputParserError> { + /// Parse all inputs included in a file and store them in `self`. + /// Currently parser does not care if file is `.in` or `.state` + pub fn parse(&mut self, file: File) -> Result<(), InputParserError> { for entry in file.entries.into_iter() { match entry { TableOrSection::Section(section) => { - self.inputs.store_definitions(section)?; + self.inputs.parse(section)?; } TableOrSection::Table(table) => { - self.state.store_definitions(table)?; + self.state.parse(table)?; } } } diff --git a/types/src/inputs/macros.rs b/types/src/inputs/macros.rs new file mode 100644 index 0000000000..9c497d9088 --- /dev/null +++ b/types/src/inputs/macros.rs @@ -0,0 +1,54 @@ +#[macro_export] +macro_rules! input_section_impl { + ($($name: ident), *) => ($( + + /// An input section declared in an input file with `[$name]` + #[derive(Clone, PartialEq, Eq)] + pub struct $name { + is_present: bool, + values: HashMap>, + } + + impl $name { + pub fn new() -> Self { + Self { + is_present: false, + values: HashMap::new(), + } + } + + /// Returns an empty version of this struct with `None` values. + /// Called during constraint synthesis to provide private inputs. + pub fn empty(&self) -> Self { + let is_present = self.is_present; + let mut values = self.values.clone(); + + values.iter_mut().for_each(|(_name, value)| { + *value = None; + }); + + Self { is_present, values } + } + + /// Returns `true` if the `$name` variable is passed as input to the main function + pub fn is_present(&self) -> bool { + self.is_present + } + + /// Parses register input definitions and stores them in `self`. + /// This function is called if the main function input contains the `$name` variable. + pub fn parse(&mut self, definitions: Vec) -> Result<(), InputParserError> { + self.is_present = true; + + for definition in definitions { + let name = definition.parameter.variable.value; + let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?; + + self.values.insert(name, Some(value)); + } + + Ok(()) + } + } + )*) +} diff --git a/types/src/inputs/mod.rs b/types/src/inputs/mod.rs index 363cc5e48b..40ac427004 100644 --- a/types/src/inputs/mod.rs +++ b/types/src/inputs/mod.rs @@ -1,3 +1,7 @@ +#[macro_use] +pub mod macros; +pub use macros::*; + pub mod inputs; pub use inputs::*; diff --git a/types/src/inputs/program_inputs/main_inputs.rs b/types/src/inputs/program_inputs/main_inputs.rs index fc12cda9e5..5e982608a7 100644 --- a/types/src/inputs/program_inputs/main_inputs.rs +++ b/types/src/inputs/program_inputs/main_inputs.rs @@ -28,41 +28,14 @@ impl MainInputs { Self { inputs } } - /// Stores main input assignments that match expected main function inputs - pub fn store_definitions(&mut self, definitions: Vec) -> Result<(), InputParserError> { - // for definition in definitions { - // - // } + /// Parses main input definitions and stores them in `self`. + pub fn parse(&mut self, definitions: Vec) -> Result<(), InputParserError> { + for definition in definitions { + let name = definition.parameter.variable.value; + let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?; - // let mut program_inputs = vec![]; - // - // for definition in definitions { - // // find input with matching name - // let matched_input = expected_inputs.clone().into_iter().find(|input| { - // // only look at program inputs - // match input { - // Input::FunctionInput(function_input) => { - // // name match - // function_input.identifier.name.eq(&definition.parameter.variable.value) - // // type match - // && function_input.type_.to_string().eq(&definition.parameter.type_.to_string()) - // } - // _ => false, - // } - // }); - // - // match matched_input { - // Some(_) => { - // let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?; - // - // // push value to main inputs - // program_inputs.push(Some(value)); - // } - // None => return Err(InputParserError::InputNotFound(definition.parameter.variable.value)), - // } - // } - // - // self.0 = program_inputs; + self.inputs.insert(name, Some(value)); + } Ok(()) } diff --git a/types/src/inputs/program_inputs/program_inputs.rs b/types/src/inputs/program_inputs/program_inputs.rs index 7efbf135a1..f3eeaa0a04 100644 --- a/types/src/inputs/program_inputs/program_inputs.rs +++ b/types/src/inputs/program_inputs/program_inputs.rs @@ -41,10 +41,11 @@ impl ProgramInputs { len } - pub fn store_definitions(&mut self, section: Section) -> Result<(), InputParserError> { + /// Parse all inputs included in a file and store them in `self`. + pub fn parse(&mut self, section: Section) -> Result<(), InputParserError> { match section.header { - Header::Main(_main) => self.main.store_definitions(section.definitions), - Header::Registers(_registers) => self.registers.store_definitions(section.definitions), + Header::Main(_main) => self.main.parse(section.definitions), + Header::Registers(_registers) => self.registers.parse(section.definitions), header => Err(InputParserError::input_section_header(header)), } } diff --git a/types/src/inputs/program_inputs/registers.rs b/types/src/inputs/program_inputs/registers.rs index 4c39809c48..4726ec6c9e 100644 --- a/types/src/inputs/program_inputs/registers.rs +++ b/types/src/inputs/program_inputs/registers.rs @@ -3,60 +3,4 @@ use leo_inputs::{definitions::Definition, InputParserError}; use std::collections::HashMap; -#[derive(Clone, PartialEq, Eq)] -pub struct Registers { - is_present: bool, - values: HashMap>, -} - -impl Registers { - pub fn new() -> Self { - Self { - is_present: false, - values: HashMap::new(), - } - } - - /// Returns an empty version of this struct with `None` values. - /// Called during constraint synthesis to provide private inputs. - pub fn empty(&self) -> Self { - let is_present = self.is_present; - let mut values = self.values.clone(); - - values.iter_mut().for_each(|(_name, value)| { - *value = None; - }); - - Self { is_present, values } - } - - /// Returns `true` if the `registers` variable is passed as input to the main function - pub fn is_present(&self) -> bool { - self.is_present - } - - /// Stores register input definitions. - /// This function is called if the main function input contains the `registers` variable. - pub fn store_definitions(&mut self, definitions: Vec) -> Result<(), InputParserError> { - self.is_present = true; - // // if the main function does not contain the `registers` variable - // // then do not parse registers - // if !expected_inputs.contains(&Input::Registers) { - // return Ok(()); - // } - // - // let mut register_inputs = vec![]; - // - // // store all registers - // for definition in definitions { - // let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?; - // - // // push value to register inputs - // register_inputs.push(Some(value)); - // } - // - // self.values = register_inputs; - - Ok(()) - } -} +input_section_impl!(Registers); 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 3eb26c60e4..bf2f37c786 100644 --- a/types/src/inputs/program_state/private_state/private_state.rs +++ b/types/src/inputs/program_state/private_state/private_state.rs @@ -43,11 +43,12 @@ impl PrivateState { len } - pub fn store_definitions(&mut self, sections: Vec
) -> Result<(), InputParserError> { + /// 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 { - Header::Record(_state) => self.record.store_definitions(section.definitions)?, - Header::StateLeaf(_state_leaf) => self.state_leaf.store_definitions(section.definitions)?, + Header::Record(_state) => self.record.parse(section.definitions)?, + Header::StateLeaf(_state_leaf) => self.state_leaf.parse(section.definitions)?, header => return Err(InputParserError::private_section(header)), } } diff --git a/types/src/inputs/program_state/private_state/record.rs b/types/src/inputs/program_state/private_state/record.rs index 83d9f87a19..5f4a61c661 100644 --- a/types/src/inputs/program_state/private_state/record.rs +++ b/types/src/inputs/program_state/private_state/record.rs @@ -1,61 +1,6 @@ use crate::{Input, InputValue}; use leo_inputs::{definitions::Definition, InputParserError}; + use std::collections::HashMap; -#[derive(Clone, PartialEq, Eq)] -pub struct Record { - is_present: bool, - values: HashMap>, -} - -impl Record { - pub fn new() -> Self { - Self { - is_present: false, - values: HashMap::new(), - } - } - - /// Returns an empty version of this struct with `None` values. - /// Called during constraint synthesis to provide private inputs. - pub fn empty(&self) -> Self { - let is_present = self.is_present; - let mut values = self.values.clone(); - - values.iter_mut().for_each(|(_name, value)| { - *value = None; - }); - - Self { is_present, values } - } - - /// Returns `true` if the `record` variable is passed as input to the main function. - pub fn is_present(&self) -> bool { - self.is_present - } - - /// Stores record input definitions. - /// This function is called if the main function input contains the `record` variable. - pub fn store_definitions(&mut self, definitions: Vec) -> Result<(), InputParserError> { - self.is_present = true; - // // if the main function does not contain the `record` variable - // // then do not parse record definitions - // if !expected_inputs.contains(&Input::Record) { - // return Ok(()); - // } - // - // let mut record_inputs = vec![]; - // - // // store all definitions - // for definition in definitions { - // let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?; - // - // // push value to register inputs - // record_inputs.push(Some(value)); - // } - // - // self.0 = record_inputs; - - Ok(()) - } -} +input_section_impl!(Record); 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 7e199b359e..30b40a6842 100644 --- a/types/src/inputs/program_state/private_state/state_leaf.rs +++ b/types/src/inputs/program_state/private_state/state_leaf.rs @@ -3,60 +3,4 @@ use leo_inputs::{definitions::Definition, InputParserError}; use std::collections::HashMap; -#[derive(Clone, PartialEq, Eq)] -pub struct StateLeaf { - is_present: bool, - values: HashMap>, -} - -impl StateLeaf { - pub fn new() -> Self { - Self { - is_present: false, - values: HashMap::new(), - } - } - - /// Returns an empty version of this struct with `None` values. - /// Called during constraint synthesis to provide private inputs. - pub fn empty(&self) -> Self { - let is_present = self.is_present; - let mut values = self.values.clone(); - - values.iter_mut().for_each(|(_name, value)| { - *value = None; - }); - - Self { is_present, values } - } - - /// Returns `true` if the `state_leaf` variable is passed as input to the main function - pub fn is_present(&self) -> bool { - self.is_present - } - - /// Stores state leaf input definitions. - /// This function is called if the main function input contains the `state_leaf` variable. - pub fn store_definitions(&mut self, definitions: Vec) -> Result<(), InputParserError> { - self.is_present = true; - // // if the main function does not contain the `state_leaf` variable - // // then do not parse state_leaf definitions - // if !expected_inputs.contains(&Input::StateLeaf) { - // return Ok(()); - // } - // - // let mut state_leaf_inputs = vec![]; - // - // // store all definitions - // for definition in definitions { - // let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?; - // - // // push value to register inputs - // state_leaf_inputs.push(Some(value)); - // } - // - // self.0 = state_leaf_inputs; - - Ok(()) - } -} +input_section_impl!(StateLeaf); diff --git a/types/src/inputs/program_state/program_state.rs b/types/src/inputs/program_state/program_state.rs index a2ad7fdb5e..ce37bc0c6b 100644 --- a/types/src/inputs/program_state/program_state.rs +++ b/types/src/inputs/program_state/program_state.rs @@ -31,10 +31,11 @@ impl ProgramState { self.public.len() + self.private.len() } - pub fn store_definitions(&mut self, table: Table) -> Result<(), InputParserError> { + /// Parse all inputs included in a file and store them in `self`. + pub fn parse(&mut self, table: Table) -> Result<(), InputParserError> { match table.visibility { - Visibility::Private(_private) => self.private.store_definitions(table.sections), - Visibility::Public(_public) => self.public.store_definitions(table.sections), + Visibility::Private(_private) => self.private.parse(table.sections), + Visibility::Public(_public) => self.public.parse(table.sections), } } } 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 99f042b047..e3bc7c2066 100644 --- a/types/src/inputs/program_state/public_state/public_state.rs +++ b/types/src/inputs/program_state/public_state/public_state.rs @@ -26,10 +26,10 @@ impl PublicState { Self { state } } - pub fn store_definitions(&mut self, sections: Vec
) -> Result<(), InputParserError> { + pub fn parse(&mut self, sections: Vec
) -> Result<(), InputParserError> { for section in sections { match section.header { - Header::State(_state) => self.state.store_definitions(section.definitions)?, + Header::State(_state) => self.state.parse(section.definitions)?, header => return Err(InputParserError::public_section(header)), } } diff --git a/types/src/inputs/program_state/public_state/state.rs b/types/src/inputs/program_state/public_state/state.rs index b1356cf29a..6e1fe7a2ae 100644 --- a/types/src/inputs/program_state/public_state/state.rs +++ b/types/src/inputs/program_state/public_state/state.rs @@ -1,62 +1,6 @@ use crate::{Input, InputValue}; use leo_inputs::{definitions::Definition, InputParserError}; + use std::collections::HashMap; -#[derive(Clone, PartialEq, Eq)] -pub struct State { - is_present: bool, - values: HashMap>, -} - -impl State { - pub fn new() -> Self { - Self { - is_present: false, - values: HashMap::new(), - } - } - - /// Returns an empty version of this struct with `None` values. - /// Called during constraint synthesis to provide private inputs. - pub fn empty(&self) -> Self { - let is_present = self.is_present; - let mut values = self.values.clone(); - - values.iter_mut().for_each(|(_name, value)| { - *value = None; - }); - - Self { is_present, values } - } - - /// Returns `true` if the `state` variable is passed as input to the main function - pub fn is_present(&self) -> bool { - self.is_present - } - - /// Stores state input definitions. - /// This function is called if the main function input contains the `state` variable. - pub fn store_definitions(&mut self, definitions: Vec) -> Result<(), InputParserError> { - self.is_present = true; - - // // if the main function does not contain the `state` variable - // // then do not parse state definitions - // if !expected_inputs.contains(&Input::State) { - // return Ok(()); - // } - // - // let mut state_inputs = vec![]; - // - // // store all definitions - // for definition in definitions { - // let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?; - // - // // push value to register inputs - // state_inputs.push(Some(value)); - // } - // - // self.values = state_inputs; - - Ok(()) - } -} +input_section_impl!(State);