001 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
002 // for details. All rights reserved. Use of this source code is governed by a
003 // BSD-style license that can be found in the LICENSE file.
004
005 package com.google.dart.compiler.backend.js.ast;
006
007 /**
008 * Represents the operator in a JavaScript binary operation.
009 */
010 public enum JsBinaryOperator implements JsOperator {
011 /*
012 * Precedence indices from "JavaScript - The Definitive Guide" 4th Edition
013 * (page 57)
014 *
015 *
016 * Precedence 15 is for really important things that have their own AST
017 * classes.
018 *
019 * Precedence 14 is for unary operators.
020 */
021
022 MUL("*", 13, LEFT | INFIX), DIV("/", 13, LEFT | INFIX), MOD("%", 13, LEFT
023 | INFIX),
024
025 ADD("+", 12, LEFT | INFIX), SUB("-", 12, LEFT | INFIX),
026
027 SHL("<<", 11, LEFT | INFIX), SHR(">>", 11, LEFT | INFIX), SHRU(">>>", 11,
028 LEFT | INFIX),
029
030 LT("<", 10, LEFT | INFIX), LTE("<=", 10, LEFT | INFIX), GT(">", 10, LEFT
031 | INFIX), GTE(">=", 10, LEFT | INFIX), INSTANCEOF("instanceof", 10, LEFT
032 | INFIX), INOP("in", 10, LEFT | INFIX),
033
034 EQ("==", 9, LEFT | INFIX), NEQ("!=", 9, LEFT | INFIX), REF_EQ("===", 9, LEFT
035 | INFIX), REF_NEQ("!==", 9, LEFT | INFIX),
036
037 BIT_AND("&", 8, LEFT | INFIX),
038
039 BIT_XOR("^", 7, LEFT | INFIX),
040
041 BIT_OR("|", 6, LEFT | INFIX),
042
043 AND("&&", 5, LEFT | INFIX),
044
045 OR("||", 4, LEFT | INFIX),
046
047 // Precedence 3 is for the condition operator.
048
049 // These assignment operators are right-associative.
050 ASG("=", 2, INFIX), ASG_ADD("+=", 2, INFIX), ASG_SUB("-=", 2, INFIX), ASG_MUL(
051 "*=", 2, INFIX), ASG_DIV("/=", 2, INFIX), ASG_MOD("%=", 2, INFIX), ASG_SHL(
052 "<<=", 2, INFIX), ASG_SHR(">>=", 2, INFIX), ASG_SHRU(">>>=", 2, INFIX), ASG_BIT_AND(
053 "&=", 2, INFIX), ASG_BIT_OR("|=", 2, INFIX), ASG_BIT_XOR("^=", 2, INFIX),
054
055 COMMA(",", 1, LEFT | INFIX);
056
057 private final int mask;
058 private final int precedence;
059 private final String symbol;
060
061 private JsBinaryOperator(String symbol, int precedence, int mask) {
062 this.symbol = symbol;
063 this.precedence = precedence;
064 this.mask = mask;
065 }
066
067 @Override
068 public int getPrecedence() {
069 return precedence;
070 }
071
072 @Override
073 public String getSymbol() {
074 return symbol;
075 }
076
077 public boolean isAssignment() {
078 return getPrecedence() == ASG.getPrecedence();
079 }
080
081 @Override
082 public boolean isKeyword() {
083 return this == INSTANCEOF || this == INOP;
084 }
085
086 @Override
087 public boolean isLeftAssociative() {
088 return (mask & LEFT) != 0;
089 }
090
091 @Override
092 public boolean isPrecedenceLessThan(JsOperator other) {
093 return precedence < other.getPrecedence();
094 }
095
096 @Override
097 public boolean isValidInfix() {
098 return (mask & INFIX) != 0;
099 }
100
101 @Override
102 public boolean isValidPostfix() {
103 return (mask & POSTFIX) != 0;
104 }
105
106 @Override
107 public boolean isValidPrefix() {
108 return (mask & PREFIX) != 0;
109 }
110
111 @Override
112 public String toString() {
113 return symbol;
114 }
115 }