mirror of
https://github.com/danog/parser.git
synced 2024-11-26 20:04:57 +01:00
Merge pull request #100 from ryangjchandler/feature/all-unary-ops
This commit is contained in:
commit
50cc9aa5d2
@ -520,6 +520,10 @@ impl Lexer {
|
||||
self.next();
|
||||
TokenKind::Colon
|
||||
}
|
||||
&[b'~', ..] => {
|
||||
self.next();
|
||||
TokenKind::BitwiseNot
|
||||
}
|
||||
&[b, ..] => unimplemented!(
|
||||
"<scripting> char: {}, line: {}, col: {}",
|
||||
b as char,
|
||||
@ -766,6 +770,7 @@ impl Lexer {
|
||||
|
||||
fn identifier_to_keyword(ident: &[u8]) -> Option<TokenKind> {
|
||||
Some(match ident {
|
||||
b"print" => TokenKind::Print,
|
||||
b"__halt_compiler" | b"__HALT_COMPILER" => TokenKind::HaltCompiler,
|
||||
b"readonly" => TokenKind::Readonly,
|
||||
b"global" => TokenKind::Global,
|
||||
|
@ -11,6 +11,7 @@ pub enum OpenTagKind {
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum TokenKind {
|
||||
Print,
|
||||
Dollar,
|
||||
HaltCompiler,
|
||||
Readonly,
|
||||
@ -161,6 +162,7 @@ pub enum TokenKind {
|
||||
Variable(ByteString),
|
||||
Yield,
|
||||
While,
|
||||
BitwiseNot,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@ -181,6 +183,8 @@ impl Default for Token {
|
||||
impl Display for TokenKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let s = match self {
|
||||
Self::Print => "print",
|
||||
Self::BitwiseNot => "~",
|
||||
Self::Dollar => "$",
|
||||
Self::HaltCompiler => "__halt_compiler",
|
||||
Self::Readonly => "readonly",
|
||||
|
@ -560,7 +560,22 @@ pub enum Expression {
|
||||
value: Box<Expression>,
|
||||
},
|
||||
Negate {
|
||||
value: Box<Expression>,
|
||||
value: Box<Self>,
|
||||
},
|
||||
UnaryPlus {
|
||||
value: Box<Self>,
|
||||
},
|
||||
BitwiseNot {
|
||||
value: Box<Self>,
|
||||
},
|
||||
PreDecrement {
|
||||
value: Box<Self>,
|
||||
},
|
||||
PreIncrement {
|
||||
value: Box<Self>,
|
||||
},
|
||||
Print {
|
||||
value: Box<Self>,
|
||||
},
|
||||
Cast {
|
||||
kind: CastKind,
|
||||
|
@ -2178,7 +2178,12 @@ fn is_prefix(op: &TokenKind) -> bool {
|
||||
matches!(
|
||||
op,
|
||||
TokenKind::Bang
|
||||
| TokenKind::Print
|
||||
| TokenKind::BitwiseNot
|
||||
| TokenKind::Decrement
|
||||
| TokenKind::Increment
|
||||
| TokenKind::Minus
|
||||
| TokenKind::Plus
|
||||
| TokenKind::StringCast
|
||||
| TokenKind::BinaryCast
|
||||
| TokenKind::ObjectCast
|
||||
@ -2197,12 +2202,27 @@ fn is_prefix(op: &TokenKind) -> bool {
|
||||
|
||||
fn prefix(op: &TokenKind, rhs: Expression) -> Expression {
|
||||
match op {
|
||||
TokenKind::Print => Expression::Print {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Bang => Expression::BooleanNot {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Minus => Expression::Negate {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Plus => Expression::UnaryPlus {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::BitwiseNot => Expression::BitwiseNot {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Decrement => Expression::PreDecrement {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Increment => Expression::PreIncrement {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::StringCast
|
||||
| TokenKind::BinaryCast
|
||||
| TokenKind::ObjectCast
|
||||
@ -4286,6 +4306,56 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unary_plus() {
|
||||
assert_ast(
|
||||
"<?php +1;",
|
||||
&[expr!(Expression::UnaryPlus {
|
||||
value: Box::new(Expression::Int { i: 1 })
|
||||
})],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bitwise_not() {
|
||||
assert_ast(
|
||||
"<?php ~2;",
|
||||
&[expr!(Expression::BitwiseNot {
|
||||
value: Box::new(Expression::Int { i: 2 })
|
||||
})],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_decrement() {
|
||||
assert_ast(
|
||||
"<?php --$a;",
|
||||
&[expr!(Expression::PreDecrement {
|
||||
value: Box::new(Expression::Variable { name: "a".into() })
|
||||
})],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_increment() {
|
||||
assert_ast(
|
||||
"<?php ++$a;",
|
||||
&[expr!(Expression::PreIncrement {
|
||||
value: Box::new(Expression::Variable { name: "a".into() })
|
||||
})],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn print_expression() {
|
||||
assert_ast(
|
||||
"<?php print $foo;",
|
||||
&[expr!(Expression::Print {
|
||||
value: Box::new(Expression::Variable { name: "foo".into() })
|
||||
})],
|
||||
);
|
||||
}
|
||||
|
||||
fn assert_ast(source: &str, expected: &[Statement]) {
|
||||
let mut lexer = Lexer::new(None);
|
||||
let tokens = lexer.tokenize(source).unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user