Ejemplo n.º 1
0
        private SObject ExecuteAsync(ScriptStatement statement)
        {
            // statement inside async block gets executed in its own thread.
            // cannot rely on any variables from outside being set on time.

            string taskName = statement.Code.Remove(0, statement.Code.IndexOf("(", StringComparison.Ordinal) + 1);

            taskName = taskName.Remove(taskName.LastIndexOf(")", StringComparison.Ordinal)).Trim();

            if (string.IsNullOrWhiteSpace(taskName))
            {
                taskName = Guid.NewGuid().ToString();
            }

            _index++;
            var nextStatement = _statements[_index];

            var processor = new ScriptProcessor(Context, GetLineNumber());

            lock (Context.AsyncTasks)
                Context.AsyncTasks.Add(taskName);

            Console.WriteLine($"Start async task ({taskName})");

            Task.Run(() =>
            {
                processor.ExecuteStatement(nextStatement);

                lock (Context.AsyncTasks)
                    Context.AsyncTasks.Remove(taskName);
            });

            return(Undefined);
        }
Ejemplo n.º 2
0
        private SObject ExecuteFor(ScriptStatement statement)
        {
            var exp = statement.Code;

            var forCode = exp.Remove(0, exp.IndexOf("for", StringComparison.Ordinal) + "for".Length).Trim().Remove(0, 1); // Remove "for" and "(".

            forCode = forCode.Remove(forCode.Length - 1, 1);                                                              // Remove ")".

            var forStatements = StatementProcessor.GetStatements(this, forCode);

            if (forStatements.Length == 0)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxExpectedExpression, ")"));
            }
            if (forStatements.Length == 1)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxMissingForInitializer));
            }
            if (forStatements.Length == 2)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxMissingForCondition));
            }
            if (forStatements.Length > 3)
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxMissingForControl));
            }

            var processor = new ScriptProcessor(Context, GetLineNumber());

            var forInitializer = forStatements[0];
            var forCondition   = forStatements[1];
            var forControl     = forStatements[2];

            if (forInitializer.Code.Length > 0)
            {
                processor.ExecuteStatement(forInitializer);
            }

            _index++;

            if (_statements.Length > _index)
            {
                var stayInFor        = true;
                var executeStatement = _statements[_index];
                var returnObject     = Undefined;

                while (stayInFor)
                {
                    if (forCondition.Code.Length > 0)
                    {
                        var conditionResult = processor.ExecuteStatement(forCondition);

                        var conditionAsBool = conditionResult as SBool;
                        stayInFor = conditionAsBool?.Value ?? conditionResult.ToBool(this).Value;
                    }

                    if (stayInFor)
                    {
                        returnObject = processor.ExecuteStatement(executeStatement);

                        if (processor._returnIssued || processor._breakIssued)
                        {
                            _breakIssued  = false;
                            _returnIssued = processor._returnIssued;
                            stayInFor     = false;
                        }
                        else if (forControl.Code.Length > 0)
                        {
                            processor.ExecuteStatement(forControl);
                        }
                    }
                }

                return(returnObject);
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxExpectedExpression, "end of script"));
            }
        }
Ejemplo n.º 3
0
        private SObject ExecuteTry(ScriptStatement statement)
        {
            var exp = statement.Code;

            if (exp != "try")
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxMissingBeforeTry));
            }

            _index++;
            if (_statements.Length > _index)
            {
                var     executeStatement   = _statements[_index];
                var     encounteredError   = false;
                var     foundCatch         = false;
                var     foundFinally       = false;
                var     foundMatchingCatch = false;
                SObject errorObject        = null;
                var     returnObject       = Undefined;

                try
                {
                    returnObject = ExecuteStatement(executeStatement);
                }
                catch (ScriptException ex)
                {
                    encounteredError = true;
                    errorObject      = ex.ErrorObject;
                }

                if (encounteredError)
                {
                    var endedCatchSearch = false;
                    var findCatchIndex   = _index + 1;
                    while (findCatchIndex < _statements.Length && !endedCatchSearch)
                    {
                        if (_statements[findCatchIndex].StatementType == StatementType.Catch)
                        {
                            _index = findCatchIndex + 1;

                            if (_statements.Length > _index)
                            {
                                if (!foundMatchingCatch)
                                {
                                    var catchExecuteStatement = _statements[_index];
                                    foundCatch = true;

                                    var catchCode    = _statements[findCatchIndex].Code;
                                    var errorVarName = "";

                                    if (catchCode != "catch")
                                    {
                                        catchCode    = catchCode.Remove(0, "catch".Length).Trim().Remove(0, 1);
                                        catchCode    = catchCode.Remove(catchCode.Length - 1, 1);
                                        errorVarName = catchCode.Trim();
                                    }

                                    if (Regex.IsMatch(catchCode, RegexCatchcondition))
                                    {
                                        errorVarName = catchCode.Remove(catchCode.IndexOf(" ", StringComparison.Ordinal));
                                        var conditionCode = catchCode.Remove(0, catchCode.IndexOf("if", StringComparison.Ordinal) + 3);

                                        var processor = new ScriptProcessor(Context, GetLineNumber());
                                        processor.Context.AddVariable(errorVarName, errorObject);

                                        var conditionResult = processor.ExecuteStatement(new ScriptStatement(conditionCode));

                                        var conditionAsBool = conditionResult as SBool;
                                        foundMatchingCatch = conditionAsBool?.Value ?? conditionResult.ToBool(this).Value;

                                        if (foundMatchingCatch)
                                        {
                                            returnObject = processor.ExecuteStatement(catchExecuteStatement);
                                        }
                                    }
                                    else
                                    {
                                        foundMatchingCatch = true;
                                        var processor = new ScriptProcessor(Context, GetLineNumber());
                                        processor.Context.AddVariable(errorVarName, errorObject);
                                        returnObject = processor.ExecuteStatement(catchExecuteStatement);
                                    }
                                }
                            }
                            else
                            {
                                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxExpectedExpression, "end of script"));
                            }
                        }
                        else
                        {
                            // end search if different statement type appears:
                            endedCatchSearch = true;
                        }

                        findCatchIndex += 2;
                    }
                }
                else
                {
                    var findCatchIndex = _index + 1;
                    while (findCatchIndex < _statements.Length)
                    {
                        if (_statements[findCatchIndex].StatementType == StatementType.Catch)
                        {
                            foundCatch = true;
                            _index     = findCatchIndex + 1;
                        }
                        else
                        {
                            findCatchIndex = _statements.Length;
                        }

                        findCatchIndex += 2;
                    }
                }

                // if no matching catch was found when an error occurred, it was not caught: throw it!
                if (encounteredError && !foundMatchingCatch)
                {
                    return(ErrorHandler.ThrowError(errorObject));
                }

                // now, try to find finally statement:
                var findFinallyIndex = _index + 1;
                while (findFinallyIndex < _statements.Length && !foundFinally)
                {
                    if (_statements[findFinallyIndex].StatementType == StatementType.Finally)
                    {
                        _index = findFinallyIndex + 1;

                        if (_statements.Length > _index)
                        {
                            var finallyExecuteStatement = _statements[_index];
                            foundFinally = true;

                            returnObject = ExecuteStatement(finallyExecuteStatement);
                        }
                        else
                        {
                            return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxExpectedExpression, "end of script"));
                        }
                    }
                    else
                    {
                        findFinallyIndex = _statements.Length;
                    }

                    findFinallyIndex += 2;
                }

                if (!foundCatch && !foundFinally) // when no catch or finally block has been found, throw an error.
                {
                    return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxMissingCatchOrFinally));
                }
                else
                {
                    return(returnObject);
                }
            }
            else
            {
                return(ErrorHandler.ThrowError(ErrorType.SyntaxError, ErrorHandler.MessageSyntaxExpectedExpression, "end of script"));
            }
        }