mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-29 22:36:05 +03:00
use input section macro in leo types
This commit is contained in:
parent
82b0b576dd
commit
d5ac5e6709
@ -52,7 +52,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
|||||||
let mut compiler = Self::new(package_name);
|
let mut compiler = Self::new(package_name);
|
||||||
compiler.set_path(main_file_path);
|
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)?;
|
compiler.parse_inputs(inputs_string)?;
|
||||||
|
|
||||||
// Generate the program abstract syntax tree and assemble the program
|
// 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> {
|
pub fn parse_inputs(&mut self, inputs_string: &str) -> Result<(), CompilerError> {
|
||||||
let syntax_tree = LeoInputsParser::parse_file(&inputs_string)?;
|
let syntax_tree = LeoInputsParser::parse_file(&inputs_string)?;
|
||||||
|
|
||||||
self.program_inputs.parse_file(syntax_tree)?;
|
self.program_inputs.parse(syntax_tree)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -27,22 +27,26 @@ impl Inputs {
|
|||||||
Self { inputs, state }
|
Self { inputs, state }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the number of input variables to pass into the `main` program function
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.inputs.len() + self.state.len()
|
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) {
|
pub fn set_main_inputs(&mut self, inputs: MainInputs) {
|
||||||
self.inputs.main = inputs;
|
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() {
|
for entry in file.entries.into_iter() {
|
||||||
match entry {
|
match entry {
|
||||||
TableOrSection::Section(section) => {
|
TableOrSection::Section(section) => {
|
||||||
self.inputs.store_definitions(section)?;
|
self.inputs.parse(section)?;
|
||||||
}
|
}
|
||||||
TableOrSection::Table(table) => {
|
TableOrSection::Table(table) => {
|
||||||
self.state.store_definitions(table)?;
|
self.state.parse(table)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
54
types/src/inputs/macros.rs
Normal file
54
types/src/inputs/macros.rs
Normal 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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*)
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
#[macro_use]
|
||||||
|
pub mod macros;
|
||||||
|
pub use macros::*;
|
||||||
|
|
||||||
pub mod inputs;
|
pub mod inputs;
|
||||||
pub use inputs::*;
|
pub use inputs::*;
|
||||||
|
|
||||||
|
@ -28,41 +28,14 @@ impl MainInputs {
|
|||||||
Self { inputs }
|
Self { inputs }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores main input assignments that match expected main function inputs
|
/// Parses main input definitions and stores them in `self`.
|
||||||
pub fn store_definitions(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
|
pub fn parse(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
|
||||||
// for definition in definitions {
|
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![];
|
self.inputs.insert(name, Some(value));
|
||||||
//
|
}
|
||||||
// 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;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -41,10 +41,11 @@ impl ProgramInputs {
|
|||||||
len
|
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 {
|
match section.header {
|
||||||
Header::Main(_main) => self.main.store_definitions(section.definitions),
|
Header::Main(_main) => self.main.parse(section.definitions),
|
||||||
Header::Registers(_registers) => self.registers.store_definitions(section.definitions),
|
Header::Registers(_registers) => self.registers.parse(section.definitions),
|
||||||
header => Err(InputParserError::input_section_header(header)),
|
header => Err(InputParserError::input_section_header(header)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,60 +3,4 @@ use leo_inputs::{definitions::Definition, InputParserError};
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
input_section_impl!(Registers);
|
||||||
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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -43,11 +43,12 @@ impl PrivateState {
|
|||||||
len
|
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 {
|
for section in sections {
|
||||||
match section.header {
|
match section.header {
|
||||||
Header::Record(_state) => self.record.store_definitions(section.definitions)?,
|
Header::Record(_state) => self.record.parse(section.definitions)?,
|
||||||
Header::StateLeaf(_state_leaf) => self.state_leaf.store_definitions(section.definitions)?,
|
Header::StateLeaf(_state_leaf) => self.state_leaf.parse(section.definitions)?,
|
||||||
header => return Err(InputParserError::private_section(header)),
|
header => return Err(InputParserError::private_section(header)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,61 +1,6 @@
|
|||||||
use crate::{Input, InputValue};
|
use crate::{Input, InputValue};
|
||||||
use leo_inputs::{definitions::Definition, InputParserError};
|
use leo_inputs::{definitions::Definition, InputParserError};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
input_section_impl!(Record);
|
||||||
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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -3,60 +3,4 @@ use leo_inputs::{definitions::Definition, InputParserError};
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
input_section_impl!(StateLeaf);
|
||||||
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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -31,10 +31,11 @@ impl ProgramState {
|
|||||||
self.public.len() + self.private.len()
|
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 {
|
match table.visibility {
|
||||||
Visibility::Private(_private) => self.private.store_definitions(table.sections),
|
Visibility::Private(_private) => self.private.parse(table.sections),
|
||||||
Visibility::Public(_public) => self.public.store_definitions(table.sections),
|
Visibility::Public(_public) => self.public.parse(table.sections),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,10 @@ impl PublicState {
|
|||||||
Self { state }
|
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 {
|
for section in sections {
|
||||||
match section.header {
|
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)),
|
header => return Err(InputParserError::public_section(header)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,62 +1,6 @@
|
|||||||
use crate::{Input, InputValue};
|
use crate::{Input, InputValue};
|
||||||
use leo_inputs::{definitions::Definition, InputParserError};
|
use leo_inputs::{definitions::Definition, InputParserError};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq)]
|
input_section_impl!(State);
|
||||||
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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user