private uint Precedence(IExpression/*?*/ expression) {
if (expression == null) return 0;
var prefix = false;
var postfix = false;
var binaryExpression = expression as IBinaryOperation;
if (binaryExpression != null) {
prefix = IsPrefix(binaryExpression);
postfix = IsPostfix(binaryExpression);
}
var assign = expression as IAssignment;
if (assign != null) return 1;
var conditional = expression as IConditional;
if (conditional != null) {
if (IsLogicalOr(conditional)) return 3;
if (IsLogicalAnd(conditional)) return 4;
return 2;
}
var bitwiseOr = expression as IBitwiseOr;
if (bitwiseOr != null) return 5;
var xor = expression as IExclusiveOr;
if (xor != null) return 6;
var bitwiseAnd = expression as IBitwiseAnd;
if (bitwiseAnd != null) return 7;
var equality = expression as IEquality;
if (equality != null) return 8;
var notEqual = expression as INotEquality;
if (notEqual != null) return 8;
var lessThan = expression as ILessThan;
if (lessThan != null) return 9;
var greaterThan = expression as IGreaterThan;
if (greaterThan != null) return 9;
var lessThanOrEqual = expression as ILessThanOrEqual;
if (lessThanOrEqual != null) return 9;
var greaterThanOrEqual = expression as IGreaterThanOrEqual;
if (greaterThanOrEqual != null) return 9;
var isTest = expression as ICheckIfInstance;
if (isTest != null) return 9;
var asTest = expression as ICastIfPossible;
if (asTest != null) return 9;
var leftShift = expression as ILeftShift;
if (leftShift != null) return 10;
var rightShift = expression as IRightShift;
if (rightShift != null) return 10;
var add = expression as IAddition;
if (add != null && !prefix && !postfix) return 11;
var sub = expression as ISubtraction;
if (sub != null && !prefix && !postfix) return 11;
var mult = expression as IMultiplication;
if (mult != null) return 12;
var div = expression as IDivision;
if (div != null) return 12;
var mod = expression as IModulus;
if (mod != null) return 12;
var unaryPlus = expression as IUnaryPlus;
if (unaryPlus != null) return 13;
var unaryMinus = expression as IUnaryNegation;
if (unaryMinus != null) return 13;
var logicalNot = expression as ILogicalNot;
if (logicalNot != null) return 13;
var bitwiseNegation = expression as IOnesComplement;
if (bitwiseNegation != null) return 13;
if (binaryExpression != null && prefix) return 13;
var cast = expression as IConversion;
if (cast != null) return 13;
// field dereference == 14
// function application == 14
var arrayIndexer = expression as IArrayIndexer;
if (arrayIndexer != null) return 14;
if (binaryExpression != null && postfix) return 14;
var newExpression = expression as ICreateObjectInstance;
if (newExpression != null) return 14;
throw new InvalidOperationException();
}