コード例 #1
0
        /// <summary>
        /// Call the constructor of the class, if exists.
        /// </summary>
        /// <param name="arguments">the argument values</param>
        internal void CreateNewInstanceCallConstructors(Collection <object> arguments)
        {
            if (arguments == null)
            {
                arguments = new Collection <object>();
            }

            var constructor = FindCorrespondingConstructor(arguments.Count);

            if (constructor == null)
            {
                if (Constructors.Count > 0)
                {
                    ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new MethodNotFoundException("ctor", $"There is no constructor with {arguments.Count} argument(s) in the class '{ClassDeclaration.Name}'.")), GetDebugInfo()));
                }
            }
            else
            {
                if (DebugMode)
                {
                    Log(this, $"Calling a constructor of '{ClassDeclaration.Name}'");
                }
                constructor = new MethodInterpreter(constructor.MethodDeclaration, DebugMode);
                constructor.StateChanged           += ChangeState;
                constructor.OnGetParentInterpreter += new Func <ClassInterpreter>(() => this);
                constructor.OnDone += new Action <MethodInterpreter>((met) =>
                {
                    met.Dispose();
                    met.StateChanged -= ChangeState;
                });
                constructor.Initialize();
                constructor.Run(false, arguments, Guid.Empty);
            }
        }
コード例 #2
0
 /// <summary>
 /// Initialize a new instance of <see cref="BlockInterpreter"/>
 /// </summary>
 /// <param name="statements">the list of statements to interpret</param>
 /// <param name="debugMode">defines is the debug mode is enabled or not</param>
 /// <param name="parentProgramInterpreter">the parent program interpreter</param>
 /// <param name="parentMethodInterpreter">the parent method interpreter</param>
 /// <param name="parentBlockInterpreter">the parent block interpreter</param>
 /// <param name="parentClassInterpreter">the parent class interpreter</param>
 internal BlockInterpreter(AlgorithmStatementCollection statements, bool debugMode, ProgramInterpreter parentProgramInterpreter, MethodInterpreter parentMethodInterpreter, BlockInterpreter parentBlockInterpreter, ClassInterpreter parentClassInterpreter)
     : base(debugMode)
 {
     ParentProgramInterpreter = parentProgramInterpreter;
     ParentMethodInterpreter  = parentMethodInterpreter;
     ParentBlockInterpreter   = parentBlockInterpreter;
     ParentClassInterpreter   = parentClassInterpreter;
     Statements = statements;
 }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <summary>
        /// Find the constructor which correspond to the given argument count
        /// </summary>
        /// <param name="argumentCount">The number of argument to search</param>
        /// <returns>Returns null if the constructor has not be found</returns>
        private MethodInterpreter FindCorrespondingConstructor(int argumentCount)
        {
            MethodInterpreter constructor = null;
            var i = 0;

            while (i < Constructors.Count && constructor == null)
            {
                if (Constructors[i].MethodDeclaration._arguments.Count == argumentCount)
                {
                    constructor = Constructors[i];
                }
                i++;
            }

            return(constructor);
        }
コード例 #5
0
        /// <summary>
        /// Initialize, after the constructor, the other properties
        /// </summary>
        internal override void Initialize()
        {
            AlgorithmClassMember member;
            var i = 0;

            IsInstance   = true;
            Variables    = new Collection <Variable>();
            Constructors = new Collection <MethodInterpreter>();
            Methods      = new Collection <MethodInterpreter>();

            while (i < ClassDeclaration.Members.Count && !FailedOrStop)
            {
                member = ClassDeclaration.Members[i];

                switch (member.DomType)
                {
                case AlgorithmDomType.ClassPropertyDeclaration:
                    AddVariable((IAlgorithmVariable)member);
                    break;

                case AlgorithmDomType.ClassConstructorDeclaration:
                    if (Constructors.Any(c => c.MethodDeclaration._arguments.Count == member._arguments.Count))
                    {
                        ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new IdenticalConstructorsException(ClassDeclaration.Name.ToString(), "A class should not have multiple constructors with the same number of arguments.")), GetDebugInfo()));
                    }
                    else
                    {
                        Constructors.Add(new MethodInterpreter(member, DebugMode));
                    }
                    break;

                case AlgorithmDomType.EntryPointMethod:
                    EntryPoint = new MethodInterpreter(member, DebugMode);
                    break;

                case AlgorithmDomType.ClassMethodDeclaration:
                    Methods.Add(new MethodInterpreter(member, DebugMode));
                    break;
                }

                i++;
            }
        }
コード例 #6
0
        /// <summary>
        /// Dispose the resources
        /// </summary>
        public override void Dispose()
        {
            Task.Run(() =>
            {
                OnDone(this);

                ClassDeclaration = null;

                if (Variables != null)
                {
                    foreach (var variable in Variables)
                    {
                        var value = variable.Value as IDisposable;
                        if (value != null)
                        {
                            value.Dispose();
                        }
                    }
                    Variables.Clear();
                }
                Variables = null;

                if (Constructors != null)
                {
                    Constructors.Clear();
                }
                Constructors = null;

                if (Methods != null)
                {
                    Methods.Clear();
                }
                Methods = null;

                EntryPoint = null;
            });
        }