public void AlgorithmClassReferenceExpression()
        {
            Assert.IsNotNull(new AlgorithmClassReferenceExpression());
            Assert.IsNotNull(new AlgorithmClassReferenceExpression("MyClass"));
            Assert.IsNotNull(new AlgorithmClassReferenceExpression("Namespace.namespace", "MyClass"));

            Assert.ThrowsException <ArgumentException>(() => { new AlgorithmClassReferenceExpression("Namespace. namespace", "MyClass"); });
            Assert.ThrowsException <ArgumentException>(() => { new AlgorithmClassReferenceExpression("Namespace.namespace", " "); });

            var classRef = new AlgorithmClassReferenceExpression("Namespace.namespace", "MyClass");

            Assert.AreEqual(classRef.ToString(), "Namespace.namespace.MyClass");
        }
Example #2
0
 /// <summary>
 /// Initialize a new instance of <see cref="Call"/>
 /// </summary>
 /// <param name="classReference">The reference to the class</param>
 /// <param name="invokeMethodExpression">The reference to the called method</param>
 internal Call(AlgorithmClassReferenceExpression classReference, AlgorithmInvokeMethodExpression invokeMethodExpression)
 {
     ClassReference         = classReference;
     InvokeMethodExpression = invokeMethodExpression;
 }
        /// <summary>
        /// Execute a method in the current thread
        /// </summary>
        /// <param name="argumentValues">the list of argument values</param>
        /// <param name="stackTraceId">the user stack trace id</param>
        /// <param name="mustClearStackAtTheEnd">defines if the user call stack must be cleared at the end of this call</param>
        private void RunSync(IReadOnlyList <object> argumentValues, Guid stackTraceId, bool mustClearStackAtTheEnd)
        {
            if (_callStackService.StackTraceCallCount.ContainsKey(stackTraceId))
            {
                if (_callStackService.StackTraceCallCount[stackTraceId] > Consts.CallStackSize)
                {
                    ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new StackOverflowException($"You called too many (more than {Consts.CallStackSize}) methods in the same thread.")), GetParentInterpreter().GetDebugInfo()));
                    return;
                }
                ++_callStackService.StackTraceCallCount[stackTraceId];
            }
            else
            {
                _callStackService.StackTraceCallCount.Add(stackTraceId, 0);
                if (DebugMode)
                {
                    _callStackService.CallStacks.Add(new CallStack(stackTraceId));
                }
            }

            StacktraceId = stackTraceId;
            if (DebugMode)
            {
                var classReference = new AlgorithmClassReferenceExpression(ParentClassInterpreter.ClassDeclaration.Name.ToString());
                var callStack      = _callStackService.CallStacks.Single(cs => cs.TaceId == stackTraceId);
                var arguments      = new List <AlgorithmExpression>();
                foreach (var argumentValue in argumentValues)
                {
                    arguments.Add(new AlgorithmPrimitiveExpression(argumentValue));
                }
                var call = new Call(classReference, new AlgorithmInvokeMethodExpression(classReference, MethodDeclaration._name.ToString(), arguments.ToArray()));
                callStack.Stack.Push(call);
            }

            var block = new BlockInterpreter(MethodDeclaration._statements, DebugMode, ParentProgramInterpreter, this, null, ParentClassInterpreter);

            block.OnGetParentInterpreter += new Func <MethodInterpreter>(() => this);
            block.StateChanged           += ChangeState;
            block.Initialize();

            for (var i = 0; i < MethodDeclaration._arguments.Count; i++)
            {
                var argDecl  = MethodDeclaration._arguments[i];
                var argValue = argumentValues[i];

                if (!(argValue is string) && argValue is IList && !argDecl.IsArray)
                {
                    ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new BadArgumentException(argDecl.Name.ToString(), $"The argument's value '{argDecl.Name}' must not be an array of values."), MethodDeclaration), GetParentInterpreter().GetDebugInfo()));
                    return;
                }
                if ((!(argValue is IList) || argValue is string) && argDecl.IsArray)
                {
                    ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new BadArgumentException(argDecl.Name.ToString(), $"The argument's value '{argDecl.Name}' must be an array of values."), MethodDeclaration), GetParentInterpreter().GetDebugInfo()));
                    return;
                }

                block.AddVariable(argDecl, argValue, true);
            }

            if (FailedOrStop)
            {
                return;
            }

            // try
            // {
            block.Run();
            // }
            // catch (Exception ex)
            // {
            //     ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(ex, MethodDeclaration), GetDebugInfo()));
            //     return;
            // }
            // finally
            // {
            block.StateChanged -= ChangeState;
            block.Dispose();
            //  }


            if (mustClearStackAtTheEnd)
            {
                _callStackService.StackTraceCallCount.Remove(stackTraceId);
            }

            if (DebugMode && !Failed)
            {
                if (mustClearStackAtTheEnd)
                {
                    _callStackService.CallStacks.Remove(_callStackService.CallStacks.Single(callStack => callStack.TaceId == stackTraceId));
                }
                else
                {
                    _callStackService.CallStacks.Single(callStack => callStack.TaceId == stackTraceId).Stack.Pop();
                }
            }



            Done = true;
            OnDone(this);
        }