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. }
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); }
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)); }
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; }
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); }
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; }