} // ParseLeftHandSideExpression // Parse a PrimaryExpression, filling in info with any declarations. void ParsePrimaryExpression(FunctionInfo info) { string id; double d; string s; if (tok.TryMatchKeyword("this")) { } else if (tok.TryMatchKeyword("null")) { } else if (tok.TryMatchKeyword("true")) { } else if (tok.TryMatchKeyword("false")) { } else if (tok.TryMatchOp("(")) { ParseExpression(info, true); tok.MatchOp(")"); } else if (tok.TryMatchOp("{")) { if (!tok.PeekOp("}")) { do { if (tok.TryMatchNumLit(out d)) { } else if (tok.TryMatchStringLit(out s)) { } else { tok.MatchID(); } tok.MatchOp(":"); ParseExpression(info, true, assignmentPrec); }while (tok.TryMatchOp(",")); } tok.MatchOp("}"); } else if (tok.TryMatchOp("[")) { bool requireComma = false; while (!tok.PeekOp("]")) { if (tok.TryMatchOp(",")) { requireComma = false; } else if (!requireComma) { ParseExpression(info, true, assignmentPrec); requireComma = true; } else { break; } } tok.MatchOp("]"); } else if (tok.TryMatchID(out id)) { if (id == "eval") { info.CallsEval(); } else if (id == "arguments") { info.UsesArgs(); } // If the id is not bound in any enclosing scope, then list it // as a potential global. Note that this is conservative -- it // may actually be bound by a declaration we haven't parsed yet. // // HACK snewman 8/9/01: as currently implemented, this will not // filter out identifiers that are bound by an enclosing "catch" // clause. if (!info.IDHasNonglobalBinding(id)) { info.program.PotentialGlobal(id); } } else if (tok.TryMatchNumLit(out d)) { } else if (tok.TryMatchStringLit(out s)) { } else { tok.Match(); ReportError("bad token when an expression was expected"); } } // ParsePrimaryExpression
} // ParseLeftHandSideExpression // Parse a PrimaryExpression, filling in info with any declarations. void ParsePrimaryExpression(FunctionInfo info) { string id; double d; string s; if (tok.TryMatchKeyword("this")) {} else if (tok.TryMatchKeyword("null")) {} else if (tok.TryMatchKeyword("true")) {} else if (tok.TryMatchKeyword("false")) {} else if (tok.TryMatchOp("(")) { ParseExpression(info, true); tok.MatchOp(")"); } else if (tok.TryMatchOp("{")) { if (!tok.PeekOp("}")) { do { if (tok.TryMatchNumLit(out d)) {} else if (tok.TryMatchStringLit(out s)) {} else tok.MatchID(); tok.MatchOp(":"); ParseExpression(info, true, assignmentPrec); } while (tok.TryMatchOp(",")); } tok.MatchOp("}"); } else if (tok.TryMatchOp("[")) { bool requireComma = false; while (!tok.PeekOp("]")) if (tok.TryMatchOp(",")) requireComma = false; else if (!requireComma) { ParseExpression(info, true, assignmentPrec); requireComma = true; } else break; tok.MatchOp("]"); } else if (tok.TryMatchID(out id)) { if (id == "eval") info.CallsEval(); else if (id == "arguments") info.UsesArgs(); // If the id is not bound in any enclosing scope, then list it // as a potential global. Note that this is conservative -- it // may actually be bound by a declaration we haven't parsed yet. // // HACK snewman 8/9/01: as currently implemented, this will not // filter out identifiers that are bound by an enclosing "catch" // clause. if (!info.IDHasNonglobalBinding(id)) info.program.PotentialGlobal(id); } else if (tok.TryMatchNumLit(out d)) {} else if (tok.TryMatchStringLit(out s)) {} else { tok.Match(); ReportError("bad token when an expression was expected"); } } // ParsePrimaryExpression