Unary operators
This commit is contained in:
parent
8c2af9ab61
commit
1f66a5f94b
40
src/parse.rs
40
src/parse.rs
|
@ -339,6 +339,7 @@ type ExprPair<'a> = Box<(Expr<'a>, Expr<'a>)>;
|
|||
#[derive(Debug)]
|
||||
pub enum Expr<'a> {
|
||||
BinaryOp(BinaryOp, ExprPair<'a>),
|
||||
UnaryOp(UnaryOp, Box<Expr<'a>>),
|
||||
Literal(Literal<'a>),
|
||||
Local(&'a str),
|
||||
Member(&'a str, Box<Expr<'a>>),
|
||||
|
@ -350,7 +351,13 @@ pub enum Expr<'a> {
|
|||
|
||||
impl<'a> Expr<'a> {
|
||||
pub fn build_start(tok: Token, lexer: &mut Lexer<'a>) -> (Option<Self>, Token) {
|
||||
let mut lhs = match tok {
|
||||
let (unary_op, tok) = if let Some(op) = UnaryOp::from_token(tok) {
|
||||
(Some(op), lexer.next().unwrap())
|
||||
} else {
|
||||
(None, tok)
|
||||
};
|
||||
|
||||
let lhs = match tok {
|
||||
Token::Identifier => Self::Local(lexer.slice()),
|
||||
Token::Dot => Self::SelfMember(lexer.eat_expect_id()),
|
||||
Token::ParanOpen => {
|
||||
|
@ -373,6 +380,12 @@ impl<'a> Expr<'a> {
|
|||
_ => lexer.panic_message("Unexpected token"),
|
||||
};
|
||||
|
||||
let mut lhs = if let Some(op) = unary_op {
|
||||
Self::UnaryOp(op, Box::new(lhs))
|
||||
} else {
|
||||
lhs
|
||||
};
|
||||
|
||||
loop {
|
||||
let tok = lexer.next().unwrap();
|
||||
|
||||
|
@ -468,6 +481,26 @@ impl BinaryOp {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum UnaryOp {
|
||||
BoolNot,
|
||||
BitNot,
|
||||
Negate,
|
||||
}
|
||||
|
||||
impl UnaryOp {
|
||||
pub fn from_token(tok: Token) -> Option<Self> {
|
||||
use Token::*;
|
||||
use UnaryOp::*;
|
||||
match tok {
|
||||
OpBoolNot => Some(BoolNot),
|
||||
OpBitNot => Some(BitNot),
|
||||
OpSub => Some(Negate),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Literal<'a> {
|
||||
BinaryInteger(&'a str),
|
||||
|
@ -672,6 +705,11 @@ mod tests {
|
|||
parse_expr("(1 + 2) * (3 / (4 + 5));")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unary_ops() {
|
||||
parse_expr("not false + -(2 + 3) * -1 / ~0xff;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn members() {
|
||||
parse_expr(".member1 * .member2;");
|
||||
|
|
Loading…
Reference in New Issue