add unary expression, unary operator, minus, and not to pest and types

This commit is contained in:
collin 2020-08-04 20:09:48 -07:00
parent 494ec62f78
commit 6cff63d752
10 changed files with 70 additions and 61 deletions

View File

@ -6,11 +6,11 @@ use crate::{
ArrayInlineExpression,
CircuitInlineExpression,
Expression,
NotExpression,
PostfixExpression,
TernaryExpression,
UnaryExpression,
},
operations::{BinaryOperation, NotOperation},
operations::{BinaryOperation, UnaryOperation},
values::Value,
};
@ -76,17 +76,18 @@ fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
Rule::expression_conditional => {
Expression::Ternary(TernaryExpression::from_pest(&mut pair.into_inner()).unwrap())
}
Rule::expression_not => {
Rule::expression_unary => {
// The following is necessary to match with the unary operator and its unary expression
let span = next.as_span();
let mut inner = next.into_inner();
let operation = match inner.next().unwrap().as_rule() {
Rule::operation_not => {
NotOperation::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
Rule::operation_unary => {
UnaryOperation::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
}
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule),
rule => unreachable!("`expression_unary` should yield `operation_unary`, found {:#?}", rule),
};
let expression = parse_term(inner.next().unwrap());
Expression::Not(NotExpression {
Expression::Unary(UnaryExpression {
operation,
expression,
span,
@ -95,21 +96,8 @@ fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
Rule::expression_postfix => {
Expression::Postfix(PostfixExpression::from_pest(&mut pair.into_inner()).unwrap())
}
Rule::expression_primitive => {
let next = next.into_inner().next().unwrap();
match next.as_rule() {
Rule::value => Expression::Value(
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
),
Rule::identifier => Expression::Identifier(
Identifier::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
),
rule => unreachable!(
"`expression_primitive` should contain one of [`value`, `identifier`], found {:#?}",
rule
),
}
}
Rule::value => Expression::Value(Value::from_pest(&mut pair.into_inner()).unwrap()),
Rule::identifier => Expression::Identifier(Identifier::from_pest(&mut pair.into_inner()).unwrap()),
rule => unreachable!(
"`term` should contain one of ['value', 'identifier', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}",
rule

View File

@ -8,7 +8,7 @@ use std::fmt;
pub enum Expression<'ast> {
Value(Value<'ast>),
Identifier(Identifier<'ast>),
Not(NotExpression<'ast>),
Unary(UnaryExpression<'ast>),
Binary(BinaryExpression<'ast>),
Ternary(TernaryExpression<'ast>),
ArrayInline(ArrayInlineExpression<'ast>),
@ -50,7 +50,7 @@ impl<'ast> Expression<'ast> {
match self {
Expression::Value(expression) => &expression.span(),
Expression::Identifier(expression) => &expression.span,
Expression::Not(expression) => &expression.span,
Expression::Unary(expression) => &expression.span,
Expression::Binary(expression) => &expression.span,
Expression::Ternary(expression) => &expression.span,
Expression::ArrayInline(expression) => &expression.span,
@ -66,7 +66,7 @@ impl<'ast> fmt::Display for Expression<'ast> {
match *self {
Expression::Value(ref expression) => write!(f, "{}", expression),
Expression::Identifier(ref expression) => write!(f, "{}", expression),
Expression::Not(ref expression) => write!(f, "!{}", expression.expression),
Expression::Unary(ref expression) => write!(f, "!{}", expression.expression),
Expression::Binary(ref expression) => write!(f, "{} == {}", expression.left, expression.right),
Expression::Ternary(ref expression) => write!(
f,

View File

@ -13,8 +13,8 @@ pub use circuit_inline_expression::*;
pub mod expression;
pub use expression::*;
pub mod not_expression;
pub use not_expression::*;
pub mod unary_expression;
pub use unary_expression::*;
pub mod postfix_expression;
pub use postfix_expression::*;

View File

@ -1,13 +1,13 @@
use crate::{ast::Rule, expressions::Expression, operations::NotOperation, SpanDef};
use crate::{ast::Rule, expressions::Expression, operations::UnaryOperation, SpanDef};
use pest::Span;
use pest_ast::FromPest;
use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::expression_not))]
pub struct NotExpression<'ast> {
pub operation: NotOperation<'ast>,
#[pest_ast(rule(Rule::expression_unary))]
pub struct UnaryExpression<'ast> {
pub operation: UnaryOperation,
pub expression: Box<Expression<'ast>>,
#[pest_ast(outer())]
#[serde(with = "SpanDef")]

View File

@ -68,8 +68,13 @@ let_ = { "let " }
/// Operations
// Declared in operations/not_operation.rs
// Declared in operations/unary_operation.rs
operation_unary = {
operation_not
| operation_minus
}
operation_not = { "!" }
operation_minus = { "-" }
// Declared in operations/binary_operation.rs
operation_and = { "&&" }
@ -263,11 +268,12 @@ expression_term = {
| expression_array_inline
| expression_circuit_inline
| expression_conditional
| expression_not
| value
| expression_unary // must be defined below value to avoid conflicts with negative values
| expression_postfix
| expression_primitive
| identifier
}
expression_primitive = { value | identifier }
expression_tuple = _{ (expression ~ ("," ~ expression)*)? }
// Declared in expressions/expression.rs
@ -284,8 +290,8 @@ inline_array_inner = _{(spread_or_expression ~ ("," ~ NEWLINE* ~ spread_or_expre
expression_circuit_inline = { identifier ~ "{" ~ NEWLINE* ~ circuit_field_list ~ NEWLINE* ~ "}" }
circuit_field_list = _{ (circuit_field ~ ("," ~ NEWLINE* ~ circuit_field)*)? ~ ","? }
// Declared in expressions/not_expression.rs
expression_not = { operation_not ~ expression_term }
// Declared in expressions/unary_expression.rs
expression_unary = { operation_unary ~ expression_term }
// Declared in expressions/postfix_expression.rs
expression_postfix = { identifier ~ access+ }

View File

@ -4,5 +4,5 @@ pub use assign_operation::*;
pub mod binary_operation;
pub use binary_operation::*;
pub mod not_operation;
pub use not_operation::*;
pub mod unary_operation;
pub use unary_operation::*;

View File

@ -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::operation_not))]
pub struct NotOperation<'ast> {
#[pest_ast(outer())]
#[serde(with = "SpanDef")]
pub span: Span<'ast>,
}

View File

@ -0,0 +1,19 @@
use crate::ast::Rule;
use pest_ast::FromPest;
use serde::Serialize;
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::operation_unary))]
pub enum UnaryOperation {
Minus(Minus),
Not(Not),
}
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::operation_not))]
pub struct Not {}
#[derive(Clone, Debug, FromPest, PartialEq, Serialize)]
#[pest_ast(rule(Rule::operation_minus))]
pub struct Minus {}

View File

@ -45,6 +45,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
}
// Binary operations
Expression::Minus(expression, span) => unimplemented!("not yet"),
Expression::Add(left, right, span) => {
let (resolved_left, resolved_right) = self.enforce_binary_expression(
cs,

View File

@ -8,11 +8,11 @@ use leo_ast::{
BinaryExpression,
CircuitInlineExpression,
Expression as AstExpression,
NotExpression,
PostfixExpression,
TernaryExpression,
UnaryExpression,
},
operations::BinaryOperation,
operations::{BinaryOperation, UnaryOperation},
values::{
AddressValue,
BooleanValue,
@ -52,6 +52,7 @@ pub enum Expression {
// Boolean operations
Not(Box<Expression>, Span),
Minus(Box<Expression>, Span),
Or(Box<Expression>, Box<Expression>, Span),
And(Box<Expression>, Box<Expression>, Span),
Eq(Box<Expression>, Box<Expression>, Span),
@ -139,6 +140,7 @@ impl<'ast> fmt::Display for Expression {
Expression::Integer(ref type_, ref integer, ref _span) => write!(f, "{}{}", integer, type_),
// Number operations
Expression::Minus(ref expression, ref _span) => write!(f, "-{}", expression),
Expression::Add(ref left, ref right, ref _span) => write!(f, "{} + {}", left, right),
Expression::Sub(ref left, ref right, ref _span) => write!(f, "{} - {}", left, right),
Expression::Mul(ref left, ref right, ref _span) => write!(f, "{} * {}", left, right),
@ -272,7 +274,7 @@ impl<'ast> From<AstExpression<'ast>> for Expression {
match expression {
AstExpression::Value(value) => Expression::from(value),
AstExpression::Identifier(variable) => Expression::from(variable),
AstExpression::Not(expression) => Expression::from(expression),
AstExpression::Unary(expression) => Expression::from(expression),
AstExpression::Binary(expression) => Expression::from(expression),
AstExpression::Ternary(expression) => Expression::from(expression),
AstExpression::ArrayInline(expression) => Expression::from(expression),
@ -426,12 +428,18 @@ impl<'ast> From<Value<'ast>> for Expression {
}
}
impl<'ast> From<NotExpression<'ast>> for Expression {
fn from(expression: NotExpression<'ast>) -> Self {
Expression::Not(
Box::new(Expression::from(*expression.expression)),
Span::from(expression.span),
)
impl<'ast> From<UnaryExpression<'ast>> for Expression {
fn from(expression: UnaryExpression<'ast>) -> Self {
match expression.operation {
UnaryOperation::Not(_) => Expression::Not(
Box::new(Expression::from(*expression.expression)),
Span::from(expression.span),
),
UnaryOperation::Minus(_) => Expression::Minus(
Box::new(Expression::from(*expression.expression)),
Span::from(expression.span),
),
}
}
}