public override bool Render(RenderContext dest) { if (Values.Count == 0) { dest.Append("{}"); return(true); } dest.Append('{'); dest.Indent(); for (var i = 0; i < Values.Count; i++) { if (i > 0) { dest.Append(','); } dest.StartLine(); // Key - if key is a valid identifier, don't quote it var kp = Values[i]; if (kp.Key.GetType() == typeof(ast.ExprNodeIdentifier)) { dest.Append(dest.Members.GetObfuscatedSymbol(((ast.ExprNodeIdentifier)kp.Key).Name)); } else if (kp.Key.GetType() == typeof(String) && Tokenizer.IsIdentifier((string)kp.Key) && !Tokenizer.IsKeyword((string)kp.Key)) { dest.Append((string)kp.Key); } else { ExprNodeLiteral.RenderValue(dest, kp.Key); } // Value dest.Append(':'); kp.Value.Render(dest); } dest.Unindent(); dest.StartLine(); dest.Append('}'); return(true); }
public override bool Render(RenderContext dest) { if (Lhs != null) { WrapAndRender(dest, Lhs, false); dest.Append("."); dest.Append(dest.Members.GetObfuscatedSymbol(Name)); } else { // Find the symbol and check if it's a constant var s = dest.CurrentScope.FindSymbol(Name); if (s != null && s.ConstValue != null) { ExprNodeLiteral.RenderValue(dest, s.ConstValue); } else { dest.Append(dest.Symbols.GetObfuscatedSymbol(Name)); } } return(true); }
// Parse an expression terminal ast.ExprNode ParseExpressionTerminal(ParseContext ctx) { switch (t.token) { case Token.literal: { var temp = new ast.ExprNodeLiteral(t.GetBookmark(), t.literal); t.Next(); return temp; } case Token.openRound: { var bmk = t.GetBookmark(); t.Next(); var temp = ParseCompositeExpressionNode(0); t.SkipRequired(Token.closeRound); return new ast.ExprNodeParens(bmk, temp); } case Token.identifier: { var temp = new ast.ExprNodeIdentifier(t.GetBookmark(), t.identifier); t.Next(); return temp; } case Token.openSquare: { // Array literal t.Next(); var temp = new ast.ExprNodeArrayLiteral(t.GetBookmark()); while (true) { if (t.token == Token.closeSquare) break; // Empty expression if (t.token == Token.comma) { t.Next(); temp.Values.Add(null); } else { // Non-empty expression temp.Values.Add(ParseSingleExpressionNode(0)); // End of list? if (!t.SkipOptional(Token.comma)) break; } // Trailing blank element? if (t.token == Token.closeSquare) { t.Compiler.RecordWarning(t.GetBookmark(), "trailing comma in array literal"); temp.Values.Add(null); } } t.SkipRequired(Token.closeSquare); return temp; } case Token.openBrace: { // Create the literal var temp = new ast.ExprNodeObjectLiteral(t.GetBookmark()); // Object literal t.Next(); while (true) { if (t.token == Token.closeBrace) break; // Key // - can be an identifier, or string/number literal object key; if (t.token == Token.identifier) { key = new ast.ExprNodeIdentifier(t.GetBookmark(), t.identifier); } else { t.Require(Token.literal); key = t.literal; } t.Next(); // Key/value delimiter t.SkipRequired(Token.colon); // Value temp.Values.Add(new ast.KeyExpressionPair(key, ParseSingleExpressionNode(0))); // Another key/value pair if (!t.SkipOptional(Token.comma)) break; if (t.token == Token.closeBrace) { t.Compiler.RecordWarning(t.GetBookmark(), "trailing comma in object literal"); } } t.SkipRequired(Token.closeBrace); return temp; } case Token.divide: case Token.divideAssign: { // Regular expressions return new ast.ExprNodeRegEx(t.GetBookmark(), t.ParseRegEx()); } case Token.kw_function: { t.Next(); return ParseFunction(); } case Token.kw_new: { var bmk = t.GetBookmark(); t.Next(); // Parse the type var newType = ParseExpressionMember(ctx | ParseContext.NoFunctionCalls); // Create the new operator var newOp = new ast.ExprNodeNew(bmk, newType); // Parse parameters if (t.SkipOptional(Token.openRound)) { if (t.token != Token.closeRound) { while (true) { newOp.Arguments.Add(ParseSingleExpressionNode(0)); if (t.SkipOptional(Token.comma)) continue; else break; } } t.SkipRequired(Token.closeRound); } return newOp; } case Token.kw_delete: { var bmk = t.GetBookmark(); t.Next(); return new ast.ExprNodeUnary(bmk, ParseExpressionMember(ctx), Token.kw_delete); } } throw new CompileError(string.Format("Invalid expression, didn't expect {0}", t.DescribeCurrentToken()), t); }
// Parse an expression terminal ast.ExprNode ParseExpressionTerminal(ParseContext ctx) { switch (t.token) { case Token.literal: { var temp = new ast.ExprNodeLiteral(t.GetBookmark(), t.literal); t.Next(); return(temp); } case Token.openRound: { var bmk = t.GetBookmark(); t.Next(); var temp = ParseCompositeExpressionNode(0); t.SkipRequired(Token.closeRound); return(new ast.ExprNodeParens(bmk, temp)); } case Token.identifier: { var temp = new ast.ExprNodeIdentifier(t.GetBookmark(), t.identifier); t.Next(); return(temp); } case Token.openSquare: { // Array literal t.Next(); var temp = new ast.ExprNodeArrayLiteral(t.GetBookmark()); while (true) { if (t.token == Token.closeSquare) { break; } // Empty expression if (t.token == Token.comma) { t.Next(); temp.Values.Add(null); } else { // Non-empty expression temp.Values.Add(ParseSingleExpressionNode(0)); // End of list? if (!t.SkipOptional(Token.comma)) { break; } } // Trailing blank element? if (t.token == Token.closeSquare) { t.Compiler.RecordWarning(t.GetBookmark(), "trailing comma in array literal"); temp.Values.Add(null); } } t.SkipRequired(Token.closeSquare); return(temp); } case Token.openBrace: { // Create the literal var temp = new ast.ExprNodeObjectLiteral(t.GetBookmark()); // Object literal t.Next(); while (true) { if (t.token == Token.closeBrace) { break; } // Key // - can be an identifier, or string/number literal object key; if (t.token == Token.identifier) { key = new ast.ExprNodeIdentifier(t.GetBookmark(), t.identifier); } else { t.Require(Token.literal); key = t.literal; } t.Next(); // Key/value delimiter t.SkipRequired(Token.colon); // Value temp.Values.Add(new ast.KeyExpressionPair(key, ParseSingleExpressionNode(0))); // Another key/value pair if (!t.SkipOptional(Token.comma)) { break; } if (t.token == Token.closeBrace) { t.Compiler.RecordWarning(t.GetBookmark(), "trailing comma in object literal"); } } t.SkipRequired(Token.closeBrace); return(temp); } case Token.divide: case Token.divideAssign: { // Regular expressions return(new ast.ExprNodeRegEx(t.GetBookmark(), t.ParseRegEx())); } case Token.kw_function: { t.Next(); return(ParseFunction()); } case Token.kw_new: { var bmk = t.GetBookmark(); t.Next(); // Parse the type var newType = ParseExpressionMember(ctx | ParseContext.NoFunctionCalls); // Create the new operator var newOp = new ast.ExprNodeNew(bmk, newType); // Parse parameters if (t.SkipOptional(Token.openRound)) { if (t.token != Token.closeRound) { while (true) { newOp.Arguments.Add(ParseSingleExpressionNode(0)); if (t.SkipOptional(Token.comma)) { continue; } else { break; } } } t.SkipRequired(Token.closeRound); } return(newOp); } case Token.kw_delete: { var bmk = t.GetBookmark(); t.Next(); return(new ast.ExprNodeUnary(bmk, ParseExpressionMember(ctx), Token.kw_delete)); } } throw new CompileError(string.Format("Invalid expression, didn't expect {0}", t.DescribeCurrentToken()), t); }