コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }