Bunch of infix ops

This commit is contained in:
2023-07-08 23:08:22 -05:00
parent f682a234c7
commit ca72b480c5
3 changed files with 89 additions and 1 deletions
+13
View File
@@ -135,6 +135,19 @@ pub enum Operator {
Mul, Mul,
Div, Div,
Mod, Mod,
And,
Or,
BitAnd,
BitOr,
Xor,
Lt,
Le,
Gt,
Ge,
Eq,
Ne,
Lshift,
Rshift,
} }
#[derive(PartialEq, Clone, Debug)] #[derive(PartialEq, Clone, Debug)]
+21 -1
View File
@@ -25,8 +25,28 @@ sub = { "-" }
mul = { "*" } mul = { "*" }
div = { "/" } div = { "/" }
modulus = { "%" } 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)* } expr = { val ~ (operator ~ val)* }
val = { // These are what get evaluated and left on the stack: val = { // These are what get evaluated and left on the stack:
number | // Literal numbers number | // Literal numbers
+55
View File
@@ -12,6 +12,14 @@ lazy_static::lazy_static! {
// Precedence is defined lowest to highest // Precedence is defined lowest to highest
PrattParser::new() 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(add, Left) | Op::infix(sub, Left))
.op(Op::infix(mul, Left) | Op::infix(div, Left) | Op::infix(modulus, 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::Mul,
"/" => Self::Div, "/" => Self::Div,
"%" => Self::Mod, "%" => 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!(), _ => unreachable!(),
} }
} }
@@ -744,6 +765,40 @@ mod test {
Ok(Expr(Expr(2.into(), Mul, 3.into()).into(), Add, 4.into())) 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 // Parens
assert_eq!( assert_eq!(
Node::from_str("(1 + 2) * 3"), Node::from_str("(1 + 2) * 3"),