parser: support equals/identical and not variant expressions

This commit is contained in:
Ryan Chandler 2022-07-28 17:01:40 +01:00
parent d955cd28da
commit 16283d1273
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
5 changed files with 70 additions and 1 deletions

View File

@ -0,0 +1,6 @@
<?php
$foo == $bar;
$foo === $bar;
$foo != $bar;
$foo !== $bar;

View File

@ -158,7 +158,24 @@ impl Lexer {
let kind = match char {
'!' => {
self.col += 1;
TokenKind::Bang
if let Some('=') = it.peek() {
self.col += 1;
it.next();
if let Some('=') = it.peek() {
self.col += 1;
it.next();
TokenKind::BangDoubleEquals
} else {
TokenKind::BangEquals
}
} else {
TokenKind::Bang
}
},
'&' => {
self.col += 1;

View File

@ -20,6 +20,8 @@ pub enum TokenKind {
Asterisk,
Attribute,
Bang,
BangEquals,
BangDoubleEquals,
BoolCast,
BooleanAnd,
BooleanOr,

View File

@ -290,6 +290,10 @@ pub enum InfixOp {
Mul,
Concat,
LessThan,
Equals,
Identical,
NotEquals,
NotIdentical,
}
impl From<TokenKind> for InfixOp {
@ -301,6 +305,10 @@ impl From<TokenKind> for InfixOp {
TokenKind::Slash => Self::Div,
TokenKind::LessThan => Self::LessThan,
TokenKind::Dot => Self::Concat,
TokenKind::DoubleEquals => Self::Equals,
TokenKind::TripleEquals => Self::Identical,
TokenKind::BangEquals => Self::NotEquals,
TokenKind::BangDoubleEquals => Self::NotIdentical,
_ => unreachable!()
}
}

View File

@ -1122,6 +1122,7 @@ fn infix_binding_power(t: &TokenKind) -> Option<(u8, u8)> {
TokenKind::Plus | TokenKind::Minus => (11, 12),
TokenKind::Dot => (11, 11),
TokenKind::LessThan => (9, 10),
TokenKind::DoubleEquals | TokenKind::TripleEquals | TokenKind::BangEquals | TokenKind::BangDoubleEquals => (7, 8),
TokenKind::Equals => (2, 1),
_ => return None,
})
@ -1262,6 +1263,41 @@ mod tests {
]);
}
#[test]
fn comparisons() {
assert_ast("<?php 1 == 1;", &[
expr!(Expression::Infix(
Box::new(Expression::Int(1)),
InfixOp::Equals,
Box::new(Expression::Int(1))
))
]);
assert_ast("<?php 1 === 1;", &[
expr!(Expression::Infix(
Box::new(Expression::Int(1)),
InfixOp::Identical,
Box::new(Expression::Int(1))
))
]);
assert_ast("<?php 1 != 1;", &[
expr!(Expression::Infix(
Box::new(Expression::Int(1)),
InfixOp::NotEquals,
Box::new(Expression::Int(1))
))
]);
assert_ast("<?php 1 !== 1;", &[
expr!(Expression::Infix(
Box::new(Expression::Int(1)),
InfixOp::NotIdentical,
Box::new(Expression::Int(1))
))
]);
}
#[test]
fn paren_expression() {
assert_ast("<?php (1 + 2);", &[