blob: 1c39b1be0bb4b8cdc44f18eefa2dcfec12c4d558 [file] [log] [blame]
/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.jack.ir.ast;
import javax.annotation.Nonnull;
/**
* For precedence indices, see the Java Programming Language, 4th Edition, p.
* 750, Table 2. I just numbered the table top to bottom as 0 through 14. Lower
* number means higher precedence.
*/
public enum JBinaryOperator {
// Don't renumber precs without checking implementation of isShiftOperator()
MUL("*", 3), DIV("/", 3), MOD("%", 3), ADD("+", 4), CONCAT("+", 4), SUB("-", 4), SHL("<<", 5),
SHR(">>", 5), SHRU(">>>", 5), LT("<", 6), LTE("<=", 6), GT(">", 6), GTE(">=", 6), EQ("==", 7),
NEQ("!=", 7), BIT_AND("&", 8), BIT_XOR("^", 9), BIT_OR("|", 10), AND("&&", 11), OR("||", 12),
ASG("=", 14), ASG_ADD("+=", 14, ADD), ASG_CONCAT("+=", 14, CONCAT), ASG_SUB("-=", 14, SUB),
ASG_MUL("*=", 14, MUL), ASG_DIV("/=", 14, DIV), ASG_MOD("%=", 14, MOD),
ASG_SHL("<<=", 14, SHL), ASG_SHR(">>=", 14, SHR), ASG_SHRU(">>>=", 14, SHRU),
ASG_BIT_AND("&=", 14, BIT_AND), ASG_BIT_OR("|=", 14, BIT_OR), ASG_BIT_XOR("^=", 14, BIT_XOR);
private final JBinaryOperator nonAsg;
private final int precedence;
private final String symbol;
private JBinaryOperator(String symbol, int precedence) {
this(symbol, precedence, null);
}
private JBinaryOperator(String symbol, int precedence, JBinaryOperator nonAsg) {
this.symbol = symbol;
this.precedence = precedence;
this.nonAsg = nonAsg;
}
public JBinaryOperator getNonAssignmentOf() {
return nonAsg;
}
public int getPrecedence() {
return precedence;
}
public boolean isConditionalOperation() {
return (this == AND || this == OR);
}
public boolean isLogicalAndBitwiseOperation() {
return (this == BIT_AND || this == BIT_OR || this == BIT_XOR);
}
@Nonnull
public JBinaryOperator getReverseOperator() throws UnsupportedOperatorException {
switch (this) {
case BIT_AND: {
return BIT_OR;
}
case BIT_OR: {
return BIT_AND;
}
// XOR: EQ:
// T XOR T = F T EQ T = T
// T XOR F = T T EQ F = F
// F XOR T = T F EQ T = F
// F XOR F = F F EQ F = T
case BIT_XOR: {
return EQ;
}
case AND: {
return OR;
}
case OR: {
return AND;
}
case LT: {
return GTE;
}
case LTE: {
return GT;
}
case GT: {
return LTE;
}
case GTE: {
return LT;
}
case EQ: {
return NEQ;
}
case NEQ: {
return EQ;
}
default: {
throw new UnsupportedOperatorException("Unsupported operator: " + this.toString());
}
}
}
public boolean isComparison() {
return (this == LT || this == LTE || this == GT || this == GTE || this == EQ || this == NEQ);
}
public boolean isAssignment() {
return (this == ASG) || (getNonAssignmentOf() != null);
}
public boolean isCompoundAssignment() {
return (getNonAssignmentOf() != null);
}
public boolean isShiftOperator() {
// Fragile implementation.
return precedence == 5 || (nonAsg != null && nonAsg.precedence == 5);
}
@Override
public String toString() {
return symbol;
}
}