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();
            }
        }
Пример #3
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();
                }
            }
        }
        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);
        }
Пример #7
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);
        }