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); }
//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(); } }
//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); }
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); }