} // FunctionExpr // Return an ObjectLiteral expression. public ExprFrag ObjectLiteralExpr(SrcLoc loc, ObjectLiteralInfo litInfo) { StringBuilder builder = new StringBuilder(); builder.Append("Support.LiteralObject("); CSharpObjectLiteral csInfo = (CSharpObjectLiteral)litInfo; bool first = true; foreach (CSharpObjectLiteral.Entry entry in csInfo.entries) { if (first) first = false; else builder.Append(", "); builder.Append("\""); builder.Append(entry.id); builder.Append("\", "); builder.Append(((CSharpExprFrag)entry.value).GenerateRHS()); } builder.Append(")"); return new CSharpRHSExpr(loc, builder.ToString()); } // ObjectLiteralExpr
} // ParseLeftHandSideExpression // Parse a PrimaryExpression. private ExprFrag ParsePrimaryExpression(FunctionInfo info) { string id; double d; string s; if (tok.TryMatchKeyword("this")) return gen.ThisExpr(tok.Prev().loc, info); else if (tok.TryMatchKeyword("null")) return gen.NullExpr(tok.Prev().loc); else if (tok.TryMatchKeyword("true")) return gen.BoolLiteralExpr(tok.Prev().loc, true); else if (tok.TryMatchKeyword("false")) return gen.BoolLiteralExpr(tok.Prev().loc, false); else if (tok.TryMatchOp("(")) { ExprFrag expr = ParseExpression(info, true); tok.MatchOp(")"); return expr; } else if (tok.TryMatchOp("{")) { SrcLoc startLoc = tok.Prev().loc; ObjectLiteralInfo litInfo = gen.NewObjectLiteralInfo(); if (!tok.PeekOp("}")) { do { double tempD; if (tok.TryMatchNumLit(out tempD)) { // HACK snewman 7/26/01: format according to the ECMA spec. id = System.Convert.ToString(tempD); } else if (tok.TryMatchStringLit(out id)) {} else id = tok.MatchID(); SrcLoc idLoc = tok.Prev().loc; tok.MatchOp(":"); ExprFrag value = ParseExpression(info, true, assignmentPrec); litInfo.AddProp(idLoc, id, value); } while (tok.TryMatchOp(",")); } tok.MatchOp("}"); return gen.ObjectLiteralExpr(startLoc, litInfo); } else if (tok.TryMatchOp("[")) { SrcLoc startLoc = tok.Prev().loc; ArrayLiteralInfo arrayInfo = gen.NewArrayLiteralInfo(); bool anyCommas = false; bool requireComma = false; while (!tok.PeekOp("]")) if (tok.TryMatchOp(",")) { anyCommas = true; if (!requireComma) arrayInfo.AddEntry(null); else requireComma = false; } else if (!requireComma) { ExprFrag value = ParseExpression(info, true, assignmentPrec); arrayInfo.AddEntry(value); requireComma = true; } else break; // If the list ends with a comma, then add one more null entry // to the end. if (anyCommas && !requireComma) arrayInfo.AddEntry(null); tok.MatchOp("]"); return gen.ArrayLiteralExpr(startLoc, arrayInfo); } else if (tok.TryMatchID(out id)) { SrcLoc idLoc = tok.Prev().loc; if (id == "eval") return gen.IdentifierExpr(idLoc, id, info, CloneStack(withs)); else if (id == "arguments") return gen.ArgumentsExpr(idLoc, info, CloneStack(withs)); else return gen.IdentifierExpr(idLoc, id, info, CloneStack(withs)); } else if (tok.TryMatchNumLit(out d)) return gen.NumLiteralExpr(tok.Prev().loc, d); else if (tok.TryMatchStringLit(out s)) return gen.StringLiteralExpr(tok.Prev().loc, s); else { // One of the if clauses should fire; if not, the phase 1 // parser would have reported an error. Trace.Assert(false); return null; } } // ParsePrimaryExpression