mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-29 11:43:28 +03:00
add unary expression, unary operator, minus, and not to pest and types
This commit is contained in:
parent
494ec62f78
commit
6cff63d752
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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::*;
|
||||
|
@ -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")]
|
@ -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+ }
|
||||
|
@ -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::*;
|
||||
|
@ -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>,
|
||||
}
|
19
ast/src/operations/unary_operation.rs
Normal file
19
ast/src/operations/unary_operation.rs
Normal 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 {}
|
@ -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,
|
||||
|
@ -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),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user