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;
 }