示例#1
0
        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));
        }
示例#2
0
        // 4.22
        int IExpressionVisitor <int> .VisitComma(CommaExpression expression)
        {
            WriteChildExpression(expression, expression.Left);
            _Writer.Write(", ");
            WriteChildExpression(expression, expression.Right);

            return(0);
        }
示例#3
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; }
示例#6
0
 public void VisitCommaExpression(CommaExpression commaExpression)
 {
     VisitExpression(commaExpression.Left);
     VisitExpression(commaExpression.Right);
 }
示例#7
0
        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);
        }
示例#8
0
        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;
    }
示例#10
0
 public virtual T Visit(CommaExpression colonExpression)
 {
     return(VisitChildren(colonExpression));
 }
示例#11
0
 protected internal virtual void PostWalk(CommaExpression node)
 {
 }
示例#12
0
 // CommaExpression
 protected internal virtual bool Walk(CommaExpression node)
 {
     return(true);
 }