public JavaScriptBlock(int start, JavaScriptBlockType type, JavaScriptBlock parent, JavaScriptTopLevelBlock topLevel, List<JavaScriptToken> tokens)
 {
     Start = start;
     End = start;
     Type = type;
     m_Parent = parent;
     m_TopLevel = topLevel;
     m_Tokens = tokens;
 }
 protected JavaScriptBlock TryParseLVar(MemoryStream<JavaScriptToken> ts)
 {
     int before = ts.Position;
     if (ts.TryMatch((token) => token.Type == JavaScriptTokenType.Identifier))
     {
         JavaScriptBlock block = new JavaScriptBlock(before, JavaScriptBlockType.LVar, this, m_TopLevel, m_Tokens);
         while (true)
         {
             while (block.TryParseBrackets(ts, "[", "]") != null)
                 ;
             if (!ts.TryMatch((token) => token.Type == JavaScriptTokenType.Operator && token.Value == "."))
                 break;
             if (!ts.TryMatch((token) => token.Type == JavaScriptTokenType.Identifier))
                 break;
         }
         block.m_SubBlocks.Clear(); // Don't want sub blocks in LVar blocks.
         AddBlock(block, ts);
         return block;
     }
     return null;
 }
 protected JavaScriptBlock TryParseFunction(MemoryStream<JavaScriptToken> ts)
 {
     int before = ts.Position;
     if (ts.TryMatch((token) => token.Type == JavaScriptTokenType.Keyword && token.Value == "function"))
     {
         JavaScriptBlock block = new JavaScriptBlock(before, JavaScriptBlockType.Function, this, m_TopLevel, m_Tokens);
         block.TryMatchComments(ts);
         block.TryParseLVar(ts); // Too generic for optional function name, but never mind
         block.TryMatchComments(ts);
         block.TryParseBrackets(ts, "(", ")");
         block.TryMatchComments(ts);
         block.m_FunctionBody = block.TryParseBrackets(ts, "{", "}");
         AddBlock(block, ts);
         return block;
     }
     return null;
 }
 protected JavaScriptBlock TryParseBrackets(MemoryStream<JavaScriptToken> ts, string ch, string endCh)
 {
     int before = ts.Position;
     if (ts.TryMatch((token) => token.Type == JavaScriptTokenType.Operator && token.Value == ch))
     {
         JavaScriptBlock block = new JavaScriptBlock(before, JavaScriptBlockType.Brackets, this, m_TopLevel, m_Tokens);
         block.TryParseAny(ts, (token) => token.Type == JavaScriptTokenType.Operator && token.Value == endCh);
         ts.Read();
         AddBlock(block, ts);
         return block;
     }
     return null;
 }
 protected void BuildBlockIndex(JavaScriptBlock[] blockPos)
 {
     int j = 0;
     for (int i = Start; i < End; )
         if (j < m_SubBlocks.Count && m_SubBlocks[j].Start == i)
         {
             m_SubBlocks[j].BuildBlockIndex(blockPos);
             i = m_SubBlocks[j++].End;
         }
         else
         {
             blockPos[i++] = this;
         }
 }
 protected void AddBlock(JavaScriptBlock block, MemoryStream<JavaScriptToken> ts)
 {
     block.End = ts.Position;
     m_SubBlocks.Add(block);
 }