/// <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(); }
/// <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 })); }