Пример #1
0
        /// <summary>
        /// Initialize a new instance of <see cref="ProgramInterpreter"/>
        /// </summary>
        /// <param name="programDeclaration">the program declaration</param>
        /// <param name="debugMode">Defines if the debug mode is enabled</param>
        internal ProgramInterpreter(AlgorithmProgram programDeclaration, bool debugMode)
            : base(debugMode)
        {
            ProgramDeclaration = programDeclaration;

            // Just for better performances after, we call it a first time
            OperatorHelperCache.Initialize();
        }
Пример #2
0
        /// <summary>
        /// Run the interpretation
        /// </summary>
        /// <returns>Returns the result of the interpretation</returns>
        internal override object Execute()
        {
            object     left;
            object     right;
            MethodInfo operatorMethod;

            left = ParentInterpreter.RunExpression(Expression._leftExpression);

            if (ParentInterpreter.FailedOrStop)
            {
                return(null);
            }

            right = ParentInterpreter.RunExpression(Expression._rightExpression);

            if (ParentInterpreter.FailedOrStop)
            {
                return(null);
            }

            if (DebugMode)
            {
                ParentInterpreter.Log(this, $"Doing an operation '{Expression._operator}'");
            }

            if (Expression._operator == AlgorithmBinaryOperatorType.Equals)
            {
                if (left == null)
                {
                    if (right == null)
                    {
                        return(true); // null == null
                    }
                    return(right.Equals(null));
                }
                return(left.Equals(right));
            }

            operatorMethod = OperatorHelperCache.GetOperator(Expression._operator, left.GetType(), right.GetType());
            if (operatorMethod == null)
            {
                ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new OperatorNotFoundException(Expression._operator.ToString(), $"Operator '{Expression._operator}' cannot be applied to operands of type '{left.GetType().FullName}' and '{right.GetType().FullName}'"), Expression), ParentInterpreter.GetDebugInfo()));
                return(null);
            }

            if (Expression._operator == AlgorithmBinaryOperatorType.Division)
            {
                long num;
                var  convertedToLong = long.TryParse(right.ToString(), out num);
                if (convertedToLong && num == 0)
                {
                    ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new DivideByZeroException("Attempted to divide by zero."), Expression), ParentInterpreter.GetDebugInfo()));
                    return(null);
                }
            }

            return(operatorMethod.Invoke(null, new[] { left, right }));
        }