diff --git a/ast/src/functions/inputs/input.rs b/ast/src/functions/inputs/input.rs index a4fb066057..679f94239c 100644 --- a/ast/src/functions/inputs/input.rs +++ b/ast/src/functions/inputs/input.rs @@ -1,6 +1,6 @@ use crate::{ ast::Rule, - functions::{FunctionInput, Record, Registers, State, StateLeaf}, + functions::{FunctionInput, InputKeyword}, }; use pest_ast::FromPest; @@ -9,9 +9,6 @@ use serde::Serialize; #[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::input))] pub enum Input<'ast> { + InputKeyword(InputKeyword<'ast>), FunctionInput(FunctionInput<'ast>), - Record(Record<'ast>), - Registers(Registers<'ast>), - State(State<'ast>), - StateLeaf(StateLeaf<'ast>), } diff --git a/ast/src/functions/inputs/input_keyword.rs b/ast/src/functions/inputs/input_keyword.rs new file mode 100644 index 0000000000..2e9bc8902d --- /dev/null +++ b/ast/src/functions/inputs/input_keyword.rs @@ -0,0 +1,18 @@ +use crate::{ + ast::{span_into_string, Rule}, + SpanDef, +}; + +use pest::Span; +use pest_ast::FromPest; +use serde::Serialize; + +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] +#[pest_ast(rule(Rule::input_keyword))] +pub struct InputKeyword<'ast> { + #[pest_ast(outer(with(span_into_string)))] + pub keyword: String, + #[pest_ast(outer())] + #[serde(with = "SpanDef")] + pub span: Span<'ast>, +} diff --git a/ast/src/functions/inputs/mod.rs b/ast/src/functions/inputs/mod.rs index ec188dab11..ab87f809fa 100644 --- a/ast/src/functions/inputs/mod.rs +++ b/ast/src/functions/inputs/mod.rs @@ -4,14 +4,5 @@ pub use function_input::*; pub mod input; pub use input::*; -pub mod record; -pub use record::*; - -pub mod registers; -pub use registers::*; - -pub mod state; -pub use state::*; - -pub mod state_leaf; -pub use state_leaf::*; +pub mod input_keyword; +pub use input_keyword::*; diff --git a/ast/src/functions/inputs/record.rs b/ast/src/functions/inputs/record.rs deleted file mode 100644 index 194ef9df01..0000000000 --- a/ast/src/functions/inputs/record.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::record))] -pub struct Record<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/ast/src/functions/inputs/registers.rs b/ast/src/functions/inputs/registers.rs deleted file mode 100644 index a3786adb9c..0000000000 --- a/ast/src/functions/inputs/registers.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::registers))] -pub struct Registers<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/ast/src/functions/inputs/state.rs b/ast/src/functions/inputs/state.rs deleted file mode 100644 index 0539087b1b..0000000000 --- a/ast/src/functions/inputs/state.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::state))] -pub struct State<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/ast/src/functions/inputs/state_leaf.rs b/ast/src/functions/inputs/state_leaf.rs deleted file mode 100644 index f8988a0891..0000000000 --- a/ast/src/functions/inputs/state_leaf.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::{ast::Rule, SpanDef}; - -use pest::Span; -use pest_ast::FromPest; -use serde::Serialize; - -#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] -#[pest_ast(rule(Rule::state_leaf))] -pub struct StateLeaf<'ast> { - #[pest_ast(outer())] - #[serde(with = "SpanDef")] - pub span: Span<'ast>, -} diff --git a/ast/src/leo.pest b/ast/src/leo.pest index 2177a06df4..0c32de5035 100644 --- a/ast/src/leo.pest +++ b/ast/src/leo.pest @@ -340,24 +340,12 @@ function_definition = { "function " ~ identifier ~ "(" ~ NEWLINE* ~ input_list ~ // Declared in functions/inputs/function_input.rs function_input = { mutable? ~ identifier ~ ":" ~ type_ } -// Declared in functions/inputs/record.rs -record = { "record" } - -// Declared in functions/inputs/registers.rs -registers = { "registers" } - -// Declared in functions/inputs/state.rs -state = { "state" } - -// Declared in functions/inputs/state_leaf.rs -state_leaf = { "state_leaf" } +// Declared in functions/inputs/input_keyword.rs +input_keyword = { "input" } // Declared in functions/inputs/input.rs input = { - record - | registers - | state_leaf - | state + input_keyword | function_input } input_list = _{ (input ~ ("," ~ NEWLINE* ~ input)*)? } diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index 98c6743760..5abd25784a 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -7,7 +7,7 @@ use crate::{ GroupType, }; -use leo_types::{Expression, Function, Input, Span}; +use leo_types::{Expression, Function, InputVariable, Span}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -40,9 +40,21 @@ 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()) { let (name, value) = match input_model { - Input::FunctionInput(input_model) => { + InputVariable::InputKeyword(identifier) => { + let input_value = self.enforce_function_input( + cs, + scope.clone(), + caller_scope.clone(), + function_name.clone(), + vec![], + input_expression, + )?; + + (identifier.name.clone(), input_value) + } + InputVariable::FunctionInput(input_model) => { // First evaluate input expression - let mut input_value = self.enforce_input( + let mut input_value = self.enforce_function_input( cs, scope.clone(), caller_scope.clone(), @@ -57,54 +69,6 @@ impl> ConstrainedProgram { (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, - )?; - - (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} diff --git a/compiler/src/function/input/input.rs b/compiler/src/function/input/function_input.rs similarity index 94% rename from compiler/src/function/input/input.rs rename to compiler/src/function/input/function_input.rs index 5dfd816c3a..c730143a3f 100644 --- a/compiler/src/function/input/input.rs +++ b/compiler/src/function/input/function_input.rs @@ -10,7 +10,7 @@ use snarkos_models::{ }; impl> ConstrainedProgram { - pub fn enforce_input>( + pub fn enforce_function_input>( &mut self, cs: &mut CS, scope: String, diff --git a/compiler/src/function/input/input_keyword.rs b/compiler/src/function/input/input_keyword.rs new file mode 100644 index 0000000000..f3c15220a4 --- /dev/null +++ b/compiler/src/function/input/input_keyword.rs @@ -0,0 +1,71 @@ +use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType}; +use leo_types::{Identifier, Inputs}; + +use snarkos_models::{ + curves::{Field, PrimeField}, + gadgets::r1cs::ConstraintSystem, +}; + +pub const RECORD_VARIABLE_NAME: &str = "record"; +pub const REGISTERS_VARIABLE_NAME: &str = "registers"; +pub const STATE_VARIABLE_NAME: &str = "state"; +pub const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf"; + +impl> ConstrainedProgram { + pub fn allocate_input_keyword>( + &mut self, + cs: &mut CS, + identifier: Identifier, + input: &Inputs, + ) -> Result, FunctionError> { + // Create an identifier for each input variable + + let registers_name = Identifier { + name: REGISTERS_VARIABLE_NAME.to_string(), + span: identifier.span.clone(), + }; + let record_name = Identifier { + name: RECORD_VARIABLE_NAME.to_string(), + span: identifier.span.clone(), + }; + let state_name = Identifier { + name: STATE_VARIABLE_NAME.to_string(), + span: identifier.span.clone(), + }; + let state_leaf_name = Identifier { + name: STATE_LEAF_VARIABLE_NAME.to_string(), + span: identifier.span.clone(), + }; + + // Fetch each input variable's definitions + + let registers_values = input.get_registers().values(); + let record_values = input.get_record().values(); + let state_values = input.get_state().values(); + let state_leaf_values = input.get_state_leaf().values(); + + // Allocate each input variable as a circuit expression + + let mut sections = vec![]; + + sections.push((registers_name, registers_values)); + sections.push((record_name, record_values)); + sections.push((state_name, state_values)); + sections.push((state_leaf_name, state_leaf_values)); + + let mut members = vec![]; + + for (name, values) in sections { + let member_name = name.clone(); + let member_value = self.allocate_input_section(cs, name, values)?; + + let member = ConstrainedCircuitMember(member_name, member_value); + + members.push(member) + } + + // Return input variable keyword as circuit expression + + Ok(ConstrainedValue::CircuitExpression(identifier, members)) + } +} diff --git a/compiler/src/function/input/section.rs b/compiler/src/function/input/input_section.rs similarity index 94% rename from compiler/src/function/input/section.rs rename to compiler/src/function/input/input_section.rs index 34a5824418..0916a55f32 100644 --- a/compiler/src/function/input/section.rs +++ b/compiler/src/function/input/input_section.rs @@ -16,7 +16,8 @@ impl> ConstrainedProgram { ) -> Result, FunctionError> { let mut members = vec![]; - // Store each section definition as a circuit member value + // Allocate 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( @@ -32,6 +33,7 @@ impl> ConstrainedProgram { } // Return section as circuit expression + Ok(ConstrainedValue::CircuitExpression(identifier, members)) } } diff --git a/compiler/src/function/input/main_input.rs b/compiler/src/function/input/main_function_input.rs similarity index 100% rename from compiler/src/function/input/main_input.rs rename to compiler/src/function/input/main_function_input.rs diff --git a/compiler/src/function/input/mod.rs b/compiler/src/function/input/mod.rs index a00b16e4f7..3e70848eca 100644 --- a/compiler/src/function/input/mod.rs +++ b/compiler/src/function/input/mod.rs @@ -3,11 +3,14 @@ pub mod array; pub use self::array::*; -pub mod input; -pub use self::input::*; +pub mod function_input; +pub use self::function_input::*; -pub mod main_input; -pub use self::main_input::*; +pub mod main_function_input; +pub use self::main_function_input::*; -pub mod section; -pub use self::section::*; +pub mod input_keyword; +pub use self::input_keyword::*; + +pub mod input_section; +pub use self::input_section::*; diff --git a/compiler/src/function/main_function.rs b/compiler/src/function/main_function.rs index 76bc30b74c..ae885f6797 100644 --- a/compiler/src/function/main_function.rs +++ b/compiler/src/function/main_function.rs @@ -7,7 +7,7 @@ use crate::{ OutputBytes, }; -use leo_types::{Expression, Function, Input, Inputs}; +use leo_types::{Expression, Function, InputVariable, Inputs}; use snarkos_models::{ curves::{Field, PrimeField}, @@ -29,7 +29,12 @@ impl> ConstrainedProgram { let mut input_variables = vec![]; for input_model in function.inputs.clone().into_iter() { let (identifier, value) = match input_model { - Input::FunctionInput(input_model) => { + InputVariable::InputKeyword(identifier) => { + let value = self.allocate_input_keyword(cs, identifier.clone(), &inputs)?; + + (identifier, value) + } + InputVariable::FunctionInput(input_model) => { let name = input_model.identifier.name.clone(); let input_option = inputs .get(&name) @@ -44,30 +49,6 @@ impl> ConstrainedProgram { (input_model.identifier, input_value) } - Input::Registers(identifier) => { - let section = inputs.get_registers().values(); - let value = self.allocate_input_section(cs, identifier.clone(), section)?; - - (identifier, value) - } - Input::Record(identifier) => { - let section = inputs.get_record().values(); - let value = self.allocate_input_section(cs, identifier.clone(), section)?; - - (identifier, value) - } - Input::State(identifier) => { - let section = inputs.get_state().values(); - let value = self.allocate_input_section(cs, identifier.clone(), section)?; - - (identifier, value) - } - Input::StateLeaf(identifier) => { - let section = inputs.get_state_leaf().values(); - let value = self.allocate_input_section(cs, identifier.clone(), section)?; - - (identifier, value) - } }; // Store input as variable with {function_name}_{identifier_name} diff --git a/compiler/src/output/output_bytes.rs b/compiler/src/output/output_bytes.rs index 4c1e0595b1..0eafc221c4 100644 --- a/compiler/src/output/output_bytes.rs +++ b/compiler/src/output/output_bytes.rs @@ -1,5 +1,5 @@ -use crate::{errors::OutputBytesError, ConstrainedValue, GroupType}; -use leo_types::{Parameter, Registers, Span, REGISTERS_VARIABLE_NAME}; +use crate::{errors::OutputBytesError, ConstrainedValue, GroupType, REGISTERS_VARIABLE_NAME}; +use leo_types::{Parameter, Registers, Span}; use snarkos_models::curves::{Field, PrimeField}; diff --git a/compiler/src/output/output_file.rs b/compiler/src/output/output_file.rs index 63940eb826..77882dfbe7 100644 --- a/compiler/src/output/output_file.rs +++ b/compiler/src/output/output_file.rs @@ -39,9 +39,7 @@ impl OutputsFile { pub fn write(&self, path: &PathBuf, bytes: &[u8]) -> Result<(), OutputsFileError> { // create output file let path = self.setup_file_path(path); - println!("setup {:?}", path); let mut file = File::create(&path)?; - println!("created"); log::info!("Writing to output registers..."); Ok(file.write_all(bytes)?) diff --git a/types/src/functions/function.rs b/types/src/functions/function.rs index 2bc6e7cc50..45fb891723 100644 --- a/types/src/functions/function.rs +++ b/types/src/functions/function.rs @@ -1,4 +1,4 @@ -use crate::{Identifier, Input, Span, Statement, Type}; +use crate::{Identifier, InputVariable, Span, Statement, Type}; use leo_ast::functions::Function as AstFunction; use serde::{Deserialize, Serialize}; @@ -7,7 +7,7 @@ use std::fmt; #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Function { pub function_name: Identifier, - pub inputs: Vec, + pub inputs: Vec, pub returns: Vec, pub statements: Vec, pub span: Span, @@ -19,7 +19,7 @@ impl<'ast> From> for Function { let parameters = function_definition .parameters .into_iter() - .map(|parameter| Input::from(parameter)) + .map(|parameter| InputVariable::from(parameter)) .collect(); let returns = function_definition .returns diff --git a/types/src/functions/inputs/input.rs b/types/src/functions/inputs/input.rs deleted file mode 100644 index 6168515e5c..0000000000 --- a/types/src/functions/inputs/input.rs +++ /dev/null @@ -1,83 +0,0 @@ -use crate::{FunctionInput, Identifier, Span}; -use leo_ast::functions::inputs::Input as AstInput; - -use serde::{Deserialize, Serialize}; -use std::fmt; - -pub const RECORD_VARIABLE_NAME: &str = "record"; -pub const REGISTERS_VARIABLE_NAME: &str = "registers"; -pub const STATE_VARIABLE_NAME: &str = "state"; -pub const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf"; - -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum Input { - FunctionInput(FunctionInput), - 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(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) - } - } - } -} - -impl Input { - fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Input::FunctionInput(function_input) => write!(f, "{}", function_input), - Input::Record(id) => write!(f, "{}", id), - Input::Registers(id) => write!(f, "{}", id), - Input::State(id) => write!(f, "{}", id), - Input::StateLeaf(id) => write!(f, "{}", id), - } - } -} - -impl fmt::Display for Input { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.format(f) - } -} - -impl fmt::Debug for Input { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.format(f) - } -} diff --git a/types/src/functions/inputs/input_variable.rs b/types/src/functions/inputs/input_variable.rs new file mode 100644 index 0000000000..6c13247078 --- /dev/null +++ b/types/src/functions/inputs/input_variable.rs @@ -0,0 +1,50 @@ +use crate::{FunctionInput, Identifier, Span}; +use leo_ast::functions::inputs::Input as AstInput; + +use serde::{Deserialize, Serialize}; +use std::fmt; + +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum InputVariable { + InputKeyword(Identifier), + FunctionInput(FunctionInput), +} + +impl<'ast> From> for InputVariable { + fn from(input: AstInput<'ast>) -> Self { + match input { + AstInput::InputKeyword(input_keyword) => { + let id = Identifier { + name: input_keyword.keyword, + span: Span::from(input_keyword.span), + }; + + InputVariable::InputKeyword(id) + } + AstInput::FunctionInput(function_input) => { + InputVariable::FunctionInput(FunctionInput::from(function_input)) + } + } + } +} + +impl InputVariable { + fn format(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + InputVariable::InputKeyword(id) => write!(f, "{}", id), + InputVariable::FunctionInput(function_input) => write!(f, "{}", function_input), + } + } +} + +impl fmt::Display for InputVariable { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.format(f) + } +} + +impl fmt::Debug for InputVariable { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.format(f) + } +} diff --git a/types/src/functions/inputs/mod.rs b/types/src/functions/inputs/mod.rs index a545b7282e..0a3a8455f7 100644 --- a/types/src/functions/inputs/mod.rs +++ b/types/src/functions/inputs/mod.rs @@ -1,5 +1,5 @@ pub mod function_input; pub use function_input::*; -pub mod input; -pub use input::*; +pub mod input_variable; +pub use input_variable::*; diff --git a/types/src/program.rs b/types/src/program.rs index 3f58ac0443..3c9542cd57 100644 --- a/types/src/program.rs +++ b/types/src/program.rs @@ -1,7 +1,7 @@ //! A typed Leo program consists of import, circuit, and function definitions. //! Each defined type consists of typed statements and expressions. -use crate::{Circuit, Function, Identifier, Import, Input, TestFunction}; +use crate::{Circuit, Function, Identifier, Import, InputVariable, TestFunction}; use leo_ast::files::File; use serde::{Deserialize, Serialize}; @@ -11,7 +11,7 @@ use std::collections::HashMap; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Program { pub name: String, - pub expected_inputs: Vec, + pub expected_inputs: Vec, pub imports: Vec, pub circuits: HashMap, pub functions: HashMap,