public override DynValue Visit(WhileLoopNode whileLoopNode)
        {
            try
            {
                LoopStack.Push(new LoopStackItem());

                while (Visit(whileLoopNode.Expression).Number != 0)
                {
                    ExecuteStatementList(whileLoopNode.StatementList).GetAwaiter().GetResult();

                    var stackTop = LoopStack.Peek();

                    if (stackTop.BreakLoop)
                    {
                        break;
                    }

                    if (stackTop.SkipThisIteration)
                    {
                        stackTop.SkipThisIteration = false;
                        continue;
                    }
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                LoopStack.Pop();
            }

            return(DynValue.Zero);
        }
Пример #2
0
        //IStatement
        public void Execute()
        {
            bool   Condition = false;
            object obj       = condition.Evaluate().GetData();

            if (obj is bool)
            {
                Condition = (bool)obj;
            }
            else
            {
                throw new Exception("Not boolen expression in Loop statement");
            }
            LoopStack.Push();
            id = LoopStack.Id();
            while (Condition)
            {
                block.Execute();
                if (id > LoopStack.Id())
                {
                    break;
                }
                Condition = (bool)condition.Evaluate().GetData();
            }
        }
        Snippet BuildSnippet(IndexReader stringReader, string path, LoopStack loopStack, string language)
        {
            var loopState = loopStack.Current;
            var startRow  = loopState.StartLine + 1;

            if (isShared && loopState.Version != null)
            {
                return(Snippet.BuildError(
                           error: "Shared snippets cannot contain a version",
                           path: path,
                           lineNumberInError: startRow,
                           key: loopState.Key));
            }
            if (!TryParseVersionAndPackage(loopState, out var snippetVersion, out var error))
            {
                return(Snippet.BuildError(
                           error: error,
                           path: path,
                           lineNumberInError: startRow,
                           key: loopState.Key));
            }
            var value = loopState.GetLines();

            if (value.IndexOfAny(invalidCharacters) > -1)
            {
                var joinedInvalidChars = $"'{string.Join("', '", invalidCharacters)}'";
                return(Snippet.BuildError(
                           error: $"Snippet contains invalid characters ({joinedInvalidChars}). This was probably caused by copying code from MS Word or Outlook. Dont do that.",
                           path: path,
                           lineNumberInError: startRow,
                           key: loopState.Key));
            }
            if (isShared)
            {
                return(Snippet.BuildShared(
                           startLine: startRow,
                           endLine: stringReader.Index,
                           key: loopState.Key,
                           value: value,
                           path: path,
                           language: language.ToLowerInvariant(),
                           includes: loopStack.GetIncludes()
                           ));
            }
            return(Snippet.Build(
                       startLine: startRow,
                       endLine: stringReader.Index,
                       key: loopState.Key,
                       version: snippetVersion,
                       value: value,
                       path: path,
                       language: language.ToLowerInvariant(),
                       package: package,
                       isCurrent: isCurrent,
                       includes: loopStack.GetIncludes()));
        }
        public override DynValue Visit(SkipNode skipNode)
        {
            if (LoopStack.Count <= 0)
            {
                throw new RuntimeException("Unexpected 'skip' outside of a loop.", skipNode.Line);
            }

            LoopStack.Peek().SkipThisIteration = true;

            return(DynValue.Zero);
        }
Пример #5
0
        public override DynValue Visit(BreakNode breakNode)
        {
            if (LoopStack.Count <= 0)
            {
                throw new RuntimeException("Unexpected 'break' outside a loop.", breakNode.Line);
            }

            LoopStack.Peek().BreakLoop = true;

            return(DynValue.Zero);
        }
Пример #6
0
        private async Task <DynValue> ExecuteStatementList(List <AstNode> statements, CancellationToken token)
        {
            var retVal = DynValue.Zero;

            if (BreakExecution)
            {
                BreakExecution = false;
                throw new ScriptTerminationException("Execution stopped by user.");
            }

            foreach (var statement in statements)
            {
                do
                {
                    token.ThrowIfCancellationRequested();
                } while (SuspendExecution);

                if (BreakExecution)
                {
                    BreakExecution = false;
                    throw new ScriptTerminationException("Execution stopped by user.");
                }

                if (LoopStack.Count > 0)
                {
                    var loopStackTop = LoopStack.Peek();

                    if (loopStackTop.BreakLoop || loopStackTop.SkipThisIteration)
                    {
                        break;
                    }
                }

                if (CallStack.Count > 0)
                {
                    var callStackTop = CallStack.Peek();

                    if (callStackTop.ReturnNow)
                    {
                        retVal = callStackTop.ReturnValue;
                        break;
                    }
                }

                retVal = Visit(statement);
            }

            return(retVal);
        }
Пример #7
0
        static Snippet BuildSnippet(string path, LoopStack loopStack, string language, int index)
        {
            var loopState = loopStack.Current;

            var value = loopState.GetLines();

            return(Snippet.Build(
                       startLine: loopState.StartLine,
                       endLine: index,
                       key: loopState.Key,
                       value: value,
                       path: path,
                       language: language.ToLowerInvariant()
                       ));
        }
Пример #8
0
 //IStatement
 public void Execute()
 {
     if (control == "break")
     {
         LoopStack.Pop();
     }
     else if (control == "continue")
     {
         LoopStack.Push();
     }
     else
     {
         throw new Exception("Unknown control");
     }
 }
        IEnumerable <Snippet> GetSnippets(IndexReader stringReader, string path)
        {
            var language = GetLanguageFromPath(path);

            var loopStack = new LoopStack();

            while (true)
            {
                var line = stringReader.ReadLine();
                if (line == null)
                {
                    if (loopStack.IsInSnippet)
                    {
                        var current = loopStack.Current;
                        yield return(Snippet.BuildError(
                                         error: "Snippet was not closed",
                                         path: path,
                                         lineNumberInError: current.StartLine + 1,
                                         key: current.Key));
                    }
                    break;
                }

                var trimmedLine = line.Trim()
                                  .Replace("  ", " ")
                                  .ToLowerInvariant();
                string version;
                Func <string, bool> endFunc;
                string key;
                if (StartEndTester.IsStart(trimmedLine, out version, out key, out endFunc))
                {
                    loopStack.Push(endFunc, key, version, stringReader.Index);
                    continue;
                }
                if (loopStack.IsInSnippet)
                {
                    if (!loopStack.Current.EndFunc(trimmedLine))
                    {
                        loopStack.AppendLine(line);
                        continue;
                    }

                    yield return(BuildSnippet(stringReader, path, loopStack.Current, language));

                    loopStack.Pop();
                }
            }
        }
Пример #10
0
        static Snippet BuildSnippet(IndexReader stringReader, string path, LoopStack loopStack, string language)
        {
            var loopState = loopStack.Current;
            var startRow  = loopState.StartLine + 1;

            var value = loopState.GetLines();

            return(Snippet.Build(
                       startLine: loopState.StartLine,
                       endLine: stringReader.Index,
                       key: loopState.Key,
                       value: value,
                       path: path,
                       language: language.ToLowerInvariant()
                       ));
        }
Пример #11
0
 public void Execute()
 {
     if (loop)
     {
         id = LoopStack.Id();
     }
     foreach (var item in block)
     {
         item.Execute();
         if (loop && id < LoopStack.Id())
         {
             LoopStack.Pop();
             break;
         }
     }
 }
Пример #12
0
        public async Task <DynValue> ExecuteAsync(string sourceCode, CancellationToken token)
        {
            Parser.LoadSource(sourceCode);
            var node = Parser.Parse();

            try
            {
                return(await Task.Run(async() => await VisitAsync(node, token), token));
            }
            catch (ExitStatementException)
            {
                CallStack.Clear();
                LoopStack.Clear();

                return(DynValue.Zero);
            }
        }
Пример #13
0
        public DynValue Execute(string sourceCode)
        {
            Parser.LoadSource(sourceCode);
            var node = Parser.Parse();

            try
            {
                return(Visit(node));
            }
            catch (ExitStatementException)
            {
                CallStack.Clear();
                LoopStack.Clear();

                return(DynValue.Zero);
            }
        }
        static IEnumerable <Snippet> GetSnippets(TextReader stringReader, string path, int maxWidth)
        {
            var language  = GetLanguageFromPath(path);
            var loopStack = new LoopStack();
            var index     = 0;

            while (true)
            {
                index++;
                var line = stringReader.ReadLine();
                if (line == null)
                {
                    if (loopStack.IsInSnippet)
                    {
                        var current = loopStack.Current;
                        yield return(Snippet.BuildError(
                                         error: "Snippet was not closed",
                                         path: path,
                                         lineNumberInError: current.StartLine + 1,
                                         key: current.Key));
                    }

                    break;
                }

                var trimmedLine = line.Trim();

                if (StartEndTester.IsStart(trimmedLine, path, out var key, out var endFunc))
                {
                    loopStack.Push(endFunc, key, index, maxWidth);
                    continue;
                }

                if (!loopStack.IsInSnippet)
                {
                    continue;
                }

                if (!loopStack.Current.EndFunc(trimmedLine))
                {
                    Snippet?error = null;
                    try
                    {
                        loopStack.AppendLine(line);
                    }
                    catch (LineTooLongException exception)
                    {
                        var current = loopStack.Current;
                        error = Snippet.BuildError(
                            error: "Line too long: " + exception.Line,
                            path: path,
                            lineNumberInError: current.StartLine + 1,
                            key: current.Key);
                    }

                    if (error != null)
                    {
                        yield return(error);

                        break;
                    }

                    continue;
                }

                yield return(BuildSnippet(path, loopStack, language, index));

                loopStack.Pop();
            }
        }
        public override DynValue Visit(ForLoopNode forLoopNode)
        {
            _ = Visit(forLoopNode.Assignment).Number;

            DynValue step = new DynValue(1);

            var targetValue = Visit(forLoopNode.TargetValue);

            if (forLoopNode.Step != null)
            {
                step = Visit(forLoopNode.Step);
            }

            var isLocalScope = false;

            var assignmentNode = (forLoopNode.Assignment as AssignmentNode);
            var iteratorName   = assignmentNode.Variable.Name;

            if (assignmentNode.LocalScope)
            {
                isLocalScope = true;
            }

            try
            {
                LoopStack.Push(new LoopStackItem());
                while (true)
                {
                    ExecuteStatementList(forLoopNode.StatementList).GetAwaiter().GetResult();

                    double iterator;
                    if (isLocalScope)
                    {
                        var callStackTop = CallStack.Peek();
                        iterator = callStackTop.LocalVariableScope[iteratorName].Number;
                    }
                    else
                    {
                        iterator = Environment.Globals[iteratorName].Number;
                    }

                    if (step.Number < 0)
                    {
                        if (iterator < targetValue.Number)
                        {
                            break;
                        }
                        else
                        {
                            iterator -= step.Number;
                        }
                    }
                    else
                    {
                        if (iterator >= targetValue.Number)
                        {
                            break;
                        }
                        else
                        {
                            iterator += step.Number;
                        }
                    }

                    if (isLocalScope)
                    {
                        // no throw on localvar token, so
                        // guaranteed we're inside a function

                        var callStackTop = CallStack.Peek();
                        callStackTop.LocalVariableScope[iteratorName] = new DynValue(iterator);
                    }
                    else
                    {
                        Environment.Globals[iteratorName] = new DynValue(iterator);
                    }

                    var loopStackTop = LoopStack.Peek();

                    if (loopStackTop.BreakLoop)
                    {
                        break;
                    }

                    if (loopStackTop.SkipThisIteration)
                    {
                        loopStackTop.SkipThisIteration = false;
                        continue;
                    }
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                LoopStack.Pop();
            }

            return(DynValue.Zero);
        }
Пример #16
0
        public override DynValue Visit(EachLoopNode eachLoopNode)
        {
            var keyName   = eachLoopNode.KeyNode.Name;
            var valueName = eachLoopNode.ValueNode.Name;

            DynValue backupKeyVar   = null;
            DynValue backupValueVar = null;

            try
            {
                var lsItem = new LoopStackItem();
                LoopStack.Push(lsItem);

                DynValue tableValue = null;
                if (eachLoopNode.TableNode is VariableNode varNode)
                {
                    var tableName = varNode.Name;
                    if (CallStack.Count > 0)
                    {
                        var csItem = CallStack.Peek();

                        if (csItem.LocalVariableScope.ContainsKey(tableName))
                        {
                            tableValue = csItem.LocalVariableScope[tableName];
                        }
                        else if (csItem.ParameterScope.ContainsKey(tableName))
                        {
                            tableValue = csItem.ParameterScope[tableName];
                        }
                    }

                    if (tableValue == null)
                    {
                        if (Environment.SupplementLocalLookupTable.ContainsKey(tableName))
                        {
                            tableValue = Environment.SupplementLocalLookupTable[tableName];
                        }
                        else if (Environment.Globals.ContainsKey(tableName))
                        {
                            tableValue = Environment.Globals[tableName];
                        }

                        else
                        {
                            throw new RuntimeException($"Variable '{tableName}' could not be found in any known scope.", eachLoopNode.TableNode.Line);
                        }
                    }
                }
                else if (eachLoopNode.TableNode is FunctionCallNode fnCallNode)
                {
                    tableValue = Visit(fnCallNode);
                }
                else
                {
                    throw new RuntimeException("Expected a variable or function call.", eachLoopNode.TableNode.Line);
                }

                if (tableValue.Type != DynValueType.Table)
                {
                    throw new RuntimeException($"Expected a table, got {tableValue.Type.ToString().ToLower()}.", eachLoopNode.TableNode.Line);
                }

                var actualTable = tableValue.Table;

                if (Environment.Globals.ContainsKey(keyName))
                {
                    backupKeyVar = Environment.Globals[keyName];
                }

                if (Environment.Globals.ContainsKey(valueName))
                {
                    backupValueVar = Environment.Globals[valueName];
                }

                try
                {
                    foreach (var element in actualTable)
                    {
                        if (Environment.Globals.ContainsKey(keyName))
                        {
                            Environment.Globals.Remove(keyName);
                        }

                        if (Environment.Globals.ContainsKey(valueName))
                        {
                            Environment.Globals.Remove(valueName);
                        }

                        Environment.Globals.Add(keyName, element.Key);
                        Environment.Globals.Add(valueName, element.Value);

                        ExecuteStatementList(eachLoopNode.StatementList).GetAwaiter().GetResult();
                    }
                }
                catch (InvalidOperationException)
                {
                    throw new RuntimeException("The table was modified, cannot continue execution.", eachLoopNode.Line);
                }
                finally
                {
                    Environment.Globals.Remove(keyName);
                    Environment.Globals.Remove(valueName);
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                if (backupKeyVar != null)
                {
                    Environment.Globals.Add(keyName, backupKeyVar);
                }

                if (backupValueVar != null)
                {
                    Environment.Globals.Add(valueName, backupValueVar);
                }

                LoopStack.Pop();
            }

            return(DynValue.Zero);
        }