private AstNode let(boolean isStatement, int pos)
        throws IOException
    {
        LetNode pn = new LetNode(pos);
        pn.setLineno(ts.lineno);
        if (mustMatchToken(Token.LP, "msg.no.paren.after.let", true))
            pn.setLp(ts.tokenBeg - pos);
        pushScope(pn);
        try {
            VariableDeclaration vars = variables(Token.LET, ts.tokenBeg, isStatement);
            pn.setVariables(vars);
            if (mustMatchToken(Token.RP, "msg.no.paren.let", true)) {
                pn.setRp(ts.tokenBeg - pos);
            }
            if (isStatement && peekToken() == Token.LC) {
                // let statement
                consumeToken();
                int beg = ts.tokenBeg;  // position stmt at LC
                AstNode stmt = statements();
                mustMatchToken(Token.RC, "msg.no.curly.let", true);
                stmt.setLength(ts.tokenEnd - beg);
                pn.setLength(ts.tokenEnd - pos);
                pn.setBody(stmt);
                pn.setType(Token.LET);
            } else {
                // let expression
                AstNode expr = expr();
                pn.setLength(getNodeEnd(expr) - pos);
                pn.setBody(expr);
                if (isStatement) {
                    // let expression in statement context
                    ExpressionStatement es =
                            new ExpressionStatement(pn, !insideFunction());
                    es.setLineno(pn.getLineno());
                    return es;
                }
            }
        } finally {
            popScope();
        }
        return pn;
    }
private AstNode let ( boolean isStatement , int pos ) throws IOException { LetNode pn = new LetNode ( pos ) ; pn . setLineno ( ts . lineno ) ; if ( mustMatchToken ( Token . LP , "msg.no.paren.after.let" , true ) ) pn . setLp ( ts . tokenBeg - pos ) ; pushScope ( pn ) ; try { VariableDeclaration vars = variables ( Token . LET , ts . tokenBeg , isStatement ) ; pn . setVariables ( vars ) ; if ( mustMatchToken ( Token . RP , "msg.no.paren.let" , true ) ) { pn . setRp ( ts . tokenBeg - pos ) ; } if ( isStatement && peekToken ( ) == Token . LC ) { consumeToken ( ) ; int beg = ts . tokenBeg ; AstNode stmt = statements ( ) ; mustMatchToken ( Token . RC , "msg.no.curly.let" , true ) ; stmt . setLength ( ts . tokenEnd - beg ) ; pn . setLength ( ts . tokenEnd - pos ) ; pn . setBody ( stmt ) ; pn . setType ( Token . LET ) ; } else { AstNode expr = expr ( ) ; pn . setLength ( getNodeEnd ( expr ) - pos ) ; pn . setBody ( expr ) ; if ( isStatement ) { ExpressionStatement es = new ExpressionStatement ( pn , ! insideFunction ( ) ) ; es . setLineno ( pn . getLineno ( ) ) ; return es ; } } } finally { popScope ( ) ; } return pn ; }
have to pass in 'let' kwd position to compute kid offsets properly