implied circuit name works

This commit is contained in:
gluaxspeed 2021-01-27 17:14:51 -05:00
parent 727981c639
commit c59ff6d107
9 changed files with 102 additions and 18 deletions

View File

@ -15,7 +15,7 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{Expression, Identifier};
use leo_grammar::circuits::CircuitVariable;
use leo_grammar::circuits::{CircuitImpliedVariable, CircuitVariable};
use serde::{Deserialize, Serialize};
@ -33,3 +33,24 @@ impl<'ast> From<CircuitVariable<'ast>> for CircuitVariableDefinition {
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct CircuitImpliedVariableDefinition {
pub identifier: Identifier,
pub expression: Option<Expression>,
}
impl<'ast> From<CircuitImpliedVariable<'ast>> for CircuitImpliedVariableDefinition {
fn from(member: CircuitImpliedVariable<'ast>) -> Self {
match member {
CircuitImpliedVariable::CircuitVariable(circuit_variable) => Self {
identifier: Identifier::from(circuit_variable.identifier),
expression: Some(Expression::from(circuit_variable.expression)),
},
CircuitImpliedVariable::Identifier(identifier) => Self {
identifier: Identifier::from(identifier),
expression: None,
},
}
}
}

View File

@ -19,7 +19,7 @@ use super::*;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CircuitInitExpression {
pub name: Identifier,
pub members: Vec<CircuitVariableDefinition>,
pub members: Vec<CircuitImpliedVariableDefinition>,
pub span: Span,
}
@ -27,7 +27,11 @@ impl fmt::Display for CircuitInitExpression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {{", self.name)?;
for (i, member) in self.members.iter().enumerate() {
write!(f, "{}: {}", member.identifier, member.expression)?;
match &member.expression {
Some(expression) => write!(f, "{}: {}", member.identifier, expression)?,
None => write!(f, "{}", member.identifier)?,
};
if i < self.members.len() - 1 {
write!(f, ", ")?;
}

View File

@ -16,7 +16,7 @@
use crate::{
ArrayDimensions,
CircuitVariableDefinition,
CircuitImpliedVariableDefinition,
GroupValue,
Identifier,
IntegerType,
@ -177,12 +177,13 @@ impl<'ast> fmt::Display for Expression {
impl<'ast> From<CircuitInlineExpression<'ast>> for Expression {
fn from(expression: CircuitInlineExpression<'ast>) -> Self {
// println!("from CircuitInlineExpression");
let circuit_name = Identifier::from(expression.name);
let members = expression
.members
.into_iter()
.map(CircuitVariableDefinition::from)
.collect::<Vec<CircuitVariableDefinition>>();
.map(CircuitImpliedVariableDefinition::from)
.collect::<Vec<CircuitImpliedVariableDefinition>>();
Expression::CircuitInit(CircuitInitExpression {
name: circuit_name,
@ -485,3 +486,9 @@ impl<'ast> From<GrammarIdentifier<'ast>> for Expression {
Expression::Identifier(Identifier::from(identifier))
}
}
impl From<Identifier> for Expression {
fn from(identifier: Identifier) -> Self {
Expression::Identifier(identifier)
}
}

View File

@ -22,7 +22,7 @@ use crate::{
value::{ConstrainedCircuitMember, ConstrainedValue},
GroupType,
};
use leo_ast::{CircuitMember, CircuitVariableDefinition, Identifier, Span};
use leo_ast::{CircuitImpliedVariableDefinition, CircuitMember, Expression, Identifier, Span};
use snarkvm_models::{
curves::{Field, PrimeField},
@ -36,7 +36,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
file_scope: &str,
function_scope: &str,
identifier: Identifier,
members: Vec<CircuitVariableDefinition>,
members: Vec<CircuitImpliedVariableDefinition>,
span: Span,
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
// Circuit definitions are located at the minimum file scope
@ -64,14 +64,25 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
.into_iter()
.find(|variable| variable.identifier.eq(&identifier));
match matched_variable {
Some(variable) => {
Some(variable) if variable.expression.is_some() => {
// Resolve and enforce circuit variable
let variable_value = self.enforce_expression(
cs,
file_scope,
function_scope,
Some(type_.clone()),
variable.expression,
variable.expression.unwrap(),
)?;
resolved_members.push(ConstrainedCircuitMember(identifier, variable_value))
}
Some(variable) => {
let variable_value = self.enforce_expression(
cs,
file_scope,
function_scope,
Some(type_.clone()),
Expression::from(variable.identifier),
)?;
resolved_members.push(ConstrainedCircuitMember(identifier, variable_value))

View File

@ -0,0 +1,27 @@
// Copyright (C) 2019-2020 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{ast::Rule, circuits::CircuitVariable, common::Identifier};
use pest_ast::FromPest;
use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::circuit_implied_variable))]
pub enum CircuitImpliedVariable<'ast> {
CircuitVariable(CircuitVariable<'ast>),
Identifier(Identifier<'ast>),
}

View File

@ -17,6 +17,9 @@
pub mod circuit;
pub use circuit::*;
pub mod circuit_implied_variable;
pub use circuit_implied_variable::*;
pub mod circuit_variable;
pub use circuit_variable::*;

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{ast::Rule, circuits::CircuitVariable, common::Identifier, types::SelfType, SpanDef};
use crate::{ast::Rule, circuits::CircuitImpliedVariable, common::Identifier, types::SelfType, SpanDef};
use pest::Span;
use pest_ast::FromPest;
@ -24,7 +24,7 @@ use serde::Serialize;
#[pest_ast(rule(Rule::expression_circuit_inline))]
pub struct CircuitInlineExpression<'ast> {
pub name: CircuitName<'ast>,
pub members: Vec<CircuitVariable<'ast>>,
pub members: Vec<CircuitImpliedVariable<'ast>>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,

View File

@ -322,6 +322,12 @@ circuit = { "circuit " ~ identifier ~ "{" ~ circuit_member* ~ "}" }
// Declared in circuits/circuit_variable.rs
circuit_variable = { identifier ~ ":" ~ expression }
// Declared in circuits/circuit_implied_variable.rs
circuit_implied_variable = {
circuit_variable
| identifier
}
// Declared in circuits/circuit_variable_definition.rs
circuit_variable_definition = { identifier ~ ":" ~ type_ ~ ","?}
@ -371,7 +377,7 @@ circuit_name = {
}
// Declared in expressions/circuit_inline_expression.rs
circuit_variable_list = _{ (circuit_variable ~ ("," ~ circuit_variable)*)? ~ ","? }
circuit_variable_list = _{ (circuit_implied_variable ~ ("," ~ circuit_implied_variable)*)? ~ ","? }
// Declared in expressions/unary_expression.rs
expression_unary = { operation_unary ~ expression_term }

View File

@ -22,7 +22,7 @@ use leo_ast::{
Assignee,
AssigneeAccess,
Block,
CircuitVariableDefinition,
CircuitImpliedVariableDefinition,
Expression,
Function,
Identifier,
@ -877,7 +877,7 @@ impl Frame {
fn parse_circuit(
&mut self,
identifier: &Identifier,
members: &[CircuitVariableDefinition],
members: &[CircuitImpliedVariableDefinition],
span: &Span,
) -> Result<Type, FrameError> {
// Check if identifier is Self circuit type.
@ -904,10 +904,15 @@ impl Frame {
// Assert members are circuit type member types.
for (expected_variable, actual_variable) in circuit_type.variables.iter().zip(members) {
// Parse actual variable expression.
let actual_type = self.parse_expression(&actual_variable.expression)?;
match &actual_variable.expression {
Some(expression) => {
let actual_type = self.parse_expression(expression)?;
// Assert expected variable type == actual variable type.
self.assert_equal(expected_variable.type_.clone(), actual_type, span)
// Assert expected variable type == actual variable type.
self.assert_equal(expected_variable.type_.clone(), actual_type, span)
}
None => {}
}
}
Ok(Type::Circuit(circuit_type.identifier))