| /* |
| * Copyright 2008 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.google.gwt.dev.jjs.impl; |
| |
| import com.google.gwt.dev.jjs.InternalCompilerException; |
| import com.google.gwt.dev.jjs.ast.Context; |
| import com.google.gwt.dev.jjs.ast.JArrayLength; |
| import com.google.gwt.dev.jjs.ast.JArrayRef; |
| import com.google.gwt.dev.jjs.ast.JBinaryOperation; |
| import com.google.gwt.dev.jjs.ast.JBooleanLiteral; |
| import com.google.gwt.dev.jjs.ast.JCastOperation; |
| import com.google.gwt.dev.jjs.ast.JCharLiteral; |
| import com.google.gwt.dev.jjs.ast.JClassLiteral; |
| import com.google.gwt.dev.jjs.ast.JConditional; |
| import com.google.gwt.dev.jjs.ast.JDoubleLiteral; |
| import com.google.gwt.dev.jjs.ast.JExpression; |
| import com.google.gwt.dev.jjs.ast.JFieldRef; |
| import com.google.gwt.dev.jjs.ast.JFloatLiteral; |
| import com.google.gwt.dev.jjs.ast.JInstanceOf; |
| import com.google.gwt.dev.jjs.ast.JIntLiteral; |
| import com.google.gwt.dev.jjs.ast.JLocalRef; |
| import com.google.gwt.dev.jjs.ast.JLongLiteral; |
| import com.google.gwt.dev.jjs.ast.JMethodCall; |
| import com.google.gwt.dev.jjs.ast.JNewArray; |
| import com.google.gwt.dev.jjs.ast.JNewInstance; |
| import com.google.gwt.dev.jjs.ast.JNullLiteral; |
| import com.google.gwt.dev.jjs.ast.JParameterRef; |
| import com.google.gwt.dev.jjs.ast.JPermutationDependentValue; |
| import com.google.gwt.dev.jjs.ast.JPostfixOperation; |
| import com.google.gwt.dev.jjs.ast.JPrefixOperation; |
| import com.google.gwt.dev.jjs.ast.JStringLiteral; |
| import com.google.gwt.dev.jjs.ast.JThisRef; |
| import com.google.gwt.dev.jjs.ast.JVisitor; |
| import com.google.gwt.dev.jjs.ast.js.JMultiExpression; |
| |
| /** |
| * 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. I also gave primaries a precedence of 0; maybe I should have |
| * started operators at 1, but in practice it won't matter since primaries can't |
| * have children. |
| */ |
| class JavaPrecedenceVisitor extends JVisitor { |
| |
| public static int exec(JExpression expression) { |
| JavaPrecedenceVisitor visitor = new JavaPrecedenceVisitor(); |
| visitor.accept(expression); |
| if (visitor.answer < 0) { |
| throw new InternalCompilerException("Precedence must be >= 0 (" + expression + ") " |
| + expression.getClass()); |
| } |
| return visitor.answer; |
| } |
| |
| private int answer = -1; |
| |
| private JavaPrecedenceVisitor() { |
| } |
| |
| @Override |
| public boolean visit(JArrayLength x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JArrayRef x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JBinaryOperation operation, Context ctx) { |
| answer = operation.getOp().getPrecedence(); |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JBooleanLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JCastOperation operation, Context ctx) { |
| answer = 2; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JCharLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JClassLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JConditional conditional, Context ctx) { |
| answer = 13; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JDoubleLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JFieldRef x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JFloatLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JInstanceOf of, Context ctx) { |
| answer = 6; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JIntLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JLocalRef x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JLongLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JMethodCall x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JMultiExpression x, Context ctx) { |
| answer = 14; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JNewArray array, Context ctx) { |
| answer = 2; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JNewInstance instance, Context ctx) { |
| answer = 2; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JNullLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JParameterRef x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JPermutationDependentValue x, Context ctx) { |
| // It's a method call. |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JPostfixOperation operation, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JPrefixOperation operation, Context ctx) { |
| answer = 1; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JStringLiteral x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| @Override |
| public boolean visit(JThisRef x, Context ctx) { |
| answer = 0; |
| return false; |
| } |
| |
| } |