/// <summary>
        /// Invoke the specified method
        /// </summary>
        /// <param name="callerInterpreter">The caller interpreter (usually a block)</param>
        /// <param name="invokeExpression">The invoke expression</param>
        /// <param name="argumentValues">The list of argument values</param>
        /// <param name="parentMethodInterpreter">The parent method interpret from where the invocation happened</param>
        /// <param name="callStackService">The user call stack service</param>
        /// <returns>Returns the result of the method</returns>
        internal object InvokeMethod(Interpret callerInterpreter, AlgorithmExpression invokeExpression, Collection <object> argumentValues, MethodInterpreter parentMethodInterpreter, CallStackService callStackService)
        {
            var methodName = invokeExpression._methodName.ToString();
            var method     = Methods.FirstOrDefault(m => m.MethodDeclaration._name.ToString() == methodName);

            if (method == null)
            {
                callerInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotFoundException(methodName, $"The method '{methodName}' does not exists in the current class or is not accessible."), ClassDeclaration), callerInterpreter.GetDebugInfo()));
                return(null);
            }

            if (!method.MethodDeclaration._isAsync && invokeExpression._await)
            {
                callerInterpreter.ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotAwaitableException(methodName), method.MethodDeclaration), callerInterpreter.GetDebugInfo()));
                return(null);
            }

            Guid stackTraceId;
            var  isAsync = method.MethodDeclaration._isAsync;

            if (parentMethodInterpreter == null)
            {
                stackTraceId = Guid.Empty;
            }
            else
            {
                stackTraceId = parentMethodInterpreter.StacktraceId;
                if (DebugMode)
                {
                    var callStack = callStackService.CallStacks.Single(cs => cs.TaceId == stackTraceId);
                    var call      = callStack.Stack.Pop();
                    if (call != null)
                    {
                        call.Variables = callerInterpreter.GetAllAccessibleVariable().DeepClone();
                        callStack.Stack.Push(call);
                    }
                }
            }

            method = new MethodInterpreter(method.MethodDeclaration, DebugMode);
            method.StateChanged           += ChangeState;
            method.OnGetParentInterpreter += new Func <ClassInterpreter>(() => this);
            method.OnDone += new Action <MethodInterpreter>((met) =>
            {
                met.Dispose();
                met.StateChanged -= ChangeState;
            });
            method.Initialize();
            method.Run(invokeExpression._await, argumentValues, stackTraceId);

            if (isAsync && !invokeExpression._await)
            {
                return(null);
            }
            return(method.ReturnedValue);
        }
        /// <summary>
        /// Execute an expression
        /// </summary>
        /// <param name="expression">The expression to interpret</param>
        /// <returns>Returns the returned value of the expression</returns>
        internal object RunExpression(AlgorithmExpression expression)
        {
            object result = null;

            switch (expression.DomType)
            {
            case AlgorithmDomType.PrimitiveExpression:
                result = new PrimitiveValue(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.PropertyReferenceExpression:
                result = new PropertyReference(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.VariableReferenceExpression:
                result = new VariableReference(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.ClassReferenceExpression:
                result = new ClassReference(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.ThisReferenceExpression:
                result = new ThisReference(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.InstanciateExpression:
                result = new Instanciate(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.InvokeCoreMethodExpression:
                result = new InvokeCoreMethod(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.InvokeMethodExpression:
                result = new InvokeMethod(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.BinaryOperatorExpression:
                result = new BinaryOperator(DebugMode, this, expression).Execute();
                break;

            case AlgorithmDomType.ArrayIndexerExpression:
                result = new ArrayIndexerExpression(DebugMode, this, expression).Execute();
                break;

            default:
                ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new InvalidCastException($"Unable to find an interpreter for this expression : '{expression.GetType().FullName}'"), expression), GetDebugInfo()));
                break;
            }

            return(FailedOrStop ? null : result);
        }
Esempio n. 3
0
        /// <summary>
        /// Returns the arguments values
        /// </summary>
        /// <returns>Returns a collection of object which represents the argument value</returns>
        internal static Collection <object> GetArgumentValues(AlgorithmExpression expression, BlockInterpreter parentInterpreter)
        {
            var argumentValues = new Collection <object>();

            foreach (var arg in expression._argumentsExpression)
            {
                if (!parentInterpreter.FailedOrStop)
                {
                    argumentValues.Add(parentInterpreter.RunExpression(arg));
                }
            }

            return(argumentValues);
        }
Esempio n. 4
0
        /// <summary>
        /// Execute the condition
        /// </summary>
        /// <param name="parentInterpreter">The parent block interpreter</param>
        /// <param name="condition">The condition expression</param>
        /// <returns>Return true, false, or null in case of error</returns>
        internal static bool?RunCondition(BlockInterpreter parentInterpreter, AlgorithmExpression condition)
        {
            if (condition == null)
            {
                parentInterpreter.ChangeState(parentInterpreter, new AlgorithmInterpreterStateEventArgs(new Error(new NullReferenceException("A conditional expression is missing.")), parentInterpreter.GetDebugInfo()));
                return(null);
            }

            var conditionResult = parentInterpreter.RunExpression(condition);

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

            var boolResult = conditionResult as bool?;

            if (boolResult != null)
            {
                return(boolResult.Value);
            }

            var intResult = conditionResult as int?;

            if (intResult != null)
            {
                switch (intResult.Value)
                {
                case 1:
                    return(true);

                case 0:
                    return(false);

                default:
                    parentInterpreter.ChangeState(parentInterpreter, new AlgorithmInterpreterStateEventArgs(new Error(new InvalidCastException("Unable to cast this number to a boolean."), condition), parentInterpreter.GetDebugInfo()));
                    return(null);
                }
            }

            parentInterpreter.ChangeState(parentInterpreter, new AlgorithmInterpreterStateEventArgs(new Error(new InvalidCastException("Unable to perform a condition statement without a boolean value as conditional expression result."), condition), parentInterpreter.GetDebugInfo()));
            return(null);
        }
Esempio n. 5
0
 /// <summary>
 /// Initialize a new instance of <see cref="PropertyReference"/>
 /// </summary>
 /// <param name="debugMode">Defines if the debug mode is enabled</param>
 /// <param name="parentInterpreter">The parent block interpreter</param>
 /// <param name="expression">The algorithm expression</param>
 internal PropertyReference(bool debugMode, BlockInterpreter parentInterpreter, AlgorithmExpression expression)
     : base(debugMode, parentInterpreter, expression)
 {
 }
Esempio n. 6
0
 /// <summary>
 /// Initialize a new instance of <see cref="Instanciate"/>
 /// </summary>
 /// <param name="debugMode">Defines if the debug mode is enabled</param>
 /// <param name="parentInterpreter">The parent block interpreter</param>
 /// <param name="expression">The algorithm expression</param>
 internal Instanciate(bool debugMode, BlockInterpreter parentInterpreter, AlgorithmExpression expression)
     : base(debugMode, parentInterpreter, expression)
 {
 }
 /// <summary>
 /// Initialize a new instance of <see cref="AlgorithmReturnStatement"/>
 /// </summary>
 /// <param name="expression">The expression to return</param>
 public AlgorithmReturnStatement(AlgorithmExpression expression)
     : base(expression)
 {
 }
Esempio n. 8
0
 /// <summary>
 /// Initialize a new instance of <see cref="InvokeMethod"/>
 /// </summary>
 /// <param name="debugMode">Defines if the debug mode is enabled</param>
 /// <param name="parentInterpreter">The parent block interpreter</param>
 /// <param name="expression">The algorithm expression</param>
 internal InvokeMethod(bool debugMode, BlockInterpreter parentInterpreter, AlgorithmExpression expression)
     : base(debugMode, parentInterpreter, expression)
 {
 }
Esempio n. 9
0
 /// <summary>
 /// Initialize a new instance of <see cref="InvokeCoreMethod"/>
 /// </summary>
 /// <param name="debugMode">Defines if the debug mode is enabled</param>
 /// <param name="parentInterpreter">The parent block interpreter</param>
 /// <param name="expression">The algorithm expression</param>
 internal InvokeCoreMethod(bool debugMode, BlockInterpreter parentInterpreter, AlgorithmExpression expression)
     : base(debugMode, parentInterpreter, expression)
 {
     _dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
 }
Esempio n. 10
0
 /// <summary>
 /// Initialize a new instance of <see cref="PrimitiveValue"/>
 /// </summary>
 /// <param name="debugMode">Defines if the debug mode is enabled</param>
 /// <param name="parentInterpreter">The parent block interpreter</param>
 /// <param name="expression">The algorithm expression</param>
 internal PrimitiveValue(bool debugMode, BlockInterpreter parentInterpreter, AlgorithmExpression expression)
     : base(debugMode, parentInterpreter, expression)
 {
 }
Esempio n. 11
0
 /// <summary>
 /// Initialize a new instance of <see cref="InterpretExpression"/>
 /// </summary>
 /// <param name="debugMode">Defines if the debug mode is enabled</param>
 /// <param name="parentInterpreter">the parent <see cref="BlockInterpreter"/></param>
 /// <param name="expression">the algorithm expression</param>
 internal InterpretExpression(bool debugMode, BlockInterpreter parentInterpreter, AlgorithmExpression expression)
     : base(debugMode)
 {
     ParentInterpreter = parentInterpreter;
     Expression        = expression;
 }
Esempio n. 12
0
 /// <summary>
 /// Initialize a new instance of <see cref="BinaryOperator"/>
 /// </summary>
 /// <param name="debugMode">Defines if the debug mode is enabled</param>
 /// <param name="parentInterpreter">The parent block interpreter</param>
 /// <param name="expression">The algorithm expression</param>
 internal BinaryOperator(bool debugMode, BlockInterpreter parentInterpreter, AlgorithmExpression expression)
     : base(debugMode, parentInterpreter, expression)
 {
 }
Esempio n. 13
0
 /// <summary>
 /// Initialize a new instance of <see cref="ArrayIndexerExpression"/>
 /// </summary>
 /// <param name="debugMode">Defines if the debug mode is enabled</param>
 /// <param name="parentInterpreter">The parent block interpreter</param>
 /// <param name="expression">The algorithm expression</param>
 internal ArrayIndexerExpression(bool debugMode, BlockInterpreter parentInterpreter, AlgorithmExpression expression)
     : base(debugMode, parentInterpreter, expression)
 {
 }