2015-10-15 18:37:21 +00:00
|
|
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
2015-10-15 12:51:30 +00:00
|
|
|
use parse::token::{Token, BinOpToken, keywords};
|
2016-02-08 12:16:12 +00:00
|
|
|
use ast::BinOpKind;
|
2015-10-15 12:51:30 +00:00
|
|
|
|
|
|
|
/// Associative operator with precedence.
|
|
|
|
///
|
|
|
|
/// This is the enum which specifies operator precedence and fixity to the parser.
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum AssocOp {
|
|
|
|
/// `+`
|
|
|
|
Add,
|
|
|
|
/// `-`
|
|
|
|
Subtract,
|
|
|
|
/// `*`
|
|
|
|
Multiply,
|
|
|
|
/// `/`
|
|
|
|
Divide,
|
|
|
|
/// `%`
|
|
|
|
Modulus,
|
|
|
|
/// `&&`
|
|
|
|
LAnd,
|
|
|
|
/// `||`
|
|
|
|
LOr,
|
|
|
|
/// `^`
|
|
|
|
BitXor,
|
|
|
|
/// `&`
|
|
|
|
BitAnd,
|
|
|
|
/// `|`
|
|
|
|
BitOr,
|
|
|
|
/// `<<`
|
|
|
|
ShiftLeft,
|
|
|
|
/// `>>`
|
|
|
|
ShiftRight,
|
|
|
|
/// `==`
|
|
|
|
Equal,
|
|
|
|
/// `<`
|
|
|
|
Less,
|
|
|
|
/// `<=`
|
|
|
|
LessEqual,
|
|
|
|
/// `!=`
|
|
|
|
NotEqual,
|
|
|
|
/// `>`
|
|
|
|
Greater,
|
|
|
|
/// `>=`
|
|
|
|
GreaterEqual,
|
|
|
|
/// `=`
|
|
|
|
Assign,
|
|
|
|
/// `<-`
|
|
|
|
Inplace,
|
|
|
|
/// `?=` where ? is one of the BinOpToken
|
|
|
|
AssignOp(BinOpToken),
|
|
|
|
/// `as`
|
|
|
|
As,
|
|
|
|
/// `..` range
|
2015-12-03 02:37:48 +00:00
|
|
|
DotDot,
|
|
|
|
/// `:`
|
|
|
|
Colon,
|
2015-10-15 12:51:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum Fixity {
|
|
|
|
/// The operator is left-associative
|
|
|
|
Left,
|
|
|
|
/// The operator is right-associative
|
|
|
|
Right,
|
|
|
|
/// The operator is not associative
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AssocOp {
|
|
|
|
/// Create a new AssocOP from a token
|
|
|
|
pub fn from_token(t: &Token) -> Option<AssocOp> {
|
|
|
|
use self::AssocOp::*;
|
|
|
|
match *t {
|
|
|
|
Token::BinOpEq(k) => Some(AssignOp(k)),
|
|
|
|
Token::LArrow => Some(Inplace),
|
|
|
|
Token::Eq => Some(Assign),
|
|
|
|
Token::BinOp(BinOpToken::Star) => Some(Multiply),
|
|
|
|
Token::BinOp(BinOpToken::Slash) => Some(Divide),
|
|
|
|
Token::BinOp(BinOpToken::Percent) => Some(Modulus),
|
|
|
|
Token::BinOp(BinOpToken::Plus) => Some(Add),
|
|
|
|
Token::BinOp(BinOpToken::Minus) => Some(Subtract),
|
|
|
|
Token::BinOp(BinOpToken::Shl) => Some(ShiftLeft),
|
|
|
|
Token::BinOp(BinOpToken::Shr) => Some(ShiftRight),
|
|
|
|
Token::BinOp(BinOpToken::And) => Some(BitAnd),
|
|
|
|
Token::BinOp(BinOpToken::Caret) => Some(BitXor),
|
|
|
|
Token::BinOp(BinOpToken::Or) => Some(BitOr),
|
|
|
|
Token::Lt => Some(Less),
|
|
|
|
Token::Le => Some(LessEqual),
|
|
|
|
Token::Ge => Some(GreaterEqual),
|
|
|
|
Token::Gt => Some(Greater),
|
|
|
|
Token::EqEq => Some(Equal),
|
|
|
|
Token::Ne => Some(NotEqual),
|
|
|
|
Token::AndAnd => Some(LAnd),
|
|
|
|
Token::OrOr => Some(LOr),
|
|
|
|
Token::DotDot => Some(DotDot),
|
2015-12-03 02:37:48 +00:00
|
|
|
Token::Colon => Some(Colon),
|
2015-10-15 12:51:30 +00:00
|
|
|
_ if t.is_keyword(keywords::As) => Some(As),
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-08 12:16:12 +00:00
|
|
|
/// Create a new AssocOp from ast::BinOpKind.
|
|
|
|
pub fn from_ast_binop(op: BinOpKind) -> Self {
|
2015-10-15 12:51:30 +00:00
|
|
|
use self::AssocOp::*;
|
|
|
|
match op {
|
2016-02-08 12:16:12 +00:00
|
|
|
BinOpKind::Lt => Less,
|
|
|
|
BinOpKind::Gt => Greater,
|
|
|
|
BinOpKind::Le => LessEqual,
|
|
|
|
BinOpKind::Ge => GreaterEqual,
|
|
|
|
BinOpKind::Eq => Equal,
|
|
|
|
BinOpKind::Ne => NotEqual,
|
|
|
|
BinOpKind::Mul => Multiply,
|
|
|
|
BinOpKind::Div => Divide,
|
|
|
|
BinOpKind::Rem => Modulus,
|
|
|
|
BinOpKind::Add => Add,
|
|
|
|
BinOpKind::Sub => Subtract,
|
|
|
|
BinOpKind::Shl => ShiftLeft,
|
|
|
|
BinOpKind::Shr => ShiftRight,
|
|
|
|
BinOpKind::BitAnd => BitAnd,
|
|
|
|
BinOpKind::BitXor => BitXor,
|
|
|
|
BinOpKind::BitOr => BitOr,
|
|
|
|
BinOpKind::And => LAnd,
|
|
|
|
BinOpKind::Or => LOr
|
2015-10-15 12:51:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets the precedence of this operator
|
|
|
|
pub fn precedence(&self) -> usize {
|
|
|
|
use self::AssocOp::*;
|
|
|
|
match *self {
|
2015-12-03 02:37:48 +00:00
|
|
|
As | Colon => 14,
|
2015-10-15 12:51:30 +00:00
|
|
|
Multiply | Divide | Modulus => 13,
|
|
|
|
Add | Subtract => 12,
|
|
|
|
ShiftLeft | ShiftRight => 11,
|
|
|
|
BitAnd => 10,
|
|
|
|
BitXor => 9,
|
|
|
|
BitOr => 8,
|
|
|
|
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => 7,
|
|
|
|
LAnd => 6,
|
|
|
|
LOr => 5,
|
|
|
|
DotDot => 4,
|
|
|
|
Inplace => 3,
|
|
|
|
Assign | AssignOp(_) => 2,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets the fixity of this operator
|
|
|
|
pub fn fixity(&self) -> Fixity {
|
|
|
|
use self::AssocOp::*;
|
|
|
|
// NOTE: it is a bug to have an operators that has same precedence but different fixities!
|
|
|
|
match *self {
|
|
|
|
Inplace | Assign | AssignOp(_) => Fixity::Right,
|
|
|
|
As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd |
|
|
|
|
BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual |
|
2015-12-03 02:37:48 +00:00
|
|
|
LAnd | LOr | Colon => Fixity::Left,
|
2015-10-15 12:51:30 +00:00
|
|
|
DotDot => Fixity::None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_comparison(&self) -> bool {
|
|
|
|
use self::AssocOp::*;
|
|
|
|
match *self {
|
|
|
|
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true,
|
|
|
|
Inplace | Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract |
|
2015-12-03 02:37:48 +00:00
|
|
|
ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | Colon => false
|
2015-10-15 12:51:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-16 19:42:06 +00:00
|
|
|
pub fn is_assign_like(&self) -> bool {
|
|
|
|
use self::AssocOp::*;
|
|
|
|
match *self {
|
|
|
|
Assign | AssignOp(_) | Inplace => true,
|
|
|
|
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide |
|
|
|
|
Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd |
|
2015-12-03 02:37:48 +00:00
|
|
|
LOr | DotDot | Colon => false
|
2015-10-16 19:42:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-08 12:16:12 +00:00
|
|
|
pub fn to_ast_binop(&self) -> Option<BinOpKind> {
|
2015-10-15 12:51:30 +00:00
|
|
|
use self::AssocOp::*;
|
|
|
|
match *self {
|
2016-02-08 12:16:12 +00:00
|
|
|
Less => Some(BinOpKind::Lt),
|
|
|
|
Greater => Some(BinOpKind::Gt),
|
|
|
|
LessEqual => Some(BinOpKind::Le),
|
|
|
|
GreaterEqual => Some(BinOpKind::Ge),
|
|
|
|
Equal => Some(BinOpKind::Eq),
|
|
|
|
NotEqual => Some(BinOpKind::Ne),
|
|
|
|
Multiply => Some(BinOpKind::Mul),
|
|
|
|
Divide => Some(BinOpKind::Div),
|
|
|
|
Modulus => Some(BinOpKind::Rem),
|
|
|
|
Add => Some(BinOpKind::Add),
|
|
|
|
Subtract => Some(BinOpKind::Sub),
|
|
|
|
ShiftLeft => Some(BinOpKind::Shl),
|
|
|
|
ShiftRight => Some(BinOpKind::Shr),
|
|
|
|
BitAnd => Some(BinOpKind::BitAnd),
|
|
|
|
BitXor => Some(BinOpKind::BitXor),
|
|
|
|
BitOr => Some(BinOpKind::BitOr),
|
|
|
|
LAnd => Some(BinOpKind::And),
|
|
|
|
LOr => Some(BinOpKind::Or),
|
2015-12-03 02:37:48 +00:00
|
|
|
Inplace | Assign | AssignOp(_) | As | DotDot | Colon => None
|
2015-10-15 12:51:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|