示例#1
0
        public override void OnSlicingExpression(SlicingExpression node)
        {
            BoundSpillSequenceBuilder builder = null;
            var target = VisitExpression(ref builder, node.Target);

            BoundSpillSequenceBuilder indicesBuilder = null;
            var indices = VisitSliceCollection(ref indicesBuilder, node.Indices);

            if (indicesBuilder != null)
            {
                // spill the array if there were await expressions in the indices
                if (builder == null)
                {
                    builder = new BoundSpillSequenceBuilder();
                }

                target = Spill(builder, target);
            }

            if (builder != null)
            {
                builder.Include(indicesBuilder);
                indicesBuilder = builder;
            }
            node.Target  = target;
            node.Indices = indices;
            ReplaceCurrentNode(UpdateExpression(indicesBuilder, node));
        }
        void ProcessDuckSlicingPropertySet(BinaryExpression node)
        {
            SlicingExpression slice = (SlicingExpression)node.Left;

            ArrayLiteralExpression args = new ArrayLiteralExpression();

            foreach (Slice index in slice.Indices)
            {
                if (AstUtil.IsComplexSlice(index))
                {
                    throw CompilerErrorFactory.NotImplemented(index, "complex slice for duck");
                }
                args.Items.Add(index.Begin);
            }
            args.Items.Add(node.Right);
            BindExpressionType(args, TypeSystemServices.ObjectArrayType);

            Expression target     = slice.Target;
            string     memberName = "";

            if (NodeType.MemberReferenceExpression == target.NodeType)
            {
                MemberReferenceExpression mre = ((MemberReferenceExpression)target);
                target     = mre.Target;
                memberName = mre.Name;
            }

            MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation(
                RuntimeServices_SetSlice,
                target,
                CodeBuilder.CreateStringLiteral(memberName),
                args);

            Replace(mie);
        }
示例#3
0
 override public void OnSlicingExpression(SlicingExpression node)
 {
     Visit(node.Target);
     Write("[");
     WriteCommaSeparatedList(node.Indices);
     Write("]");
 }
 void CompleteOmittedExpressions(SlicingExpression node)
 {
     foreach (var index in node.Indices.Where(slice => slice.Begin == OmittedExpression.Default))
     {
         index.Begin = CodeBuilder.CreateIntegerLiteral(0);
     }
 }
        private MethodInvocationExpression ComplexStringSlicingExpressionFor(SlicingExpression node)
        {
            var slice = node.Indices[0];

            if (IsNullOrOmitted(slice.End))
            {
                if (NeedsNormalization(slice.Begin))
                {
                    var mie = CodeBuilder.CreateEvalInvocation(node.LexicalInfo);
                    mie.ExpressionType = TypeSystemServices.StringType;

                    var temp = DeclareTempLocal(TypeSystemServices.StringType);
                    mie.Arguments.Add(
                        CodeBuilder.CreateAssignment(
                            CodeBuilder.CreateReference(temp),
                            node.Target));

                    mie.Arguments.Add(
                        CodeBuilder.CreateMethodInvocation(
                            CodeBuilder.CreateReference(temp),
                            MethodCache.String_Substring_Int,
                            CodeBuilder.CreateMethodInvocation(
                                MethodCache.RuntimeServices_NormalizeStringIndex,
                                CodeBuilder.CreateReference(temp),
                                slice.Begin)));

                    return(mie);
                }
                return(CodeBuilder.CreateMethodInvocation(node.Target, MethodCache.String_Substring_Int, slice.Begin));
            }
            return(CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_Mid, node.Target, slice.Begin, slice.End));
        }
        void ImplementRegularICallableCall(
            Method call,
            InternalCallableType type,
            ClassDefinition node,
            CallableSignature signature)
        {
            MethodInvocationExpression mie = CreateInvokeInvocation(type);

            IParameter[] parameters = signature.Parameters;
            for (int i = 0; i < parameters.Length; ++i)
            {
                SlicingExpression slice = CodeBuilder.CreateSlicing(
                    CodeBuilder.CreateReference(call.Parameters[0]),
                    i);
                mie.Arguments.Add(slice);
            }

            if (TypeSystemServices.VoidType == signature.ReturnType)
            {
                call.Body.Add(mie);
            }
            else
            {
                call.Body.Add(new ReturnStatement(mie));
            }
        }
示例#7
0
        public override void PropagateChanges(MethodInvocationExpression eval, List chain)
        {
            ExpressionCollection items = new ExpressionCollection();

            foreach (object local1 in chain.Reversed)
            {
                if (!(local1 is ProcessAssignmentsToSpecialMembers.ChainItem))
                {
                }
                ProcessAssignmentsToSpecialMembers.ChainItem item = (ProcessAssignmentsToSpecialMembers.ChainItem)RuntimeServices.Coerce(local1, typeof(ProcessAssignmentsToSpecialMembers.ChainItem));
                if (item.Container is MethodInvocationExpression)
                {
                    break;
                }
                if (item.Container is SlicingExpression)
                {
                    SlicingExpression expression       = (SlicingExpression)item.Container;
                    Expression[]      expressionArray1 = new Expression[] { expression.Target.CloneNode(), expression.Indices[0].Begin.CloneNode(), this.CodeBuilder.CreateReference(item.Local) };
                    items.Add(this.CreateConstructorInvocation(this._sliceValueTypeChangeConstructor, expressionArray1));
                    break;
                }
                MemberReferenceExpression container = (MemberReferenceExpression)item.Container;
                Expression[] args = new Expression[] { container.Target.CloneNode(), this.CodeBuilder.CreateStringLiteral(container.Name), this.CodeBuilder.CreateReference(item.Local) };
                items.Add(this.CreateConstructorInvocation(this._valueTypeChangeConstructor, args));
            }
            MethodInvocationExpression expression3 = this.CodeBuilder.CreateMethodInvocation(this._propagateChanges);
            IArrayType arrayType = this._valueTypeChangeType.MakeArrayType(1);

            expression3.Arguments.Add(this.CodeBuilder.CreateArray(arrayType, items));
            eval.Arguments.Add(expression3);
        }
示例#8
0
        private static SlicingExpression CreateRawArraySlicing(ReferenceExpression arrayRef, Expression numRef, IType elementType)
        {
            SlicingExpression expression = new SlicingExpression(arrayRef.CloneNode(), numRef.CloneNode());

            expression.ExpressionType = elementType;
            AstAnnotations.MarkRawArrayIndexing(expression);
            return(expression);
        }
示例#9
0
        public override void Switch(IAstTransformer transformer, out Node resultingNode)
        {
            SlicingExpression thisNode           = (SlicingExpression)this;
            Expression        resultingTypedNode = thisNode;

            transformer.OnSlicingExpression(thisNode, ref resultingTypedNode);
            resultingNode = resultingTypedNode;
        }
示例#10
0
 private static string GetSlicingMemberName(SlicingExpression node)
 {
     if (NodeType.MemberReferenceExpression == node.Target.NodeType)
     {
         MemberReferenceExpression mre = ((MemberReferenceExpression)node.Target);
         return(mre.Name);
     }
     return("");
 }
示例#11
0
        private ArrayLiteralExpression GetArrayForIndices(SlicingExpression node)
        {
            var args = new ArrayLiteralExpression();

            foreach (var index in node.Indices)
            {
                args.Items.Add(index.Begin);
            }
            BindExpressionType(args, TypeSystemServices.ObjectArrayType);
            return(args);
        }
示例#12
0
 override public void LeaveSlicingExpression(SlicingExpression node)
 {
     if (IsDuckTyped(node.Target))
     {
         BindDuck(node);
     }
     else
     {
         base.LeaveSlicingExpression(node);
     }
 }
示例#13
0
        override public void OnSlicingExpression(SlicingExpression node)
        {
            var tern = ProcessTargets(node);

            if (tern != null)
            {
                Visit(node.Indices);
                ReplaceCurrentNode(tern);
            }
            base.OnSlicingExpression(node);
        }
示例#14
0
        private static Expression GetSlicingTarget(SlicingExpression node)
        {
            Expression target = node.Target;

            if (NodeType.MemberReferenceExpression == target.NodeType)
            {
                MemberReferenceExpression mre = ((MemberReferenceExpression)target);
                return(mre.Target);
            }
            return(target);
        }
        void ExpandComplexArraySlicing(SlicingExpression node)
        {
            if (node.Indices.Count > 1)
            {
                MethodInvocationExpression mie = null;
                var computeEnd = new ArrayLiteralExpression();
                var collapse   = new ArrayLiteralExpression();
                var ranges     = new ArrayLiteralExpression();
                for (int i = 0; i < node.Indices.Count; i++)
                {
                    ranges.Items.Add(node.Indices[i].Begin);
                    if (node.Indices[i].End == null)
                    {
                        var end = new BinaryExpression(BinaryOperatorType.Addition, node.Indices[i].Begin, new IntegerLiteralExpression(1));
                        ranges.Items.Add(end);
                        BindExpressionType(end, GetExpressionType(node.Indices[i].Begin));
                        computeEnd.Items.Add(new BoolLiteralExpression(false));
                        collapse.Items.Add(new BoolLiteralExpression(true));
                    }
                    else if (node.Indices[i].End == OmittedExpression.Default)
                    {
                        var end = new IntegerLiteralExpression(0);
                        ranges.Items.Add(end);
                        BindExpressionType(end, GetExpressionType(node.Indices[i].Begin));
                        computeEnd.Items.Add(new BoolLiteralExpression(true));
                        collapse.Items.Add(new BoolLiteralExpression(false));
                    }
                    else
                    {
                        ranges.Items.Add(node.Indices[i].End);
                        computeEnd.Items.Add(new BoolLiteralExpression(false));
                        collapse.Items.Add(new BoolLiteralExpression(false));
                    }
                }
                mie = CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_GetMultiDimensionalRange1, node.Target, ranges);
                mie.Arguments.Add(computeEnd);
                mie.Arguments.Add(collapse);

                BindExpressionType(ranges, TypeSystemServices.Map(typeof(int[])));
                BindExpressionType(computeEnd, TypeSystemServices.Map(typeof(bool[])));
                BindExpressionType(collapse, TypeSystemServices.Map(typeof(bool[])));
                node.ParentNode.Replace(node, mie);
            }
            else
            {
                var slice = node.Indices[0];
                var mie   = IsNullOrOmitted(slice.End)
                                        ? CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_GetRange1, node.Target, slice.Begin)
                                        : CodeBuilder.CreateMethodInvocation(MethodCache.RuntimeServices_GetRange2, node.Target, slice.Begin, slice.End);
                node.ParentNode.Replace(node, mie);
            }
        }
示例#16
0
        private ArrayLiteralExpression GetArrayForIndices(SlicingExpression node)
        {
            ArrayLiteralExpression args = new ArrayLiteralExpression();

            foreach (Slice index in node.Indices)
            {
                if (AstUtil.IsComplexSlice(index))
                {
                    throw CompilerErrorFactory.NotImplemented(index, "complex slice for duck");
                }
                args.Items.Add(index.Begin);
            }
            BindExpressionType(args, TypeSystemServices.ObjectArrayType);
            return(args);
        }
示例#17
0
 private void ProcessAssignment(BinaryExpression node)
 {
     if (NodeType.SlicingExpression == node.Left.NodeType)
     {
         SlicingExpression slice = (SlicingExpression)node.Left;
         if (IsDuckTyped(slice.Target))
         {
             ProcessDuckSlicingPropertySet(node);
         }
     }
     else if (TypeSystemServices.IsQuackBuiltin(node.Left))
     {
         ProcessQuackPropertySet(node);
     }
 }
示例#18
0
        public SlicingExpression CreateSlicing(Expression target, int begin)
        {
            SlicingExpression expression = new SlicingExpression(target,
                                                                 CreateIntegerLiteral(begin));

            IType      expressionType = _tss.ObjectType;
            IArrayType arrayType      = target.ExpressionType as IArrayType;

            if (null != arrayType)
            {
                expressionType = arrayType.GetElementType();
            }
            expression.ExpressionType = expressionType;
            return(expression);
        }
示例#19
0
        public override void OnSlicingExpression(SlicingExpression node)
        {
            base.OnSlicingExpression(node);

            var arrayType = GetExpressionType(node.Target) as IArrayType;

            if (arrayType == null)
            {
                return;
            }

            if (arrayType.Rank != node.Indices.Count)
            {
                Error(CompilerErrorFactory.InvalidArrayRank(node, node.Target.ToCodeString(), arrayType.Rank, node.Indices.Count));
            }
        }
示例#20
0
 public override void OnSlicingExpression(SlicingExpression node)
 {
     Switch(node.Target);
     Write("[");
     Switch(node.Begin);
     if (null != node.End || WasOmitted(node.Begin))
     {
         Write(":");
     }
     Switch(node.End);
     if (null != node.Step)
     {
         Write(":");
         Switch(node.Step);
     }
     Write("]");
 }
示例#21
0
        void ProcessDuckSlicingPropertySet(BinaryExpression node)
        {
            SlicingExpression slice = (SlicingExpression)node.Left;

            ArrayLiteralExpression args = GetArrayForIndices(slice);

            args.Items.Add(node.Right);

            MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation(
                node.LexicalInfo,
                RuntimeServices_SetSlice,
                GetSlicingTarget(slice),
                CodeBuilder.CreateStringLiteral(GetSlicingMemberName(slice)),
                args);

            Replace(mie);
        }
        public override void OnSlicingExpression(SlicingExpression node)
        {
            base.OnSlicingExpression(node);

            if (!node.IsComplexSlicing())
            {
                return;
            }

            if (node.IsTargetOfAssignment())
            {
                return;
            }

            CompleteOmittedExpressions(node);
            ExpandComplexSlicing(node);
        }
示例#23
0
        void ImplementRegularICallableCall(
            Method call,
            InternalCallableType type,
            ClassDefinition node,
            CallableSignature signature)
        {
            MethodInvocationExpression mie = CreateInvokeInvocation(type);

            IParameter[] parameters            = signature.Parameters;
            int          fixedParametersLength = signature.AcceptVarArgs ? parameters.Length - 1 : parameters.Length;

            for (int i = 0; i < fixedParametersLength; ++i)
            {
                SlicingExpression slice = CodeBuilder.CreateSlicing(
                    CodeBuilder.CreateReference(call.Parameters[0]),
                    i);
                mie.Arguments.Add(slice);
            }

            if (signature.AcceptVarArgs)
            {
                if (parameters.Length == 1)
                {
                    mie.Arguments.Add(CodeBuilder.CreateReference(call.Parameters[0]));
                }
                else
                {
                    mie.Arguments.Add(
                        CodeBuilder.CreateMethodInvocation(
                            RuntimeServices_GetRange1,
                            CodeBuilder.CreateReference(call.Parameters[0]),
                            CodeBuilder.CreateIntegerLiteral(fixedParametersLength)));
                }
            }

            if (TypeSystemServices.VoidType == signature.ReturnType)
            {
                call.Body.Add(mie);
            }
            else
            {
                call.Body.Add(new ReturnStatement(mie));
            }
            CheckMethodGenerics(call, node);
        }
示例#24
0
        override public void LeaveSlicingExpression(SlicingExpression node)
        {
            if (!IsDuckTyped(node.Target))
            {
                return;
            }
            if (AstUtil.IsLhsOfAssignment(node))
            {
                return;
            }

            // todo
            // a[foo]
            // RuntimeServices.GetSlice(a, "", (foo,))
            ArrayLiteralExpression args = new ArrayLiteralExpression();

            foreach (Slice index in node.Indices)
            {
                if (AstUtil.IsComplexSlice(index))
                {
                    throw CompilerErrorFactory.NotImplemented(index, "complex slice for duck");
                }
                args.Items.Add(index.Begin);
            }
            BindExpressionType(args, TypeSystemServices.ObjectArrayType);

            Expression target     = node.Target;
            string     memberName = "";

            if (NodeType.MemberReferenceExpression == target.NodeType)
            {
                MemberReferenceExpression mre = ((MemberReferenceExpression)target);
                target     = mre.Target;
                memberName = mre.Name;
            }

            MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation(
                RuntimeServices_GetSlice,
                target,
                CodeBuilder.CreateStringLiteral(memberName),
                args);

            Replace(mie);
        }
        void ExpandComplexListSlicing(SlicingExpression node)
        {
            var slice = node.Indices[0];

            MethodInvocationExpression mie;

            if (IsNullOrOmitted(slice.End))
            {
                mie = CodeBuilder.CreateMethodInvocation(node.Target, MethodCache.List_GetRange1);
                mie.Arguments.Add(slice.Begin);
            }
            else
            {
                mie = CodeBuilder.CreateMethodInvocation(node.Target, MethodCache.List_GetRange2);
                mie.Arguments.Add(slice.Begin);
                mie.Arguments.Add(slice.End);
            }
            node.ParentNode.Replace(node, mie);
        }
示例#26
0
        public override void OnSlicingExpression(SlicingExpression node)
        {
            ClearResult();
            Visit(node.Target);
            if (node.Indices.Count > 0)
            {
                Slice slice = node.Indices[0];
                if (slice.End != null)
                {
                    // Boo slice, returns a part of the source -> same type as source
                    return;
                }
            }
            IReturnType rt = (resolveResult != null) ? resolveResult.ResolvedType : null;

            if (rt == null)
            {
                ClearResult();
                return;
            }
            List <IProperty> indexers = rt.GetProperties();

            // remove non-indexers:
            for (int i = 0; i < indexers.Count; i++)
            {
                if (!indexers[i].IsIndexer)
                {
                    indexers.RemoveAt(i--);
                }
            }
            IReturnType[] parameters = new IReturnType[node.Indices.Count];
            for (int i = 0; i < parameters.Length; i++)
            {
                Expression expr = node.Indices[i].Begin as Expression;
                if (expr != null)
                {
                    ClearResult();
                    Visit(expr);
                    parameters[i] = (resolveResult != null) ? resolveResult.ResolvedType : null;
                }
            }
            MakeResult(MemberLookupHelper.FindOverload(indexers.ToArray(), parameters));
        }
        private void ExpandComplexSlicing(SlicingExpression node)
        {
            var targetType = GetExpressionType(node.Target);

            if (IsString(targetType))
            {
                ExpandComplexStringSlicing(node);
            }
            else if (IsList(targetType))
            {
                ExpandComplexListSlicing(node);
            }
            else if (targetType.IsArray)
            {
                ExpandComplexArraySlicing(node);
            }
            else
            {
                NotImplemented(node, "complex slicing for anything but lists, arrays and strings");
            }
        }
示例#28
0
        void PropagateByRefParameterChanges(Method call, IParameter[] parameters, InternalLocal[] temporaries)
        {
            int byRefIndex = 0;

            for (int i = 0; i < parameters.Length; ++i)
            {
                if (!parameters[i].IsByRef)
                {
                    continue;
                }

                SlicingExpression slice = CodeBuilder.CreateSlicing(
                    CodeBuilder.CreateReference(call.Parameters[0]),
                    i);
                call.Body.Add(
                    CodeBuilder.CreateAssignment(
                        slice,
                        CodeBuilder.CreateReference(temporaries[byRefIndex])));
                ++byRefIndex;
            }
        }
示例#29
0
        public override void OnMethodInvocationExpression(MethodInvocationExpression node)
        {
            base.OnMethodInvocationExpression(node);

            var target = node.Target as MemberReferenceExpression;

            if (target == null)
            {
                return;
            }

            var method = target.Entity as IMethod;

            if (method == null || !method.IsSpecialName)
            {
                return;
            }

            if (target.Name == "set_Item")
            {
                var indexerArgs       = node.Arguments.Take(node.Arguments.Count - 1).Select(arg => new Slice(arg)).ToArray();
                var slicingExpression = new SlicingExpression(target.Target, indexerArgs);
                var right             = node.Arguments.Last();

                node.ParentNode.Replace(node, new BinaryExpression(BinaryOperatorType.Assign, slicingExpression, right));
                return;
            }

            if (target.Name == "get_Item" || target.Name == "get_Chars")
            {
                var indexerArgs       = node.Arguments.Take(node.Arguments.Count).Select(arg => new Slice(arg)).ToArray();
                var slicingExpression = new SlicingExpression(target.Target, indexerArgs);

                node.ParentNode.Replace(node, slicingExpression);
            }
        }
示例#30
0
        override public void LeaveBinaryExpression(BinaryExpression node)
        {
            if (BinaryOperatorType.Assign == node.Operator)
            {
                if (NodeType.SlicingExpression == node.Left.NodeType)
                {
                    SlicingExpression slice = (SlicingExpression)node.Left;
                    if (IsDuckTyped(slice.Target))
                    {
                        ProcessDuckSlicingPropertySet(node);
                    }
                }
                else if (TypeSystemServices.IsQuackBuiltin(node.Left))
                {
                    ProcessQuackPropertySet(node);
                }
                return;
            }

            if (!AstUtil.IsOverloadableOperator(node.Operator))
            {
                return;
            }
            if (!IsDuckTyped(node.Left) && !IsDuckTyped(node.Right))
            {
                return;
            }

            MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation(
                RuntimeServices_InvokeBinaryOperator,
                CodeBuilder.CreateStringLiteral(
                    AstUtil.GetMethodNameForOperator(node.Operator)),
                node.Left, node.Right);

            Replace(mie);
        }