public void Visit(PostfixExpression_ArrayAccess x)
		{//TODO for Slices: Omit opIndex overloads if it's obvious that we don't want them -- a[1.. |
			if (x.Arguments != null)
				res.CurrentlyTypedArgumentIndex = x.Arguments.Length;

			res.IsMethodArguments = true;
			res.ParsedExpression = x;

			var overloads = new List<AbstractType>();

			if (x.PostfixForeExpression == null)
				return;

			var b = ExpressionTypeEvaluation.EvaluateType(x.PostfixForeExpression, ctxt);

			var ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpSliceIdHash, b, ctxt, x, false);
			if (ov != null)
				overloads.AddRange(ov);

			ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpIndexIdHash, b, ctxt, x, false);
			if (ov != null)
				overloads.AddRange(ov);

			if (overloads.Count == 0)
			{
				b = DResolver.StripMemberSymbols(b);
				var toTypeDecl = new DTypeToTypeDeclVisitor();
				var aa = b as AssocArrayType;
				if (aa != null){
					var retType = aa.ValueType != null ? aa.ValueType.Accept(toTypeDecl) : null;
					var dm = new DMethod { 
						Name = "opIndex",
						Type = retType
					};
					dm.Parameters.Add(new DVariable { 
						Name = "index",
						Type = aa.KeyType != null ? aa.KeyType.Accept(toTypeDecl) : null 
					});
					overloads.Add(new MemberSymbol(dm, aa.ValueType));

					if ((aa is ArrayType) && !(aa as ArrayType).IsStaticArray)
					{
						dm = new DMethod
						{
							Name = "opSlice",
							Type = retType
						};
						overloads.Add(new MemberSymbol(dm, aa.ValueType));
					}
				}
				else if (b is PointerType)
				{
					b = (b as PointerType).Base;
					var dm = new DMethod
					{
						Name = "opIndex",
						Type = b != null ? b.Accept(toTypeDecl) : null
					};
					dm.Parameters.Add(new DVariable
					{
						Name = "index",
						Type = new IdentifierDeclaration("size_t")
					});
					overloads.Add(new MemberSymbol(dm, b));
				}
			}

			res.ResolvedTypesOrMethods = overloads.ToArray();
		}
Esempio n. 2
0
		IExpression ParseAsmPrimaryExpression(IBlockNode Scope, IStatement Parent)
		{
			switch (laKind)
			{
				case OpenSquareBracket:
					Step ();
					var e = new PostfixExpression_ArrayAccess (ParseAsmExpression (Scope, Parent));
					Expect (CloseSquareBracket);
					e.EndLocation = t.EndLocation;
					return e;
				case Dollar:
					var ins = Parent as AsmStatement.InstructionStatement;
					if (ins == null || (!ins.IsJmpFamily && ins.Operation != AsmStatement.InstructionStatement.OpCode.call))
						SynErr(Dollar, "The $ operator is only valid on jmp and call instructions!");
					Step();
					return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation };
				case Literal:
					Step();
					return new IdentifierExpression(t.LiteralValue, t.LiteralFormat, t.Subformat) { Location = t.Location, EndLocation = t.EndLocation };
				case This:
					Step();
					return new TokenExpression(This) { Location = t.Location, EndLocation = t.EndLocation };

				// AsmTypePrefix
				case DTokens.Byte:
				case DTokens.Short:
				case DTokens.Int:
				case DTokens.Float:
				case DTokens.Double:
				case DTokens.Real:

				case __LOCAL_SIZE:
					Step ();
					return new TokenExpression(t.Kind)  { Location = t.Location, EndLocation = t.EndLocation };
				case Identifier:
					Step();
					if (AsmRegisterExpression.IsRegister(t.Value))
					{
						string reg = t.Value;
						if (reg == "ST" && laKind == OpenParenthesis)
						{
							reg += "(";
							Step();
							if (Expect(Literal))
							{
								reg += t.LiteralValue.ToString();
								if (laKind != CloseParenthesis)
									SynErr(CloseParenthesis);
								else
									Step();
								reg += ")";
							}
						}
						switch (reg)
						{
							case "ES":
							case "CS":
							case "SS":
							case "DS":
							case "GS":
							case "FS":
								if (laKind == Colon)
								{
									var ex = new AsmRegisterExpression() { Location = t.Location, EndLocation = t.EndLocation, Register = string.Intern(reg) };
									Step();
									// NOTE: DMD actually allows you to not have an expression after a
									//       segment specifier, however I consider this a bug, and, as
									//       such, am making an expression in that form fail to parse.
									return new UnaryExpression_SegmentBase() { RegisterExpression = ex, UnaryExpression = ParseAsmExpression(Scope, Parent) };
								}
								goto default;
							default:
								// This check is required because of how ST registers are handled.
								if (AsmRegisterExpression.IsRegister(reg))
									return new AsmRegisterExpression() { Location = t.Location, EndLocation = t.EndLocation, Register = string.Intern(reg) };
								SynErr(Identifier, "Unknown register!");
								return IsEOF ? new TokenExpression(Incomplete) : null;
						}
					}
					else
					{
						IExpression outer = new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation };
						while (laKind == Dot)
						{
							Step();
							if (Expect(Identifier))
								outer = new PostfixExpression_Access() { AccessExpression = new IdentifierExpression(t.Value), PostfixForeExpression = outer };
							else
								outer = new TokenExpression(Incomplete);
							Step();
						}
						return outer;
					}
				default:
					SynErr(Identifier, "Expected a $, literal or an identifier!");
					Step();
					if (IsEOF)
						return new TokenExpression(Incomplete);
					return null;
			}
		}
Esempio n. 3
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(Scope);

					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 ();
						var loc = t.Location;
						var args = new List<PostfixExpression_ArrayAccess.IndexArgument> ();

						if (laKind != CloseSquareBracket) {
							do {
								var firstEx = AssignExpression (Scope);
								// [ AssignExpression .. AssignExpression ] || ArgumentList
								if (laKind == DoubleDot) {
									Step ();
									args.Add (new PostfixExpression_ArrayAccess.SliceArgument (firstEx, AssignExpression (Scope)));
								} else
									args.Add (new PostfixExpression_ArrayAccess.IndexArgument (firstEx));
							} while(laKind == Comma && Expect (Comma) &&
								laKind != CloseSquareBracket); // Trailing comma allowed https://github.com/aBothe/D_Parser/issues/170
						}

						Expect (CloseSquareBracket);
						leftExpr = new PostfixExpression_ArrayAccess(args.ToArray()){ 
							EndLocation = t.EndLocation,
							PostfixForeExpression = leftExpr
						};
						break;
					default:
						return leftExpr;
				}
			}

			return leftExpr;
		}
Esempio n. 4
0
		IExpression ParseAsmBracketExpression(IBlockNode Scope, IStatement Parent)
		{
			var left = ParseAsmUnaryExpression(Scope, Parent);
			while (laKind == OpenSquareBracket)
			{
				Step();
				left = new PostfixExpression_ArrayAccess(ParseAsmExpression(Scope, Parent)) { PostfixForeExpression = left };
				Expect(CloseSquareBracket);
				(left as PostfixExpression_ArrayAccess).EndLocation = t.EndLocation;
			}
			return left;
		}
		public override void Visit(PostfixExpression_ArrayAccess x)
		{
			CallExpressionStack.Push(x);
			base.Visit(x);
			CallExpressionStack.Pop();
		}