Ejemplo n.º 1
0
        ///
        /// <summary>
        ///		Parses arithmetic expressions
        /// </summary>
        ///
        /// <param name="leftOperand">Left operand</param>
        /// <param name="rightOperand">Right operand</param>
        /// <param name="arithType">Arithmetic operator type</param>
        ///
        /// <remarks>
        ///		Only works with operands that evaluate to either numeric or string types. If both operands are strings
        ///		and arithType is ADD, concatenation is performed. Else, if either operand is of a float type, both are
        ///		treated as float type. Else, both are treated as int types. This is to ensure proper behavior of operators
        ///		such as addition and division. If operands are of int type, result is then parsed as a literal expression
        ///		to ensure correct return type.
        ///	</remarks>
        ///
        /// <returns>Result of arithmetic operation</returns>
        ///
        /// <exception cref="CseLogicExceptionType.ARITH_EXCEPTION" />
        /// <exception cref="CseLogicExceptionType.LEFT_OP_NON_NUM" />
        /// <exception cref="CseLogicExceptionType.RIGHT_OP_NON_NUM" />
        ///
        internal static CseObject Parse(CseObject leftOperand, CseObject rightOperand, ArithType arithType)
        {
            dynamic result       = null;
            dynamic leftOpValue  = leftOperand.Value;
            dynamic rightOpValue = rightOperand.Value;
            string  methOpName   = null;

            try {
                switch (arithType)
                {
                case ArithType.ADD:
                    methOpName = OpOverloadNames.ADD;
                    result     = leftOpValue + rightOpValue;
                    break;

                case ArithType.DIV:
                    methOpName = OpOverloadNames.DIV;
                    result     = leftOpValue / rightOpValue;
                    break;

                case ArithType.MOD:
                    methOpName = OpOverloadNames.MOD;
                    result     = leftOpValue % rightOpValue;
                    break;

                case ArithType.MUL:
                    methOpName = OpOverloadNames.MUL;
                    result     = leftOpValue * rightOpValue;
                    break;

                case ArithType.POW:
                    result = Math.Pow(leftOpValue, rightOpValue);
                    break;

                case ArithType.SUB:
                    methOpName = OpOverloadNames.SUB;
                    result     = leftOpValue - rightOpValue;
                    break;
                }
                return(new CseObject(result));
            }
            catch {
                if (methOpName == null)
                {
                    throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
                }

                MethodInfo leftOpMeth  = leftOpValue.GetType().GetMethod(methOpName, OpOverloadNames.Flags);
                MethodInfo rightOpMeth = rightOpValue.GetType().GetMethod(methOpName, OpOverloadNames.Flags);

                if (leftOpMeth == null && rightOpMeth == null)
                {
                    throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
                }
                else if (leftOpMeth != null)
                {
                    try {
                        result = new CseObject(leftOpMeth.Invoke(leftOpValue, new object[] { leftOpValue, rightOpValue }));
                    }
                    catch {
                        throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
                    }
                }
                else if (rightOpMeth != null)
                {
                    try {
                        result = new CseObject(rightOpMeth.Invoke(rightOpValue, new object[] { leftOpValue, rightOpValue }));
                    }
                    catch {
                        throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
                    }
                }
                else
                {
                    throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
                }
            }

            return(new CseObject(result));
        }
Ejemplo n.º 2
0
		///
		/// <summary>
		///		Parses arithmetic expressions
		/// </summary>
		/// 
		/// <param name="leftOperand">Left operand</param>
		/// <param name="rightOperand">Right operand</param>
		/// <param name="arithType">Arithmetic operator type</param>
		/// 
		/// <remarks>
		///		Only works with operands that evaluate to either numeric or string types. If both operands are strings
		///		and arithType is ADD, concatenation is performed. Else, if either operand is of a float type, both are 
		///		treated as float type. Else, both are treated as int types. This is to ensure proper behavior of operators 
		///		such as addition and division. If operands are of int type, result is then parsed as a literal expression
		///		to ensure correct return type.
		///	</remarks>
		///	
		/// <returns>Result of arithmetic operation</returns>
		/// 
		/// <exception cref="CseLogicExceptionType.ARITH_EXCEPTION" />
		/// <exception cref="CseLogicExceptionType.LEFT_OP_NON_NUM" />
		/// <exception cref="CseLogicExceptionType.RIGHT_OP_NON_NUM" />
		/// 
		internal static CseObject Parse(CseObject leftOperand, CseObject rightOperand, ArithType arithType) {
			dynamic result = null;
			dynamic leftOpValue = leftOperand.Value;
			dynamic rightOpValue = rightOperand.Value;
			string methOpName = null;

			try {
				switch (arithType) {
					case ArithType.ADD:
						methOpName = OpOverloadNames.ADD;
						result = leftOpValue + rightOpValue;
						break;
					case ArithType.DIV:
						methOpName = OpOverloadNames.DIV;
						result = leftOpValue / rightOpValue;
						break;
					case ArithType.MOD:
						methOpName = OpOverloadNames.MOD;
						result = leftOpValue % rightOpValue;
						break;
					case ArithType.MUL:
						methOpName = OpOverloadNames.MUL;
						result = leftOpValue * rightOpValue;
						break;
					case ArithType.POW:
						result = Math.Pow(leftOpValue, rightOpValue);
						break;
					case ArithType.SUB:
						methOpName = OpOverloadNames.SUB;
						result = leftOpValue - rightOpValue;
						break;
				}
				return new CseObject(result);
			}
			catch {
				if (methOpName == null)
					throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);

				MethodInfo leftOpMeth = leftOpValue.GetType().GetMethod(methOpName, OpOverloadNames.Flags);
				MethodInfo rightOpMeth = rightOpValue.GetType().GetMethod(methOpName, OpOverloadNames.Flags);

				if (leftOpMeth == null && rightOpMeth == null)
					throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
				else if (leftOpMeth != null) {
					try {
						result = new CseObject(leftOpMeth.Invoke(leftOpValue, new object[] { leftOpValue, rightOpValue }));
					}
					catch {
						throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
					}
				}
				else if (rightOpMeth != null) {
					try {
						result = new CseObject(rightOpMeth.Invoke(rightOpValue, new object[] { leftOpValue, rightOpValue }));
					}
					catch {
						throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
					}
				}
				else {
					throw new CseLogicException(CseLogicExceptionType.ARITH_EXCEPTION, leftOpValue, rightOpValue);
				}
			}

			return new CseObject(result);
		}