コード例 #1
0
        internal MSA.Expression /*!*/ TransformWrite(AstGenerator /*!*/ gen, Arguments /*!*/ rightValues)
        {
            Debug.Assert(!rightValues.IsEmpty);
            Assert.NotEmpty(_leftValues);

            if (_leftValues.Length == 1)
            {
                // (...) = RHS is equivalent to ... = RHS:
                CompoundLeftValue compound = _leftValues[0] as CompoundLeftValue;
                if (compound != null)
                {
                    return(compound.TransformWrite(gen, rightValues));
                }

                if (!HasUnsplattedValue)
                {
                    return(_leftValues[0].TransformWrite(gen, rightValues.TransformToArray(gen)));
                }
            }

            if (rightValues.Expressions.Length == 1)
            {
                return(TransformWrite(gen, rightValues.Expressions[0].TransformRead(gen), true));
            }
            else
            {
                return(TransformWrite(gen, rightValues.TransformToArray(gen), false));
            }
        }
コード例 #2
0
        public ParallelAssignmentExpression(CompoundLeftValue/*!*/ lhs, CompoundRightValue/*!*/ rhs, SourceSpan location)
            : base(null, location) {
            Assert.NotNull(lhs, rhs);

            _lhs = lhs;
            _rhs = rhs;
        }
コード例 #3
0
 public ForLoopExpression(LexicalScope /*!*/ definedScope, CompoundLeftValue /*!*/ variables, Expression /*!*/ list, Statements body, SourceSpan location)
     : base(location)
 {
     Assert.NotNull(definedScope, variables, list);
     _block = new BlockDefinition(definedScope, variables, body, location);
     _list  = list;
 }
コード例 #4
0
 public ForLoopExpression(CompoundLeftValue/*!*/ variables, Expression/*!*/ list, Statements body, SourceSpan location)
     : base(location) {
     Assert.NotNull(variables, list);
     
     _block = new BlockDefinition(null, variables, body, location);
     _list = list;
 }
コード例 #5
0
ファイル: Walker.cs プロジェクト: stjordanis/ironruby
 internal protected virtual void Walk(CompoundLeftValue /*!*/ node)
 {
     if (Enter(node))
     {
         VisitList(node.LeftValues);
     }
     Exit(node);
 }
コード例 #6
0
        public ParallelAssignmentExpression(CompoundLeftValue /*!*/ lhs, Expression /*!*/[] /*!*/ rhs, SourceSpan location)
            : base(null, location)
        {
            Assert.NotNull(lhs, rhs);

            _lhs = lhs;
            _rhs = rhs;
        }
コード例 #7
0
        public BlockDefinition(LexicalScope definedScope, CompoundLeftValue/*!*/ parameters, List<Expression>/*!*/ body, SourceSpan location)
            : base(location) {
            Assert.NotNull(parameters, body);

            _definedScope = definedScope;
            _body = body;
            _parameters = parameters;
        }
コード例 #8
0
ファイル: BlockDefinition.cs プロジェクト: nieve/ironruby
        public BlockDefinition(LexicalScope/*!*/ definedScope, CompoundLeftValue/*!*/ parameters, Statements/*!*/ body, SourceSpan location)
            : base(location) {
            Assert.NotNull(definedScope, parameters, body);

            _definedScope = definedScope;
            _body = body;
            _parameters = parameters;
        }
コード例 #9
0
        public ForLoopExpression(CompoundLeftValue /*!*/ variables, Expression /*!*/ list, List <Expression> body, SourceSpan location)
            : base(location)
        {
            Assert.NotNull(variables, list);

            _block = new BlockDefinition(null, variables, body, location);
            _list  = list;
        }
コード例 #10
0
        public BlockDefinition(LexicalScope definedScope, CompoundLeftValue /*!*/ parameters, List <Expression> /*!*/ body, SourceSpan location)
            : base(location)
        {
            Assert.NotNull(parameters, body);

            _definedScope = definedScope;
            _body         = body;
            _parameters   = parameters;
        }
コード例 #11
0
ファイル: BlockDefinition.cs プロジェクト: rudimk/dlr-dotnet
        public BlockDefinition(LexicalScope /*!*/ definedScope, CompoundLeftValue /*!*/ parameters, Statements /*!*/ body, SourceSpan location)
            : base(location)
        {
            Assert.NotNull(definedScope, parameters, body);

            _definedScope = definedScope;
            _body         = body;
            _parameters   = parameters;
        }
コード例 #12
0
        internal protected virtual void Walk(CompoundLeftValue /*!*/ node)
        {
            if (Enter(node))
            {
                VisitList(node.LeftValues);

                if (node.UnsplattedValue != null)
                {
                    node.UnsplattedValue.Walk(this);
                }
            }
            Exit(node);
        }
コード例 #13
0
 public virtual bool Enter(CompoundLeftValue /*!*/ node)
 {
     return(true);
 }
コード例 #14
0
        private MSA.Expression /*!*/ TransformWrite(AstGenerator /*!*/ gen, AstExpressions /*!*/ rightValues, MSA.Expression splattedValue)
        {
            // We need to distinguish various special cases here.
            // Each of the bool variables defined below is true iff the corresponding special form of LHS/RHS occurs.
            // These flags drive the DLR AST being produced by this method.
            // For parallel assignment specification, see "Ruby Language.docx/Runtime/Parallel Assignment".

            // L(0,-) not applicable
            Debug.Assert(!(_leftValues.Count == 0 && _unsplattedValue == null));

            // L(1,-)?
            bool leftOneNone = _leftValues.Count == 1 && _unsplattedValue == null;

            // L(0,*)?
            bool leftNoneSplat = _leftValues.Count == 0 && _unsplattedValue != null;

            // R(0,*)?
            bool rightNoneSplat = rightValues.Count == 0 && splattedValue != null;

            // R(1,-)?
            bool rightOneNone = rightValues.Count == 1 && splattedValue == null;

            // R(1,*)?
            bool rightOneSplat = rightValues.Count == 1 && splattedValue != null;

            // R(0,-) not applicable
            Debug.Assert(!(rightValues.Count == 0 && splattedValue == null));

            MSA.Expression resultExpression;

            if (leftOneNone)
            {
                // L(1,-):

                // recurse right away (X) = RHS is equivalent to X = RHS:
                CompoundLeftValue compound = _leftValues[0] as CompoundLeftValue;
                if (compound != null)
                {
                    return(compound.TransformWrite(gen, rightValues, splattedValue));
                }

                if (rightOneSplat)
                {
                    // R(1,*)
                    resultExpression = Methods.SplatPair.OpCall(
                        AstUtils.Box(rightValues[0]),
                        AstUtils.LightDynamic(SplatAction.Make(gen.Context), typeof(IList), splattedValue)
                        );
                }
                else
                {
                    // case 1: R(1,-)
                    // case 2: R(0,*)
                    // case 3: otherwise
                    resultExpression = Arguments.TransformRead(gen, rightValues, splattedValue, true /* Splat */);
                }

                return(_leftValues[0].TransformWrite(gen, resultExpression));
            }

            bool optimizeReads = true;

            if (rightOneNone && !leftNoneSplat)
            {
                // R(1,-) && !L(0,*)
                resultExpression = Methods.Unsplat.OpCall(
                    AstUtils.LightDynamic(ConvertToArraySplatAction.Make(gen.Context), rightValues[0])
                    );
                optimizeReads = false;
            }
            else
            {
                // case 1: R(0,*) = L
                // case 2: otherwise
                resultExpression = Arguments.TransformRead(gen, rightValues, splattedValue, false /* Unsplat */);
                optimizeReads    = !rightNoneSplat;
            }

            var writes = new AstBlock();

            MSA.Expression result = gen.CurrentScope.DefineHiddenVariable("#rhs", typeof(IList));
            writes.Add(Ast.Assign(result, resultExpression));

            MethodInfo itemGetter = Methods.IList_get_Item;

            for (int i = 0; i < _leftValues.Count; i++)
            {
                MSA.Expression rvalue;

                if (optimizeReads)
                {
                    if (i < rightValues.Count)
                    {
                        // unchecked get item:
                        rvalue = Ast.Call(result, itemGetter, AstUtils.Constant(i));
                    }
                    else if (splattedValue != null)
                    {
                        // checked get item:
                        rvalue = Methods.GetArrayItem.OpCall(result, AstUtils.Constant(i));
                    }
                    else
                    {
                        // missing item:
                        rvalue = AstUtils.Constant(null);
                    }
                }
                else
                {
                    rvalue = Methods.GetArrayItem.OpCall(result, AstUtils.Constant(i));
                }

                writes.Add(_leftValues[i].TransformWrite(gen, rvalue));
            }

            // unsplatting the rest of rhs values into an array:
            if (_unsplattedValue != null)
            {
                // copies the rest of resulting array to the *LHS;
                // the resulting array contains splatted *RHS - no need for additional appending:
                MSA.Expression array = Methods.GetArraySuffix.OpCall(result, AstUtils.Constant(_leftValues.Count));

                // assign the array (possibly empty) to *LHS:
                writes.Add(_unsplattedValue.TransformWrite(gen, array));
            }

            writes.Add(result);
            return(writes);
        }
コード例 #15
0
 public virtual void Exit(CompoundLeftValue /*!*/ node)
 {
 }
コード例 #16
0
 public virtual void Exit(CompoundLeftValue/*!*/ node) { }
コード例 #17
0
 public virtual bool Enter(CompoundLeftValue/*!*/ node) { return true; }