remove custom eq/hash implementations, add node implementations, remove range_or_expression

This commit is contained in:
Protryon 2020-12-12 05:26:18 -08:00
parent b7f2790247
commit 91cac5f9d0
16 changed files with 146 additions and 162 deletions

View File

@ -14,19 +14,16 @@
// 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::{PositiveNumber, Span};
use crate::PositiveNumber;
use leo_grammar::types::ArrayDimensions as GrammarArrayDimensions;
use leo_input::types::ArrayDimensions as InputArrayDimensions;
use serde::{Deserialize, Serialize};
use std::{
fmt,
hash::{Hash, Hasher},
};
use std::fmt;
/// A vector of positive numbers that represent array dimensions.
/// Can be used in an array [`Type`] or an array initializer [`Expression`].
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Default, Hash)]
pub struct ArrayDimensions(pub Vec<PositiveNumber>);
impl ArrayDimensions {
@ -34,10 +31,9 @@ impl ArrayDimensions {
/// Creates a new `PositiveNumber` from the given `usize` and `Span`.
/// Appends the new `PositiveNumber` to the array dimensions.
///
pub fn push_usize(&mut self, number: usize, span: Span) {
pub fn push_usize(&mut self, number: usize) {
let positive_number = PositiveNumber {
value: number.to_string(),
span,
};
self.0.push(positive_number)
@ -145,24 +141,3 @@ impl fmt::Display for ArrayDimensions {
}
}
}
/// Compares two array dimensions and ignores `Span`s.
impl PartialEq for ArrayDimensions {
fn eq(&self, other: &Self) -> bool {
// If the number of dimensions differs return false.
if self.0.len() != other.0.len() {
return false;
}
// Compare all dimensions and ignore `Span`s.
self.0.eq(&other.0)
}
}
impl Eq for ArrayDimensions {}
impl Hash for ArrayDimensions {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state)
}
}

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::Span;
use crate::{Node, Span};
use leo_grammar::functions::InputKeyword as GrammarInputKeyword;
use serde::{Deserialize, Serialize};
@ -22,7 +22,7 @@ use std::fmt;
/// The `input` keyword can view program register, record, and state values.
/// Values cannot be modified. The `input` keyword cannot be made mutable.
#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct InputKeyword {
pub span: Span,
}
@ -40,3 +40,13 @@ impl fmt::Display for InputKeyword {
write!(f, "input")
}
}
impl Node for InputKeyword {
fn span(&self) -> &Span {
&self.span
}
fn set_span(&mut self, span: Span) {
self.span = span;
}
}

View File

@ -29,9 +29,6 @@ pub use mut_self_keyword::*;
pub mod positive_number;
pub use positive_number::*;
pub mod range_or_expression;
pub use range_or_expression::*;
pub mod self_keyword;
pub use self_keyword::*;

View File

@ -14,14 +14,14 @@
// 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::Span;
use crate::{Node, Span};
use leo_grammar::common::MutSelfKeyword as GrammarMutSelfKeyword;
use serde::{Deserialize, Serialize};
use std::fmt;
/// The `mut self` keyword can view and modify circuit values inside of a circuit function.
#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct MutSelfKeyword {
pub span: Span,
}
@ -39,3 +39,13 @@ impl fmt::Display for MutSelfKeyword {
write!(f, "mut self")
}
}
impl Node for MutSelfKeyword {
fn span(&self) -> &Span {
&self.span
}
fn set_span(&mut self, span: Span) {
self.span = span;
}
}

View File

@ -14,21 +14,16 @@
// 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::Span;
use leo_grammar::values::PositiveNumber as GrammarPositiveNumber;
use leo_input::values::PositiveNumber as InputPositiveNumber;
use serde::{Deserialize, Serialize};
use std::{
fmt,
hash::{Hash, Hasher},
};
use std::fmt;
/// A number string guaranteed to be positive by the pest grammar.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
pub struct PositiveNumber {
pub value: String,
pub span: Span,
}
impl PositiveNumber {
@ -43,20 +38,14 @@ impl PositiveNumber {
/// Create a new [`PositiveNumber`] from a [`GrammarPositiveNumber`] in a Leo program file.
impl<'ast> From<GrammarPositiveNumber<'ast>> for PositiveNumber {
fn from(array: GrammarPositiveNumber<'ast>) -> Self {
Self {
value: array.value,
span: Span::from(array.span),
}
Self { value: array.value }
}
}
/// Create a new [`PositiveNumber`] from an [`InputPositiveNumber`] in a Leo input file.
impl<'ast> From<InputPositiveNumber<'ast>> for PositiveNumber {
fn from(array: InputPositiveNumber<'ast>) -> Self {
Self {
value: array.value,
span: Span::from(array.span),
}
Self { value: array.value }
}
}
@ -65,18 +54,3 @@ impl fmt::Display for PositiveNumber {
write!(f, "{}", self.value)
}
}
/// Compares two positive numbers and ignores `Span`s.
impl PartialEq for PositiveNumber {
fn eq(&self, other: &Self) -> bool {
self.value.eq(&other.value)
}
}
impl Eq for PositiveNumber {}
impl Hash for PositiveNumber {
fn hash<H: Hasher>(&self, state: &mut H) {
self.value.hash(state)
}
}

View File

@ -1,55 +0,0 @@
// 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::Expression;
use leo_grammar::common::RangeOrExpression as GrammarRangeOrExpression;
use serde::{Deserialize, Serialize};
use std::fmt;
/// Range or expression enum
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum RangeOrExpression {
Range(Option<Expression>, Option<Expression>),
Expression(Expression),
}
impl<'ast> From<GrammarRangeOrExpression<'ast>> for RangeOrExpression {
fn from(range_or_expression: GrammarRangeOrExpression<'ast>) -> Self {
match range_or_expression {
GrammarRangeOrExpression::Range(range) => {
RangeOrExpression::Range(range.from.map(Expression::from), range.to.map(Expression::from))
}
GrammarRangeOrExpression::Expression(expression) => {
RangeOrExpression::Expression(Expression::from(expression))
}
}
}
}
impl fmt::Display for RangeOrExpression {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
RangeOrExpression::Range(ref from, ref to) => write!(
f,
"{}..{}",
from.as_ref().map(|e| e.to_string()).unwrap_or_default(),
to.as_ref().map(|e| e.to_string()).unwrap_or_default()
),
RangeOrExpression::Expression(ref e) => write!(f, "{}", e),
}
}
}

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::Span;
use crate::{Node, Span};
use leo_grammar::common::SelfKeyword as GrammarSelfKeyword;
use serde::{Deserialize, Serialize};
@ -22,7 +22,7 @@ use std::fmt;
/// The `self` keyword can view circuit values inside of a circuit function.
/// Circuit values cannot be modified. To modify values use the `mut self` [MutSelfKeyword].
#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct SelfKeyword {
pub span: Span,
}
@ -40,3 +40,13 @@ impl fmt::Display for SelfKeyword {
write!(f, "self")
}
}
impl Node for SelfKeyword {
fn span(&self) -> &Span {
&self.span
}
fn set_span(&mut self, span: Span) {
self.span = span;
}
}

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::Expression;
use crate::{Expression, Node, Span};
use leo_grammar::{
common::SpreadOrExpression as GrammarSpreadOrExpression,
expressions::Expression as GrammarExpression,
@ -57,3 +57,19 @@ impl fmt::Display for SpreadOrExpression {
}
}
}
impl Node for SpreadOrExpression {
fn span(&self) -> &Span {
use SpreadOrExpression::*;
match self {
Spread(expression) | Expression(expression) => expression.span(),
}
}
fn set_span(&mut self, span: Span) {
use SpreadOrExpression::*;
match self {
Spread(expression) | Expression(expression) => expression.set_span(span),
}
}
}

View File

@ -21,13 +21,12 @@ use crate::{
Identifier,
IntegerType,
PositiveNumber,
RangeOrExpression,
Span,
SpreadOrExpression,
};
use leo_grammar::{
access::{Access, AssigneeAccess},
common::{Assignee, Identifier as GrammarIdentifier},
common::{Assignee, Identifier as GrammarIdentifier, RangeOrExpression as GrammarRangeOrExpression},
expressions::{
ArrayInitializerExpression,
ArrayInlineExpression as GrammarArrayInlineExpression,
@ -206,18 +205,22 @@ impl<'ast> From<PostfixExpression<'ast>> for Expression {
.into_iter()
.fold(variable, |acc, access| match access {
// Handle array accesses
Access::Array(array) => match RangeOrExpression::from(array.expression) {
RangeOrExpression::Expression(expression) => Expression::ArrayAccess(ArrayAccessExpression {
array: Box::new(acc),
index: Box::new(expression),
span: Span::from(array.span),
}),
RangeOrExpression::Range(left, right) => Expression::ArrayRangeAccess(ArrayRangeAccessExpression {
array: Box::new(acc),
left: left.map(Box::new),
right: right.map(Box::new),
span: Span::from(array.span),
}),
Access::Array(array) => match array.expression {
GrammarRangeOrExpression::Expression(expression) => {
Expression::ArrayAccess(ArrayAccessExpression {
array: Box::new(acc),
index: Box::new(Expression::from(expression)),
span: Span::from(array.span),
})
}
GrammarRangeOrExpression::Range(range) => {
Expression::ArrayRangeAccess(ArrayRangeAccessExpression {
array: Box::new(acc),
left: range.from.map(Expression::from).map(Box::new),
right: range.to.map(Expression::from).map(Box::new),
span: Span::from(array.span),
})
}
},
// Handle tuple access
@ -285,18 +288,22 @@ impl<'ast> From<Assignee<'ast>> for Expression {
span: Span::from(circuit_member.span),
})
}
AssigneeAccess::Array(array) => match RangeOrExpression::from(array.expression) {
RangeOrExpression::Expression(expression) => Expression::ArrayAccess(ArrayAccessExpression {
array: Box::new(acc),
index: Box::new(expression),
span: Span::from(array.span),
}),
RangeOrExpression::Range(left, right) => Expression::ArrayRangeAccess(ArrayRangeAccessExpression {
array: Box::new(acc),
left: left.map(Box::new),
right: right.map(Box::new),
span: Span::from(array.span),
}),
AssigneeAccess::Array(array) => match array.expression {
GrammarRangeOrExpression::Expression(expression) => {
Expression::ArrayAccess(ArrayAccessExpression {
array: Box::new(acc),
index: Box::new(Expression::from(expression)),
span: Span::from(array.span),
})
}
GrammarRangeOrExpression::Range(range) => {
Expression::ArrayRangeAccess(ArrayRangeAccessExpression {
array: Box::new(acc),
left: range.from.map(Expression::from).map(Box::new),
right: range.to.map(Expression::from).map(Box::new),
span: Span::from(array.span),
})
}
},
AssigneeAccess::Tuple(tuple) => Expression::TupleAccess(TupleAccessExpression {
tuple: Box::new(acc),

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::{Block, FunctionInput, Identifier, Span, Type};
use crate::{Block, FunctionInput, Identifier, Node, Span, Type};
use leo_grammar::functions::Function as GrammarFunction;
use serde::{Deserialize, Serialize};
@ -107,3 +107,13 @@ impl fmt::Debug for Function {
self.format(f)
}
}
impl Node for Function {
fn span(&self) -> &Span {
&self.span
}
fn set_span(&mut self, span: Span) {
self.span = span;
}
}

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::{Identifier, Span, Type};
use crate::{Identifier, Node, Span, Type};
use leo_grammar::functions::FunctionInput as GrammarFunctionInput;
use serde::{Deserialize, Serialize};
@ -61,3 +61,13 @@ impl fmt::Debug for FunctionInputVariable {
self.format(f)
}
}
impl Node for FunctionInputVariable {
fn span(&self) -> &Span {
&self.span
}
fn set_span(&mut self, span: Span) {
self.span = span;
}
}

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::{FunctionInputVariable, InputKeyword, MutSelfKeyword, SelfKeyword};
use crate::{FunctionInputVariable, InputKeyword, MutSelfKeyword, Node, SelfKeyword, Span};
use leo_grammar::functions::input::Input as GrammarInput;
use serde::{Deserialize, Serialize};
@ -105,3 +105,25 @@ impl PartialEq for FunctionInput {
}
impl Eq for FunctionInput {}
impl Node for FunctionInput {
fn span(&self) -> &Span {
use FunctionInput::*;
match self {
InputKeyword(keyword) => &keyword.span,
SelfKeyword(keyword) => &keyword.span,
MutSelfKeyword(keyword) => &keyword.span,
Variable(variable) => &variable.span,
}
}
fn set_span(&mut self, span: Span) {
use FunctionInput::*;
match self {
InputKeyword(keyword) => keyword.span = span,
SelfKeyword(keyword) => keyword.span = span,
MutSelfKeyword(keyword) => keyword.span = span,
Variable(variable) => variable.span = span,
}
}
}

View File

@ -118,13 +118,13 @@ impl ExpressionError {
Self::new_from_span(message, span)
}
pub fn invalid_first_dimension(expected: &PositiveNumber, actual: &PositiveNumber) -> Self {
pub fn invalid_first_dimension(expected: &PositiveNumber, actual: &PositiveNumber, span: Span) -> Self {
let message = format!(
"expected array dimension {}, found array dimension {}",
expected, actual
);
Self::new_from_span(message, actual.span.to_owned())
Self::new_from_span(message, span)
}
pub fn invalid_index(actual: String, span: &Span) -> Self {

View File

@ -127,7 +127,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Case 3: expected first dimension != actual first dimension => return mismatched dimensions error
if let Some(Type::Array(type_, mut expected_dimensions)) = expected_type {
if expected_dimensions.eq(&actual_dimensions) {
if expected_dimensions == actual_dimensions {
// Case 1 - enforce expression with array element type
let mut value =
self.enforce_expression(cs, file_scope, function_scope, Some(*type_), element_expression)?;
@ -145,7 +145,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
Ok(value)
} else if expected_dimensions.first().eq(&actual_dimensions.first()) {
} else if expected_dimensions.first() == actual_dimensions.first() {
// Case 2 - enforce expression with updated array type.
let dimension = match expected_dimensions.remove_first() {
Some(number) => {
@ -200,7 +200,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
.ok_or_else(|| ExpressionError::undefined_first_dimension(span.clone()))?,
actual_dimensions
.first()
.ok_or_else(|| ExpressionError::undefined_first_dimension(span))?,
.ok_or_else(|| ExpressionError::undefined_first_dimension(span.clone()))?,
span,
))
}
} else {

View File

@ -115,7 +115,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
ConstrainedValue::Array(array) => {
let array_type = array[0].to_type(span)?;
let mut dimensions = ArrayDimensions::default();
dimensions.push_usize(array.len(), span.to_owned());
dimensions.push_usize(array.len());
// Nested array type
if let Type::Array(inner_type, inner_dimensions) = &array_type {

View File

@ -82,7 +82,6 @@ impl CoreCircuit for Blake2sCircuit {
Box::new(Type::IntegerType(IntegerType::U8)),
ArrayDimensions(vec![PositiveNumber {
value: 32usize.to_string(),
span: span.clone(),
}]),
),
span: span.clone(),
@ -97,7 +96,6 @@ impl CoreCircuit for Blake2sCircuit {
Box::new(Type::IntegerType(IntegerType::U8)),
ArrayDimensions(vec![PositiveNumber {
value: 32usize.to_string(),
span: span.clone(),
}]),
),
span: span.clone(),
@ -107,7 +105,6 @@ impl CoreCircuit for Blake2sCircuit {
Box::new(Type::IntegerType(IntegerType::U8)),
ArrayDimensions(vec![PositiveNumber {
value: 32usize.to_string(),
span: span.clone(),
}]),
)),
block: Block {