/// <summary> /// Run the interpretation /// </summary> /// <returns>Returns the result of the interpretation</returns> internal override object Execute() { object type; var fullName = Expression.ToString(); if (DebugMode) { ParentInterpreter.Log(this, $"Reference to the class : {fullName}"); } if (Expression._type != null) { return(Expression._type); } if (string.IsNullOrWhiteSpace(Expression._namespace)) { type = GetProjectClassReference(fullName); } else { type = GetCoreClassReference(fullName); } if (type != null) { return(type); } ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new ClassNotFoundException(fullName, $"Unable to find the class '{fullName}' because it does not exist or it is not accessible."), Expression), ParentInterpreter.GetDebugInfo())); return(null); }
/// <summary> /// Run the interpretation /// </summary> internal override void Execute() { if (DebugMode) { ParentInterpreter.Log(this, "Breakpoint intercepted"); ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(AlgorithmInterpreterState.PauseBreakpoint, ParentInterpreter.GetDebugInfo(false))); } }
/// <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 })); }
/// <summary> /// Run the interpretation /// </summary> /// <returns>Returns the result of the interpretation</returns> internal override object Execute() { if (Expression._targetObject == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NullReferenceException("Unable to invoke a method when the TargetObject of an AlgorithmInvokeMethodExpression is null."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (DebugMode) { ParentInterpreter.Log(this, $"Calling method '{Expression._targetObject}.{Expression._methodName}'"); } var referenceClass = ParentInterpreter.RunExpression(Expression._targetObject) as ClassInterpreter; var callerMethod = ParentInterpreter.ParentMethodInterpreter; if (ParentInterpreter.FailedOrStop) { return(null); } if (referenceClass == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new ClassNotFoundException("{Unknow}", "It looks like the reference class does not exists."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (!referenceClass.IsInstance) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NoInstanceReferenceException("Unable to invoke a method of a not instancied class."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } var argumentValues = GetArgumentValues(Expression, ParentInterpreter); if (!ParentInterpreter.FailedOrStop) { var callStackService = ParentInterpreter.ParentProgramInterpreter.DebugInfo.CallStackService; _result = null; if (callStackService.CallCount > Consts.InvokeMethodCountBeforeNewThread) { // Make a new thread avoid the stack overflow. callStackService.CallCount = 0; CallMethodNewThread(referenceClass, argumentValues, callerMethod, callStackService).Wait(); } else { callStackService.CallCount++; _result = referenceClass.InvokeMethod(ParentInterpreter, Expression, argumentValues, callerMethod, callStackService); } return(_result); } return(null); }
/// <summary> /// Invoke a code method /// </summary> /// <param name="type">The type which contains the method</param> /// <param name="obj">The instance</param> /// <returns>Returns the result of the invoke</returns> private object InvokeMethod(Type type, object obj) { if (Expression._argumentsTypes == null) { Expression._argumentsTypes = new Type[0]; } object result; Collection <object> arguments; var method = type.GetRuntimeMethod(Expression._methodName.ToString(), Expression._argumentsTypes); if (method == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotFoundException(Expression._methodName.ToString(), $"The method '{Expression._methodName}' does not exists in the current class or is not accessible."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (obj == null && !method.IsStatic) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NoInstanceReferenceException($"Unable to invoke the non-static core method '{method.Name}' without instanciate the class."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } arguments = Expressions.InvokeMethod.GetArgumentValues(Expression, ParentInterpreter); if (ParentInterpreter.FailedOrStop) { return(null); } result = null; _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { try { result = method.Invoke(obj, arguments.ToArray()); } catch (Exception ex) { if (ex is ArgumentException) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new BadArgumentException("{Unknow}", ex.Message), Expression), ParentInterpreter.GetDebugInfo())); } else if (ex is TargetParameterCountException) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotFoundException(Expression._methodName.ToString(), $"There is a method '{Expression._methodName}' in the class '{Expression._targetObject}', but it does not have {arguments.Count} argument(s)."), Expression), ParentInterpreter.GetDebugInfo())); } else { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(ex, Expression), ParentInterpreter.GetDebugInfo())); } } }).AsTask().Wait(); return(result); }
/// <summary> /// Returns the corresponding assignable object /// </summary> /// <returns>the assignable object</returns> public object GetAssignableObject() { if (Expression._targetObject == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NullReferenceException("Unable to access to a property or variable when the TargetObject of an AlgorithmArrayIndexerExpression is null."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (DebugMode) { ParentInterpreter.Log(this, $"Getting the value '{Expression}'"); } var indexableValue = ParentInterpreter.RunExpression(Expression._targetObject); if (ParentInterpreter.FailedOrStop) { return(null); } if (indexableValue == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NoInstanceReferenceException("Unable to get a value because the array is null."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } // ReSharper disable once UseIsOperator.1 // ReSharper disable once UseMethodIsInstanceOfType if (!typeof(IList).IsAssignableFrom(indexableValue.GetType())) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new IndexerException(Expression._propertyName.ToString()), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (ParentInterpreter.FailedOrStop) { return(null); } var indiceValue = ParentInterpreter.RunExpression(Expression._indice); if (ParentInterpreter.FailedOrStop) { return(null); } var indexValue = indiceValue as int?; if (indexValue != null) { IndexValue = indexValue.Value; return(indexableValue); } ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new InvalidCastException("Unable to cast this value to a number."), Expression), ParentInterpreter.GetDebugInfo())); return(null); }
/// <summary> /// Returns the corresponding assignable object /// </summary> /// <returns>the assignable object</returns> public object GetAssignableObject() { var variable = ParentInterpreter.FindVariable(Expression._name.ToString()); if (variable == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new VariableNotFoundException(Expression._name.ToString()), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (DebugMode) { ParentInterpreter.Log(this, "Value of the variable '{0}' is {1}", variable.Name, variable.Value == null ? "{null}" : $"'{variable.Value}' (type:{variable.Value.GetType().FullName})"); } return(variable); }
/// <summary> /// Run the interpretation /// </summary> internal override void Execute() { var methodInterpreter = ParentInterpreter.ParentMethodInterpreter; if (methodInterpreter == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotFoundException("{Unknow}", "It looks like the caller/parent's method does not exists."), Statement), ParentInterpreter.GetDebugInfo())); return; } methodInterpreter.ReturnedValue = ParentInterpreter.RunExpression(Statement._expression); if (DebugMode && !ParentInterpreter.FailedOrStop) { ParentInterpreter.Log(this, "({0}) Return : {1}", methodInterpreter.MethodDeclaration._name, methodInterpreter.ReturnedValue == null ? "{null}" : $"'{methodInterpreter.ReturnedValue}' (type:{methodInterpreter.ReturnedValue.GetType().FullName})"); } }
/// <summary> /// Run the interpretation /// </summary> /// <returns>Returns the result of the interpretation</returns> internal override object Execute() { IndexValue = -1; var indexableValue = (IList)GetAssignableObject(); if (ParentInterpreter.FailedOrStop || indexableValue == null) { return(null); } if (IndexValue < 0 || IndexValue >= indexableValue.Count) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new IndexOutOfRangeException($"Unable to get the item number '{IndexValue}' because the limit of the array is '{indexableValue.Count - 1}'."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } return(indexableValue[IndexValue]); }
/// <summary> /// Run the interpretation /// </summary> /// <returns>Returns the result of the interpretation</returns> internal override object Execute() { var parentClass = ParentInterpreter.ParentClassInterpreter; if (parentClass == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new ClassNotFoundException("{Unknow}", "It looks like the parent class does not exists."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (!parentClass.IsInstance) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NoInstanceReferenceException("Unable to get the instance of the parent class of a static method."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (DebugMode) { ParentInterpreter.Log(this, $"Reference to the current instance : {parentClass.ClassDeclaration.Name}"); } return(parentClass); }
/// <summary> /// Run the interpretation /// </summary> internal override void Execute() { int indexValue = -1; object targetObject = null; object leftValue = null; object rightValue; PropertyInfo propertyInfo; Variable propertyVariable; IList propertyVariableList; var leftExpression = Statement._leftExpression; var rightExpression = Statement._rightExpression; if (DebugMode) { ParentInterpreter.Log(this, $"Assign '{leftExpression}' to '{rightExpression}'"); if (!typeof(IAlgorithmAssignable).IsAssignableFrom(leftExpression.GetType())) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NotAssignableException($"The left expression is not assignable."), Statement), ParentInterpreter.GetDebugInfo())); return; } } switch (leftExpression.DomType) { case AlgorithmDomType.PropertyReferenceExpression: var propertyReferenceInterpreter = new PropertyReference(DebugMode, ParentInterpreter, leftExpression); leftValue = propertyReferenceInterpreter.GetAssignableObject(); targetObject = propertyReferenceInterpreter.TargetObject; break; case AlgorithmDomType.VariableReferenceExpression: leftValue = new VariableReference(DebugMode, ParentInterpreter, leftExpression).GetAssignableObject(); break; case AlgorithmDomType.ArrayIndexerExpression: var arrayIndexerInterpreter = new ArrayIndexerExpression(DebugMode, ParentInterpreter, leftExpression); leftValue = arrayIndexerInterpreter.GetAssignableObject(); indexValue = arrayIndexerInterpreter.IndexValue; break; default: ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new InvalidCastException($"Unable to find an interpreter for this expression : '{leftExpression.GetType().FullName}'"), Statement), ParentInterpreter.GetDebugInfo())); break; } if (ParentInterpreter.FailedOrStop) { return; } rightValue = ParentInterpreter.RunExpression(rightExpression); if (ParentInterpreter.FailedOrStop) { return; } propertyInfo = leftValue as PropertyInfo; if (propertyInfo != null) { if (!propertyInfo.CanWrite) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NotAssignableException($"This core property is not assignable."), Statement), ParentInterpreter.GetDebugInfo())); return; } propertyInfo.SetValue(targetObject, rightValue); } propertyVariable = leftValue as Variable; if (propertyVariable != null) { if (propertyVariable.IsArray && !(typeof(Array).IsAssignableFrom(rightValue.GetType()) || typeof(IList).IsAssignableFrom(rightValue.GetType()))) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NotAssignableException($"The left expression wait for an array, but the right value is not an array."), Statement), ParentInterpreter.GetDebugInfo())); return; } if (!propertyVariable.IsArray && (typeof(Array).IsAssignableFrom(rightValue.GetType()) || typeof(IList).IsAssignableFrom(rightValue.GetType()))) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NotAssignableException($"The left expression does not support array value, but the right value is an array."), Statement), ParentInterpreter.GetDebugInfo())); return; } propertyVariable.Value = rightValue; } propertyVariableList = leftValue as IList; if (propertyVariableList != null) { if (indexValue < 0 || indexValue >= propertyVariableList.Count) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new IndexOutOfRangeException($"Unable to get the item number '{indexValue}' because the limit of the array is '{propertyVariableList.Count - 1}'."), Statement), ParentInterpreter.GetDebugInfo())); return; } propertyVariableList[indexValue] = rightValue; } if (DebugMode) { ParentInterpreter.Log(this, "'{0}' is now equal to {1}", leftExpression.ToString(), rightValue == null ? "{null}" : $"'{rightValue}' (type:{rightValue.GetType().FullName})"); } }
/// <summary> /// Returns the corresponding assignable object /// </summary> /// <returns>the assignable object</returns> public object GetAssignableObject() { if (Expression._targetObject == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NullReferenceException("Unable to access to a property when the TargetObject of an AlgorithmPropertyReferenceExpression is null."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } object property; object value = null; PropertyInfo propertyInfo; ClassInterpreter classTargetObject; Variable propertyVariable; if (DebugMode) { ParentInterpreter.Log(this, $"Getting the property '{Expression}'"); } TargetObject = ParentInterpreter.RunExpression(Expression._targetObject); if (ParentInterpreter.FailedOrStop) { return(null); } if (TargetObject == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new ClassNotFoundException("{Unknow}", "It looks like the reference object does not exists."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } classTargetObject = TargetObject as ClassInterpreter; if (classTargetObject != null) { propertyVariable = classTargetObject.FindVariableInTheCurrentInterpreter(Expression._propertyName.ToString()); if (propertyVariable == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new PropertyNotFoundException(Expression._propertyName.ToString()), Expression), ParentInterpreter.GetDebugInfo())); return(null); } property = propertyVariable; if (DebugMode) { value = propertyVariable.Value; } } else { propertyInfo = TargetObject.GetType().GetProperty(Expression._propertyName.ToString()); if (propertyInfo == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new PropertyNotFoundException(Expression._propertyName.ToString()), Expression), ParentInterpreter.GetDebugInfo())); return(null); } property = propertyInfo; if (DebugMode) { value = propertyInfo.GetValue(TargetObject); } } if (DebugMode) { ParentInterpreter.Log(this, "Value of the property '{0}' is {1}", Expression._propertyName.ToString(), value == null ? "{null}" : $"'{value}' (type:{value.GetType().FullName})"); } return(property); }
/// <summary> /// Run the interpretation /// </summary> /// <returns>Returns the result of the interpretation</returns> internal override object Execute() { Collection <object> argumentValues; var createType = Expression._createType; var reference = ParentInterpreter.RunExpression(createType); if (ParentInterpreter.FailedOrStop) { return(null); } if (DebugMode) { ParentInterpreter.Log(this, $"Creating a new instance of '{createType}'"); } var classInterpreter = reference as ClassInterpreter; if (classInterpreter != null) { var program = ParentInterpreter.ParentProgramInterpreter; var classInstance = classInterpreter.CreateNewInstance(); classInstance.StateChanged += ParentInterpreter.ChangeState; classInstance.OnGetParentInterpreter += new Func <ProgramInterpreter>(() => program); classInstance.OnDone += new Action <ClassInterpreter>((cl) => { cl.StateChanged -= ParentInterpreter.ChangeState; }); classInstance.Initialize(); argumentValues = InvokeMethod.GetArgumentValues(Expression, ParentInterpreter); if (ParentInterpreter.FailedOrStop) { return(null); } classInstance.CreateNewInstanceCallConstructors(argumentValues); return(classInstance); } var type = reference as Type; if (type != null) { object classInstance = null; argumentValues = InvokeMethod.GetArgumentValues(Expression, ParentInterpreter); if (ParentInterpreter.FailedOrStop) { return(null); } try { classInstance = Activator.CreateInstance(type, argumentValues.ToArray()); } catch (Exception ex) { if (ex is ArgumentException) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new BadArgumentException("{Unknow}", ex.Message), Expression), ParentInterpreter.GetDebugInfo())); } else if (ex is TargetParameterCountException) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotFoundException("ctor", $"There is no constructor with {argumentValues.Count} argument(s) in the class '{Expression._createType}'."), Expression), ParentInterpreter.GetDebugInfo())); } else { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(ex, Expression), ParentInterpreter.GetDebugInfo())); } return(null); } return(classInstance); } return(null); }
/// <summary> /// Run the interpretation /// </summary> /// <returns>Returns the result of the interpretation</returns> internal override object Execute() { if (Expression._targetObject == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new NullReferenceException("Unable to invoke a core method when the TargetObject of an AlgorithmInvokeCoreMethodExpression is null."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } object referenceClass; object returnedValue; Type type; Task task; if (DebugMode) { ParentInterpreter.Log(this, $"Calling core method '{Expression._targetObject}.{Expression._methodName}'"); } referenceClass = ParentInterpreter.RunExpression(Expression._targetObject); if (ParentInterpreter.FailedOrStop) { return(null); } if (referenceClass == null) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new ClassNotFoundException("{Unknow}", "It looks like the reference object does not exists."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } if (referenceClass is ClassInterpreter) { ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new ClassNotFoundException("{Unknow}", "Unable to call a core method from a class made with AlgorithmDOM."), Expression), ParentInterpreter.GetDebugInfo())); return(null); } type = referenceClass as Type; if (type != null) { returnedValue = InvokeMethod(type, null); } else { returnedValue = InvokeMethod(referenceClass.GetType(), referenceClass); } if (ParentInterpreter.FailedOrStop) { return(null); } if (Expression._await) { task = returnedValue as Task; if (task != null) { task.Wait(); var resultPropertyInfo = task.GetType().GetProperty("Result"); if (resultPropertyInfo != null && resultPropertyInfo.PropertyType.Name != "VoidTaskResult") { return(resultPropertyInfo.GetValue(task)); } return(null); } ParentInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotAwaitableException($"{Expression._targetObject}.{Expression._methodName}"), Expression), ParentInterpreter.GetDebugInfo())); return(null); } return(returnedValue); }