mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-21 10:49:59 +03:00
compiler successfully parsing record, registers, state, state_leaf variables with access
This commit is contained in:
parent
d5ac5e6709
commit
3d3e8f5e72
@ -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<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
self.program_inputs.set_main_inputs(program_inputs);
|
||||
}
|
||||
|
||||
fn load_program(&mut self) -> Result<String, CompilerError> {
|
||||
// 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<String, CompilerError> {
|
||||
// Read in the main file as string
|
||||
let unparsed_file = fs::read_to_string(&self.main_file_path)
|
||||
@ -101,41 +129,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
generate_test_constraints::<F, G>(cs, self.program, self.program_inputs, &self.imported_programs)
|
||||
}
|
||||
|
||||
fn load_program(&mut self) -> Result<String, CompilerError> {
|
||||
// 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<Vec<u8>, CompilerError> {
|
||||
Ok(bincode::serialize(&self.program)?)
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CompilerError> {
|
||||
let program: Program = bincode::deserialize(bytes)?;
|
||||
let mut program_inputs = Inputs::new();
|
||||
let program_inputs = Inputs::new();
|
||||
|
||||
Ok(Self {
|
||||
package_name: program.name.clone(),
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -39,28 +39,77 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// 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
|
||||
|
@ -8,3 +8,6 @@ pub use self::input::*;
|
||||
|
||||
pub mod main_input;
|
||||
pub use self::main_input::*;
|
||||
|
||||
pub mod section;
|
||||
pub use self::section::*;
|
||||
|
37
compiler/src/function/input/section.rs
Normal file
37
compiler/src/function/input/section.rs
Normal file
@ -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<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
pub fn allocate_input_section<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
identifier: Identifier,
|
||||
section: HashMap<Parameter, Option<InputValue>>,
|
||||
) -> Result<ConstrainedValue<F, G>, 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))
|
||||
}
|
||||
}
|
@ -30,12 +30,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
|
||||
// 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<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
|
||||
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)
|
||||
|
@ -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<Self::Output, CLIError> {
|
||||
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();
|
||||
|
||||
|
@ -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<AstIdentifier<'ast>> for Identifier {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<InputsAstIdentifier<'ast>> 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)
|
||||
|
@ -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::<usize>().expect("Unable to read array size")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for Expression {
|
||||
@ -398,7 +403,7 @@ impl<'ast> From<ArrayInlineExpression<'ast>> for Expression {
|
||||
|
||||
impl<'ast> From<ArrayInitializerExpression<'ast>> 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))
|
||||
|
@ -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<AstInput<'ast>> 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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<InputValue> {
|
||||
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
self.inputs.get(name)
|
||||
}
|
||||
|
||||
/// Returns the runtime register input values
|
||||
pub fn get_registers(&self) -> HashMap<Parameter, Option<InputValue>> {
|
||||
self.inputs.get_registers()
|
||||
}
|
||||
|
||||
/// Returns the runtime record input values
|
||||
pub fn get_record(&self) -> HashMap<Parameter, Option<InputValue>> {
|
||||
self.state.get_record()
|
||||
}
|
||||
|
||||
/// Returns the runtime state input values
|
||||
pub fn get_state(&self) -> HashMap<Parameter, Option<InputValue>> {
|
||||
self.state.get_state()
|
||||
}
|
||||
|
||||
/// Returns the runtime state leaf input values
|
||||
pub fn get_state_leaf(&self) -> HashMap<Parameter, Option<InputValue>> {
|
||||
self.state.get_state_leaf()
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ macro_rules! input_section_impl {
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct $name {
|
||||
is_present: bool,
|
||||
values: HashMap<String, Option<InputValue>>,
|
||||
values: HashMap<Parameter, Option<InputValue>>,
|
||||
}
|
||||
|
||||
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<Parameter, Option<InputValue>> {
|
||||
self.values.clone()
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
@ -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::*;
|
||||
|
||||
|
2
types/src/inputs/parameters/mod.rs
Normal file
2
types/src/inputs/parameters/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod parameter;
|
||||
pub use parameter::*;
|
19
types/src/inputs/parameters/parameter.rs
Normal file
19
types/src/inputs/parameters/parameter.rs
Normal file
@ -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<AstParameter<'ast>> for Parameter {
|
||||
fn from(parameter: AstParameter<'ast>) -> Self {
|
||||
Self {
|
||||
variable: Identifier::from(parameter.variable),
|
||||
type_: Type::from(parameter.type_),
|
||||
span: Span::from(parameter.span),
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Definition>) -> 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<InputValue> {
|
||||
self.inputs.get(name).unwrap().clone()
|
||||
/// Returns an `Option` of the main function input at `name`
|
||||
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
self.inputs.get(name).map(|input| input.clone())
|
||||
}
|
||||
}
|
||||
|
@ -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<InputValue> {
|
||||
/// Returns the main function input value with the given `name`
|
||||
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
|
||||
self.main.get(name)
|
||||
}
|
||||
|
||||
/// Returns the runtime register input values
|
||||
pub fn get_registers(&self) -> HashMap<Parameter, Option<InputValue>> {
|
||||
self.registers.values()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{Input, InputValue};
|
||||
use crate::{InputValue, Parameter};
|
||||
use leo_inputs::{definitions::Definition, InputParserError};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
@ -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<Parameter, Option<InputValue>> {
|
||||
self.record.values()
|
||||
}
|
||||
|
||||
/// Returns the runtime state leaf input values
|
||||
pub fn get_state_leaf(&self) -> HashMap<Parameter, Option<InputValue>> {
|
||||
self.state_leaf.values()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{Input, InputValue};
|
||||
use crate::{InputValue, Parameter};
|
||||
use leo_inputs::{definitions::Definition, InputParserError};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{Input, InputValue};
|
||||
use crate::{InputValue, Parameter};
|
||||
use leo_inputs::{definitions::Definition, InputParserError};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
@ -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<Parameter, Option<InputValue>> {
|
||||
self.private.get_record()
|
||||
}
|
||||
|
||||
/// Returns the runtime state input values
|
||||
pub fn get_state(&self) -> HashMap<Parameter, Option<InputValue>> {
|
||||
self.public.get_state()
|
||||
}
|
||||
|
||||
/// Returns the runtime state leaf input values
|
||||
pub fn get_state_leaf(&self) -> HashMap<Parameter, Option<InputValue>> {
|
||||
self.private.get_state_leaf()
|
||||
}
|
||||
}
|
||||
|
@ -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<Section>) -> 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<Parameter, Option<InputValue>> {
|
||||
self.state.values()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{Input, InputValue};
|
||||
use crate::{InputValue, Parameter};
|
||||
use leo_inputs::{definitions::Definition, InputParserError};
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
@ -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<AstIntegerType> for IntegerType {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InputsAstIntegerType> 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 {
|
||||
|
@ -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<DataType> for Type {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<ArrayType<'ast>> for Type {
|
||||
fn from(array_type: ArrayType<'ast>) -> Self {
|
||||
impl<'ast> From<InputsArrayType<'ast>> 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<CircuitType<'ast>> for Type {
|
||||
}
|
||||
|
||||
impl<'ast> From<AstType<'ast>> 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<InputsDataType> 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<ArrayType<'ast>> 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<InputsAstType<'ast>> 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<usize>) -> Self {
|
||||
let type_ = self.clone();
|
||||
|
Loading…
Reference in New Issue
Block a user