public static void RegisterDefaultAliases(ExpressionParser parser)
 {
     parser.RegisterOperator("AND", 4, LogicalAndMatrix.Create(), ShortCircuitMode.LogicalAnd);
     parser.RegisterOperator("OR", 4, LogicalOrMatrix.Create(), ShortCircuitMode.LogicalOr);
     parser.RegisterOperator("LT", 4, LessThanMatrix.Create());
     parser.RegisterOperator("LTE", 4, LessThanOrEqualMatrix.Create());
     parser.RegisterOperator("GT", 4, GreaterThanMatrix.Create());
     parser.RegisterOperator("GTE", 4, GreaterThanOrEqualMatrix.Create());
     parser.RegisterOperator("BAND", 4, BitwiseAndMatrix.Create());
     parser.RegisterOperator("BOR", 4, BitwiseOrMatrix.Create());
 }
        public ExpressionParser()
        {
            Operators        = new Dictionary <string, IOperator>();
            OperatorVectors  = new Dictionary <IOperator, SingleOperandFunctionVector>();
            OperatorMatrices = new Dictionary <IOperator, DoubleOperandFunctionMatrix>();
            // Got operator precedence from here: http://www.tutorialspoint.com/csharp/csharp_operators_precedence.htm

            // This is better as it includes functions: http://en.cppreference.com/w/c/language/operator_precedence


            #region Casts

            {
                var castMatrix = UnaryCastMatrix.Create();

                RegisterUnaryCastOperator(OperandType.Sbyte, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Byte, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Short, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Ushort, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Int, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Uint, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Long, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Ulong, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Char, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Float, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Double, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Bool, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Decimal, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableSbyte, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableByte, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableShort, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableUshort, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableInt, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableUint, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableLong, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableUlong, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableChar, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableFloat, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableDouble, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableBool, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.NullableDecimal, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.String, 12, castMatrix);
                RegisterUnaryCastOperator(OperandType.Object, 12, castMatrix);
            }

            #endregion

            // Register UnaryMinus ...
            UnaryMinus = RegisterUnaryOperator("UnaryMinus", 12, UnaryMinusVector.Create());
            UnaryPlus  = RegisterUnaryOperator("UnaryPlus", 12, AddVector.Create());
            RegisterUnaryOperator("!", 12, UnaryNotVector.Create());
            RegisterUnaryOperator("~", 12, UnaryComplementVector.Create());
            RegisterOperator("*", 11, MultiplyMatrix.Create());
            RegisterOperator("/", 11, DivideMatrix.Create());
            RegisterOperator("%", 11, ModuloMatrix.Create());
            PlusOperator  = RegisterOperator("+", 10, AddMatrix.Create());
            MinusOperator = RegisterOperator("-", 10, SubtractMatrix.Create());
            RegisterOperator("<", 9, LessThanMatrix.Create());
            RegisterOperator(">", 9, GreaterThanMatrix.Create());
            RegisterOperator(">=", 9, GreaterThanOrEqualMatrix.Create());
            RegisterOperator("<=", 9, LessThanOrEqualMatrix.Create());
            RegisterOperator("!=", 8, NotEqualMatrix.Create());
            RegisterOperator("==", 8, EqualityMatrix.Create());
            RegisterOperator("&", 7, BitwiseAndMatrix.Create());
            RegisterOperator("^", 6, BitwiseXorMatrix.Create());
            RegisterOperator("|", 5, BitwiseOrMatrix.Create());
            RegisterOperator("&&", 4, LogicalAndMatrix.Create(), ShortCircuitMode.LogicalAnd);
            RegisterOperator("||", 3, LogicalOrMatrix.Create(), ShortCircuitMode.LogicalOr);

            // Register operators ...
            RegisterSetEqualsOperator("=", 2, SetEqualsMatrix.Create()); // Can do assignment to a variable.
            CommaOperator            = RegisterOperator(",", 1, null);   // Do nothing. Correct???
            OpenParenthesisOperator  = RegisterOperator("(", 0, null, ShortCircuitMode.None, OperatorType.OpenParenthesis);
            CloseParenthesisOperator = RegisterOperator(")", 13, null, ShortCircuitMode.None, OperatorType.CloseParenthesis);

            // Register functions ...
            Functions = new Dictionary <string, IOperator>();
            RegisterFunction("_debug_mul", OperatorActions.DoMultiply, 2);
            // TODO: What should the precedence be? I don't think it matters because it is never read.
        }