parser/lexer: support unary bitwise not

This commit is contained in:
Ryan Chandler 2022-09-16 14:47:06 +01:00
parent b6f61bb344
commit 33a481f13a
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
4 changed files with 20 additions and 2 deletions

View File

@ -520,6 +520,10 @@ impl Lexer {
self.next();
TokenKind::Colon
}
&[b'~', ..] => {
self.next();
TokenKind::BitwiseNot
}
&[b, ..] => unimplemented!(
"<scripting> char: {}, line: {}, col: {}",
b as char,

View File

@ -161,6 +161,7 @@ pub enum TokenKind {
Variable(ByteString),
Yield,
While,
BitwiseNot,
}
#[derive(Debug, Clone, PartialEq)]
@ -181,6 +182,7 @@ impl Default for Token {
impl Display for TokenKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::BitwiseNot => "~",
Self::Dollar => "$",
Self::HaltCompiler => "__halt_compiler",
Self::Readonly => "readonly",

View File

@ -560,10 +560,13 @@ pub enum Expression {
value: Box<Expression>,
},
Negate {
value: Box<Expression>,
value: Box<Self>,
},
UnaryPlus {
value: Box<Expression>,
value: Box<Self>,
},
BitwiseNot {
value: Box<Self>,
},
Cast {
kind: CastKind,

View File

@ -2178,6 +2178,7 @@ fn is_prefix(op: &TokenKind) -> bool {
matches!(
op,
TokenKind::Bang
| TokenKind::BitwiseNot
| TokenKind::Minus
| TokenKind::Plus
| TokenKind::StringCast
@ -2205,6 +2206,7 @@ fn prefix(op: &TokenKind, rhs: Expression) -> Expression {
value: Box::new(rhs),
},
TokenKind::Plus => Expression::UnaryPlus { value: Box::new(rhs) },
TokenKind::BitwiseNot => Expression::BitwiseNot { value: Box::new(rhs) },
TokenKind::StringCast
| TokenKind::BinaryCast
| TokenKind::ObjectCast
@ -4295,6 +4297,13 @@ mod tests {
]);
}
#[test]
fn bitwise_not() {
assert_ast("<?php ~2;", &[
expr!(Expression::BitwiseNot { value: Box::new(Expression::Int { i: 2 }) })
]);
}
fn assert_ast(source: &str, expected: &[Statement]) {
let mut lexer = Lexer::new(None);
let tokens = lexer.tokenize(source).unwrap();