use input section macro in leo types

This commit is contained in:
collin 2020-07-28 21:22:31 -07:00
parent 82b0b576dd
commit d5ac5e6709
13 changed files with 94 additions and 279 deletions

View File

@ -52,7 +52,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
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<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
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(())
}

View File

@ -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)?;
}
}
}

View File

@ -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<String, Option<InputValue>>,
}
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<Definition>) -> 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(())
}
}
)*)
}

View File

@ -1,3 +1,7 @@
#[macro_use]
pub mod macros;
pub use macros::*;
pub mod inputs;
pub use inputs::*;

View File

@ -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<Definition>) -> Result<(), InputParserError> {
// for definition in definitions {
//
// }
/// Parses main input definitions and stores them in `self`.
pub fn parse(&mut self, definitions: Vec<Definition>) -> 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(())
}

View File

@ -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)),
}
}

View File

@ -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<String, Option<InputValue>>,
}
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<Definition>) -> 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);

View File

@ -43,11 +43,12 @@ impl PrivateState {
len
}
pub fn store_definitions(&mut self, sections: Vec<Section>) -> Result<(), InputParserError> {
/// Parse all inputs included in a file and store them in `self`.
pub fn parse(&mut self, sections: Vec<Section>) -> 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)),
}
}

View File

@ -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<String, Option<InputValue>>,
}
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<Definition>) -> 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);

View File

@ -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<String, Option<InputValue>>,
}
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<Definition>) -> 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);

View File

@ -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),
}
}
}

View File

@ -26,10 +26,10 @@ impl PublicState {
Self { state }
}
pub fn store_definitions(&mut self, sections: Vec<Section>) -> Result<(), InputParserError> {
pub fn parse(&mut self, sections: Vec<Section>) -> 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)),
}
}

View File

@ -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<String, Option<InputValue>>,
}
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<Definition>) -> 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);