Пример #1
0
        public AbstractType Visit(PostfixExpression_Slice x)
        {
            var foreExpression = EvalForeExpression(x);

            // myArray[0]; myArray[0..5];
            // opIndex/opSlice ?
            if (foreExpression is MemberSymbol)
            {
                foreExpression = DResolver.StripMemberSymbols(foreExpression);
            }

            return(foreExpression);            // Still of the array's type.
        }
Пример #2
0
        public AbstractType Visit(PostfixExpression_Slice x)
        {
            var foreExpression = EvalForeExpression(x);

            // myArray[0]; myArray[0..5];
            if (foreExpression is MemberSymbol)
            {
                foreExpression = DResolver.StripMemberSymbols(foreExpression);
            }

            var udt = foreExpression as UserDefinedType;

            if (udt == null)
            {
                return(foreExpression);
            }

            AbstractType[] sliceArgs;
            if (x.FromExpression == null && x.ToExpression == null)
            {
                sliceArgs = null;
            }
            else
            {
                sliceArgs = new AbstractType[2];
                if (x.FromExpression != null)
                {
                    sliceArgs[0] = x.FromExpression.Accept(this);
                }
                if (x.ToExpression != null)
                {
                    sliceArgs[1] = x.ToExpression.Accept(this);
                }
            }

            ctxt.CurrentContext.IntroduceTemplateParameterTypes(udt);

            var overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(OpSliceIdHash, AmbiguousType.TryDissolve(foreExpression), ctxt, x, false);

            overloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(overloads, sliceArgs, true, ctxt);

            ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(udt);
            return(TryPretendMethodExecution(AmbiguousType.Get(overloads, x), x, sliceArgs) ?? foreExpression);
        }
Пример #3
0
 public void Visit(PostfixExpression_Slice x)
 {        //TODO: Omit opIndex overloads if it's obvious, that we don't want them -- a[1.. |
     HandleIndexSliceExpression(x);
     res.CurrentlyTypedArgumentIndex = x.ToExpression == null ? 1 : 2;
 }
        public ISymbolValue Visit(PostfixExpression_Slice x)
        {
            var foreExpression = EvalForeExpression(x);

            if (!(foreExpression is ArrayValue))
            {
                EvalError(x.PostfixForeExpression, "Must be an array");
                return(null);
            }

            var ar = (ArrayValue)foreExpression;
            var sl = (PostfixExpression_Slice)x;

            // If the [ ] form is used, the slice is of the entire array.
            if (sl.FromExpression == null && sl.ToExpression == null)
            {
                return(foreExpression);
            }

            // Make $ operand available
            var arrLen_Backup = ValueProvider.CurrentArrayLength;
            var len           = ar.Length;

            ValueProvider.CurrentArrayLength = len;

            var bound_lower = sl.FromExpression != null?sl.FromExpression.Accept(this) as PrimitiveValue : null;

            var bound_upper = sl.ToExpression != null?sl.ToExpression.Accept(this) as PrimitiveValue : null;

            ValueProvider.CurrentArrayLength = arrLen_Backup;

            if (bound_lower == null || bound_upper == null)
            {
                EvalError(bound_lower == null ? sl.FromExpression : sl.ToExpression, "Must be of an integral type");
                return(null);
            }

            int lower = -1, upper = -1;

            try
            {
                lower = Convert.ToInt32(bound_lower.Value);
                upper = Convert.ToInt32(bound_upper.Value);
            }
            catch
            {
                EvalError(lower != -1 ? sl.FromExpression : sl.ToExpression, "Boundary expression must base an integral type");
                return(null);
            }

            if (lower < 0)
            {
                EvalError(sl.FromExpression, "Lower boundary must be greater than 0"); return(new NullValue(ar.RepresentedType));
            }
            if (lower >= len && len > 0)
            {
                EvalError(sl.FromExpression, "Lower boundary must be smaller than " + len); return(new NullValue(ar.RepresentedType));
            }
            if (upper < lower)
            {
                EvalError(sl.ToExpression, "Upper boundary must be greater than " + lower); return(new NullValue(ar.RepresentedType));
            }
            else if (upper > len)
            {
                EvalError(sl.ToExpression, "Upper boundary must be smaller than " + len); return(new NullValue(ar.RepresentedType));
            }

            if (ar.IsString)
            {
                return(new ArrayValue(ar.RepresentedType as ArrayType, ar.StringValue.Substring(lower, upper - lower)));
            }

            var rawArraySlice = new ISymbolValue[upper - lower];
            int j             = 0;

            for (int i = lower; i < upper; i++)
            {
                rawArraySlice[j++] = ar.Elements[i];
            }

            return(new ArrayValue(ar.RepresentedType as ArrayType, rawArraySlice));
        }
Пример #5
0
        IExpression PostfixExpression(IBlockNode Scope = null)
        {
            IExpression leftExpr = null;

            /*
             * Despite the following syntax is an explicit UnaryExpression (see http://dlang.org/expression.html#UnaryExpression),
             * stuff like (MyType).init[] is actually allowed - so it's obviously a PostfixExpression! (Nov 13 2013)
             */

            // ( Type ) . Identifier
            if (laKind == OpenParenthesis)
            {
                Lexer.StartPeek();
                OverPeekBrackets(OpenParenthesis, false);
                var dotToken = Lexer.CurrentPeekToken;

                if (Lexer.CurrentPeekToken.Kind == DTokens.Dot &&
                    (Peek().Kind == DTokens.Identifier || Lexer.CurrentPeekToken.Kind == EOF))
                {
                    var wkParsing = AllowWeakTypeParsing;
                    AllowWeakTypeParsing = true;
                    Lexer.PushLookAheadBackup();
                    Step();
                    var startLoc = t.Location;

                    var td = Type();

                    AllowWeakTypeParsing = wkParsing;

                    /*
                     * (a. -- expression: (a.myProp + 2) / b;
                     * (int. -- must be expression anyway
                     * (const).asdf -- definitely unary expression ("type")
                     * (const). -- also treat it as type accessor
                     */
                    if (td != null &&
                        laKind == CloseParenthesis && Lexer.CurrentPeekToken == dotToken) // Also take it as a type declaration if there's nothing following (see Expression Resolving)
                    {
                        Step();  // Skip to )
                        if (laKind == DTokens.Dot)
                        {
                            Step();  // Skip to .
                            if ((laKind == DTokens.Identifier && Peek(1).Kind != Not && Peek(1).Kind != OpenParenthesis) || IsEOF)
                            {
                                Lexer.PopLookAheadBackup();
                                Step();  // Skip to identifier

                                leftExpr = new UnaryExpression_Type()
                                {
                                    Type = td,
                                    AccessIdentifier = t.Value,
                                    Location = startLoc,
                                    EndLocation = t.EndLocation
                                };
                            }
                            else
                                Lexer.RestoreLookAheadBackup();
                        }
                        else
                            Lexer.RestoreLookAheadBackup();
                    }
                    else
                        Lexer.RestoreLookAheadBackup();
                }
            }

            // PostfixExpression
            if(leftExpr == null)
                leftExpr = PrimaryExpression(Scope);

            while (!IsEOF)
            {
                switch (laKind)
                {
                    case Dot:
                        Step();

                        var pea = new PostfixExpression_Access {
                            PostfixForeExpression = leftExpr
                        };

                        leftExpr = pea;

                        if (laKind == New)
                            pea.AccessExpression = PostfixExpression(Scope);
                        else if (IsTemplateInstance)
                            pea.AccessExpression = TemplateInstance(Scope);
                        else if (Expect(Identifier))
                            pea.AccessExpression = new IdentifierExpression(t.Value) {
                                Location = t.Location,
                                EndLocation = t.EndLocation
                            };
                        else if (IsEOF)
                            pea.AccessExpression = new TokenExpression(DTokens.Incomplete);

                        pea.EndLocation = t.EndLocation;
                        break;
                    case Increment:
                    case Decrement:
                        Step();
                        var peid = t.Kind == Increment ? (PostfixExpression)new PostfixExpression_Increment() : new PostfixExpression_Decrement();
                        peid.EndLocation = t.EndLocation;
                        peid.PostfixForeExpression = leftExpr;
                        leftExpr = peid;
                        break;
                    // Function call
                    case OpenParenthesis:
                        Step();
                        var pemc = new PostfixExpression_MethodCall();
                        pemc.PostfixForeExpression = leftExpr;
                        leftExpr = pemc;

                        if (laKind == CloseParenthesis)
                            Step();
                        else
                        {
                            pemc.Arguments = ArgumentList(Scope).ToArray();
                            Expect(CloseParenthesis);
                        }

                        if(IsEOF)
                            pemc.EndLocation = CodeLocation.Empty;
                        else
                            pemc.EndLocation = t.EndLocation;
                        break;
                    // IndexExpression | SliceExpression
                    case OpenSquareBracket:
                        Step();

                        if (laKind != CloseSquareBracket)
                        {
                            var firstEx = AssignExpression(Scope);
                            // [ AssignExpression .. AssignExpression ]
                            if (laKind == DoubleDot)
                            {
                                Step();

                                leftExpr = new PostfixExpression_Slice()
                                {
                                    FromExpression = firstEx,
                                    PostfixForeExpression = leftExpr,
                                    ToExpression = AssignExpression(Scope)
                                };
                            }
                            // [ ArgumentList ]
                            else if (laKind == CloseSquareBracket || laKind == (Comma))
                            {
                                var args = new List<IExpression>();
                                args.Add(firstEx);
                                if (laKind == Comma)
                                {
                                    Step();
                                    args.AddRange(ArgumentList(Scope));
                                }

                                leftExpr = new PostfixExpression_Index()
                                {
                                    PostfixForeExpression = leftExpr,
                                    Arguments = args.ToArray()
                                };
                            }
                        }
                        else // Empty array literal = SliceExpression
                        {
                            leftExpr = new PostfixExpression_Slice()
                            {
                                PostfixForeExpression=leftExpr
                            };
                        }

                        Expect(CloseSquareBracket);
                        if(leftExpr is PostfixExpression)
                            ((PostfixExpression)leftExpr).EndLocation = t.EndLocation;
                        break;
                    default:
                        return leftExpr;
                }
            }

            return leftExpr;
        }
Пример #6
0
 public override void Visit(PostfixExpression_Slice x)
 {
     CallExpressionStack.Push(x);
     base.Visit(x);
     CallExpressionStack.Pop();
 }
        ISemantic E(PostfixExpression_Slice x, ISemantic foreExpression)
        {
            if (!eval)
                return foreExpression; // Still of the array's type.

            if (!(foreExpression is ArrayValue)){
                EvalError(x.PostfixForeExpression, "Must be an array");
                return null;
            }

            var ar = (ArrayValue)foreExpression;
            var sl = (PostfixExpression_Slice)x;

            // If the [ ] form is used, the slice is of the entire array.
            if (sl.FromExpression == null && sl.ToExpression == null)
                return foreExpression;

            // Make $ operand available
            var arrLen_Backup = ValueProvider.CurrentArrayLength;
            ValueProvider.CurrentArrayLength = ar.Elements.Length;

            var bound_lower = E(sl.FromExpression) as PrimitiveValue;
            var bound_upper = E(sl.ToExpression) as PrimitiveValue;

            ValueProvider.CurrentArrayLength = arrLen_Backup;

            if (bound_lower == null || bound_upper == null){
                EvalError(bound_lower == null ? sl.FromExpression : sl.ToExpression, "Must be of an integral type");
                return null;
            }

            int lower = -1, upper = -1;
            try
            {
                lower = Convert.ToInt32(bound_lower.Value);
                upper = Convert.ToInt32(bound_upper.Value);
            }
            catch { EvalError(lower != -1 ? sl.FromExpression : sl.ToExpression, "Boundary expression must base an integral type");
                return null;
            }

            if (lower < 0){
                EvalError(sl.FromExpression, "Lower boundary must be greater than 0");return null;}
            if (lower >= ar.Elements.Length){
                EvalError(sl.FromExpression, "Lower boundary must be smaller than " + ar.Elements.Length);return null;}
            if (upper < lower){
                EvalError(sl.ToExpression, "Upper boundary must be greater than " + lower);return null;}
            if (upper >= ar.Elements.Length){
                EvalError(sl.ToExpression, "Upper boundary must be smaller than " + ar.Elements.Length);return null;}

            var rawArraySlice = new ISymbolValue[upper - lower];
            int j = 0;
            for (int i = lower; i < upper; i++)
                rawArraySlice[j++] = ar.Elements[i];

            return new ArrayValue(ar.RepresentedType as ArrayType, rawArraySlice);
        }
Пример #8
0
        IExpression PostfixExpression(IBlockNode Scope = null)
        {
            var curLastParsedObj = LastParsedObject;

            // PostfixExpression
            IExpression leftExpr = PrimaryExpression(Scope);

            if(curLastParsedObj==LastParsedObject)
                LastParsedObject = leftExpr;

            while (!IsEOF)
            {
                if (laKind == Dot)
                {
                    Step();

                    var e = new PostfixExpression_Access {
                        PostfixForeExpression=leftExpr
                    };
                    LastParsedObject = e;

                    leftExpr = e;

                    if (laKind == New)
                        e.AccessExpression = NewExpression(Scope);
                    else if (IsTemplateInstance)
                        e.AccessExpression = TemplateInstance();
                    else if (Expect(Identifier))
                        e.AccessExpression = new IdentifierExpression(t.Value) { Location=t.Location, EndLocation=t.EndLocation };

                    e.EndLocation = t.EndLocation;
                }
                else if (laKind == Increment || laKind == Decrement)
                {
                    Step();
                    var e = t.Kind == Increment ? (PostfixExpression)new PostfixExpression_Increment() : new PostfixExpression_Decrement();
                    LastParsedObject = e;
                    e.EndLocation = t.EndLocation;
                    e.PostfixForeExpression = leftExpr;
                    leftExpr = e;
                }

                // Function call
                else if (laKind == OpenParenthesis)
                {
                    Step();
                    var ae = new PostfixExpression_MethodCall();
                    LastParsedObject = ae;
                    ae.PostfixForeExpression = leftExpr;
                    leftExpr = ae;

                    if (laKind != CloseParenthesis)
                        ae.Arguments = ArgumentList(Scope).ToArray();
                    Step();
                    ae.EndLocation = t.EndLocation;
                }

                // IndexExpression | SliceExpression
                else if (laKind == OpenSquareBracket)
                {
                    Step();

                    if (laKind != CloseSquareBracket)
                    {
                        var firstEx = AssignExpression(Scope);
                        // [ AssignExpression .. AssignExpression ]
                        if (laKind == DoubleDot)
                        {
                            Step();

                            leftExpr = new PostfixExpression_Slice()
                            {
                                FromExpression = firstEx,
                                PostfixForeExpression = leftExpr,
                                ToExpression = AssignExpression(Scope)
                            };
                            LastParsedObject = leftExpr;
                        }
                        // [ ArgumentList ]
                        else if (laKind == CloseSquareBracket || laKind == (Comma))
                        {
                            var args = new List<IExpression>();
                            args.Add(firstEx);
                            if (laKind == Comma)
                            {
                                Step();
                                args.AddRange(ArgumentList(Scope));
                            }

                            leftExpr = new PostfixExpression_Index()
                            {
                                PostfixForeExpression = leftExpr,
                                Arguments = args.ToArray()
                            };
                            LastParsedObject = leftExpr;
                        }
                    }
                    else // Empty array literal = SliceExpression
                    {
                        leftExpr = new PostfixExpression_Slice()
                        {
                            PostfixForeExpression=leftExpr
                        };
                        LastParsedObject = leftExpr;
                    }

                    Expect(CloseSquareBracket);
                    if(leftExpr is PostfixExpression)
                        ((PostfixExpression)leftExpr).EndLocation = t.EndLocation;
                }
                else break;
            }

            return leftExpr;
        }