protected virtual CascadeMessageSequenceNode ParseCascadeMessageSequenceNode(ICascadeMessageSequenceParentNode parent, Token semicolon) { // PARSE: <cascaded messages> ::= (';' <messages>)* if (!Parser.IsCascadeDelimiter(semicolon)) { this.ResidueToken = semicolon; return(null); // Not a cascade message ... return null. } CascadeMessageSequenceNode result = new CascadeMessageSequenceNode(parent, (SpecialCharacterToken)semicolon); Token token = this.GetNextTokenxx(Preference.Default); MessageSequenceNode messages = this.ParseMessages(result, token); if (messages == null) { this.ReportParserError(result, SemanticErrors.MissingMessagePattern, token); return(result); } token = this.GetNextTokenxx(Preference.Default); CascadeMessageSequenceNode nextCascade = null; if (Parser.IsCascadeDelimiter(token)) { nextCascade = this.ParseCascadeMessageSequenceNode(result, (SpecialCharacterToken)token); } else { this.ResidueToken = token; } result.SetContents(messages, nextCascade); return(result); }
public override Expression VisitBasicExpression(BasicExpressionNode node) { // First, try to encode inline loop Expression result = this.EncodeInlinedLoop(node); if (result != null) { return(result); } // X3J20 definition: basic_expression ::= primary [messages cascaded_messages]. PrimaryVisitor visitor = new PrimaryVisitor(this); result = node.Primary.Accept(visitor); this.IsConstant = visitor.IsConstant; if (node.Messages != null) { MessageVisitor messageVisitor = new MessageVisitor(this, result, visitor.IsSuperSend, this.IsConstant, (node.CascadeMessages != null)); result = node.Messages.Accept(messageVisitor); this.IsConstant = false; // After first message send, we are no longer a constant // Cascade messages ... this is handled by telling the message-visitor above that we have cascade messages // and need the receiver for cascade messages. The message-visitor has created a temporary variable for us // that contains the result of the next-last message (i.e. the receiver for cascade messages). It has // also noted if the send for that receiver was a super-send and if it is constant (for optimization). CascadeMessageSequenceNode cascade = node.CascadeMessages; if (cascade != null) { List <Expression> cascadeExpressions = new List <Expression>(); cascadeExpressions.Add(result); while (cascade != null) { // Loop and process each cascade in the cascade chain. There is nothing special here. // The receiver, self/super send etc. is determined from the visitor of the original message send. // We create new message-visitor for each cascade iteration, which has fresh receiver // and other parameters. The result of the cascade messages is added to an expression list, // which is converted to expression block. The block fulfills the semantics that the last // expression in the list caries the result of the evaluation (same as required for sacsades). MessageVisitor cascadeVisitor = new MessageVisitor(this, messageVisitor.CascadeReceiver, messageVisitor.CascadeSuperSend, messageVisitor.CascadeConstantReceiver, false); cascadeExpressions.Add(cascade.Messages.Accept(cascadeVisitor)); cascade = cascade.NextCascade; } result = Expression.Block(typeof(object), new ParameterExpression[] { messageVisitor.CascadeReceiver }, cascadeExpressions); } } else if (visitor.IsSuperSend) { throw (new SemanticCodeGenerationException(CodeGenerationErrors.SuperNotFollowedByMessage)).SetErrorLocation(node); } return(result); }
/// <summary> /// Visits the Cascade Message Sequence node. /// </summary> /// <param name="node">The node to visit.</param> public virtual TResult VisitCascadeMessageSequence(CascadeMessageSequenceNode node) { if (node.Messages != null) { node.Messages.Accept(this); } if (node.NextCascade != null) { node.NextCascade.Accept(this); } return(default(TResult)); // The default naive implementation }
protected virtual void ParseBaseicExpressionMessages(BasicExpressionNode expression, IPrimaryNode primary, Token token) { MessageSequenceNode messages = this.ParseMessages(expression, token); if (messages == null) { expression.SetContents(primary, null, null); return; } token = this.GetNextTokenxx(Preference.Default); CascadeMessageSequenceNode cascadeMessages = this.ParseCascadeMessageSequenceNode(expression, token); expression.SetContents(primary, messages, cascadeMessages); }
/// <summary> /// Visits the Cascade Message Sequence node. /// </summary> /// <param name="node">The node to visit.</param> public override bool VisitCascadeMessageSequence(CascadeMessageSequenceNode node) { if (node.Parent == null) { return(false); } if (node.Semicolon == null) { return(false); } if ((node.Messages == null) || !node.Messages.Accept(this)) { return(false); } if ((node.NextCascade != null) && !node.NextCascade.Accept(this)) { return(false); } return(true); }
/// <summary> /// Visits the Cascade Message Sequence node. /// </summary> /// <param name="node">The node to visit.</param> public virtual TResult VisitCascadeMessageSequence(CascadeMessageSequenceNode node) { throw new NotImplementedException(); }