mirror of
https://github.com/circify/circ.git
synced 2026-01-10 22:27:55 -05:00
Update pest parsers to use PrattParser (#108)
pest::prec_climber has been deprecated. also, fix some clippy lints
This commit is contained in:
5
Cargo.lock
generated
5
Cargo.lock
generated
@@ -900,10 +900,11 @@ checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ bincode = "1"
|
||||
lang-c = { version = "0.10.1", optional = true}
|
||||
logos = "0.12"
|
||||
pairing = "0.21"
|
||||
pest = "2.1"
|
||||
pest = "2.4"
|
||||
pest_derive = "2.1"
|
||||
pest-ast = "0.3"
|
||||
from-pest = "0.3"
|
||||
|
||||
@@ -137,7 +137,7 @@ impl<'ast> Gen<'ast> {
|
||||
fn rule_cases(&mut self, rule: &'ast ast::Rule_) -> Result<'ast, term::T> {
|
||||
rule.conds.iter().try_fold(term::bool_lit(false), |x, y| {
|
||||
let cond = self.condition(y)?;
|
||||
term::or(&x, &cond).map_err(|e| Error::from(e).with_span(rule.span.clone()))
|
||||
term::or(&x, &cond).map_err(|e| Error::from(e).with_span(rule.span))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ impl<'ast> Gen<'ast> {
|
||||
}
|
||||
c.exprs.iter().try_fold(term::bool_lit(true), |x, y| {
|
||||
let cond = self.expr(y, true)?;
|
||||
term::and(&x, &cond).map_err(|e| Error::from(e).with_span(y.span().clone()))
|
||||
term::and(&x, &cond).map_err(|e| Error::from(e).with_span(*y.span()))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ impl<'ast> Gen<'ast> {
|
||||
let arr = self.ident(&c.arr)?;
|
||||
c.idxs.iter().try_fold(arr, |arr, idx| {
|
||||
let idx_v = self.expr(idx, false)?;
|
||||
term::array_idx(&arr, &idx_v).map_err(|err| Error::new(err, idx.span().clone()))
|
||||
term::array_idx(&arr, &idx_v).map_err(|err| Error::new(err, *idx.span()))
|
||||
})
|
||||
}
|
||||
ast::Expression::Call(ref c) => {
|
||||
@@ -188,7 +188,7 @@ impl<'ast> Gen<'ast> {
|
||||
match c.fn_name.value {
|
||||
"to_field" => {
|
||||
assert_eq!(1, args.len(), "to_field takes 1 argument: {:?}", c.span);
|
||||
term::uint_to_field(&args[0]).map_err(|err| Error::new(err, c.span.clone()))
|
||||
term::uint_to_field(&args[0]).map_err(|err| Error::new(err, c.span))
|
||||
}
|
||||
name => {
|
||||
assert!(
|
||||
@@ -281,7 +281,7 @@ impl<'ast> Gen<'ast> {
|
||||
ast::BinaryOperator::Lte => term::lte(&l, &r),
|
||||
ast::BinaryOperator::Gte => term::gte(&l, &r),
|
||||
};
|
||||
res.map_err(|err| Error::new(err, e.span.clone()))
|
||||
res.map_err(|err| Error::new(err, e.span))
|
||||
}
|
||||
fn un_expr(&mut self, e: &'ast ast::UnaryExpression) -> Result<'ast, term::T> {
|
||||
let l = self.expr(&e.expression, false)?;
|
||||
@@ -290,7 +290,7 @@ impl<'ast> Gen<'ast> {
|
||||
ast::UnaryOperator::Not(_) => term::not(&l),
|
||||
ast::UnaryOperator::Neg(_) => term::neg(&l),
|
||||
};
|
||||
res.map_err(|err| Error::new(err, e.span.clone()))
|
||||
res.map_err(|err| Error::new(err, e.span))
|
||||
}
|
||||
|
||||
// Begin prim-rec linting
|
||||
@@ -298,7 +298,7 @@ impl<'ast> Gen<'ast> {
|
||||
let rules: Vec<&'ast ast::Rule_> = self.rules.values().cloned().collect();
|
||||
let bug_if = rules.iter().try_fold(term::bool_lit(false), |x, rule| {
|
||||
let cond = self.lint_rule(rule)?;
|
||||
term::or(&x, &cond).map_err(|e| Error::from(e).with_span(rule.span.clone()))
|
||||
term::or(&x, &cond).map_err(|e| Error::from(e).with_span(rule.span))
|
||||
})?;
|
||||
self.circ.assert(bug_if.as_bool());
|
||||
Ok(())
|
||||
@@ -353,14 +353,12 @@ impl<'ast> Gen<'ast> {
|
||||
&bug_conditions
|
||||
.into_iter()
|
||||
.try_fold(term::bool_lit(true), |x, y| {
|
||||
term::and(&x, &y)
|
||||
.map_err(|e| Error::from(e).with_span(rule.span.clone()))
|
||||
term::and(&x, &y).map_err(|e| Error::from(e).with_span(rule.span))
|
||||
})?,
|
||||
&bad_recursion
|
||||
.into_iter()
|
||||
.try_fold(term::bool_lit(false), |x, y| {
|
||||
term::or(&x, &y)
|
||||
.map_err(|e| Error::from(e).with_span(rule.span.clone()))
|
||||
term::or(&x, &y).map_err(|e| Error::from(e).with_span(rule.span))
|
||||
})?,
|
||||
)?);
|
||||
self.circ.exit_scope();
|
||||
@@ -369,7 +367,7 @@ impl<'ast> Gen<'ast> {
|
||||
bug_in_rule_if_any
|
||||
.into_iter()
|
||||
.try_fold(term::bool_lit(false), |x, y| {
|
||||
term::or(&x, &y).map_err(|e| Error::from(e).with_span(rule.span.clone()))
|
||||
term::or(&x, &y).map_err(|e| Error::from(e).with_span(rule.span))
|
||||
})
|
||||
} else {
|
||||
Ok(term::bool_lit(false))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Datalog parser
|
||||
#![allow(missing_docs)]
|
||||
#![allow(clippy::clone_on_copy)]
|
||||
|
||||
use pest::error::Error;
|
||||
use pest::Parser;
|
||||
@@ -18,7 +19,7 @@ pub mod ast {
|
||||
use from_pest::Void;
|
||||
use lazy_static::lazy_static;
|
||||
use pest::iterators::{Pair, Pairs};
|
||||
use pest::prec_climber::{Assoc, Operator, PrecClimber};
|
||||
use pest::pratt_parser::{Assoc, Op, PrattParser};
|
||||
pub use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
||||
@@ -131,28 +132,27 @@ pub mod ast {
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref PREC_CLIMBER: PrecClimber<Rule> = build_precedence_climber();
|
||||
static ref PREC_CLIMBER: PrattParser<Rule> = build_precedence_climber();
|
||||
}
|
||||
|
||||
// based on https://docs.python.org/3/reference/expressions.html#operator-precedence
|
||||
fn build_precedence_climber() -> PrecClimber<Rule> {
|
||||
PrecClimber::new(vec![
|
||||
Operator::new(Rule::or, Assoc::Left),
|
||||
Operator::new(Rule::and, Assoc::Left),
|
||||
Operator::new(Rule::lt, Assoc::Left)
|
||||
| Operator::new(Rule::lte, Assoc::Left)
|
||||
| Operator::new(Rule::gt, Assoc::Left)
|
||||
| Operator::new(Rule::gte, Assoc::Left)
|
||||
| Operator::new(Rule::eq, Assoc::Left),
|
||||
Operator::new(Rule::bitor, Assoc::Left),
|
||||
Operator::new(Rule::bitxor, Assoc::Left),
|
||||
Operator::new(Rule::bitand, Assoc::Left),
|
||||
Operator::new(Rule::shl, Assoc::Left) | Operator::new(Rule::shr, Assoc::Left),
|
||||
Operator::new(Rule::add, Assoc::Left) | Operator::new(Rule::sub, Assoc::Left),
|
||||
Operator::new(Rule::mul, Assoc::Left)
|
||||
| Operator::new(Rule::div, Assoc::Left)
|
||||
| Operator::new(Rule::urem, Assoc::Left),
|
||||
])
|
||||
fn build_precedence_climber() -> PrattParser<Rule> {
|
||||
PrattParser::new()
|
||||
.op(Op::infix(Rule::or, Assoc::Left))
|
||||
.op(Op::infix(Rule::and, Assoc::Left))
|
||||
.op(Op::infix(Rule::lt, Assoc::Left)
|
||||
| Op::infix(Rule::lte, Assoc::Left)
|
||||
| Op::infix(Rule::gt, Assoc::Left)
|
||||
| Op::infix(Rule::gte, Assoc::Left)
|
||||
| Op::infix(Rule::eq, Assoc::Left))
|
||||
.op(Op::infix(Rule::bitor, Assoc::Left))
|
||||
.op(Op::infix(Rule::bitxor, Assoc::Left))
|
||||
.op(Op::infix(Rule::bitand, Assoc::Left))
|
||||
.op(Op::infix(Rule::shl, Assoc::Left) | Op::infix(Rule::shr, Assoc::Left))
|
||||
.op(Op::infix(Rule::add, Assoc::Left) | Op::infix(Rule::sub, Assoc::Left))
|
||||
.op(Op::infix(Rule::mul, Assoc::Left)
|
||||
| Op::infix(Rule::div, Assoc::Left)
|
||||
| Op::infix(Rule::urem, Assoc::Left))
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -297,7 +297,10 @@ pub mod ast {
|
||||
|
||||
// Create an Expression from an `expression`. `build_factor` turns each term into an `Expression` and `infix_rule` turns each (Expression, operator, Expression) into an Expression
|
||||
pub fn climb(pair: Pair<Rule>) -> Box<Expression> {
|
||||
PREC_CLIMBER.climb(pair.into_inner(), build_factor, infix_rule)
|
||||
PREC_CLIMBER
|
||||
.map_primary(build_factor)
|
||||
.map_infix(infix_rule)
|
||||
.parse(pair.into_inner())
|
||||
}
|
||||
|
||||
// Create an Expression from a `term`.
|
||||
|
||||
@@ -91,7 +91,7 @@ fn canon_type<'ast>(ty: &ast::StructType<'ast>, zgen: &ZGen<'ast>) -> ZResult<as
|
||||
Ok(sd) => ast::Type::Struct(ast::StructType {
|
||||
id: sd.id.clone(),
|
||||
explicit_generics: None,
|
||||
span: sd.span.clone(),
|
||||
span: sd.span,
|
||||
}),
|
||||
Err(t) => t.ty.clone(),
|
||||
})
|
||||
|
||||
@@ -101,22 +101,22 @@ impl<'ast> ZVisitorMut<'ast> for ZConstLiteralRewriter {
|
||||
self.found = true;
|
||||
dle.suffix.replace(match self.to_ty.as_ref().unwrap() {
|
||||
Ty::Uint(8) => Ok(ast::DecimalSuffix::U8(ast::U8Suffix {
|
||||
span: dle.span.clone(),
|
||||
span: dle.span,
|
||||
})),
|
||||
Ty::Uint(16) => Ok(ast::DecimalSuffix::U16(ast::U16Suffix {
|
||||
span: dle.span.clone(),
|
||||
span: dle.span,
|
||||
})),
|
||||
Ty::Uint(32) => Ok(ast::DecimalSuffix::U32(ast::U32Suffix {
|
||||
span: dle.span.clone(),
|
||||
span: dle.span,
|
||||
})),
|
||||
Ty::Uint(64) => Ok(ast::DecimalSuffix::U64(ast::U64Suffix {
|
||||
span: dle.span.clone(),
|
||||
span: dle.span,
|
||||
})),
|
||||
Ty::Uint(_) => Err(
|
||||
"ZConstLiteralRewriter: Uint size must be divisible by 8".to_string(),
|
||||
),
|
||||
Ty::Field => Ok(ast::DecimalSuffix::Field(ast::FieldSuffix {
|
||||
span: dle.span.clone(),
|
||||
span: dle.span,
|
||||
})),
|
||||
_ => Err(
|
||||
"ZConstLiteralRewriter: rewriting DecimalLiteralExpression to incompatible type"
|
||||
|
||||
@@ -132,11 +132,13 @@ impl<'ast, 'ret> ZStatementWalker<'ast, 'ret> {
|
||||
.zip(call.arguments.expressions.iter_mut())
|
||||
.try_for_each(|(pty, arg)| self.unify_expression(pty, arg))?;
|
||||
|
||||
let ret_ty = fdef.returns.first().cloned().unwrap_or_else(|| {
|
||||
ast::Type::Basic(ast::BasicType::Boolean(ast::BooleanType {
|
||||
span: call.span.clone(),
|
||||
}))
|
||||
});
|
||||
let ret_ty =
|
||||
fdef.returns
|
||||
.first()
|
||||
.cloned()
|
||||
.unwrap_or(ast::Type::Basic(ast::BasicType::Boolean(
|
||||
ast::BooleanType { span: call.span },
|
||||
)));
|
||||
if let Some(ty) = rty {
|
||||
self.eq_type(ty, &ret_ty)?;
|
||||
}
|
||||
@@ -211,9 +213,7 @@ impl<'ast, 'ret> ZStatementWalker<'ast, 'ret> {
|
||||
assert!(!at.dimensions.is_empty());
|
||||
|
||||
// XXX(unimpl) does not check array lengths, just unifies ai.count with U32!
|
||||
let u32_ty = Basic(ast::BasicType::U32(ast::U32Type {
|
||||
span: ai.span.clone(),
|
||||
}));
|
||||
let u32_ty = Basic(ast::BasicType::U32(ast::U32Type { span: ai.span }));
|
||||
self.unify_expression(u32_ty, &mut *ai.count)?;
|
||||
|
||||
let arr_ty = if at.dimensions.len() > 1 {
|
||||
@@ -297,7 +297,7 @@ impl<'ast, 'ret> ZStatementWalker<'ast, 'ret> {
|
||||
ast::Type::Array(ast::ArrayType {
|
||||
ty: at.ty.clone(),
|
||||
dimensions: Vec::from(&at.dimensions[1..]),
|
||||
span: at.span.clone(),
|
||||
span: at.span,
|
||||
})
|
||||
};
|
||||
ia.expressions.iter_mut().try_for_each(|soe| match soe {
|
||||
@@ -320,9 +320,7 @@ impl<'ast, 'ret> ZStatementWalker<'ast, 'ret> {
|
||||
te: &mut ast::TernaryExpression<'ast>,
|
||||
) -> ZVisitorResult {
|
||||
// first expr must have type Bool, others the expected output type
|
||||
let bool_ty = ast::Type::Basic(ast::BasicType::Boolean(ast::BooleanType {
|
||||
span: te.span.clone(),
|
||||
}));
|
||||
let bool_ty = ast::Type::Basic(ast::BasicType::Boolean(ast::BooleanType { span: te.span }));
|
||||
self.unify_expression(bool_ty, &mut te.first)?;
|
||||
self.unify_expression(ty.clone(), &mut te.second)?;
|
||||
self.unify_expression(ty, &mut te.third)
|
||||
@@ -351,12 +349,9 @@ impl<'ast, 'ret> ZStatementWalker<'ast, 'ret> {
|
||||
)),
|
||||
},
|
||||
RightShift | LeftShift => match &bt {
|
||||
U8(_) | U16(_) | U32(_) | U64(_) => Ok((
|
||||
Basic(bt),
|
||||
Basic(U32(ast::U32Type {
|
||||
span: be.span.clone(),
|
||||
})),
|
||||
)),
|
||||
U8(_) | U16(_) | U32(_) | U64(_) => {
|
||||
Ok((Basic(bt), Basic(U32(ast::U32Type { span: be.span }))))
|
||||
}
|
||||
_ => Err(ZVisitorError(
|
||||
"ZStatementWalker: << and >> operators require U* left operand".to_owned(),
|
||||
)),
|
||||
@@ -421,12 +416,7 @@ impl<'ast, 'ret> ZStatementWalker<'ast, 'ret> {
|
||||
},
|
||||
Pow => match &bt {
|
||||
// XXX does POW operator really require U32 RHS?
|
||||
Field(_) => Ok((
|
||||
Basic(bt),
|
||||
Basic(U32(ast::U32Type {
|
||||
span: be.span.clone(),
|
||||
})),
|
||||
)),
|
||||
Field(_) => Ok((Basic(bt), Basic(U32(ast::U32Type { span: be.span })))),
|
||||
_ => Err(ZVisitorError(
|
||||
"ZStatementWalker: pow operator must take Field LHS and U32 RHS".to_owned(),
|
||||
)),
|
||||
@@ -539,21 +529,11 @@ impl<'ast, 'ret> ZStatementWalker<'ast, 'ret> {
|
||||
"ZStatementWalker: DecimalLiteral wanted Bool:\n{}",
|
||||
span_to_string(&dle.span),
|
||||
))),
|
||||
Field(_) => Ok(DS::Field(ast::FieldSuffix {
|
||||
span: dle.span.clone(),
|
||||
})),
|
||||
U8(_) => Ok(DS::U8(ast::U8Suffix {
|
||||
span: dle.span.clone(),
|
||||
})),
|
||||
U16(_) => Ok(DS::U16(ast::U16Suffix {
|
||||
span: dle.span.clone(),
|
||||
})),
|
||||
U32(_) => Ok(DS::U32(ast::U32Suffix {
|
||||
span: dle.span.clone(),
|
||||
})),
|
||||
U64(_) => Ok(DS::U64(ast::U64Suffix {
|
||||
span: dle.span.clone(),
|
||||
})),
|
||||
Field(_) => Ok(DS::Field(ast::FieldSuffix { span: dle.span })),
|
||||
U8(_) => Ok(DS::U8(ast::U8Suffix { span: dle.span })),
|
||||
U16(_) => Ok(DS::U16(ast::U16Suffix { span: dle.span })),
|
||||
U32(_) => Ok(DS::U32(ast::U32Suffix { span: dle.span })),
|
||||
U64(_) => Ok(DS::U64(ast::U64Suffix { span: dle.span })),
|
||||
}
|
||||
.map(|ds| {
|
||||
dle.suffix.replace(ds);
|
||||
@@ -684,7 +664,7 @@ impl<'ast, 'ret> ZStatementWalker<'ast, 'ret> {
|
||||
if self.generic_defined(&id.value) {
|
||||
// generics are always U32
|
||||
Ok(ast::Type::Basic(ast::BasicType::U32(ast::U32Type {
|
||||
span: id.span.clone(),
|
||||
span: id.span,
|
||||
})))
|
||||
} else if let Some(t) = self.zgen.const_ty_lookup_(&id.value) {
|
||||
Ok(t.clone())
|
||||
@@ -775,7 +755,7 @@ impl<'ast, 'ret> ZVisitorMut<'ast> for ZStatementWalker<'ast, 'ret> {
|
||||
asrt: &mut ast::AssertionStatement<'ast>,
|
||||
) -> ZVisitorResult {
|
||||
let bool_ty = ast::Type::Basic(ast::BasicType::Boolean(ast::BooleanType {
|
||||
span: asrt.span.clone(),
|
||||
span: asrt.span,
|
||||
}));
|
||||
self.unify(Some(bool_ty), &mut asrt.expression)?;
|
||||
walk_assertion_statement(self, asrt)
|
||||
|
||||
@@ -48,12 +48,12 @@ impl<'ast, 'ret, 'wlk> ZExpressionTyper<'ast, 'ret, 'wlk> {
|
||||
Basic(bty) => ast::ArrayType {
|
||||
ty: ast::BasicOrStructType::Basic(bty),
|
||||
dimensions: vec![cnt],
|
||||
span: spn.clone(),
|
||||
span: *spn,
|
||||
},
|
||||
Struct(sty) => ast::ArrayType {
|
||||
ty: ast::BasicOrStructType::Struct(sty),
|
||||
dimensions: vec![cnt],
|
||||
span: spn.clone(),
|
||||
span: *spn,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -106,14 +106,12 @@ impl<'ast, 'ret, 'wlk> ZVisitorMut<'ast> for ZExpressionTyper<'ast, 'ret, 'wlk>
|
||||
assert!(self.ty.is_none());
|
||||
match &be.op {
|
||||
Or | And | Eq | NotEq | Lt | Gt | Lte | Gte => {
|
||||
self.ty.replace(Basic(Boolean(ast::BooleanType {
|
||||
span: be.span.clone(),
|
||||
})));
|
||||
self.ty
|
||||
.replace(Basic(Boolean(ast::BooleanType { span: be.span })));
|
||||
}
|
||||
Pow => {
|
||||
self.ty.replace(Basic(Field(ast::FieldType {
|
||||
span: be.span.clone(),
|
||||
})));
|
||||
self.ty
|
||||
.replace(Basic(Field(ast::FieldType { span: be.span })));
|
||||
}
|
||||
BitXor | BitAnd | BitOr | RightShift | LeftShift | Add | Sub | Mul | Div | Rem => {
|
||||
self.visit_expression(&mut be.left)?;
|
||||
@@ -190,9 +188,7 @@ impl<'ast, 'ret, 'wlk> ZVisitorMut<'ast> for ZExpressionTyper<'ast, 'ret, 'wlk>
|
||||
) -> ZVisitorResult {
|
||||
assert!(self.ty.is_none());
|
||||
self.ty.replace(ast::Type::Basic(ast::BasicType::Boolean(
|
||||
ast::BooleanType {
|
||||
span: ble.span.clone(),
|
||||
},
|
||||
ast::BooleanType { span: ble.span },
|
||||
)));
|
||||
Ok(())
|
||||
}
|
||||
@@ -201,21 +197,13 @@ impl<'ast, 'ret, 'wlk> ZVisitorMut<'ast> for ZExpressionTyper<'ast, 'ret, 'wlk>
|
||||
assert!(self.ty.is_none());
|
||||
use ast::{BasicType::*, DecimalSuffix as DS, Type::*};
|
||||
match ds {
|
||||
DS::U8(s) => self.ty.replace(Basic(U8(ast::U8Type {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
DS::U16(s) => self.ty.replace(Basic(U16(ast::U16Type {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
DS::U32(s) => self.ty.replace(Basic(U32(ast::U32Type {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
DS::U64(s) => self.ty.replace(Basic(U64(ast::U64Type {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
DS::Field(s) => self.ty.replace(Basic(Field(ast::FieldType {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
DS::U8(s) => self.ty.replace(Basic(U8(ast::U8Type { span: s.span }))),
|
||||
DS::U16(s) => self.ty.replace(Basic(U16(ast::U16Type { span: s.span }))),
|
||||
DS::U32(s) => self.ty.replace(Basic(U32(ast::U32Type { span: s.span }))),
|
||||
DS::U64(s) => self.ty.replace(Basic(U64(ast::U64Type { span: s.span }))),
|
||||
DS::Field(s) => self
|
||||
.ty
|
||||
.replace(Basic(Field(ast::FieldType { span: s.span }))),
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
@@ -227,18 +215,10 @@ impl<'ast, 'ret, 'wlk> ZVisitorMut<'ast> for ZExpressionTyper<'ast, 'ret, 'wlk>
|
||||
assert!(self.ty.is_none());
|
||||
use ast::{BasicType::*, HexNumberExpression as HNE, Type::*};
|
||||
match hne {
|
||||
HNE::U8(s) => self.ty.replace(Basic(U8(ast::U8Type {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
HNE::U16(s) => self.ty.replace(Basic(U16(ast::U16Type {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
HNE::U32(s) => self.ty.replace(Basic(U32(ast::U32Type {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
HNE::U64(s) => self.ty.replace(Basic(U64(ast::U64Type {
|
||||
span: s.span.clone(),
|
||||
}))),
|
||||
HNE::U8(s) => self.ty.replace(Basic(U8(ast::U8Type { span: s.span }))),
|
||||
HNE::U16(s) => self.ty.replace(Basic(U16(ast::U16Type { span: s.span }))),
|
||||
HNE::U32(s) => self.ty.replace(Basic(U32(ast::U32Type { span: s.span }))),
|
||||
HNE::U64(s) => self.ty.replace(Basic(U64(ast::U64Type { span: s.span }))),
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
@@ -324,9 +304,9 @@ impl<'ast, 'ret, 'wlk> ZVisitorMut<'ast> for ZExpressionTyper<'ast, 'ret, 'wlk>
|
||||
ast::HexLiteralExpression {
|
||||
value: ast::HexNumberExpression::U32(ast::U32NumberExpression {
|
||||
value: format!("{:04x}", acc_len),
|
||||
span: iae.span.clone(),
|
||||
span: iae.span,
|
||||
}),
|
||||
span: iae.span.clone(),
|
||||
span: iae.span,
|
||||
},
|
||||
)),
|
||||
&iae.span,
|
||||
|
||||
@@ -6,7 +6,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
zokrates_parser = { version = "0.2.0", path = "../zokrates_parser" }
|
||||
pest = "2.0"
|
||||
pest = "2.4"
|
||||
pest-ast = "0.3.3"
|
||||
from-pest = "0.3.1"
|
||||
lazy_static = "1.3.0"
|
||||
|
||||
@@ -31,37 +31,36 @@ mod ast {
|
||||
use from_pest::FromPest;
|
||||
use from_pest::Void;
|
||||
use pest::iterators::{Pair, Pairs};
|
||||
use pest::prec_climber::{Assoc, Operator, PrecClimber};
|
||||
use pest::pratt_parser::{Assoc, Op, PrattParser};
|
||||
pub use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
use zokrates_parser::Rule;
|
||||
|
||||
lazy_static! {
|
||||
static ref PREC_CLIMBER: PrecClimber<Rule> = build_precedence_climber();
|
||||
static ref PREC_CLIMBER: PrattParser<Rule> = build_precedence_climber();
|
||||
}
|
||||
|
||||
// based on https://docs.python.org/3/reference/expressions.html#operator-precedence
|
||||
fn build_precedence_climber() -> PrecClimber<Rule> {
|
||||
PrecClimber::new(vec![
|
||||
Operator::new(Rule::op_ternary, Assoc::Right),
|
||||
Operator::new(Rule::op_or, Assoc::Left),
|
||||
Operator::new(Rule::op_and, Assoc::Left),
|
||||
Operator::new(Rule::op_lt, Assoc::Left)
|
||||
| Operator::new(Rule::op_lte, Assoc::Left)
|
||||
| Operator::new(Rule::op_gt, Assoc::Left)
|
||||
| Operator::new(Rule::op_gte, Assoc::Left)
|
||||
| Operator::new(Rule::op_not_equal, Assoc::Left)
|
||||
| Operator::new(Rule::op_equal, Assoc::Left),
|
||||
Operator::new(Rule::op_bit_or, Assoc::Left),
|
||||
Operator::new(Rule::op_bit_xor, Assoc::Left),
|
||||
Operator::new(Rule::op_bit_and, Assoc::Left),
|
||||
Operator::new(Rule::op_left_shift, Assoc::Left)
|
||||
| Operator::new(Rule::op_right_shift, Assoc::Left),
|
||||
Operator::new(Rule::op_add, Assoc::Left) | Operator::new(Rule::op_sub, Assoc::Left),
|
||||
Operator::new(Rule::op_mul, Assoc::Left)
|
||||
| Operator::new(Rule::op_div, Assoc::Left)
|
||||
| Operator::new(Rule::op_rem, Assoc::Left),
|
||||
])
|
||||
fn build_precedence_climber() -> PrattParser<Rule> {
|
||||
PrattParser::new()
|
||||
.op(Op::infix(Rule::op_ternary, Assoc::Right))
|
||||
.op(Op::infix(Rule::op_or, Assoc::Left))
|
||||
.op(Op::infix(Rule::op_and, Assoc::Left))
|
||||
.op(Op::infix(Rule::op_lt, Assoc::Left)
|
||||
| Op::infix(Rule::op_lte, Assoc::Left)
|
||||
| Op::infix(Rule::op_gt, Assoc::Left)
|
||||
| Op::infix(Rule::op_gte, Assoc::Left)
|
||||
| Op::infix(Rule::op_not_equal, Assoc::Left)
|
||||
| Op::infix(Rule::op_equal, Assoc::Left))
|
||||
.op(Op::infix(Rule::op_bit_or, Assoc::Left))
|
||||
.op(Op::infix(Rule::op_bit_xor, Assoc::Left))
|
||||
.op(Op::infix(Rule::op_bit_and, Assoc::Left))
|
||||
.op(Op::infix(Rule::op_left_shift, Assoc::Left)
|
||||
| Op::infix(Rule::op_right_shift, Assoc::Left))
|
||||
.op(Op::infix(Rule::op_add, Assoc::Left) | Op::infix(Rule::op_sub, Assoc::Left))
|
||||
.op(Op::infix(Rule::op_mul, Assoc::Left)
|
||||
| Op::infix(Rule::op_div, Assoc::Left)
|
||||
| Op::infix(Rule::op_rem, Assoc::Left))
|
||||
}
|
||||
|
||||
// Create an Expression from left and right terms and an operator
|
||||
@@ -105,9 +104,13 @@ mod ast {
|
||||
})
|
||||
}
|
||||
|
||||
// Create an Expression from an `expression`. `build_factor` turns each term into an `Expression` and `infix_rule` turns each (Expression, operator, Expression) into an Expression
|
||||
// Create an Expression from an `expression`. `build_factor` turns each term into
|
||||
// an `Expression` and `infix_rule` turns each (Expression, operator, Expression) into an Expression
|
||||
pub fn climb(pair: Pair<Rule>) -> Box<Expression> {
|
||||
PREC_CLIMBER.climb(pair.into_inner(), build_factor, infix_rule)
|
||||
PREC_CLIMBER
|
||||
.map_primary(build_factor)
|
||||
.map_infix(infix_rule)
|
||||
.parse(pair.into_inner())
|
||||
}
|
||||
|
||||
// Create an Expression from a `unaried_term`.
|
||||
|
||||
Reference in New Issue
Block a user