static Statement MakeTailCallReturn(bool allowtailcall, Expression e) { //if (allowtailcall) { if (e is MethodCallExpression) { MethodCallExpression mce = ((MethodCallExpression)e); mce.TailCall = /*!mce.Method.ReturnType.IsValueType &&*/ allowtailcall; } else if (e is ConditionalExpression) { ConditionalExpression ce = (ConditionalExpression)e; Statement truestmt = OptimizeBody(MakeTailCallReturn(allowtailcall, ce.IfTrue)); Statement falsestmt = OptimizeBody(MakeTailCallReturn(allowtailcall, ce.IfFalse)); return(Ast.IfThenElse(ce.Test, truestmt, falsestmt)); } else if (e is CommaExpression) { CommaExpression ce = (CommaExpression)e; if (ce.ValueIndex + 1 == ce.Expressions.Count) { List <Statement> ss = new List <Statement>(); for (int i = 0; i < ce.Expressions.Count - 1; i++) { ss.Add(Ast.Statement(ce.Expressions[i])); } ss.Add(MakeTailCallReturn(allowtailcall, ce.Expressions[ce.Expressions.Count - 1])); return(OptimizeBody(Ast.Block(ss))); } } else if (e is NewExpression || e is BoundExpression || e is ConstantExpression || e is MemberExpression) { // ignore } else if (e is UnaryExpression && e.NodeType == AstNodeType.Convert) { var op = ((UnaryExpression)e).Operand; if (op is ConditionalExpression) { ConditionalExpression ce = (ConditionalExpression)op; Statement truestmt = OptimizeBody(MakeTailCallReturn(allowtailcall, Ast.ConvertHelper(ce.IfTrue, e.Type))); Statement falsestmt = OptimizeBody(MakeTailCallReturn(allowtailcall, Ast.ConvertHelper(ce.IfFalse, e.Type))); return(Ast.IfThenElse(ce.Test, truestmt, falsestmt)); } } else if (e is VoidExpression) { return(Ast.Return(Ast.Comma(e, Ast.ReadField(null, Unspecified)))); } else { } } return(Ast.Return(e)); }
// 4.22 int IExpressionVisitor <int> .VisitComma(CommaExpression expression) { WriteChildExpression(expression, expression.Left); _Writer.Write(", "); WriteChildExpression(expression, expression.Right); return(0); }
private static int RelocateVar(BlockStatement block, int insertAt, VarDeclaration varStatement) { var forInParent = varStatement.Parent as ForInStatement; if (forInParent != null) { insertAt = ReorderScopeVisitor.RelocateForInVar(block, insertAt, varStatement, forInParent); } else { // if the var statement is at the next position to insert, then we don't need // to do anything. if (block[insertAt] != varStatement) { // check to see if the current position is a var and we are the NEXT statement. // if that's the case, we don't need to break out the initializer, just append all the // vardecls as-is to the current position. ForStatement forStatement; var existingVar = block[insertAt] as VarDeclaration; if (existingVar != null && block[insertAt + 1] == varStatement) { // two var-s one right after the other. // just append our vardecls to the insertion point, then delete our statement existingVar.Append(varStatement); block.RemoveAt(insertAt + 1); } else if (existingVar != null && (forStatement = varStatement.Parent as ForStatement) != null && forStatement.Initializer == varStatement && forStatement == block[insertAt + 1]) { // this var statement is the initializer of a for-statement, which is // immediately after the var we would insert our vardecls into. // rather than moving our vardecls into the outside var-statement, let's // move the outside var-statement into our for-statement. varStatement.InsertAt(0, existingVar); block.RemoveAt(insertAt); } else { // iterate through the decls and count how many have initializers var initializerCount = 0; for (var ndx = 0; ndx < varStatement.Count; ++ndx) { // count the number of vardecls with initializers if (varStatement[ndx].Initializer != null) { ++initializerCount; } } // if there are more than two decls with initializers, then we won't actually // be gaining anything by moving the var to the top. We'll get rid of the four // bytes for the "var ", but we'll be adding two bytes for the name and comma // because name=init will still need to remain behind. if (initializerCount <= 2) { // first iterate through all the declarations in the var statement, // constructing an expression statement that is made up of assignment // operators for each of the declarations that have initializers (if any) // and removing all the initializers var assignments = new List <AstNode>(); for (var ndx = 0; ndx < varStatement.Count; ++ndx) { var varDecl = varStatement[ndx]; if (varDecl.Initializer != null) { // hold on to the object so we don't lose it to the GC var initializer = varDecl.Initializer; // remove it from the vardecl varDecl.Initializer = null; var reference = BindingTransform.FromBinding(varDecl.Binding); if (varDecl.IsCCSpecialCase) { // we don't want to add the special-case to the binary operator class, // so just create a copy of the vardecl for this location, using a reference // for the "binding" assignments.Add(new VariableDeclaration(varDecl.Context) { Binding = reference, AssignContext = varDecl.AssignContext, Initializer = initializer, IsCCSpecialCase = true, UseCCOn = varDecl.UseCCOn, TerminatingContext = varDecl.TerminatingContext }); } else { assignments.Add(new BinaryExpression(varDecl.Context) { Operand1 = reference, Operand2 = initializer, OperatorToken = JSToken.Assign, OperatorContext = varDecl.AssignContext }); } } // if the vardecl we are moving isn't a binding pattern, we need to // break it down into a simple list of names. if (!(varDecl.Binding is BindingIdentifier)) { // place the original vardecl with the first one var first = true; foreach (var declName in BindingsVisitor.Bindings(varDecl.Binding)) { if (first) { varStatement[ndx] = new VariableDeclaration(declName.Context) { Binding = new BindingIdentifier(declName.Context) { Name = declName.Name, VariableField = declName.VariableField } }; first = false; } else { // otherwise we want to insert a new one at the current position + 1 varStatement.InsertAt(++ndx, new VariableDeclaration(declName.Context) { Binding = new BindingIdentifier(declName.Context) { Name = declName.Name, VariableField = declName.VariableField } }); } } } } // now if there were any initializers... if (assignments.Count > 0) { // we want to create one big expression from all the assignments and replace the // var statement with the assignment(s) expression. Start at position n=1 and create // a binary operator of n-1 as the left, n as the right, and using a comma operator. var expression = assignments[0]; for (var ndx = 1; ndx < assignments.Count; ++ndx) { expression = CommaExpression.CombineWithComma(expression.Context.FlattenToStart(), expression, assignments[ndx]); } // replace the var with the expression. // we still have a pointer to the var, so we can insert it back into the proper // place next. varStatement.Parent.ReplaceChild(varStatement, expression); } else { // no initializers. // just remove the var statement altogether varStatement.Parent.ReplaceChild(varStatement, null); } // if the statement at the insertion point is a var-statement already, // then we just need to append our vardecls to it. Otherwise we'll insert our // var statement at the right point if (existingVar != null) { // append the varstatement we want to move to the existing var, which will // transfer all the vardecls to it. existingVar.Append(varStatement); } else { // move the var to the insert point, incrementing the position or next time block.Insert(insertAt, varStatement); } } } } } return(insertAt); }
protected internal virtual void PostWalk(CommaExpression node) { }
// CommaExpression protected internal virtual bool Walk(CommaExpression node) { return true; }
public void VisitCommaExpression(CommaExpression commaExpression) { VisitExpression(commaExpression.Left); VisitExpression(commaExpression.Right); }
public static AstNode CombineWithComma(SourceContext context, AstNode operand1, AstNode operand2) { var comma = new CommaExpression(context); // if the left is a comma-operator already.... var leftBinary = operand1 as BinaryExpression; var rightBinary = operand2 as BinaryExpression; if (leftBinary != null && leftBinary.OperatorToken == JSToken.Comma) { // the left-hand side is already a comma operator. Instead of nesting these, we're // going to combine them // move the old list's left-hand side to our left-hand side comma.Operand1 = leftBinary.Operand1; AstNodeList list; if (rightBinary != null && rightBinary.OperatorToken == JSToken.Comma) { // the right is ALSO a comma operator. Create a new list, append all the rest of the operands // and set our right-hand side to be the list list = new AstNodeList(leftBinary.Context.FlattenToStart()); list.Append(leftBinary.Operand2).Append(rightBinary.Operand1).Append(rightBinary.Operand2); } else { // the right is not a comma operator. // see if the left-hand side already has a list we can use list = leftBinary.Operand2 as AstNodeList; if (list == null) { // it's not a list already // create a new list with the left's right and our right and set it to our right list = new AstNodeList(leftBinary.Operand2.Context.FlattenToStart()); list.Append(leftBinary.Operand2); } // and add our right-hand operand to the end of the list list.Append(operand2); } // set the list on the right comma.Operand2 = list; } else if (rightBinary != null && rightBinary.OperatorToken == JSToken.Comma) { // the left hand side is NOT a comma operator. comma.Operand1 = operand1; // the right-hand side is already a comma-operator, but the left is not. // see if it already has a list we can reuse var rightList = rightBinary.Operand2 as AstNodeList; if (rightList != null) { // it does. Prepend its right-hand operand and use the list rightList.Insert(0, rightBinary.Operand1); } else { // it's not -- create a new list containing the operands rightList = new AstNodeList(rightBinary.Context); rightList.Append(rightBinary.Operand1); rightList.Append(rightBinary.Operand2); } comma.Operand2 = rightList; } else { comma.Operand1 = operand1; comma.Operand2 = operand2; } return(comma); }
static AstNode CreateSplitNodeFromEnd(AstNodeList nodeList, int ndx) { AstNode newNode; if (ndx == nodeList.Count - 1) { // the LAST one can be broken. Pull it off the list and we will just // insert it after the current node. newNode = nodeList[ndx]; nodeList.RemoveAt(ndx); } else if (ndx == nodeList.Count - 2) { // the PENULTIMATE item can be broken. So create a new comma operator // with the just the last two item and we'll insert it after the current node var left = nodeList[ndx]; nodeList.RemoveAt(ndx); var right = nodeList[ndx]; nodeList.RemoveAt(ndx); newNode = new CommaExpression(left.Context.FlattenToStart()) { Operand1 = left, Operand2 = right }; } else { // at least three items will be pulled off, which means there will // be at least two items on the right, so we'll create a new astlist to // insert those items into a new comma operator var left = nodeList[ndx]; nodeList.RemoveAt(ndx); // if we were passed zero, then just reuse the node list. // otherwise we need to create a new one and move the items // from the index position over. AstNodeList right; if (ndx == 0) { right = nodeList; } else { right = new AstNodeList(nodeList[ndx].Context.FlattenToStart()); while (ndx < nodeList.Count) { var temp = nodeList[ndx]; nodeList.RemoveAt(ndx); right.Append(temp); } } newNode = new CommaExpression(left.Context.FlattenToStart()) { Operand1 = left, Operand2 = right }; } return(newNode); }
// $ANTLR start "expression" // JavaScript.g:206:1: expression : n= assignmentExpression ( ( ( LT )* ',' ( LT )* assignmentExpression ) ( ( LT )* ',' ( LT )* assignmentExpression )* )? ; public JavaScriptParser.expression_return expression() // throws RecognitionException [1] { JavaScriptParser.expression_return retval = new JavaScriptParser.expression_return(); retval.Start = input.LT(1); object root_0 = null; IToken LT228 = null; IToken char_literal229 = null; IToken LT230 = null; IToken LT232 = null; IToken char_literal233 = null; IToken LT234 = null; JavaScriptParser.assignmentExpression_return n = default(JavaScriptParser.assignmentExpression_return); JavaScriptParser.assignmentExpression_return assignmentExpression231 = default(JavaScriptParser.assignmentExpression_return); JavaScriptParser.assignmentExpression_return assignmentExpression235 = default(JavaScriptParser.assignmentExpression_return); object LT228_tree=null; object char_literal229_tree=null; object LT230_tree=null; object LT232_tree=null; object char_literal233_tree=null; object LT234_tree=null; try { // JavaScript.g:207:2: (n= assignmentExpression ( ( ( LT )* ',' ( LT )* assignmentExpression ) ( ( LT )* ',' ( LT )* assignmentExpression )* )? ) // JavaScript.g:207:4: n= assignmentExpression ( ( ( LT )* ',' ( LT )* assignmentExpression ) ( ( LT )* ',' ( LT )* assignmentExpression )* )? { root_0 = (object)adaptor.GetNilNode(); PushFollow(FOLLOW_assignmentExpression_in_expression1751); n = assignmentExpression(); state.followingStackPointer--; if (state.failed) return retval; if ( state.backtracking == 0 ) adaptor.AddChild(root_0, n.Tree); // JavaScript.g:207:27: ( ( ( LT )* ',' ( LT )* assignmentExpression ) ( ( LT )* ',' ( LT )* assignmentExpression )* )? int alt124 = 2; alt124 = dfa124.Predict(input); switch (alt124) { case 1 : // JavaScript.g:207:28: ( ( LT )* ',' ( LT )* assignmentExpression ) ( ( LT )* ',' ( LT )* assignmentExpression )* { // JavaScript.g:207:28: ( ( LT )* ',' ( LT )* assignmentExpression ) // JavaScript.g:207:29: ( LT )* ',' ( LT )* assignmentExpression { // JavaScript.g:207:31: ( LT )* do { int alt119 = 2; int LA119_0 = input.LA(1); if ( (LA119_0 == LT) ) { alt119 = 1; } switch (alt119) { case 1 : // JavaScript.g:207:31: LT { LT228=(IToken)Match(input,LT,FOLLOW_LT_in_expression1755); if (state.failed) return retval; } break; default: goto loop119; } } while (true); loop119: ; // Stops C# compiler whining that label 'loop119' has no statements char_literal229=(IToken)Match(input,43,FOLLOW_43_in_expression1759); if (state.failed) return retval; if ( state.backtracking == 0 ) {char_literal229_tree = new CommaExpression(char_literal229) ; root_0 = (object)adaptor.BecomeRoot(char_literal229_tree, root_0); } // JavaScript.g:207:58: ( LT )* do { int alt120 = 2; int LA120_0 = input.LA(1); if ( (LA120_0 == LT) ) { alt120 = 1; } switch (alt120) { case 1 : // JavaScript.g:207:58: LT { LT230=(IToken)Match(input,LT,FOLLOW_LT_in_expression1765); if (state.failed) return retval; } break; default: goto loop120; } } while (true); loop120: ; // Stops C# compiler whining that label 'loop120' has no statements PushFollow(FOLLOW_assignmentExpression_in_expression1769); assignmentExpression231 = assignmentExpression(); state.followingStackPointer--; if (state.failed) return retval; if ( state.backtracking == 0 ) adaptor.AddChild(root_0, assignmentExpression231.Tree); } // JavaScript.g:207:83: ( ( LT )* ',' ( LT )* assignmentExpression )* do { int alt123 = 2; alt123 = dfa123.Predict(input); switch (alt123) { case 1 : // JavaScript.g:207:84: ( LT )* ',' ( LT )* assignmentExpression { // JavaScript.g:207:86: ( LT )* do { int alt121 = 2; int LA121_0 = input.LA(1); if ( (LA121_0 == LT) ) { alt121 = 1; } switch (alt121) { case 1 : // JavaScript.g:207:86: LT { LT232=(IToken)Match(input,LT,FOLLOW_LT_in_expression1773); if (state.failed) return retval; } break; default: goto loop121; } } while (true); loop121: ; // Stops C# compiler whining that label 'loop121' has no statements char_literal233=(IToken)Match(input,43,FOLLOW_43_in_expression1777); if (state.failed) return retval; // JavaScript.g:207:96: ( LT )* do { int alt122 = 2; int LA122_0 = input.LA(1); if ( (LA122_0 == LT) ) { alt122 = 1; } switch (alt122) { case 1 : // JavaScript.g:207:96: LT { LT234=(IToken)Match(input,LT,FOLLOW_LT_in_expression1780); if (state.failed) return retval; } break; default: goto loop122; } } while (true); loop122: ; // Stops C# compiler whining that label 'loop122' has no statements PushFollow(FOLLOW_assignmentExpression_in_expression1784); assignmentExpression235 = assignmentExpression(); state.followingStackPointer--; if (state.failed) return retval; if ( state.backtracking == 0 ) adaptor.AddChild(root_0, assignmentExpression235.Tree); } break; default: goto loop123; } } while (true); loop123: ; // Stops C# compiler whining that label 'loop123' has no statements } break; } } retval.Stop = input.LT(-1); if ( (state.backtracking==0) ) { retval.Tree = (object)adaptor.RulePostProcessing(root_0); adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);} } catch (RecognitionException re) { ReportError(re); Recover(input,re); // Conversion of the second argument necessary, but harmless retval.Tree = (object)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re); } finally { } return retval; }
public virtual T Visit(CommaExpression colonExpression) { return(VisitChildren(colonExpression)); }
// CommaExpression protected internal virtual bool Walk(CommaExpression node) { return(true); }