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); }
public override Expression VisitKeywordArgument(Compiler.SemanticNodes.KeywordArgumentNode node) { PrimaryVisitor visitor = new PrimaryVisitor(this); Expression result = node.Primary.Accept(visitor); if (node.Messages != null) { result = node.Messages.Accept(new MessageVisitor(this, result, visitor.IsSuperSend, visitor.IsConstant, false)); } else if (visitor.IsSuperSend) { throw (new SemanticCodeGenerationException(CodeGenerationErrors.SuperNotFollowedByMessage)).SetErrorLocation(node); } return(result); }