public AbstractType Visit(TypeidExpression x) { //TODO: Split up into more detailed typeinfo objects (e.g. for arrays, pointers, classes etc.) return(TypeDeclarationResolver.ResolveSingle(new IdentifierDeclaration("TypeInfo") { InnerDeclaration = new IdentifierDeclaration("object") }, ctxt)); }
public ISymbolValue Visit(TypeidExpression tid) { /* * Depending on what's given as argument, it's needed to find out what kind of TypeInfo_ class to return * AND to fill it with all required information. * * http://dlang.org/phobos/object.html#TypeInfo */ throw new NotImplementedException("TypeInfo creation not supported yet"); }
public ISemantic E(TypeidExpression tid) { //TODO: Split up into more detailed typeinfo objects (e.g. for arrays, pointers, classes etc.) if(!eval) return TypeDeclarationResolver.ResolveSingle(new IdentifierDeclaration("TypeInfo") { InnerDeclaration = new IdentifierDeclaration("object") }, ctxt); /* * Depending on what's given as argument, it's needed to find out what kind of TypeInfo_ class to return * AND to fill it with all required information. * * http://dlang.org/phobos/object.html#TypeInfo */ throw new NotImplementedException("TypeInfo creation not supported yet"); }
public ISemantic E(TypeidExpression tid) { //TODO: Split up into more detailed typeinfo objects (e.g. for arrays, pointers, classes etc.) if (!eval) { return(TypeDeclarationResolver.ResolveSingle(new IdentifierDeclaration("TypeInfo") { InnerDeclaration = new IdentifierDeclaration("object") }, ctxt)); } /* * Depending on what's given as argument, it's needed to find out what kind of TypeInfo_ class to return * AND to fill it with all required information. * * http://dlang.org/phobos/object.html#TypeInfo */ throw new NotImplementedException("TypeInfo creation not supported yet"); }
public void Visit(TypeidExpression x) { }
IExpression PrimaryExpression(IBlockNode Scope=null) { bool isModuleScoped = laKind == Dot; if (isModuleScoped) { Step(); if (IsEOF) { var dot = new TokenExpression(Dot) { Location = t.Location, EndLocation = t.EndLocation }; return new PostfixExpression_Access{ PostfixForeExpression = dot, AccessExpression = new TokenExpression(DTokens.Incomplete) }; } } // TemplateInstance if (IsTemplateInstance) { var tix = TemplateInstance(Scope); if (tix != null) tix.ModuleScopedIdentifier = isModuleScoped; return tix; } if (IsLambaExpression()) return LambaExpression(Scope); CodeLocation startLoc; switch (laKind) { // ArrayLiteral | AssocArrayLiteral case OpenSquareBracket: return ArrayLiteral(Scope); case New: return NewExpression(Scope); case Typeof: return new TypeDeclarationExpression(TypeOf()); case __traits: return TraitsExpression(); // Dollar (== Array length expression) case Dollar: Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; case Identifier: Step(); return new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation, ModuleScoped = isModuleScoped }; // SpecialTokens (this,super,null,true,false,$) // $ has been handled before case This: case Super: case Null: case True: case False: Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; case OpenParenthesis: if (IsFunctionLiteral()) goto case Function; // ( Expression ) Step(); var ret = new SurroundingParenthesesExpression() {Location=t.Location }; ret.Expression = Expression(); Expect(CloseParenthesis); ret.EndLocation = t.EndLocation; return ret; case Literal: Step(); startLoc = t.Location; // Concatenate multiple string literals here if (t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { var sb = new StringBuilder(t.RawCodeRepresentation ?? t.Value); while (la.LiteralFormat == LiteralFormat.StringLiteral || la.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { Step(); sb.Append(t.RawCodeRepresentation ?? t.Value); } return new IdentifierExpression(sb.ToString(), t.LiteralFormat, t.Subformat) { Location = startLoc, EndLocation = t.EndLocation }; } //else if (t.LiteralFormat == LiteralFormat.CharLiteral)return new IdentifierExpression(t.LiteralValue) { LiteralFormat=t.LiteralFormat,Location = startLoc, EndLocation = t.EndLocation }; return new IdentifierExpression(t.LiteralValue, t.LiteralFormat, t.Subformat) { Location = startLoc, EndLocation = t.EndLocation }; // FunctionLiteral case Delegate: case Function: case OpenCurlyBrace: var fl = new FunctionLiteral() { Location=la.Location}; fl.AnonymousMethod.Location = la.Location; if (laKind == Delegate || laKind == Function) { Step(); fl.LiteralToken = t.Kind; } // file.d:1248 /* listdir (".", delegate bool (DirEntry * de) { auto s = std.string.format("%s : c %s, w %s, a %s", de.name, toUTCString (de.creationTime), toUTCString (de.lastWriteTime), toUTCString (de.lastAccessTime)); return true; } ); */ if (laKind != OpenCurlyBrace) // foo( 1, {bar();} ); -> is a legal delegate { if (!IsFunctionAttribute && Lexer.CurrentPeekToken.Kind == OpenParenthesis) fl.AnonymousMethod.Type = BasicType(); else if (laKind != OpenParenthesis && laKind != OpenCurlyBrace) fl.AnonymousMethod.Type = Type(); if (laKind == OpenParenthesis) fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod); FunctionAttributes(fl.AnonymousMethod); } if (!IsEOF) { FunctionBody(fl.AnonymousMethod); fl.EndLocation = fl.AnonymousMethod.EndLocation; } else fl.EndLocation = la.Location; if (Scope != null) Scope.Add(fl.AnonymousMethod); return fl; // AssertExpression case Assert: Step(); startLoc = t.Location; Expect(OpenParenthesis); var ce = new AssertExpression() { Location=startLoc}; var exprs = new List<IExpression>(); exprs.Add(AssignExpression()); if (laKind == (Comma)) { Step(); exprs.Add(AssignExpression()); } ce.AssignExpressions = exprs.ToArray(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; // MixinExpression case Mixin: Step(); var me = new MixinExpression() { Location=t.Location}; if (Expect(OpenParenthesis)) { me.AssignExpression = AssignExpression(); Expect(CloseParenthesis); } me.EndLocation = t.EndLocation; return me; // ImportExpression case Import: Step(); var ie = new ImportExpression() { Location=t.Location}; Expect(OpenParenthesis); ie.AssignExpression = AssignExpression(); Expect(CloseParenthesis); ie.EndLocation = t.EndLocation; return ie; // TypeidExpression case Typeid: Step(); var tide = new TypeidExpression() { Location=t.Location}; Expect(OpenParenthesis); if (IsAssignExpression()) tide.Expression = AssignExpression(Scope); else { Lexer.PushLookAheadBackup(); AllowWeakTypeParsing = true; tide.Type = Type(); AllowWeakTypeParsing = false; if (tide.Type == null || laKind != CloseParenthesis) { Lexer.RestoreLookAheadBackup(); tide.Expression = AssignExpression(); } else Lexer.PopLookAheadBackup(); } Expect (CloseParenthesis); tide.EndLocation = t.EndLocation; return tide; // IsExpression case Is: Step(); var ise = new IsExpression() { Location = t.Location }; Expect(OpenParenthesis); if ((ise.TestedType = Type()) == null) SynErr(laKind, "In an IsExpression, either a type or an expression is required!"); if (ise.TestedType != null) { if (laKind == Identifier && (Lexer.CurrentPeekToken.Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Equal || Lexer.CurrentPeekToken.Kind == Colon)) { Step(); Strings.Add(strVal); ise.TypeAliasIdentifierHash = strVal.GetHashCode(); ise.TypeAliasIdLocation = t.Location; } else if (IsEOF) ise.TypeAliasIdentifierHash = DTokens.IncompleteIdHash; } if (laKind == Colon || laKind == Equal) { Step(); ise.EqualityTest = t.Kind == Equal; } else if (laKind == CloseParenthesis) { Step(); ise.EndLocation = t.EndLocation; return ise; } /* TypeSpecialization: Type struct union class interface enum function delegate super const immutable inout shared return */ bool specialTest = false; if (ise.EqualityTest) { switch (laKind) { case Typedef: // typedef is possible although it's not yet documented in the syntax docs case Enum: case Delegate: case Function: case Super: case Return: specialTest = true; break; case Const: case Immutable: case InOut: case Shared: specialTest = Peek(1).Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Comma; break; default: specialTest = IsClassLike(laKind); break; } } if (specialTest) { Step(); ise.TypeSpecializationToken = t.Kind; } else ise.TypeSpecialization = Type(); // TemplateParameterList if (laKind == Comma) { var tempParam = new List<TemplateParameter>(); do { Step(); tempParam.Add(TemplateParameter(null)); } while (laKind == Comma); ise.TemplateParameterList = tempParam.ToArray(); } Expect(CloseParenthesis); ise.EndLocation = t.EndLocation; return ise; default: if (DTokens.IsMetaIdentifier(laKind)) goto case Dollar; else if (IsBasicType()) { // BasicType . Identifier startLoc = la.Location; var bt=BasicType(); if ((bt is TypeOfDeclaration || bt is MemberFunctionAttributeDecl) && laKind!=Dot) return new TypeDeclarationExpression(bt); // Things like incomplete 'float.' expressions shall be parseable, too if (Expect(Dot) && (Expect(Identifier) || IsEOF)) return new PostfixExpression_Access() { PostfixForeExpression = new TypeDeclarationExpression(bt), AccessExpression = IsEOF ? new TokenExpression(Incomplete) as IExpression : new IdentifierExpression(t.Value) { Location=t.Location, EndLocation=t.EndLocation }, EndLocation = t.EndLocation }; return null; } SynErr(Identifier); if(laKind != CloseCurlyBrace) Step(); if (IsEOF) return new TokenExpression (DTokens.Incomplete) { Location = t.Location, EndLocation = t.Location }; // Don't know why, in rare situations, t tends to be null.. if (t == null) return null; return new TokenExpression() { Location = t.Location, EndLocation = t.EndLocation }; } }
IExpression PrimaryExpression(IBlockNode Scope=null) { bool isModuleScoped = laKind == Dot; if (isModuleScoped) { Step(); if (IsEOF) { LastParsedObject = new TokenExpression(Dot) { Location = t.Location, EndLocation = t.EndLocation }; TrackerVariables.ExpectingIdentifier = true; } } // Dollar (== Array length expression) if (laKind == Dollar || DTokens.MetaIdentifiers[laKind]) { Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; } // TemplateInstance if (IsTemplateInstance) { var tix = TemplateInstance(Scope); if (tix != null) tix.ModuleScopedIdentifier = isModuleScoped; return tix; } if (IsLambaExpression()) return LambaExpression(Scope); // Identifier if (laKind == Identifier) { Step(); return new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation, ModuleScoped = isModuleScoped }; } // SpecialTokens (this,super,null,true,false,$) // $ has been handled before if (laKind == (This) || laKind == (Super) || laKind == (Null) || laKind == (True) || laKind == (False)) { Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; } #region Literal if (laKind == Literal) { Step(); var startLoc = t.Location; // Concatenate multiple string literals here if (t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { var sb = new StringBuilder(t.RawCodeRepresentation ?? t.Value); while (la.LiteralFormat == LiteralFormat.StringLiteral || la.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { Step(); sb.Append(t.RawCodeRepresentation ?? t.Value); } return new IdentifierExpression(sb.ToString(), t.LiteralFormat, t.Subformat) { Location = startLoc, EndLocation = t.EndLocation }; } //else if (t.LiteralFormat == LiteralFormat.CharLiteral)return new IdentifierExpression(t.LiteralValue) { LiteralFormat=t.LiteralFormat,Location = startLoc, EndLocation = t.EndLocation }; return new IdentifierExpression(t.LiteralValue, t.LiteralFormat, t.Subformat) { Location = startLoc, EndLocation = t.EndLocation }; } #endregion #region ArrayLiteral | AssocArrayLiteral if (laKind == (OpenSquareBracket)) { Step(); var startLoc = t.Location; // Empty array literal if (laKind == CloseSquareBracket) { Step(); return new ArrayLiteralExpression(null) {Location=startLoc, EndLocation = t.EndLocation }; } /* * If it's an initializer, allow NonVoidInitializers as values. * Normal AssignExpressions otherwise. */ bool isInitializer = TrackerVariables.IsParsingInitializer; var firstExpression = isInitializer? NonVoidInitializer(Scope) : AssignExpression(Scope); // Associtative array if (laKind == Colon) { Step(); var ae = isInitializer ? new ArrayInitializer { Location = startLoc } : new AssocArrayExpression { Location=startLoc }; LastParsedObject = ae; var firstValueExpression = isInitializer? NonVoidInitializer(Scope) : AssignExpression(); ae.Elements.Add(new KeyValuePair<IExpression,IExpression>(firstExpression, firstValueExpression)); while (laKind == Comma) { Step(); if (laKind == CloseSquareBracket) break; var keyExpr = AssignExpression(); var valExpr=Expect(Colon) ? (isInitializer? NonVoidInitializer(Scope) : AssignExpression(Scope)) : null; ae.Elements.Add(new KeyValuePair<IExpression,IExpression>(keyExpr,valExpr)); } Expect(CloseSquareBracket); ae.EndLocation = t.EndLocation; return ae; } else // Normal array literal { var ae = new List<IExpression>(); LastParsedObject = ae; ae.Add(firstExpression); while (laKind == Comma) { Step(); if (laKind == CloseSquareBracket) // And again, empty expressions are allowed break; ae.Add(isInitializer? NonVoidInitializer(Scope) : AssignExpression(Scope)); } Expect(CloseSquareBracket); return new ArrayLiteralExpression(ae){ Location=startLoc, EndLocation = t.EndLocation }; } } #endregion #region FunctionLiteral if (laKind == Delegate || laKind == Function || laKind == OpenCurlyBrace || (laKind == OpenParenthesis && IsFunctionLiteral())) { var fl = new FunctionLiteral() { Location=la.Location}; LastParsedObject = fl; fl.AnonymousMethod.Location = la.Location; if (laKind == Delegate || laKind == Function) { Step(); fl.LiteralToken = t.Kind; } // file.d:1248 /* listdir (".", delegate bool (DirEntry * de) { auto s = std.string.format("%s : c %s, w %s, a %s", de.name, toUTCString (de.creationTime), toUTCString (de.lastWriteTime), toUTCString (de.lastAccessTime)); return true; } ); */ if (laKind != OpenCurlyBrace) // foo( 1, {bar();} ); -> is a legal delegate { if (!IsFunctionAttribute && Lexer.CurrentPeekToken.Kind == OpenParenthesis) fl.AnonymousMethod.Type = BasicType(); else if (laKind != OpenParenthesis && laKind != OpenCurlyBrace) fl.AnonymousMethod.Type = Type(); if (laKind == OpenParenthesis) fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod); FunctionAttributes(fl.AnonymousMethod); } if(!IsEOF) FunctionBody(fl.AnonymousMethod); fl.EndLocation = t.EndLocation; if (Scope != null) Scope.Add(fl.AnonymousMethod); return fl; } #endregion #region AssertExpression if (laKind == (Assert)) { Step(); var startLoc = t.Location; Expect(OpenParenthesis); var ce = new AssertExpression() { Location=startLoc}; LastParsedObject = ce; var exprs = new List<IExpression>(); exprs.Add(AssignExpression()); if (laKind == (Comma)) { Step(); exprs.Add(AssignExpression()); } ce.AssignExpressions = exprs.ToArray(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion #region MixinExpression | ImportExpression if (laKind == Mixin) { Step(); var e = new MixinExpression() { Location=t.Location}; LastParsedObject = e; if (Expect(OpenParenthesis)) { e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); } e.EndLocation = t.EndLocation; return e; } if (laKind == Import) { Step(); var e = new ImportExpression() { Location=t.Location}; LastParsedObject = e; Expect(OpenParenthesis); e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); e.EndLocation = t.EndLocation; return e; } #endregion if (laKind == (Typeof)) { return new TypeDeclarationExpression(TypeOf()); } // TypeidExpression if (laKind == (Typeid)) { Step(); var ce = new TypeidExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); if (IsAssignExpression()) ce.Expression = AssignExpression(Scope); else { Lexer.PushLookAheadBackup(); AllowWeakTypeParsing = true; ce.Type = Type(); AllowWeakTypeParsing = false; if (ce.Type == null || laKind != CloseParenthesis) { Lexer.RestoreLookAheadBackup(); ce.Expression = AssignExpression(); } else Lexer.PopLookAheadBackup(); } if (!Expect(CloseParenthesis) && IsEOF) LastParsedObject = (ISyntaxRegion)ce.Type ?? ce.Expression; ce.EndLocation = t.EndLocation; return ce; } #region IsExpression if (laKind == Is) { Step(); var ce = new IsExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); if((ce.TestedType = Type())==null) SynErr(laKind, "In an IsExpression, either a type or an expression is required!"); if (ce.TestedType!=null && laKind == Identifier && (Lexer.CurrentPeekToken.Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Equal || Lexer.CurrentPeekToken.Kind == Colon)) { Step(); Strings.Add(strVal); ce.TypeAliasIdentifierHash = strVal.GetHashCode(); ce.TypeAliasIdLocation = t.Location; } if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } if (laKind == Colon || laKind == Equal) { Step(); ce.EqualityTest = t.Kind == Equal; } else if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } /* TypeSpecialization: Type struct union class interface enum function delegate super const immutable inout shared return */ if (ce.EqualityTest && (ClassLike[laKind] || laKind==Typedef || // typedef is possible although it's not yet documented in the syntax docs laKind==Enum || laKind==Delegate || laKind==Function || laKind==Super || laKind==Return || ((laKind==Const || laKind == Immutable || laKind == InOut || laKind == Shared) && (Peek(1).Kind==CloseParenthesis || Lexer.CurrentPeekToken.Kind==Comma)))) { Step(); ce.TypeSpecializationToken = t.Kind; } else ce.TypeSpecialization = Type(); // TemplateParameterList if (laKind == Comma) { var ret = new List<TemplateParameter>(); do { Step(); ret.Add(TemplateParameter(null)); } while (laKind == Comma); ce.TemplateParameterList = ret.ToArray(); } Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion // NewExpression if (laKind == (New)) return NewExpression(Scope); // ( Expression ) if (laKind == OpenParenthesis) { Step(); var ret = new SurroundingParenthesesExpression() {Location=t.Location }; LastParsedObject = ret; ret.Expression = Expression(); Expect(CloseParenthesis); ret.EndLocation = t.EndLocation; return ret; } // TraitsExpression if (laKind == (__traits)) return TraitsExpression(); #region BasicType . Identifier if (IsBasicType()) { var startLoc = la.Location; var bt=BasicType(); if ((bt is TypeOfDeclaration || bt is MemberFunctionAttributeDecl) && laKind!=Dot) return new TypeDeclarationExpression(bt); // Things like incomplete 'float.' expressions shall be parseable, too if (Expect(Dot) && (Expect(Identifier) || IsEOF)) return new PostfixExpression_Access() { PostfixForeExpression = new TypeDeclarationExpression(bt), AccessExpression = string.IsNullOrEmpty(t.Value) ? null : new IdentifierExpression(t.Value) { Location=t.Location, EndLocation=t.EndLocation }, EndLocation = t.EndLocation }; return null; } #endregion SynErr(Identifier); if(laKind != CloseCurlyBrace) Step(); // Don't know why, in rare situations, t tends to be null.. if (t == null) return null; return new TokenExpression() { Location = t.Location, EndLocation = t.EndLocation }; }
IExpression PrimaryExpression(IBlockNode Scope=null) { bool isModuleScoped = false; // For minimizing possible overhead, skip 'useless' tokens like an initial dot <<< TODO if (isModuleScoped= laKind == Dot) Step(); if (laKind == __FILE__ || laKind == __LINE__) { Step(); object id = null; if (t.Kind == __FILE__ && doc != null) id = doc.FileName; else if(t.Kind==__LINE__) id = t.line; return new IdentifierExpression(id) { Location=t.Location, EndLocation=t.EndLocation }; } // Dollar (== Array length expression) if (laKind == Dollar) { Step(); return new TokenExpression(laKind) { Location = t.Location, EndLocation = t.EndLocation }; } // TemplateInstance if (laKind == (Identifier) && Lexer.CurrentPeekToken.Kind == (Not) && (Peek().Kind != Is && Lexer.CurrentPeekToken.Kind != In) /* Very important: The 'template' could be a '!is'/'!in' expression - With two tokens each! */) return TemplateInstance(); // Identifier if (laKind == (Identifier)) { Step(); return new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation }; } // SpecialTokens (this,super,null,true,false,$) // $ has been handled before if (laKind == (This) || laKind == (Super) || laKind == (Null) || laKind == (True) || laKind == (False)) { Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; } #region Literal if (laKind == Literal) { Step(); var startLoc = t.Location; // Concatenate multiple string literals here if (t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { var a = t.LiteralValue as string; while (la.LiteralFormat == LiteralFormat.StringLiteral || la.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { Step(); a += t.LiteralValue as string; } return new IdentifierExpression(a, t.LiteralFormat) { Location = startLoc, EndLocation = t.EndLocation }; } //else if (t.LiteralFormat == LiteralFormat.CharLiteral)return new IdentifierExpression(t.LiteralValue) { LiteralFormat=t.LiteralFormat,Location = startLoc, EndLocation = t.EndLocation }; return new IdentifierExpression(t.LiteralValue, t.LiteralFormat) { Location = startLoc, EndLocation = t.EndLocation }; } #endregion #region ArrayLiteral | AssocArrayLiteral if (laKind == (OpenSquareBracket)) { Step(); var startLoc = t.Location; // Empty array literal if (laKind == CloseSquareBracket) { Step(); return new ArrayLiteralExpression() {Location=startLoc, EndLocation = t.EndLocation }; } var firstExpression = AssignExpression(); // Associtative array if (laKind == Colon) { Step(); var ae = new AssocArrayExpression() { Location=startLoc}; LastParsedObject = ae; var firstValueExpression = AssignExpression(); ae.KeyValuePairs.Add(firstExpression, firstValueExpression); while (laKind == Comma) { Step(); var keyExpr = AssignExpression(); Expect(Colon); var valueExpr = AssignExpression(); ae.KeyValuePairs.Add(keyExpr, valueExpr); } Expect(CloseSquareBracket); ae.EndLocation = t.EndLocation; return ae; } else // Normal array literal { var ae = new ArrayLiteralExpression() { Location=startLoc}; LastParsedObject = ae; var expressions = new List<IExpression>(); expressions.Add(firstExpression); while (laKind == Comma) { Step(); if (laKind == CloseSquareBracket) // And again, empty expressions are allowed break; expressions.Add(AssignExpression()); } ae.Expressions = expressions; Expect(CloseSquareBracket); ae.EndLocation = t.EndLocation; return ae; } } #endregion #region FunctionLiteral if (laKind == Delegate || laKind == Function || laKind == OpenCurlyBrace || (laKind == OpenParenthesis && IsFunctionLiteral())) { var fl = new FunctionLiteral() { Location=la.Location}; LastParsedObject = fl; fl.AnonymousMethod.StartLocation = la.Location; if (laKind == Delegate || laKind == Function) { Step(); fl.LiteralToken = t.Kind; } // file.d:1248 /* listdir (".", delegate bool (DirEntry * de) { auto s = std.string.format("%s : c %s, w %s, a %s", de.name, toUTCString (de.creationTime), toUTCString (de.lastWriteTime), toUTCString (de.lastAccessTime)); return true; } ); */ if (laKind != OpenCurlyBrace) // foo( 1, {bar();} ); -> is a legal delegate { if (!MemberFunctionAttribute[laKind] && Lexer.CurrentPeekToken.Kind == OpenParenthesis) fl.AnonymousMethod.Type = BasicType(); else if (laKind != OpenParenthesis && laKind != OpenCurlyBrace) fl.AnonymousMethod.Type = Type(); if (laKind == OpenParenthesis) fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod); } FunctionBody(fl.AnonymousMethod); fl.EndLocation = t.EndLocation; if (Scope != null) Scope.Add(fl.AnonymousMethod); return fl; } #endregion #region AssertExpression if (laKind == (Assert)) { Step(); var startLoc = t.Location; Expect(OpenParenthesis); var ce = new AssertExpression() { Location=startLoc}; LastParsedObject = ce; var exprs = new List<IExpression>(); exprs.Add(AssignExpression()); if (laKind == (Comma)) { Step(); exprs.Add(AssignExpression()); } ce.AssignExpressions = exprs.ToArray(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion #region MixinExpression | ImportExpression if (laKind == Mixin) { Step(); var e = new MixinExpression() { Location=t.Location}; LastParsedObject = e; Expect(OpenParenthesis); e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); e.EndLocation = t.EndLocation; return e; } if (laKind == Import) { Step(); var e = new ImportExpression() { Location=t.Location}; LastParsedObject = e; Expect(OpenParenthesis); e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); e.EndLocation = t.EndLocation; return e; } #endregion if (laKind == (Typeof)) { var startLoc = la.Location; return new TypeDeclarationExpression(TypeOf()) {Location=startLoc,EndLocation=t.EndLocation}; } // TypeidExpression if (laKind == (Typeid)) { Step(); var ce = new TypeidExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); AllowWeakTypeParsing = true; ce.Type = Type(); AllowWeakTypeParsing = false; if (ce.Type==null) ce.Expression = AssignExpression(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #region IsExpression if (laKind == Is) { Step(); var ce = new IsExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); var LookAheadBackup = la; AllowWeakTypeParsing = true; ce.TestedType = Type(); AllowWeakTypeParsing = false; if (ce.TestedType!=null && laKind == Identifier && (Lexer.CurrentPeekToken.Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Equal || Lexer.CurrentPeekToken.Kind == Colon)) { Step(); ce.TypeAliasIdentifier = strVal; } else // D Language specs mistake: In an IsExpression there also can be expressions! if(ce.TestedType==null || !(laKind==CloseParenthesis || laKind==Equal||laKind==Colon)) { // Reset lookahead token to prior position la = LookAheadBackup; // Reset wrongly parsed type declaration ce.TestedType = null; ce.TestedExpression = ConditionalExpression(); } if(ce.TestedExpression==null && ce.TestedType==null) SynErr(laKind,"In an IsExpression, either a type or an expression is required!"); if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } if (laKind == Colon || laKind == Equal) { Step(); ce.EqualityTest = t.Kind == Equal; } else if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } /* TypeSpecialization: Type struct union class interface enum function delegate super const immutable inout shared return */ if (ClassLike[laKind] || laKind==Typedef || // typedef is possible although it's not yet documented in the syntax docs laKind==Enum || laKind==Delegate || laKind==Function || laKind==Super || laKind==Return) { Step(); ce.TypeSpecializationToken = t.Kind; } else ce.TypeSpecialization = Type(); if (laKind == Comma) { Step(); ce.TemplateParameterList = TemplateParameterList(false); } Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion // ( Expression ) if (laKind == OpenParenthesis) { Step(); var ret = new SurroundingParenthesesExpression() {Location=t.Location }; LastParsedObject = ret; ret.Expression = Expression(); Expect(CloseParenthesis); ret.EndLocation = t.EndLocation; return ret; } // TraitsExpression if (laKind == (__traits)) return TraitsExpression(); #region BasicType . Identifier if (laKind == (Const) || laKind == (Immutable) || laKind == (Shared) || laKind == (InOut) || BasicTypes[laKind]) { Step(); var startLoc = t.Location; IExpression left = null; if (!BasicTypes[t.Kind]) { int tk = t.Kind; // Put an artificial parenthesis around the following type declaration if (laKind != OpenParenthesis) { var mttd = new MemberFunctionAttributeDecl(tk); LastParsedObject = mttd; mttd.InnerType = Type(); left = new TypeDeclarationExpression(mttd) { Location = startLoc, EndLocation = t.EndLocation }; } else { Expect(OpenParenthesis); var mttd = new MemberFunctionAttributeDecl(tk); LastParsedObject = mttd; mttd.InnerType = Type(); Expect(CloseParenthesis); left = new TypeDeclarationExpression(mttd) { Location = startLoc, EndLocation = t.EndLocation }; } } else left = new TokenExpression(t.Kind) {Location=startLoc,EndLocation=t.EndLocation }; if (laKind == (Dot) && Peek(1).Kind==Identifier) { Step(); Step(); var meaex = new PostfixExpression_Access() { PostfixForeExpression=left, TemplateOrIdentifier=new IdentifierDeclaration(t.Value),EndLocation=t.EndLocation }; return meaex; } return left; } #endregion // TODO? Expressions can of course be empty... //return null; SynErr(Identifier); Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; }