Exemple #1
0
        private EntryPointMethod GetEntryPointMethod()
        {
            var entryPoints = _program.Methods.OfType <EntryPointMethod>().ToList();

            if (entryPoints.Count == 0)
            {
                BaZicInterpreter.ChangeState(this, new MissingEntryPointMethodException());
                return(null);
            }
            else if (entryPoints.Count > 1)
            {
                BaZicInterpreter.ChangeState(this, new SeveralEntryPointMethodException(), entryPoints.Last());
                return(null);
            }

            var entryPoint = entryPoints.Single();

            if (entryPoint.Arguments.Count != 1)
            {
                BaZicInterpreter.ChangeState(this, new BadArgumentException(L.BaZic.Parser.Statements.UniqueArgumentEntryPoint), entryPoint);
                return(null);
            }
            else if (!entryPoint.Arguments.Single().IsArray)
            {
                BaZicInterpreter.ChangeState(this, new BadArgumentException(L.BaZic.Parser.Statements.EntryPointArgumentArrayExpected), entryPoint.Arguments.Single());
                return(null);
            }

            return(entryPoint);
        }
Exemple #2
0
        /// <summary>
        /// Set the value of the specified variable currently in memory based on its unique ID.
        /// </summary>
        /// <param name="variableRef">The reference to the variable to set.</param>
        /// <param name="value">The value to give to the variable</param>
        internal void SetVariable(VariableReferenceExpression variableRef, object value)
        {
            var variable = GetVariable(variableRef.VariableDeclarationID, variableRef.Name.Identifier, true);

            if (IsAborted)
            {
                return;
            }

            var valueInfo = ValueInfo.GetValueInfo(value);

            if (!valueInfo.IsNull)
            {
                if (variable.IsArray && !valueInfo.IsArray)
                {
                    BaZicInterpreter.ChangeState(this, new NotAssignableException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedArrayExpected(variableRef.Name)), variableRef);
                    return;
                }
                else if (!variable.IsArray && valueInfo.IsArray)
                {
                    BaZicInterpreter.ChangeState(this, new NotAssignableException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedNotArrayExpected(variableRef.Name)), variableRef);
                    return;
                }
            }

            variable.SetValue(value, valueInfo);

            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.Interpreter.FormattedVariableSetted(variable.Name, variable));
            }
        }
Exemple #3
0
        /// <summary>
        /// Retrieves the parent interpreter of the current executed method.
        /// </summary>
        /// <param name="includeThis">(optional) Defines whether the search must include the current interpreter.</param>
        /// <param name="throwIfNotFound">(optional) Defines whether an error must be thrown if the parent interpreter is not found.</param>
        /// <returns>The parent <see cref="MethodInterpreter"/></returns>
        internal MethodInterpreter GetParentMethodInterpreter(bool includeThis = false, bool throwIfNotFound = true)
        {
            if (includeThis && this is MethodInterpreter thisMethodInterpreter)
            {
                return(thisMethodInterpreter);
            }

            var parentInterpreter = ParentInterpreter;

            while (parentInterpreter != null)
            {
                if (parentInterpreter is MethodInterpreter methodInterpreter)
                {
                    return(methodInterpreter);
                }

                parentInterpreter = parentInterpreter.ParentInterpreter;
            }

            if (throwIfNotFound)
            {
                BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Interpreter.ParentMethodNotFound));
            }
            return(null);
        }
Exemple #4
0
        /// <summary>
        /// Look for the specified variable currently in memory based on its unique ID.
        /// </summary>
        /// <param name="variableId">The unique ID that represents the variable.</param>
        /// <param name="variableName">The friendly name of the variable.</param>
        /// <param name="throwIfNotFound">(optional) Indicates whether an exception must be thrown if the variable is not found. By default, this argument is True.</param>
        /// <param name="searchInParents">Defines whether finding a variable can be performed in the parent interpreters.</param>
        /// <returns>Returns the variable if it has been found, otherwise, null or throws an exception.</returns>
        internal Variable GetVariable(Guid variableId, string variableName, bool throwIfNotFound = true, bool searchInParents = true)
        {
            var interpreter = this;

            do
            {
                var variable = interpreter.Variables.FirstOrDefault(v => v.Id == variableId);

                if (variable != null)
                {
                    return(variable);
                }

                if (searchInParents)
                {
                    interpreter = interpreter.ParentInterpreter;
                }
            } while (searchInParents && interpreter != null);

            if (throwIfNotFound)
            {
                BaZicInterpreter.ChangeState(this, new VariableNotFoundException(variableName));
            }

            return(null);
        }
Exemple #5
0
        /// <summary>
        /// Assigns the specified value to a property.
        /// </summary>
        /// <param name="propertyReference">The reference to the property to set.</param>
        /// <param name="value">The value to assign.</param>
        private void AssignProperty(PropertyReferenceExpression propertyReference, object value)
        {
            if (string.IsNullOrWhiteSpace(propertyReference.PropertyName?.Identifier))
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.PropertyReferenceInterpreter.UndefinedName), propertyReference);
            }
            var targetObjectValue = ParentInterpreter.RunExpression(propertyReference.TargetObject);

            if (ParentInterpreter.IsAborted)
            {
                return;
            }

            if (targetObjectValue == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.PropertyReferenceInterpreter.NullValue), propertyReference);
                return;
            }

            if (propertyReference.TargetObject is ClassReferenceExpression && targetObjectValue is Type)
            {
                BaZicInterpreter.Reflection.SetStaticProperty((Type)targetObjectValue, propertyReference.PropertyName.Identifier, value);
            }
            else if (targetObjectValue is FrameworkElement)
            {
                BaZicInterpreter.ProgramInterpreter.UIDispatcher.Invoke(() =>
                {
                    BaZicInterpreter.Reflection.SetProperty(targetObjectValue, propertyReference.PropertyName.Identifier, value);
                }, System.Windows.Threading.DispatcherPriority.Background);
            }
            else
            {
                BaZicInterpreter.Reflection.SetProperty(targetObjectValue, propertyReference.PropertyName.Identifier, value);
            }
        }
Exemple #6
0
        /// <inheritdoc/>
        internal override object Run()
        {
            var declarations = BaZicInterpreter.MethodDeclarations.Where(m => string.Compare(m.Name.Identifier, Expression.MethodName.Identifier, StringComparison.Ordinal) == 0);

            if (declarations.Count() == 0)
            {
                BaZicInterpreter.ChangeState(this, new MethodNotFoundException(Expression.MethodName.Identifier, L.BaZic.Runtime.Interpreters.Expressions.InvokeMethodInterpreter.FormattedMethodNotFound(Expression.MethodName)), Expression);
                return(null);
            }
            else if (declarations.Count() > 1)
            {
                BaZicInterpreter.ChangeState(this, new MethodNotFoundException(Expression.MethodName.Identifier, L.BaZic.Runtime.Interpreters.Expressions.InvokeMethodInterpreter.FormattedSeveralMethods(Expression.MethodName)), Expression);
                return(null);
            }

            // If the invocation is made manually by the user (outisde of the execution flow).
            if (_failIfNotExtern)
            {
                if (!declarations.Single().IsExtern)
                {
                    BaZicInterpreter.ChangeState(this, new MethodNotFoundException(Expression.MethodName.Identifier, L.BaZic.Runtime.Interpreters.Expressions.InvokeMethodInterpreter.FormattedMethodNotFound(Expression.MethodName)), Expression);
                    return(null);
                }

                if (!declarations.Single().IsAsync&& Expression.Await)
                {
                    Expression.Await = false;
                }
            }

            var methodInterpreter = new MethodInterpreter(BaZicInterpreter, ParentInterpreter, declarations.Single(), Expression, _executionFlowId);

            return(methodInterpreter.Invoke());
        }
Exemple #7
0
        /// <inheritdoc/>
        internal override void Run()
        {
            if (!ParentInterpreter.State.IsInIteration)
            {
                BaZicInterpreter.ChangeState(this, new IncoherentStatementException(L.BaZic.Runtime.Interpreters.Statements.BreakInterpreter.Illegal), Statement);
            }

            ParentInterpreter.State.ExitIteration = true;
        }
Exemple #8
0
        /// <summary>
        /// Invoke a public method accessible from outside of the interpreter (EXTERN FUNCTION).
        /// </summary>
        /// <param name="executionFlowId">A GUID that defines in which callstack is linked.</param>
        /// <param name="methodName">The name of the method.</param>
        /// <param name="awaitIfAsync">Await if the method is maked as asynchronous.</param>
        /// <param name="args">The arguments to pass to the method.</param>
        /// <returns>Returns the result of the invocation (a <see cref="Task"/> in the case of a not awaited asynchronous method, or the value returned by the method).</returns>
        internal object InvokeMethod(Guid executionFlowId, string methodName, bool awaitIfAsync, Code.AbstractSyntaxTree.Expression[] args)
        {
            InitializeGlobalState();

            BaZicInterpreter.CheckState(BaZicInterpreterState.Idle, BaZicInterpreterState.Stopped, BaZicInterpreterState.StoppedWithError);

            var invokeExpression = new InvokeMethodExpression(methodName, awaitIfAsync).WithParameters(args);

            BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Running));

            return(new InvokeMethodInterpreter(BaZicInterpreter, this, invokeExpression, executionFlowId, true).Run());
        }
Exemple #9
0
        /// <inheritdoc/>
        internal override void Run()
        {
            var expression = ParentInterpreter.RunExpression(Statement.Expression);

            var exception = expression as Exception;

            if (exception == null)
            {
                BaZicInterpreter.ChangeState(this, new BadTypeException(L.BaZic.Runtime.Interpreters.Statements.ThrowInterpreter.FormattedExceptionExpected(typeof(Exception).FullName)));
                return;
            }

            throw exception;
        }
Exemple #10
0
        /// <inheritdoc/>
        internal override object Run()
        {
            var parentBlockInterpreter = ParentInterpreter as BlockInterpreter;

            if (parentBlockInterpreter == null)
            {
                BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Expressions.ExceptionInterpreter.BlockExpected), Expression);
            }

            if (parentBlockInterpreter.CaughtException == null)
            {
                BaZicInterpreter.ChangeState(this, new IncoherentStatementException(L.BaZic.Runtime.Interpreters.Expressions.ExceptionInterpreter.TryCatchExpected), Expression);
            }

            return(parentBlockInterpreter.CaughtException);
        }
        /// <inheritdoc/>
        internal override object Run()
        {
            if (BaZicInterpreter.Verbose)
            {
                ParentInterpreter.VerboseLog(L.BaZic.Runtime.Interpreters.Expressions.PropertyReferenceInterpreter.FormattedGettingProperty(Expression));
            }

            if (Expression.TargetObject == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.PropertyReferenceInterpreter.NullValue), Expression);
                return(null);
            }
            else if (string.IsNullOrWhiteSpace(Expression.PropertyName?.Identifier))
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.PropertyReferenceInterpreter.UndefinedName), Expression);
                return(null);
            }

            var targetObjectValue = ParentInterpreter.RunExpression(Expression.TargetObject);

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

            if (targetObjectValue == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.PropertyReferenceInterpreter.NullValue), Expression);
                return(null);
            }

            if (Expression.TargetObject is ClassReferenceExpression && targetObjectValue is Type)
            {
                return(BaZicInterpreter.Reflection.GetStaticPropertyOrEnum((Type)targetObjectValue, Expression.PropertyName.Identifier));
            }

            if (targetObjectValue is FrameworkElement)
            {
                return(BaZicInterpreter.ProgramInterpreter.UIDispatcher.Invoke(() =>
                {
                    return BaZicInterpreter.Reflection.GetProperty(targetObjectValue, Expression.PropertyName.Identifier);
                }, System.Windows.Threading.DispatcherPriority.Background));
            }

            return(BaZicInterpreter.Reflection.GetProperty(targetObjectValue, Expression.PropertyName.Identifier));
        }
Exemple #12
0
        /// <summary>
        /// Adds a new variable to the memory.
        /// </summary>
        /// <param name="variableDeclaration">The variable declaration.</param>
        /// <param name="variable">The variable created from the <paramref name="variableDeclaration"/>.</param>
        /// <param name="defaultValue">The default value retrieved from the <paramref name="variableDeclaration"/>.</param>
        /// <param name="defaultValueInfo">The information about the <paramref name="defaultValue"/>.</param>
        /// <param name="setValueIfNull">Defines whether the value of the variable must be set if the given default value is null.</param>
        private void AddVariable(VariableDeclaration variableDeclaration, Variable variable, object defaultValue, ValueInfo defaultValueInfo, bool setValueIfNull)
        {
            if (IsAborted)
            {
                return;
            }

            if (!defaultValueInfo.IsNull)
            {
                if (variable.IsArray && !defaultValueInfo.IsArray)
                {
                    BaZicInterpreter.ChangeState(this, new NotAssignableException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedNotArrayExpected(variableDeclaration.Name)), variableDeclaration.DefaultValue);
                    return;
                }
                else if (!variable.IsArray && defaultValueInfo.IsArray)
                {
                    BaZicInterpreter.ChangeState(this, new NotAssignableException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedArrayExpected(variableDeclaration.Name)), variableDeclaration.DefaultValue);
                    return;
                }
            }

            if (defaultValueInfo.IsNull)
            {
                if (setValueIfNull)
                {
                    variable.SetValue(defaultValue, defaultValueInfo);
                }
            }
            else
            {
                variable.SetValue(defaultValue, defaultValueInfo);
            }

            _variables.Add(variable);

            if (GetType() != typeof(ProgramInterpreter))
            {
                GetParentMethodInterpreter(includeThis: true).DebugCallInfo.Variables.Add(variable);
            }

            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.Interpreter.FormattedVariableDeclared(variable.Name, variable));
            }
        }
Exemple #13
0
        /// <inheritdoc/>
        internal override void Run()
        {
            if (BaZicInterpreter.Verbose)
            {
                ParentInterpreter.VerboseLog(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.FormattedAssign(Statement.LeftExpression, Statement.RightExpression));
            }

            if (!typeof(IAssignable).IsAssignableFrom(Statement.LeftExpression.GetType()))
            {
                BaZicInterpreter.ChangeState(this, new NotAssignableException(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.NotAssignable), Statement);
                return;
            }

            var rightValue = ParentInterpreter.RunExpression(Statement.RightExpression);

            if (ParentInterpreter.IsAborted)
            {
                return;
            }

            switch (Statement.LeftExpression)
            {
            case ArrayIndexerExpression arrayIndexer:
                AssignArrayValue(arrayIndexer, rightValue);
                break;

            case PropertyReferenceExpression propertyReference:
                AssignProperty(propertyReference, rightValue);
                break;

            case VariableReferenceExpression variableReference:
                ParentInterpreter.SetVariable(variableReference, rightValue);
                break;

            default:
                throw new InternalException(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.FormattedNoInterpreter(Statement.LeftExpression.GetType().FullName));
            }

            if (BaZicInterpreter.Verbose && !ParentInterpreter.IsAborted)
            {
                var rightValueString = rightValue == null ? L.BaZic.Runtime.Debugger.ValueInfo.Null : $"'{rightValue}'(type:{ rightValue.GetType().FullName})";
                ParentInterpreter.VerboseLog(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.FormattedNowEqualsTo(Statement.LeftExpression, rightValueString));
            }
        }
Exemple #14
0
        /// <inheritdoc/>
        internal override object Run()
        {
            if (Expression.CreateType == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.InstantiateInterpreter.FormattedCreateTypeNull(nameof(InstantiateExpression.CreateType), nameof(InstantiateExpression))), Expression);
                return(null);
            }

            var createType = ParentInterpreter.RunExpression(Expression.CreateType) as Type;

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

            if (BaZicInterpreter.Verbose)
            {
                ParentInterpreter.VerboseLog(L.BaZic.Runtime.Interpreters.Expressions.InstantiateInterpreter.FormattedCreateInstance(Expression.CreateType));
            }

            // Execute argument's values.
            if (BaZicInterpreter.Verbose)
            {
                ParentInterpreter.VerboseLog(L.BaZic.Runtime.Interpreters.MethodInterpreter.ExecutingArguments);
            }
            var argumentValues = new List <object>();

            for (var i = 0; i < Expression.Arguments.Count; i++)
            {
                var argumentValue = ParentInterpreter.RunExpression(Expression.Arguments[i]);
                argumentValues.Add(argumentValue);
            }

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

            return(BaZicInterpreter.Reflection.Instantiate(createType, argumentValues.ToArray()));
        }
Exemple #15
0
        /// <summary>
        /// Move the execution cursor to the specified label. If the label is in a parent block, it sets a flag to exit the current block.
        /// </summary>
        /// <param name="labelName">The name of the label to jump to.</param>
        private void JumpToLabel(string labelName)
        {
            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.BlockInterpreter.FormattedGoTo(labelName));
            }

            var cursor = -1;

            if (!_labelRegistry.TryGetValue(labelName, out cursor))
            {
                if (ParentInterpreter is BlockInterpreter blockInterpreter)
                {
                    State.ExitBlockBecauseOfLabelJump = true;
                    blockInterpreter.JumpToLabel(labelName);
                    return;
                }

                BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.BlockInterpreter.FormattedLabelNotFound(labelName)));
            }

            _executionCursor = cursor;
        }
Exemple #16
0
        /// <inheritdoc/>
        internal override object Run()
        {
            if (Expression.Expression == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.NotOperatorInterpreter.FormattedExpressionNull(nameof(NotOperatorExpression))), Expression);
                return(null);
            }

            var expressionValue = ParentInterpreter.RunExpression(Expression.Expression);

            if (expressionValue == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.NotOperatorInterpreter.ValueNull), Expression);
                return(null);
            }
            else if (expressionValue.GetType() != typeof(bool))
            {
                BaZicInterpreter.ChangeState(this, new BadTypeException(L.BaZic.Runtime.Interpreters.Expressions.NotOperatorInterpreter.FormattedBooleanExpected(expressionValue.GetType().Name)), Expression);
                return(null);
            }

            return(!(bool)expressionValue);
        }
Exemple #17
0
        /// <summary>
        /// Creates a new variable in memory.
        /// </summary>
        /// <param name="variableDeclaration">The variable declaration to use.</param>
        /// <param name="searchInParents">Defines whether finding a variable can be performed in the parent interpreters.</param>
        internal void AddVariable(VariableDeclaration variableDeclaration, bool searchInParents = true)
        {
            var existingVariable = GetVariable(variableDeclaration.Id, variableDeclaration.Name.Identifier, false, searchInParents);

            if (existingVariable != null)
            {
                if (!BaZicInterpreter.ProgramIsOptimized)
                {
                    BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedDuplicatedVariableId(variableDeclaration.Id)), variableDeclaration);
                    return;
                }
                else
                {
                    var variableRef = new VariableReferenceExpression(existingVariable.Name)
                    {
                        Line                  = variableDeclaration.Line,
                        Column                = variableDeclaration.Column,
                        StartOffset           = variableDeclaration.StartOffset,
                        NodeLength            = variableDeclaration.NodeLength,
                        VariableDeclarationID = existingVariable.Id
                    };
                    SetVariable(variableRef, RunExpression(variableDeclaration.DefaultValue));
                    return;
                }
            }

            if (IsAborted)
            {
                return;
            }

            var defaultValue     = RunExpression(variableDeclaration.DefaultValue);
            var defaultValueInfo = ValueInfo.GetValueInfo(defaultValue);
            var variable         = new Variable(variableDeclaration);

            AddVariable(variableDeclaration, variable, defaultValue, defaultValueInfo, true);
        }
Exemple #18
0
        /// <summary>
        /// Creates a new control accessor in memory.
        /// </summary>
        /// <param name="controlAccessorDeclaration">The control accessor declaration to use.</param>
        internal void AddVariable(ControlAccessorDeclaration controlAccessorDeclaration)
        {
            if (GetType() != typeof(ProgramInterpreter))
            {
                BaZicInterpreter.ChangeState(this, new IncoherentStatementException(L.BaZic.Runtime.Interpreters.Interpreter.ForbiddenBinding), controlAccessorDeclaration);
                return;
            }

            var existingVariable = GetVariable(controlAccessorDeclaration.Id, controlAccessorDeclaration.Variable.Name.Identifier, false, true);

            if (existingVariable != null)
            {
                BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedDuplicatedVariableId(controlAccessorDeclaration.Id)), controlAccessorDeclaration);
                return;
            }

            var defaultValue     = RunExpression(controlAccessorDeclaration.Variable.DefaultValue);
            var defaultValueInfo = ValueInfo.GetValueInfo(defaultValue);

            if (IsAborted)
            {
                return;
            }

            var targetControl = ((ProgramInterpreter)this).UserInterface.FindName(controlAccessorDeclaration.ControlName);

            if (targetControl == null)
            {
                BaZicInterpreter.ChangeState(this, new UiException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedUiControlNotFound(controlAccessorDeclaration.ControlName)));
                return;
            }

            var binding = new ControlAccessor(controlAccessorDeclaration, targetControl, BaZicInterpreter);

            AddVariable(controlAccessorDeclaration.Variable, binding, defaultValue, defaultValueInfo, false);
        }
        /// <inheritdoc/>
        internal override object Run()
        {
            var expressionValue = ParentInterpreter.RunExpression(Expression.TargetObject);

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

            if (expressionValue == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.NullValue), Expression);
                return(null);
            }

            var valueInfo = ValueInfo.GetValueInfo(expressionValue);

            if (!valueInfo.IsArray)
            {
                BaZicInterpreter.ChangeState(this, new BadTypeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedIndexerForbidden(valueInfo.Type.Name)), Expression);
                return(null);
            }

            if (Expression.Indexes.Length != 1)
            {
                BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.OneIndexerAllowed), Expression);
                return(null);
            }

            var index = ParentInterpreter.RunExpression(Expression.Indexes[0]);

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

            if (index == null)
            {
                BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.IndexMustNotBeNull), Expression);
                return(null);
            }

            if (valueInfo.Type == typeof(ObservableDictionary))
            {
                var    dictionary = (ObservableDictionary)expressionValue;
                object val        = null;
                if (dictionary.TryGetValue(index, out val))
                {
                    return(val);
                }

                BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedKeyDoesNotExist(index?.ToString())), Expression);
                return(null);
            }
            else if (typeof(IDictionary).IsAssignableFrom(valueInfo.Type))
            {
                return(((IDictionary)expressionValue)[index]);
            }
            else
            {
                var indexValue = index as int?;

                if (indexValue == null)
                {
                    BaZicInterpreter.ChangeState(this, new BadArgumentException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.CastToNumber), Expression);
                    return(null);
                }

                if (indexValue < 0 || indexValue >= valueInfo.Length)
                {
                    BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedOutOfRange(indexValue.ToString(), (valueInfo.Length - 1).ToString())), Expression);
                    return(null);
                }

                if (valueInfo.Type.IsArray || valueInfo.Type == typeof(Array))
                {
                    return(((Array)expressionValue).GetValue(indexValue.Value));
                }
                else if (typeof(IList).IsAssignableFrom(valueInfo.Type))
                {
                    return(((IList)expressionValue)[indexValue.Value]);
                }
            }

            BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedUnsupportedArray(valueInfo.Type.FullName)), Expression);
            return(null);
        }
Exemple #20
0
        /// <inheritdoc/>
        internal override object Run()
        {
            var leftValue = ParentInterpreter.RunExpression(Expression.LeftExpression);

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

            var rightValue = ParentInterpreter.RunExpression(Expression.RightExpression);

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

            if (BaZicInterpreter.Verbose)
            {
                ParentInterpreter.VerboseLog(L.BaZic.Runtime.Interpreters.Expressions.BinaryOperatorInterpreter.FormattedPerformOperation(Expression.Operator));
            }

            dynamic dynamicLeftValue  = leftValue;
            dynamic dynamicRightValue = rightValue;

            switch (Expression.Operator)
            {
            case BinaryOperatorType.Equality:
                return(dynamicLeftValue == dynamicRightValue);

            case BinaryOperatorType.BitwiseOr:
                return(dynamicLeftValue | dynamicRightValue);

            case BinaryOperatorType.BitwiseAnd:
                return(dynamicLeftValue & dynamicRightValue);

            case BinaryOperatorType.LogicalOr:
                return(dynamicLeftValue || dynamicRightValue);

            case BinaryOperatorType.LogicalAnd:
                return(dynamicLeftValue && dynamicRightValue);

            case BinaryOperatorType.LessThan:
                return(dynamicLeftValue < dynamicRightValue);

            case BinaryOperatorType.LessThanOrEqual:
                return(dynamicLeftValue <= dynamicRightValue);

            case BinaryOperatorType.GreaterThan:
                return(dynamicLeftValue > dynamicRightValue);

            case BinaryOperatorType.GreaterThanOrEqual:
                return(dynamicLeftValue >= dynamicRightValue);

            case BinaryOperatorType.Addition:
                return(dynamicLeftValue + dynamicRightValue);

            case BinaryOperatorType.Subtraction:
                return(dynamicLeftValue - dynamicRightValue);

            case BinaryOperatorType.Multiply:
                return(dynamicLeftValue * dynamicRightValue);

            case BinaryOperatorType.Division:
                var convertedToLong = long.TryParse(rightValue.ToString(), out long num);
                if (convertedToLong && num == 0)
                {
                    BaZicInterpreter.ChangeState(this, new DivideByZeroException(L.BaZic.Runtime.Interpreters.Expressions.BinaryOperatorInterpreter.DivideByZero), Expression.RightExpression);
                    return(null);
                }

                return(dynamicLeftValue / dynamicRightValue);

            case BinaryOperatorType.Modulus:
                return(dynamicLeftValue % dynamicRightValue);

            default:
                throw new InternalException(L.BaZic.Runtime.Interpreters.Expressions.BinaryOperatorInterpreter.FormattedOperatorNotImplemented(Expression.Operator, nameof(BinaryOperatorInterpreter)));
            }
        }
Exemple #21
0
        /// <summary>
        /// Assigns the specified value to an array.
        /// </summary>
        /// <param name="arrayIndexer">The reference to the position in the array to set.</param>
        /// <param name="value">The value to assign.</param>
        private void AssignArrayValue(ArrayIndexerExpression arrayIndexer, object value)
        {
            var expressionValue = ParentInterpreter.RunExpression(arrayIndexer.TargetObject);

            if (ParentInterpreter.IsAborted)
            {
                return;
            }

            if (expressionValue == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.TargetObjectNull), arrayIndexer);
                return;
            }

            var valueInfo = ValueInfo.GetValueInfo(expressionValue);

            if (!valueInfo.IsArray)
            {
                BaZicInterpreter.ChangeState(this, new BadTypeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedIndexerForbidden(valueInfo.Type.Name)), arrayIndexer);
                return;
            }

            if (arrayIndexer.Indexes.Length != 1)
            {
                BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.OneIndexerAllowed), arrayIndexer);
                return;
            }

            var index = ParentInterpreter.RunExpression(arrayIndexer.Indexes[0]);

            if (ParentInterpreter.IsAborted)
            {
                return;
            }

            if (index == null)
            {
                BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.IndexMustNotBeNull), arrayIndexer.Indexes[0]);
                return;
            }

            if (valueInfo.Type == typeof(ObservableDictionary))
            {
                ((ObservableDictionary)expressionValue)[index] = value;
                return;
            }
            else if (typeof(IDictionary).IsAssignableFrom(valueInfo.Type))
            {
                ((IDictionary)expressionValue)[index] = value;
                return;
            }
            else
            {
                var indexValue = index as int?;

                if (indexValue == null)
                {
                    BaZicInterpreter.ChangeState(this, new BadArgumentException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.CastToNumber), arrayIndexer);
                    return;
                }

                if (indexValue < 0 || indexValue >= valueInfo.Length)
                {
                    BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.FormattedOutOfRange(indexValue, valueInfo.Length - 1)), arrayIndexer);
                    return;
                }

                if (valueInfo.Type.IsArray || valueInfo.Type == typeof(Array))
                {
                    ((Array)expressionValue).SetValue(value, indexValue.Value);
                    return;
                }
                else if (typeof(IList).IsAssignableFrom(valueInfo.Type))
                {
                    ((IList)expressionValue)[indexValue.Value] = value;
                    return;
                }
            }

            BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.FormattedUnsupportedArray(valueInfo.Type.FullName)), arrayIndexer);
        }
Exemple #22
0
 /// <summary>
 /// Add a new log
 /// </summary>
 /// <param name="message">the message</param>
 internal void VerboseLog(string message)
 {
     BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(message));
 }
Exemple #23
0
        /// <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(Code.AbstractSyntaxTree.Expression expression)
        {
            if (expression == null)
            {
                return(null);
            }

            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.Interpreter.FormattedExecutingExpression(expression.GetType().Name));
            }

            object expressionResult = null;

            switch (expression)
            {
            case ArrayCreationExpression arrayCreation:
                expressionResult = new ArrayCreationInterpreter(BaZicInterpreter, this, arrayCreation).Run();
                break;

            case ArrayIndexerExpression arrayIndexer:
                expressionResult = new ArrayIndexerInterpreter(BaZicInterpreter, this, arrayIndexer).Run();
                break;

            case BinaryOperatorExpression binaryOperator:
                expressionResult = new BinaryOperatorInterpreter(BaZicInterpreter, this, binaryOperator).Run();
                break;

            case ClassReferenceExpression classReference:
                expressionResult = new ClassReferenceInterpreter(BaZicInterpreter, this, classReference).Run();
                break;

            case ExceptionReferenceExpression exceptionReference:
                expressionResult = new ExceptionInterpreter(BaZicInterpreter, this, exceptionReference).Run();
                break;

            case InstantiateExpression instantiate:
                expressionResult = new InstantiateInterpreter(BaZicInterpreter, this, instantiate).Run();
                break;

            case InvokeCoreMethodExpression invokeCoreMethod:
                expressionResult = new InvokeCoreMethodInterpreter(BaZicInterpreter, this, invokeCoreMethod, ExecutionFlowId).Run();
                break;

            case InvokeMethodExpression invokeMethod:
                expressionResult = new InvokeMethodInterpreter(BaZicInterpreter, this, invokeMethod, ExecutionFlowId).Run();
                break;

            case NotOperatorExpression notOperator:
                expressionResult = new NotOperatorInterpreter(BaZicInterpreter, this, notOperator).Run();
                break;

            case PrimitiveExpression primitive:
                expressionResult = new PrimitiveInterpreter(BaZicInterpreter, this, primitive).Run();
                break;

            case PropertyReferenceExpression propertyReference:
                expressionResult = new PropertyReferenceInterpreter(BaZicInterpreter, this, propertyReference).Run();
                break;

            case VariableReferenceExpression variableReference:
                expressionResult = new VariableReferenceInterpreter(BaZicInterpreter, this, variableReference).Run();
                break;

            default:
                BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedInterpreterNotFound(expression.GetType().Name)), expression);
                break;
            }

            if (IsAborted)
            {
                return(null);
            }

            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.Interpreter.FormattedExpressionReturnedValue(expressionResult, ValueInfo.GetValueInfo(expressionResult)));
            }

            return(expressionResult);
        }
Exemple #24
0
        private void RunStatement(Code.AbstractSyntaxTree.Statement statement)
        {
            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.BlockInterpreter.FormattedExecutingStatement(statement.GetType().Name));
            }

            switch (statement)
            {
            case AssignStatement assign:
                new AssignInterpreter(BaZicInterpreter, this, ExecutionFlowId, assign).Run();
                break;

            case BreakStatement @break:
                new BreakInterpreter(BaZicInterpreter, this, ExecutionFlowId, @break).Run();
                break;

            case CommentStatement comment:
                // Just ignore
                break;

            case ConditionStatement condition:
                var conditionInterpreter = new ConditionInterpreter(BaZicInterpreter, this, ExecutionFlowId, condition);
                conditionInterpreter.Run();
                ApplyChildBlockState(conditionInterpreter.ChildBlockState);
                break;

            case GoToLabelStatement goToLabel:
                JumpToLabel(goToLabel.Name.Identifier);
                break;

            case IterationStatement iteration:
                var iterationInterpreter = new IterationInterpreter(BaZicInterpreter, this, ExecutionFlowId, iteration);
                iterationInterpreter.Run();
                ApplyChildBlockState(iterationInterpreter.ChildBlockState);
                break;

            case LabelConditionStatement labelCondition:
                var labelConditionInterpreter = new LabelConditionInterpreter(BaZicInterpreter, this, ExecutionFlowId, labelCondition);
                labelConditionInterpreter.Run();
                if (!IsAborted && labelConditionInterpreter.ConditionValidated)
                {
                    JumpToLabel(labelCondition.LabelName.Identifier);
                }
                break;

            case LabelDeclaration labelDeclaration:
                // Just ignore
                break;

            case ReturnStatement @return:
                new ReturnInterpreter(BaZicInterpreter, this, ExecutionFlowId, @return).Run();
                break;

            case ThrowStatement @throw:
                new ThrowInterpreter(BaZicInterpreter, this, ExecutionFlowId, @throw).Run();
                break;

            case TryCatchStatement tryCatch:
                var tryCatchInterpreter = new TryCatchInterpreter(BaZicInterpreter, this, ExecutionFlowId, tryCatch);
                tryCatchInterpreter.Run();
                ApplyChildBlockState(tryCatchInterpreter.ChildBlockState);
                break;

            case VariableDeclaration variableDeclaration:
                new VariableDeclarationInterpreter(BaZicInterpreter, this, ExecutionFlowId, variableDeclaration).Run();
                break;

            case ExpressionStatement expressionStatement:
                new ExpressionStatementInterpreter(BaZicInterpreter, this, ExecutionFlowId, expressionStatement).Run();
                break;

            case BreakpointStatement breakpoint:
                if (BaZicInterpreter.Verbose)
                {
                    VerboseLog(L.BaZic.Runtime.Interpreters.BlockInterpreter.BreakpointIntercepted);
                }
                BaZicInterpreter.Pause();
                Task.Delay(100).Wait();
                break;

            default:
                BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.BlockInterpreter.FormattedInterpreterNotFound(statement.GetType().FullName)), statement);
                break;
            }

            if (BaZicInterpreter.Verbose && (State.ExitMethod || State.ExitIteration || State.ExitBlockBecauseOfLabelJump))
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.BlockInterpreter.ExitingBlock);
            }
        }
        /// <inheritdoc/>
        internal override object Run()
        {
            if (Expression.TargetObject == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.InvokeCoreMethodInterpreter.TargetObjectNull), Expression);
                return(null);
            }
            else if (string.IsNullOrWhiteSpace(Expression.MethodName?.Identifier))
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.InvokeCoreMethodInterpreter.UndefinedMethodName), Expression);
                return(null);
            }

            var targetObjectValue = ParentInterpreter.RunExpression(Expression.TargetObject);

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

            if (targetObjectValue == null)
            {
                BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.InvokeCoreMethodInterpreter.TargetObjectNull), Expression);
                return(null);
            }


            // Execute argument's values.
            if (BaZicInterpreter.Verbose)
            {
                ParentInterpreter.VerboseLog(L.BaZic.Runtime.Interpreters.MethodInterpreter.ExecutingArguments);
            }
            var argumentValues = new List <object>();

            for (var i = 0; i < Expression.Arguments.Count; i++)
            {
                var argumentValue = ParentInterpreter.RunExpression(Expression.Arguments[i]);
                argumentValues.Add(argumentValue);
            }

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

            object result = null;

            if (Expression.TargetObject is ClassReferenceExpression && targetObjectValue is Type)
            {
                result = BaZicInterpreter.Reflection.InvokeStaticMethod((Type)targetObjectValue, Expression.MethodName.Identifier, argumentValues.ToArray());
            }
            else if (targetObjectValue is FrameworkElement)
            {
                BaZicInterpreter.ProgramInterpreter.UIDispatcher.Invoke(() =>
                {
                    result = BaZicInterpreter.Reflection.InvokeMethod(targetObjectValue, Expression.MethodName.Identifier, argumentValues.ToArray());
                }, System.Windows.Threading.DispatcherPriority.Background);
            }
            else
            {
                result = BaZicInterpreter.Reflection.InvokeMethod(targetObjectValue, Expression.MethodName.Identifier, argumentValues.ToArray());
            }

            if (Expression.Await)
            {
                if (result == null || !typeof(Task).IsAssignableFrom(result.GetType()))
                {
                    BaZicInterpreter.ChangeState(this, new MethodNotAwaitableException(Expression.MethodName.Identifier), Expression);
                    return(null);
                }
                else
                {
                    var task = (Task)result;
                    task.Wait();
                    var type = task.GetType();
                    if (!type.IsGenericType)
                    {
                        result = null;
                    }
                    else
                    {
                        result = type.GetProperty(nameof(Task <object> .Result)).GetValue(task);
                    }
                    task.Dispose();
                }
            }
            else if (result != null && typeof(Task).IsAssignableFrom(result.GetType()))
            {
                var task = (Task)result;
                BaZicInterpreter.RunningStateManager.AddUnwaitedMethodInvocation(_executionFlowId, task);
            }

            return(result);
        }
Exemple #26
0
        internal object Invoke()
        {
            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.MethodInterpreter.FormattedPreparing(_invokeMethod.MethodName));
            }

            DebugCallInfo = new Call(_invokeMethod);

            var awaitCall = _invokeMethod.Await;

            if (awaitCall && !_methodDeclaration.IsAsync)
            {
                BaZicInterpreter.ChangeState(this, new MethodNotAwaitableException(_methodDeclaration.Name.Identifier), _invokeMethod);
                return(ReturnedValue);
            }

            if (_methodDeclaration.Arguments.Count != _invokeMethod.Arguments.Count)
            {
                BaZicInterpreter.ChangeState(this, new MethodNotFoundException(_methodDeclaration.Name.Identifier, L.BaZic.Runtime.Interpreters.MethodInterpreter.FormattedBadArgumentCount(_methodDeclaration.Name, _invokeMethod.Arguments.Count)), _invokeMethod);
                return(ReturnedValue);
            }

            // Execute argument's values.
            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.MethodInterpreter.ExecutingArguments);
            }
            var argumentValues = new List <object>();

            for (var i = 0; i < _invokeMethod.Arguments.Count; i++)
            {
                var argumentValue = RunExpression(_invokeMethod.Arguments[i]);
                argumentValues.Add(argumentValue);
            }

            if (IsAborted)
            {
                return(ReturnedValue);
            }

            if (BaZicInterpreter.ProgramInterpreter.TotalSynchronousCallCount > 0 && BaZicInterpreter.ProgramInterpreter.TotalSynchronousCallCount % 500 == 0)
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }

            // Execute the method.
            if (_methodDeclaration.IsAsync)
            {
                if (awaitCall)
                {
                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.MethodInterpreter.FormattedAwait(_invokeMethod.MethodName));
                    }
                    RunAsync(argumentValues).Wait();
                    return(ReturnedValue);
                }
                else
                {
                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.MethodInterpreter.FormattedAsync(_invokeMethod.MethodName));
                    }
                    AsyncMethodCalledWithoutAwait = true;
                    var task = RunAsync(argumentValues);
                    BaZicInterpreter.RunningStateManager.AddUnwaitedMethodInvocation(ExecutionFlowId, task);
                    return(task);
                }
            }
            else
            {
                if (BaZicInterpreter.Verbose)
                {
                    VerboseLog(L.BaZic.Runtime.Interpreters.MethodInterpreter.FormattedSync(_invokeMethod.MethodName));
                }

                BaZicInterpreter.ProgramInterpreter.SynchronousCallCount++;
                BaZicInterpreter.ProgramInterpreter.TotalSynchronousCallCount++;

                if (BaZicInterpreter.ProgramInterpreter.TotalSynchronousCallCount >= Consts.StackOverflowLimit)
                {
                    BaZicInterpreter.ChangeState(this, new Debugger.Exceptions.StackOverflowException(L.BaZic.Runtime.Interpreters.MethodInterpreter.FormattedStackOverflow(Consts.StackOverflowLimit)));
                    return(ReturnedValue);
                }

                if (BaZicInterpreter.ProgramInterpreter.SynchronousCallCount >= Consts.CallLimitBeforeNewThread)
                {
                    BaZicInterpreter.ProgramInterpreter.SynchronousCallCount = 0;
                    CallMethodNewThread(argumentValues).Wait();
                }
                else
                {
                    RunSync(argumentValues);
                }
                return(ReturnedValue);
            }
        }
Exemple #27
0
        internal void Start(object[] args)
        {
            BaZicInterpreter.CheckState(BaZicInterpreterState.Preparing);

            InitializeGlobalState();

            var entryPoint = GetEntryPointMethod();

            if (IsAborted)
            {
                return;
            }

            if (BaZicInterpreter.Verbose)
            {
                VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.EntryPointDetected);
            }

            BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Running));

            var argsExpressions = new List <Code.AbstractSyntaxTree.Expression>();

            if (args != null)
            {
                foreach (var argument in args)
                {
                    argsExpressions.Add(new PrimitiveExpression(argument));
                }
            }

            var entryPointInvocation  = new InvokeMethodExpression(Consts.EntryPointMethodName, false).WithParameters(new ArrayCreationExpression().WithValues(argsExpressions.ToArray()));
            var entryPointInterpreter = new MethodInterpreter(BaZicInterpreter, this, entryPoint, entryPointInvocation, ExecutionFlowId);

            ProgramResult = entryPointInterpreter.Invoke();

            if (IsAborted)
            {
                return;
            }

            if (_uiProgram != null && ProgramResult == null)
            {
                Exception eventException = null;

                ThreadHelper.RunOnStaThread(() =>
                {
                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.LoadingUi);
                    }

                    _uiThread = Thread.CurrentThread;

                    LoadUserInterface();

                    if (UserInterface == null)
                    {
                        BaZicInterpreter.ChangeState(this, new UiException(L.BaZic.Parser.XamlUnknownParsingError));
                        return;
                    }

                    UIDispatcher = UserInterface.Dispatcher;

                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.DeclaringEvents);
                    }

                    foreach (var uiEvent in _uiProgram.UiEvents)
                    {
                        var targetObject = UserInterface.FindName(uiEvent.ControlName);

                        if (targetObject == null)
                        {
                            BaZicInterpreter.ChangeState(this, new UiException($"Unable to find the control named '{uiEvent.ControlName}'."));
                            return;
                        }

                        var action = new Action(() =>
                        {
                            if (BaZicInterpreter.Verbose)
                            {
                                VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.EventRaised);
                            }

                            BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Running));
                            var eventMethodDeclaration = _uiProgram.Methods.Single(m => m.Id == uiEvent.MethodId);
                            var eventInvocation        = new InvokeMethodExpression(eventMethodDeclaration.Name.Identifier, false);
                            var eventMethodInterpreter = new MethodInterpreter(BaZicInterpreter, this, eventMethodDeclaration, eventInvocation, ExecutionFlowId);

                            if (targetObject is Window && uiEvent.ControlEventName == nameof(Window.Closed))
                            {
                                ProgramResult = eventMethodInterpreter.Invoke();
                            }
                            else
                            {
                                eventMethodInterpreter.Invoke();
                            }

                            BaZicInterpreter.RunningStateManager.SetIsRunningMainFunction(false); // In all cases, at this point, the main function is done. The UI is running. Idle state must be able to be setted.
                            BaZicInterpreter.RunningStateManager.UpdateState();
                        });

                        BaZicInterpreter.Reflection.SubscribeEvent(targetObject, uiEvent.ControlEventName, action);
                    }

                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.DeclaringBindings);
                    }

                    foreach (var controlAccessor in _uiProgram.UiControlAccessors)
                    {
                        AddVariable(controlAccessor);
                    }

                    if (BaZicInterpreter.Verbose)
                    {
                        VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.ShowUi);
                    }

                    var window = UserInterface as Window;

                    try
                    {
                        if (window != null)
                        {
                            window.Closed += (sender, e) =>
                            {
                                if (BaZicInterpreter.Verbose)
                                {
                                    VerboseLog(L.BaZic.Runtime.Interpreters.ProgramInterpreter.CloseUi);
                                }
                                UserInterface?.Dispatcher?.InvokeShutdown();
                            };
                        }

                        BaZicInterpreter.ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Idle));
                        window?.Show();
                        Dispatcher.Run();
                    }
                    catch (Exception exception)
                    {
                        CoreHelper.ReportException(exception);
                        eventException = exception;
                    }
                    finally
                    {
                        try
                        {
                            window?.Close();
                        }
                        catch (Exception exception)
                        {
                            CoreHelper.ReportException(exception);
                        }
                        finally
                        {
                            RuntimeResourceManager.DeleteResources(ExecutionFlowId.ToString());

                            foreach (var variable in Variables)
                            {
                                variable.Dispose();
                            }

                            BaZicInterpreter.Reflection.UnsubscribeAllEvents();
                            UserInterface = null;
                        }
                    }
                });

                if (eventException != null)
                {
                    throw eventException;
                }
            }
        }