/// <summary> /// Yields all of the nodes in the tree represented by <paramref name="value"/>, starting at the top. /// /// <para> /// This is a depth-first pre-order traversal. /// </para> /// /// <seealso cref="DescendantsAndSelf"/> /// </summary> /// <example> /// <code> /// Expr expr = new Add( /// new Add( /// new Lit(1), /// new Lit(2) /// ), /// new Lit(3) /// ); /// Expr[] expected = new[] /// { /// expr, /// new Add(new Lit(1), new Lit(2)), /// new Lit(1), /// new Lit(2), /// new Lit(3), /// }; /// Assert.Equal(expected, rewriter.SelfAndDescendants(expr)); /// </code> /// </example> /// <typeparam name="T">The rewritable tree type</typeparam> /// <param name="rewriter">The rewriter</param> /// <param name="value">The value to traverse</param> /// <returns>An enumerable containing all of the nodes in the tree represented by <paramref name="value"/>, starting at the top.</returns> public static IEnumerable <T> SelfAndDescendants <T>(this IRewriter <T> rewriter, T value) { if (rewriter == null) { throw new ArgumentNullException(nameof(rewriter)); } IEnumerable <T> Iterator() { var stack = new ChunkStack <T>(); stack.Allocate(1)[0] = value; try { while (!stack.IsEmpty) { var x = stack.Pop(); yield return(x); var count = rewriter.CountChildren(x); var span = stack.Allocate(count); rewriter.GetChildren(span, x); span.Reverse(); // pop them in left to right order } } finally { stack.Dispose(); } } return(Iterator()); }
public long SyntaxScore(string line) { long score = 0; char chpopped; ChunkStack.Clear(); foreach (var ch in line.ToCharArray()) { switch (ch) { case '(': ChunkStack.Push(ch); break; case ')': chpopped = ChunkStack.Pop(); if (chpopped != '(') { // bad chunk score += 3; } break; case '[': ChunkStack.Push(ch); break; case ']': chpopped = ChunkStack.Pop(); if (chpopped != '[') { // bad chunk score += 57; } break; case '{': ChunkStack.Push(ch); break; case '}': chpopped = ChunkStack.Pop(); if (chpopped != '{') { // bad chunk score += 1197; } break; case '<': ChunkStack.Push(ch); break; case '>': chpopped = ChunkStack.Pop(); if (chpopped != '<') { // bad chunk score += 25137; } break; default: break; } if (score > 0) { break; } } if (score == 0) { // an incomplete row long compScore = 0; while (ChunkStack.Count > 0) { char ch = ChunkStack.Pop(); switch (ch) { case '(': compScore = 5 * compScore + 1; break; case '[': compScore = 5 * compScore + 2; break; case '{': compScore = 5 * compScore + 3; break; case '<': compScore = 5 * compScore + 4; break; default: break; } } CompScores.Add(compScore); } return(score); }