Bunch of infix ops
This commit is contained in:
@@ -135,6 +135,19 @@ pub enum Operator {
|
||||
Mul,
|
||||
Div,
|
||||
Mod,
|
||||
And,
|
||||
Or,
|
||||
BitAnd,
|
||||
BitOr,
|
||||
Xor,
|
||||
Lt,
|
||||
Le,
|
||||
Gt,
|
||||
Ge,
|
||||
Eq,
|
||||
Ne,
|
||||
Lshift,
|
||||
Rshift,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
|
||||
@@ -25,8 +25,28 @@ sub = { "-" }
|
||||
mul = { "*" }
|
||||
div = { "/" }
|
||||
modulus = { "%" }
|
||||
log_and = { "&&" }
|
||||
log_or = { "||" }
|
||||
bit_and = { "&" }
|
||||
bit_or = { "|" }
|
||||
xor = { "^" }
|
||||
lt = { "<" }
|
||||
le = { "<=" }
|
||||
gt = { ">" }
|
||||
ge = { ">=" }
|
||||
eq = { "==" }
|
||||
ne = { "!=" }
|
||||
lshift = { "<<" }
|
||||
rshift = { ">>" }
|
||||
|
||||
operator = _{ add | sub | mul | div | modulus }
|
||||
operator = _{
|
||||
add | sub |
|
||||
mul | div | modulus |
|
||||
log_and | log_or |
|
||||
bit_and | bit_or | xor |
|
||||
lshift | rshift |
|
||||
lt | le | gt | ge |
|
||||
eq | ne }
|
||||
expr = { val ~ (operator ~ val)* }
|
||||
val = { // These are what get evaluated and left on the stack:
|
||||
number | // Literal numbers
|
||||
|
||||
@@ -12,6 +12,14 @@ lazy_static::lazy_static! {
|
||||
|
||||
// Precedence is defined lowest to highest
|
||||
PrattParser::new()
|
||||
.op(Op::infix(log_or, Left))
|
||||
.op(Op::infix(log_and, Left))
|
||||
.op(Op::infix(bit_or, Left))
|
||||
.op(Op::infix(xor, Left))
|
||||
.op(Op::infix(bit_and, Left))
|
||||
.op(Op::infix(eq, Left) | Op::infix(ne, Left))
|
||||
.op(Op::infix(gt, Left) | Op::infix(ge, Left) | Op::infix(lt, Left) | Op::infix(le, Left))
|
||||
.op(Op::infix(lshift, Left) | Op::infix(rshift, Left))
|
||||
.op(Op::infix(add, Left) | Op::infix(sub, Left))
|
||||
.op(Op::infix(mul, Left) | Op::infix(div, Left) | Op::infix(modulus, Left))
|
||||
};
|
||||
@@ -475,6 +483,19 @@ impl AstNode for Operator {
|
||||
"*" => Self::Mul,
|
||||
"/" => Self::Div,
|
||||
"%" => Self::Mod,
|
||||
"&&" => Self::And,
|
||||
"||" => Self::Or,
|
||||
"&" => Self::BitAnd,
|
||||
"|" => Self::BitOr,
|
||||
"^" => Self::Xor,
|
||||
">" => Self::Gt,
|
||||
">=" => Self::Ge,
|
||||
"<" => Self::Lt,
|
||||
"<=" => Self::Le,
|
||||
"==" => Self::Eq,
|
||||
"!=" => Self::Ne,
|
||||
"<<" => Self::Lshift,
|
||||
">>" => Self::Rshift,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -744,6 +765,40 @@ mod test {
|
||||
Ok(Expr(Expr(2.into(), Mul, 3.into()).into(), Add, 4.into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Node::from_str("1 || 2 && 3"),
|
||||
Ok(Expr(1.into(), Or, Expr(2.into(), And, 3.into()).into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Node::from_str("2 && &blah"),
|
||||
Ok(Expr(2.into(), And, Address("blah".into()).into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Node::from_str("2 & &blah"),
|
||||
Ok(Expr(2.into(), BitAnd, Address("blah".into()).into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Node::from_str("1 | 2 ^ 3"),
|
||||
Ok(Expr(1.into(), BitOr, Expr(2.into(), Xor, 3.into()).into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Node::from_str("x == y > z"),
|
||||
Ok(Expr(
|
||||
Name("x".into()).into(),
|
||||
Eq,
|
||||
Expr(Name("y".into()).into(), Gt, Name("z".into()).into()).into()
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Node::from_str("1 << 6"),
|
||||
Ok(Expr(1.into(), Lshift, 6.into()))
|
||||
);
|
||||
|
||||
// Parens
|
||||
assert_eq!(
|
||||
Node::from_str("(1 + 2) * 3"),
|
||||
|
||||
Reference in New Issue
Block a user