public override void AfterVisit(NewObjectExpression node) { var args = _expressionStack.Pop(node.ConstructorAgs.Length + 1).ToArray(); _expressionStack.Push(node, this.dynamicCreate(args)); base.AfterVisit(node); }
public virtual void AfterVisit(NewObjectExpression node) { this.AfterVisitCatchAll(node); }
public virtual void BeforeVisit(NewObjectExpression node) { this.BeforeVisitCatchAll(node); }
private ExpressionNodeBase ParseExpression(ExpressionContext context) { if(!isNextTokenAValidForFirstTokenInExpression()) _errorCollector.UnexpectedToken(_lexer.NextToken()); ExpressionNodeBase retval; Stack<AstNodeBase> expStack = new Stack<AstNodeBase>(); Stack<Operator> operatorStack = new Stack<Operator>(); int parenCount = 0; Token currToken = _lexer.PeekToken(); HappySourceLocation startLocation = currToken.Location; Action<Operator> insertOperatorAndUpdateStacks = oper => { while (operatorStack.Count > 0 && operatorStack.Peek().PrecedenceLevel >= oper.PrecedenceLevel) expStack.Push(operatorStack.Pop()); operatorStack.Push(oper); }; if (currToken.HappyTokenKind == HappyTokenKind.LiteralNull) { _lexer.NextToken(); retval = this.PromoteToExpression(currToken); } else { //Rules for existing the while loop below: // Always stop parsing when a keyword other than new is encountered. // If the languageContext is argument list, stop parsing when "," or ")" that is not matched by a corresponding "(" is encountered // if the languageContext is nested parens, stop parsing when ")" that is not matched by a corresponding "(" is encountered // if the languageContext is new statement, stop parsing when "(" is encountered while ( (!currToken.IsKeyword || currToken.HappyTokenKind == HappyTokenKind.KeywordNew) && !(context == ExpressionContext.ArgumentList && currToken.HappyTokenKind == HappyTokenKind.Comma) && !((context == ExpressionContext.NestedParens || context == ExpressionContext.ArgumentList) && parenCount == 0 && currToken.HappyTokenKind == HappyTokenKind.OperatorCloseParen) && !(context == ExpressionContext.Indexer && (currToken.HappyTokenKind == HappyTokenKind.OperatorCloseBracket || currToken.HappyTokenKind == HappyTokenKind.Comma))) { //Check exit conditions first: bool lastWasArithOperator; _lexer.NextToken(); if (currToken.IsOperator) { lastWasArithOperator = false; switch(currToken.HappyTokenKind) { case HappyTokenKind.OperatorOpenParen: parenCount++; break; case HappyTokenKind.OperatorCloseParen: parenCount--; if (parenCount < 0) { HappySourceLocation location = HappySourceLocation.Merge(startLocation, this._lexer.PeekToken().Location); this._errorCollector.MismatchedCloseParen(location); throw new AbortParseException(location); } break; case HappyTokenKind.OperatorOpenBracket: List<ExpressionNodeBase> arguments = new List<ExpressionNodeBase> { this.ParseExpression(ExpressionContext.Indexer) }; while (this.EatNextTokenIf(HappyTokenKind.Comma)) arguments.Add(this.ParseExpression(ExpressionContext.Indexer)); var endsAt = this.Expect(HappyTokenKind.OperatorCloseBracket, "]").Location; var indexOperator = new Operator(currToken); insertOperatorAndUpdateStacks(indexOperator); expStack.Push(new ArgumentList(HappySourceLocation.Merge(currToken.Location, endsAt), arguments.ToArray())); break; default: lastWasArithOperator = true; Operator oper = new Operator(currToken) { PrecedenceLevelModifier = parenCount * Operator.PrecedenceModifierStep }; insertOperatorAndUpdateStacks(oper); break; } } else if(currToken.HappyTokenKind == HappyTokenKind.KeywordNew) { Expect(HappyTokenKind.OperatorOpenParen, "("); ExpressionNodeBase exp = this.ParseExpression(ExpressionContext.ArgumentList); List<ExpressionNodeBase> constructorArgs = new List<ExpressionNodeBase>(); Token commaOrCloseParen = Expect(HappyTokenKind.OperatorCloseParen, HappyTokenKind.Comma, MiscMessages.CommaOrCloseParen); if (commaOrCloseParen.HappyTokenKind == HappyTokenKind.Comma) do { constructorArgs.Add(this.ParseExpression(ExpressionContext.ArgumentList)); commaOrCloseParen = this.Expect(HappyTokenKind.Comma, HappyTokenKind.OperatorCloseParen, MiscMessages.CommaOrCloseParen); } while (commaOrCloseParen.HappyTokenKind != HappyTokenKind.OperatorCloseParen); ExpressionNodeBase newExpression = new NewObjectExpression(currToken.Location, commaOrCloseParen.Location, exp, constructorArgs.ToArray()); expStack.Push(newExpression); lastWasArithOperator = false; } else { expStack.Push(this.PromoteToExpression(currToken)); lastWasArithOperator = false; } currToken = _lexer.PeekToken(); if (!lastWasArithOperator && !currToken.IsOperator && parenCount <= 0) break; } if (parenCount > 0) { HappySourceLocation location = HappySourceLocation.Merge(startLocation, currToken.Location); _errorCollector.MismatchedOpenParen(location); throw new AbortParseException(location); } while (operatorStack.Count > 0) expStack.Push(operatorStack.Pop()); retval = this.RecurseExp(expStack); } return retval; }