public override ISymbolValue this[DVariable variable] { get { ISymbolValue v; if (Locals.TryGetValue(variable, out v)) return v; // Assign a default value to the variable var t = TypeResolution.TypeDeclarationResolver.HandleNodeMatch(variable, base.ResolutionContext) as MemberSymbol; if (t != null) { if (t.Base is PrimitiveType) v= new PrimitiveValue(0M, t.Base as PrimitiveType); else v = new NullValue(t.Base as DSymbol); } else v = new NullValue(); Locals[variable] = v; return v; } set { if (variable == null) throw new CtfeException("variable must not be null"); Locals[variable] = value; } }
public virtual void Visit(DVariable n) { if (n.Initializer != null) { n.Initializer.Accept(this); } VisitDNode(n); }
static AbstractVisitor() { __ctfe = new DVariable { Name = "__ctfe", Type = new DTokenDeclaration(DTokens.Bool), Initializer = new TokenExpression(DTokens.True), Description = @"The __ctfe boolean pseudo-variable, which evaluates to true at compile time, but false at run time, can be used to provide an alternative execution path to avoid operations which are forbidden at compile time.", Attributes = new List<DAttribute>{new Modifier(DTokens.Static),new Modifier(DTokens.Const)} }; }
public override ISymbolValue this[DVariable n] { get { var dv = n as DebugVariable; if (dv != null) return Backtrace.EvaluateSymbol(dv.Symbol); return base[n]; } set { //TODO? base[n] = value; } }
public override ISymbolValue this[DVariable variable] { get { ISymbolValue v; if (Locals.TryGetValue(variable, out v)) return v; throw new CtfeException("Variable "+variable.ToString()+" not set yet!"); } set { if (variable == null) throw new CtfeException("Can't set non-existent variable"); Locals[variable] = value; } }
public AliasedType(DVariable AliasDefinition, AbstractType Type, ISyntaxRegion td, ReadOnlyCollection<TemplateParameterSymbol> deducedTypes=null) : base(AliasDefinition,Type, td, deducedTypes) { }
/// <summary> /// Adds init, max, min to the completion list /// </summary> public static void AddIntegralTypeProperties(int TypeToken, ISemantic rr, ICompletionDataGenerator cdg, INode relatedNode = null, bool DontAddInitProperty = false) { var intType = new DTokenDeclaration(TypeToken); if (!DontAddInitProperty) { var prop_Init = new DVariable() { Type = intType, Initializer = new IdentifierExpression(0, LiteralFormat.Scalar) }; if (relatedNode != null) prop_Init.AssignFrom(relatedNode); // Override the initializer variable's name and description prop_Init.Name = "init"; prop_Init.Description = "A type's or variable's static initializer expression"; cdg.Add(prop_Init); } CreateArtificialProperties(IntegralProps, cdg, intType); }
public static void AddFloatingTypeProperties(int TypeToken, ISemantic rr, ICompletionDataGenerator cdg, INode relatedNode = null, bool DontAddInitProperty = false) { var intType = new DTokenDeclaration(TypeToken); if (!DontAddInitProperty) { var prop_Init = new DVariable() { Type = intType, Initializer = new PostfixExpression_Access() { PostfixForeExpression = new TokenExpression(TypeToken), AccessExpression = new IdentifierExpression("nan") } }; if (relatedNode != null) prop_Init.AssignFrom(relatedNode); // Override the initializer variable's name and description prop_Init.Name = "init"; prop_Init.Description = "A type's or variable's static initializer expression"; cdg.Add(prop_Init); } CreateArtificialProperties(FloatingTypeProps, cdg, intType); }
/// <summary> /// Parse parameters /// </summary> List<INode> Parameters(DMethod Parent) { var ret = new List<INode>(); Expect(OpenParenthesis); // Empty parameter list if (laKind == (CloseParenthesis)) { Step(); return ret; } var stk_backup = BlockAttributes; BlockAttributes = new Stack<DAttribute>(); DNode p; if (laKind != TripleDot && (p = Parameter(Parent)) != null) { p.Parent = Parent; ret.Add(p); } while (laKind == (Comma)) { Step(); if (laKind == TripleDot || laKind==CloseParenthesis || (p = Parameter(Parent)) == null) break; p.Parent = Parent; ret.Add(p); } // It's not specified in the official D syntax spec, but we treat id-only typed anonymous parameters as non-typed id-full parameters if(Parent != null && Parent.SpecialType == DMethod.MethodType.AnonymousDelegate) { foreach(var r in ret) if (r.NameHash == 0 && r.Type is IdentifierDeclaration && r.Type.InnerDeclaration == null) { r.NameHash = (r.Type as IdentifierDeclaration).IdHash; r.Type = null; } } /* * There can be only one '...' in every parameter list */ if (laKind == TripleDot) { // If it doesn't have a comma, add a VarArgDecl to the last parameter bool HadComma = t.Kind == (Comma); Step(); if (!HadComma && ret.Count > 0) { // Put a VarArgDecl around the type of the last parameter ret[ret.Count - 1].Type = new VarArgDecl(ret[ret.Count - 1].Type); } else { var dv = new DVariable(); dv.Type = new VarArgDecl(); dv.Parent = Parent; ret.Add(dv); } } Expect(CloseParenthesis); BlockAttributes = stk_backup; return ret; }
ForeachStatement ForeachStatement(IBlockNode Scope,IStatement Parent) { Step(); var dbs = new ForeachStatement() { Location = t.Location, IsReverse = t.Kind == Foreach_Reverse, Parent = Parent }; if(!Expect(OpenParenthesis)) return dbs; var tl = new List<DVariable>(); bool init=true; while(init || laKind == Comma) { if (init) init = false; else Step(); var forEachVar = new DVariable{ Parent = Scope }; forEachVar.Location = la.Location; CheckForStorageClasses(Scope); ApplyAttributes(forEachVar); if(IsEOF){ SynErr (Identifier, "Element variable name or type expected"); forEachVar.NameHash = DTokens.IncompleteIdHash; } else if (laKind == (Identifier) && (Lexer.CurrentPeekToken.Kind == (Semicolon) || Lexer.CurrentPeekToken.Kind == Comma)) { Step(); forEachVar.NameLocation = t.Location; forEachVar.Name = t.Value; } else { var type = BasicType(); var tnode = Declarator(type, false, Scope); if (!(tnode is DVariable)) break; if(forEachVar.Attributes != null) if(tnode.Attributes == null) tnode.Attributes = new List<DAttribute>(forEachVar.Attributes); else tnode.Attributes.AddRange(forEachVar.Attributes); tnode.Location = forEachVar.Location; forEachVar = tnode as DVariable; } forEachVar.EndLocation = t.EndLocation; tl.Add(forEachVar); } dbs.ForeachTypeList = tl.ToArray(); if(Expect(Semicolon)) dbs.Aggregate = Expression(Scope); // ForeachRangeStatement if (laKind == DoubleDot) { Step(); dbs.UpperAggregate = Expression(); } if(Expect(CloseParenthesis)) dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; }
/// <summary> /// Parses a type declarator /// </summary> /// <returns>A dummy node that contains the return type, the variable name and possible parameters of a function declaration</returns> DNode Declarator(ITypeDeclaration basicType,bool IsParam, INode parent) { DNode ret = new DVariable() { Type=basicType, Location = la.Location, Parent = parent }; ApplyAttributes (ret); while (IsBasicType2()) { if (ret.Type == null) ret.Type = BasicType2(); else { var ttd = BasicType2(); if(ttd!=null) ttd.InnerDeclaration = ret.Type; ret.Type = ttd; } } if (laKind != (OpenParenthesis)) { // On external function declarations, no parameter names are required. // extern void Cfoo(HANDLE,char**); if (IsParam && laKind != (Identifier)) { if ((!(ret.Type is DTokenDeclaration) || (ret.Type as DTokenDeclaration).Token != DTokens.Incomplete) && IsEOF) ret.NameHash = DTokens.IncompleteIdHash; return ret; } if (Expect(Identifier)) { ret.Name = t.Value; ret.NameLocation = t.Location; // enum asdf(...) = ...; if (laKind == OpenParenthesis && OverPeekBrackets(DTokens.OpenParenthesis, true) && Lexer.CurrentPeekToken.Kind == Assign) { var eponymousTemplateDecl = new EponymousTemplate (); eponymousTemplateDecl.AssignFrom (ret); ret = eponymousTemplateDecl; TemplateParameterList (eponymousTemplateDecl); return ret; } } else { if (IsEOF) { ret.NameHash = DTokens.IncompleteIdHash; return ret; } return null; // Code error! - to prevent infinite declaration loops, step one token forward anyway! if(laKind != CloseCurlyBrace && laKind != CloseParenthesis) Step(); return null; } } else OldCStyleFunctionPointer(ret, IsParam); if (IsDeclaratorSuffix || IsFunctionAttribute) { var dm = new DMethod { Parent = parent, Parameters = null }; dm.AssignFrom(ret); DeclaratorSuffixes(dm); if (dm.Parameters != null) ret = dm; } return ret; }
INode Constructor(DBlockNode scope,bool IsStruct) { Expect(This); var dm = new DMethod(){ Parent = scope, SpecialType = DMethod.MethodType.Constructor, Location = t.Location, Name = DMethod.ConstructorIdentifier, NameLocation = t.Location }; ApplyAttributes (dm); dm.Description = GetComments(); if (IsTemplateParameterList()) TemplateParameterList(dm); // http://dlang.org/struct.html#StructPostblit if (IsStruct && laKind == (OpenParenthesis) && Peek(1).Kind == (This)) { var dv = new DVariable { Parent = dm, Name = "this" }; dm.Parameters.Add(dv); Step(); Step(); Expect(CloseParenthesis); } else { dm.Parameters = Parameters(dm); } // handle post argument attributes FunctionAttributes(dm); if (laKind == If) Constraint(dm); // handle post argument attributes FunctionAttributes(dm); if(IsFunctionBody) FunctionBody(dm); return dm; }
public IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null) { if (EmptyAllowed && laKind == Semicolon) { LastParsedObject = null; Step(); return null; } if (BlocksAllowed && laKind == OpenCurlyBrace) return BlockStatement(Scope,Parent); #region LabeledStatement (loc:... goto loc;) if (laKind == Identifier && Lexer.CurrentPeekToken.Kind == Colon) { Step(); var ret = new LabeledStatement() { Location = t.Location, Identifier = t.Value, Parent = Parent }; LastParsedObject = null; Step(); ret.EndLocation = t.EndLocation; return ret; } #endregion #region IfStatement else if (laKind == (If)) { Step(); var dbs = new IfStatement{ Location = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); // IfCondition IfCondition(dbs); // ThenStatement if(Expect(CloseParenthesis)) dbs.ThenStatement = Statement(Scope: Scope, Parent: dbs); // ElseStatement if (laKind == (Else)) { Step(); dbs.ElseStatement = Statement(Scope: Scope, Parent: dbs); } if(t != null) dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Conditions else if ((laKind == Static && Lexer.CurrentPeekToken.Kind == If) || laKind == Version || laKind == Debug) return StmtCondition(Parent, Scope); #endregion #region WhileStatement else if (laKind == While) { Step(); var dbs = new WhileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; Expect(OpenParenthesis); dbs.Condition = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) { dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; } return dbs; } #endregion #region DoStatement else if (laKind == (Do)) { Step(); var dbs = new WhileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; if(!IsEOF) dbs.ScopedStatement = Statement(true, false, Scope, dbs); if(Expect(While) && Expect(OpenParenthesis)) { dbs.Condition = Expression(Scope); Expect(CloseParenthesis); if (Expect(Semicolon)) LastParsedObject = null; dbs.EndLocation = t.EndLocation; } return dbs; } #endregion #region ForStatement else if (laKind == (For)) return ForStatement(Scope, Parent); #endregion #region ForeachStatement else if (laKind == Foreach || laKind == Foreach_Reverse) return ForeachStatement(Scope, Parent); #endregion #region [Final] SwitchStatement else if ((laKind == (Final) && Lexer.CurrentPeekToken.Kind == (Switch)) || laKind == (Switch)) { var dbs = new SwitchStatement { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; if (laKind == (Final)) { dbs.IsFinal = true; Step(); } Step(); Expect(OpenParenthesis); dbs.SwitchExpression = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region CaseStatement else if (laKind == (Case)) { Step(); var dbs = new SwitchStatement.CaseStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; dbs.ArgumentList = Expression(Scope); if (Expect(Colon)) LastParsedObject = null; // CaseRangeStatement if (laKind == DoubleDot) { Step(); Expect(Case); dbs.LastExpression = AssignExpression(); if (Expect(Colon)) LastParsedObject = null; } var sl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: dbs); if (stmt != null) { stmt.Parent = dbs; sl.Add(stmt); } } dbs.ScopeStatementList = sl.ToArray(); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Default else if (laKind == (Default)) { Step(); var dbs = new SwitchStatement.DefaultStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = dbs; Expect(Colon); var sl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: dbs); if (stmt != null) { stmt.Parent = dbs; sl.Add(stmt); } } dbs.ScopeStatementList = sl.ToArray(); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region Continue | Break else if (laKind == (Continue)) { Step(); var s = new ContinueStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.Identifier = t.Value; } if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } else if (laKind == (Break)) { Step(); var s = new BreakStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.Identifier = t.Value; } if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } #endregion #region Return else if (laKind == (Return)) { Step(); var s = new ReturnStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind != (Semicolon)) s.ReturnExpression = Expression(Scope); if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } #endregion #region Goto else if (laKind == (Goto)) { Step(); var s = new GotoStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; if (laKind == (Identifier)) { Step(); s.StmtType = GotoStatement.GotoStmtType.Identifier; s.LabelIdentifier = t.Value; } else if (laKind == Default) { Step(); s.StmtType = GotoStatement.GotoStmtType.Default; } else if (laKind == (Case)) { Step(); s.StmtType = GotoStatement.GotoStmtType.Case; if (laKind != (Semicolon)) s.CaseExpression = Expression(Scope); } if (Expect(Semicolon)) LastParsedObject = null; s.EndLocation = t.EndLocation; return s; } #endregion #region WithStatement else if (laKind == (With)) { Step(); var dbs = new WithStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; if(Expect(OpenParenthesis)) { // Symbol dbs.WithExpression = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); } dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region SynchronizedStatement else if (laKind == (Synchronized)) { Step(); var dbs = new SynchronizedStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = dbs; if (laKind == (OpenParenthesis)) { Step(); dbs.SyncExpression = Expression(Scope); Expect(CloseParenthesis); } if(!IsEOF) dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; } #endregion #region TryStatement else if (laKind == (Try)) { Step(); var s = new TryStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ScopedStatement = Statement(Scope: Scope, Parent: s); if (!(laKind == (Catch) || laKind == (Finally))) SemErr(Catch, "At least one catch or a finally block expected!"); var catches = new List<TryStatement.CatchStatement>(); // Catches while (laKind == (Catch)) { Step(); var c = new TryStatement.CatchStatement() { Location = t.Location, Parent = s }; LastParsedObject = c; // CatchParameter if (laKind == (OpenParenthesis)) { Step(); if (laKind == CloseParenthesis || IsEOF) { SemErr(CloseParenthesis, "Catch parameter expected, not ')'"); Step(); } else { var catchVar = new DVariable { Parent = Scope, Location = t.Location }; LastParsedObject = catchVar; Lexer.PushLookAheadBackup(); catchVar.Type = BasicType(); if (laKind == CloseParenthesis) { Lexer.RestoreLookAheadBackup(); catchVar.Type = new IdentifierDeclaration("Exception"); } else Lexer.PopLookAheadBackup(); if (Expect(Identifier)) { catchVar.Name = t.Value; catchVar.NameLocation = t.Location; Expect(CloseParenthesis); } else if(IsEOF) ExpectingNodeName = true; catchVar.EndLocation = t.EndLocation; c.CatchParameter = catchVar; } } if(!IsEOF) c.ScopedStatement = Statement(Scope: Scope, Parent: c); c.EndLocation = t.EndLocation; catches.Add(c); } if (catches.Count > 0) s.Catches = catches.ToArray(); if (laKind == (Finally)) { Step(); var f = new TryStatement.FinallyStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = f; f.ScopedStatement = Statement(); f.EndLocation = t.EndLocation; s.FinallyStmt = f; } s.EndLocation = t.EndLocation; return s; } #endregion #region ThrowStatement else if (laKind == (Throw)) { Step(); var s = new ThrowStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ThrowExpression = Expression(Scope); Expect(Semicolon); s.EndLocation = t.EndLocation; return s; } #endregion #region ScopeGuardStatement else if (laKind == DTokens.Scope) { Step(); if (laKind == OpenParenthesis) { var s = new ScopeGuardStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; Step(); if (Expect(Identifier) && t.Value != null) // exit, failure, success s.GuardedScope = t.Value.ToLower(); if (Expect(CloseParenthesis)) TrackerVariables.ExpectingIdentifier = false; if (!IsEOF) s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } else PushAttribute(new Modifier(DTokens.Scope), false); } #endregion #region AsmStmt else if (laKind == Asm) return AsmStatement(Parent); #endregion #region PragmaStatement else if (laKind == (Pragma)) { var s = new PragmaStatement { Location = la.Location }; s.Pragma = _Pragma(); s.Parent = Parent; s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } #endregion #region MixinStatement else if (laKind == (Mixin)) { if (Peek(1).Kind == OpenParenthesis) { OverPeekBrackets(OpenParenthesis); if (Lexer.CurrentPeekToken.Kind != Semicolon) return ExpressionStatement(Scope, Parent); return MixinDeclaration(Scope, Parent); } else { var tmx = TemplateMixin(Scope, Parent); if (tmx.MixinId == null) return tmx; else return new DeclarationStatement { Declarations = new[] { new NamedTemplateMixinNode(tmx) }, Parent = Parent }; } } #endregion #region (Static) AssertExpression else if (laKind == Assert || (laKind == Static && Lexer.CurrentPeekToken.Kind == Assert)) { var isStatic = laKind == Static; AssertStatement s; if (isStatic) { Step(); s = new StaticAssertStatement { Location = la.Location, Parent = Parent }; } else s = new AssertStatement() { Location = la.Location, Parent = Parent }; LastParsedObject = s; Step(); if (Expect(OpenParenthesis)) { s.AssertedExpression = Expression(Scope); if(Expect(CloseParenthesis) && Expect(Semicolon)) LastParsedObject = null; } s.EndLocation = t.EndLocation; return s; } #endregion #region D1: VolatileStatement else if (laKind == Volatile) { Step(); var s = new VolatileStatement() { Location = t.Location, Parent = Parent }; LastParsedObject = s; s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } #endregion // ImportDeclaration else if (laKind == Import || (laKind == Static && Lexer.CurrentPeekToken.Kind == Import)) { if(laKind == Static) Step(); // Will be handled in ImportDeclaration return ImportDeclaration(Scope); } else if (!(ClassLike[laKind] || BasicTypes[laKind] || laKind == Enum || Modifiers[laKind] || IsAtAttribute || laKind == Alias || laKind == Typedef) && IsAssignExpression()) return ExpressionStatement(Scope, Parent); var ds = new DeclarationStatement() { Location = la.Location, Parent = Parent, ParentNode = Scope }; LastParsedObject = ds; ds.Declarations = Declaration(Scope); ds.EndLocation = t.EndLocation; return ds; }
ForeachStatement ForeachStatement(IBlockNode Scope,IStatement Parent) { Step(); var dbs = new ForeachStatement() { Location = t.Location, IsReverse = t.Kind == Foreach_Reverse, Parent = Parent }; LastParsedObject = dbs; if(!Expect(OpenParenthesis)) return dbs; var tl = new List<DVariable>(); bool init=true; while(init || laKind == Comma) { if (init) init = false; else Step(); var forEachVar = new DVariable{ Parent = Scope }; forEachVar.Location = la.Location; if (laKind == Ref || laKind == InOut) { Step(); if(forEachVar.Attributes == null) forEachVar.Attributes = new List<DAttribute>(); forEachVar.Attributes.Add(new Modifier(t.Kind)); } if(IsEOF){ TrackerVariables.ExpectingIdentifier = true; SynErr(t.Kind,"Basic type or iteration variable identifier expected."); return dbs; } LastParsedObject = forEachVar; if (laKind == (Identifier) && (Lexer.CurrentPeekToken.Kind == (Semicolon) || Lexer.CurrentPeekToken.Kind == Comma)) { Step(); forEachVar.NameLocation = t.Location; forEachVar.Name = t.Value; } else { var type = BasicType(); var tnode = Declarator(type, false, Scope); if (tnode == null) break; if(forEachVar.Attributes != null) if(tnode.Attributes == null) tnode.Attributes = new List<DAttribute>(forEachVar.Attributes); else tnode.Attributes.AddRange(forEachVar.Attributes); tnode.Location = forEachVar.Location; forEachVar = (DVariable)tnode; } forEachVar.EndLocation = t.EndLocation; tl.Add(forEachVar); } dbs.ForeachTypeList = tl.ToArray(); if(Expect(Semicolon)) dbs.Aggregate = Expression(Scope); // ForeachRangeStatement if (laKind == DoubleDot) { Step(); dbs.UpperAggregate = Expression(); } if(Expect(CloseParenthesis)) dbs.ScopedStatement = Statement(Scope: Scope, Parent: dbs); dbs.EndLocation = t.EndLocation; return dbs; }
private INode[] EnumDeclaration(INode Parent) { Expect(Enum); var ret = new List<INode>(); var mye = new DEnum() { Location = t.Location, Description = GetComments(), Parent=Parent }; LastParsedObject = mye; ApplyAttributes(mye); if (laKind != Identifier && IsBasicType()) mye.Type = Type(); else if (laKind == Auto) { Step(); mye.Attributes.Add(new Modifier(Auto)); } if (laKind == (Identifier)) { // Normal enum identifier if (Lexer.CurrentPeekToken.Kind == (Assign) || // enum e = 1234; Lexer.CurrentPeekToken.Kind == (OpenCurlyBrace) || // enum e { A,B,C, } Lexer.CurrentPeekToken.Kind == (Semicolon) || // enum e; Lexer.CurrentPeekToken.Kind == Colon) { // enum e : uint {..} Step (); mye.Name = t.Value; mye.NameLocation = t.Location; } else { if (mye.Type == null) mye.Type = Type(); if (Expect(Identifier)) { mye.Name = t.Value; mye.NameLocation = t.Location; } } } else if (IsEOF) ExpectingNodeName = true; if (IsDeclaratorSuffix) { DeclaratorSuffixes(mye); } // Enum inhertance type if (laKind == (Colon)) { Step(); mye.Type = Type(); } // Variables with 'enum' as base type if (laKind == (Assign) || laKind == (Semicolon)) { do { var enumVar = new DVariable(); LastParsedObject = enumVar; enumVar.AssignFrom(mye); enumVar.Attributes.Add(new Modifier(Enum)); if (mye.Type != null) enumVar.Type = mye.Type; else enumVar.Type = new DTokenDeclaration(Enum); if (laKind == (Comma)) { Step(); Expect(Identifier); enumVar.Name = t.Value; enumVar.NameLocation = t.Location; } if (laKind == (Assign)) { //Step(); -- expected by initializer enumVar.Initializer = Initializer(); // Seems to be specified wrongly - theoretically there must be an AssignExpression(); } enumVar.EndLocation = t.Location; ret.Add(enumVar); } while (laKind == Comma); Expect(Semicolon); } else if (laKind == OpenCurlyBrace) // Normal enum block { EnumBody(mye); ret.Add(mye); } mye.Description += CheckForPostSemicolonComment(); return ret.ToArray(); }
DVariable AliasThisDeclaration(DVariable initiallyParsedNode, IBlockNode Scope) { var dv = new DVariable { Description = initiallyParsedNode.Description, Location=t.Location, IsAlias=true, IsAliasThis = true, NameHash = DVariable.AliasThisIdentifierHash, Parent = Scope, Attributes = initiallyParsedNode.Attributes }; if(!(Scope is DClassLike)) SemErr(DTokens.This, "alias this declarations are only allowed in structs and classes!"); // alias this = Identifier if(laKind == This && Lexer.CurrentPeekToken.Kind == Assign) { Step(); // Step beyond 'this' dv.NameLocation=t.Location; Step(); // Step beyond '=' if(Expect(Identifier)) { dv.Type= new IdentifierDeclaration(t.Value) { Location = t.Location, EndLocation = t.EndLocation }; } } else { Step(); // Step beyond Identifier dv.Type = new IdentifierDeclaration(t.Value) { Location=dv.NameLocation =t.Location, EndLocation=t.EndLocation }; Step(); // Step beyond 'this' dv.NameLocation=t.Location; } dv.EndLocation = t.EndLocation; Expect(Semicolon); dv.Description += CheckForPostSemicolonComment(); return dv; }
public virtual void Visit(DVariable n) { if (n.Initializer != null) n.Initializer.Accept(this); VisitDNode(n); }
List<INode> Decl(IBlockNode Scope, DAttribute StorageClass = null) { var startLocation = la.Location; var initialComment = GetComments(); ITypeDeclaration ttd = null; CheckForStorageClasses(Scope); // Autodeclaration if(StorageClass == null) StorageClass = DTokens.ContainsStorageClass(DeclarationAttributes); if (laKind == Enum) { Step(); PushAttribute(StorageClass = new Modifier(Enum) { Location = t.Location, EndLocation = t.EndLocation },false); } // If there's no explicit type declaration, leave our node's type empty! if ((StorageClass != Modifier.Empty && laKind == (Identifier) && (DeclarationAttributes.Count > 0 || Lexer.CurrentPeekToken.Kind == OpenParenthesis))) // public auto var=0; // const foo(...) {} { if (Lexer.CurrentPeekToken.Kind == Assign || Lexer.CurrentPeekToken.Kind ==OpenParenthesis) { } else if (Lexer.CurrentPeekToken.Kind == Semicolon) { SemErr(t.Kind, "Initializer expected for auto type, semicolon found!"); } else ttd = BasicType(); } else if(!IsEOF) ttd = BasicType(); if (IsEOF) { /* * T! -- tix.Arguments == null * T!(int, -- last argument == null * T!(int, bool, -- ditto * T!(int) -- now every argument is complete */ var tix=ttd as TemplateInstanceExpression; if (tix != null) { if (tix.Arguments == null || tix.Arguments.Length == 0 || (tix.Arguments [tix.Arguments.Length - 1] is TokenExpression && (tix.Arguments [tix.Arguments.Length - 1] as TokenExpression).Token == DTokens.INVALID)) { return null; } } else if (ttd is MemberFunctionAttributeDecl && (ttd as MemberFunctionAttributeDecl).InnerType == null) { return null; } } // Declarators var firstNode = Declarator(ttd,false, Scope); if (firstNode == null) return null; firstNode.Description = initialComment; firstNode.Location = startLocation; // Check for declaration constraints if (laKind == (If)) Constraint(firstNode); // BasicType Declarators ; if (laKind==Assign || laKind==Comma || laKind==Semicolon) { // DeclaratorInitializer if (laKind == (Assign)) { var init = Initializer (Scope); var dv = firstNode as DVariable; if (dv != null) dv.Initializer = init; } firstNode.EndLocation = t.EndLocation; var ret = new List<INode>(); ret.Add(firstNode); // DeclaratorIdentifierList while (laKind == Comma) { Step(); if (IsEOF || Expect (Identifier)) { var otherNode = new DVariable (); // Note: In DDoc, all declarations that are made at once (e.g. int a,b,c;) get the same pre-declaration-description! otherNode.Description = initialComment; otherNode.AssignFrom (firstNode); otherNode.Location = t.Location; if (t.Kind == DTokens.Identifier) otherNode.Name = t.Value; else if(IsEOF) otherNode.NameHash = IncompleteIdHash; otherNode.NameLocation = t.Location; if (laKind == OpenParenthesis) TemplateParameterList (otherNode); if (laKind == Assign) otherNode.Initializer = Initializer (Scope); otherNode.EndLocation = t.EndLocation; ret.Add (otherNode); } else break; } Expect(Semicolon); // Note: In DDoc, only the really last declaration will get the post semicolon comment appended if (ret.Count > 0) ret[ret.Count - 1].Description += CheckForPostSemicolonComment(); return ret; } // BasicType Declarator FunctionBody else if (firstNode is DMethod && (IsFunctionBody || IsEOF)) { firstNode.Description += CheckForPostSemicolonComment(); FunctionBody((DMethod)firstNode); firstNode.Description += CheckForPostSemicolonComment(); var ret = new List<INode> (); ret.Add (firstNode); return ret; } else SynErr(OpenCurlyBrace, "; or function body expected after declaration stub."); if (IsEOF) return new List<INode>{ firstNode }; return null; }
public AssocArrayPointer(DVariable accessedArray, AssocArrayType arrayType, ISymbolValue accessedItemKey) : base(new MemberSymbol(accessedArray, arrayType,null)) { Key = accessedItemKey; }
/// <summary> /// http://www.digitalmars.com/d/2.0/declaration.html#Declarator2 /// The next bug: Following the definition strictly, this function would end up in an endless loop of requesting another Declarator2 /// /// So here I think that a Declarator2 only consists of a couple of BasicType2's and some DeclaratorSuffixes /// </summary> /// <returns></returns> ITypeDeclaration Declarator2() { ITypeDeclaration td = null; if (laKind == (OpenParenthesis)) { Step(); td = Declarator2(); if (AllowWeakTypeParsing && (td == null||(t.Kind==OpenParenthesis && laKind==CloseParenthesis) /* -- means if an argumentless function call has been made, return null because this would be an expression */|| laKind!=CloseParenthesis)) return null; Expect(CloseParenthesis); // DeclaratorSuffixes if (laKind == (OpenSquareBracket)) { var dn = new DVariable(); dn.Type = td; DeclaratorSuffixes(dn); td = dn.Type; if(dn.Attributes!= null && dn.Attributes.Count != 0) foreach(var attr in dn.Attributes) DeclarationAttributes.Push(attr); } return td; } while (IsBasicType2()) { var ttd = BasicType2(); if (AllowWeakTypeParsing && ttd == null) return null; if(ttd!=null) ttd.InnerDeclaration = td; td = ttd; } return td; }
public StaticVariableValue(DVariable artificialVariable, AbstractType propType) : base(new MemberSymbol(artificialVariable, propType, null)) { }
FunctionLiteral LambaExpression(IBlockNode Scope=null) { var fl = new FunctionLiteral(true); fl.Location = fl.AnonymousMethod.Location = la.Location; if(laKind == Function || laKind == Delegate) { fl.LiteralToken = laKind; Step(); } if (laKind == Identifier) { Step(); var p = new DVariable { Name = t.Value, Location = t.Location, EndLocation = t.EndLocation, Attributes = new List<DAttribute>{new Modifier(Auto)} }; fl.AnonymousMethod.Parameters.Add(p); } else if (laKind == OpenParenthesis) fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod); LambdaBody(fl.AnonymousMethod); fl.EndLocation = fl.AnonymousMethod.EndLocation; if (Scope != null) Scope.Add(fl.AnonymousMethod); return fl; }
public VariableValue(MemberSymbol mr) : base(mr.Base) { this.Member = mr; this.Variable = mr.Definition as DVariable; }
public IStatement Statement(bool BlocksAllowed = true, bool EmptyAllowed = true, IBlockNode Scope = null, IStatement Parent=null) { switch (laKind) { case Semicolon: if (!EmptyAllowed) goto default; Step(); return null; case OpenCurlyBrace: if (!BlocksAllowed) goto default; return BlockStatement(Scope,Parent); // LabeledStatement (loc:... goto loc;) case Identifier: if (Lexer.CurrentPeekToken.Kind != Colon) goto default; Step(); var ls = new LabeledStatement() { Location = t.Location, Identifier = t.Value, Parent = Parent }; Step(); ls.EndLocation = t.EndLocation; return ls; // IfStatement case If: Step(); var iS = new IfStatement{ Location = t.Location, Parent = Parent }; Expect(OpenParenthesis); // IfCondition IfCondition(iS); // ThenStatement if(Expect(CloseParenthesis)) iS.ThenStatement = Statement(Scope: Scope, Parent: iS); // ElseStatement if (laKind == (Else)) { Step(); iS.ElseStatement = Statement(Scope: Scope, Parent: iS); } if(t != null) iS.EndLocation = t.EndLocation; return iS; // Conditions case Version: case Debug: return StmtCondition(Parent, Scope); case Static: if (Lexer.CurrentPeekToken.Kind == If) return StmtCondition(Parent, Scope); else if (Lexer.CurrentPeekToken.Kind == Assert) goto case Assert; else if (Lexer.CurrentPeekToken.Kind == Import) goto case Import; goto default; case For: return ForStatement(Scope, Parent); case Foreach: case Foreach_Reverse: return ForeachStatement(Scope, Parent); case While: Step(); var ws = new WhileStatement() { Location = t.Location, Parent = Parent }; Expect(OpenParenthesis); ws.Condition = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) { ws.ScopedStatement = Statement(Scope: Scope, Parent: ws); ws.EndLocation = t.EndLocation; } return ws; case Do: Step(); var dws = new WhileStatement() { Location = t.Location, Parent = Parent }; if(!IsEOF) dws.ScopedStatement = Statement(true, false, Scope, dws); if(Expect(While) && Expect(OpenParenthesis)) { dws.Condition = Expression(Scope); Expect(CloseParenthesis); Expect(Semicolon); dws.EndLocation = t.EndLocation; } return dws; // [Final] SwitchStatement case Final: if (Lexer.CurrentPeekToken.Kind != Switch) goto default; goto case Switch; case Switch: var ss = new SwitchStatement { Location = la.Location, Parent = Parent }; if (laKind == (Final)) { ss.IsFinal = true; Step(); } Step(); Expect(OpenParenthesis); ss.SwitchExpression = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) ss.ScopedStatement = Statement(Scope: Scope, Parent: ss); ss.EndLocation = t.EndLocation; return ss; case Case: Step(); var sscs = new SwitchStatement.CaseStatement() { Location = la.Location, Parent = Parent }; sscs.ArgumentList = Expression(Scope); Expect(Colon); // CaseRangeStatement if (laKind == DoubleDot) { Step(); Expect(Case); sscs.LastExpression = AssignExpression(); Expect(Colon); } var sscssl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: sscs); if (stmt != null) { stmt.Parent = sscs; sscssl.Add(stmt); } } sscs.ScopeStatementList = sscssl.ToArray(); sscs.EndLocation = t.EndLocation; return sscs; case Default: Step(); var ssds = new SwitchStatement.DefaultStatement() { Location = la.Location, Parent = Parent }; Expect(Colon); var ssdssl = new List<IStatement>(); while (laKind != Case && laKind != Default && laKind != CloseCurlyBrace && !IsEOF) { var stmt = Statement(Scope: Scope, Parent: ssds); if (stmt != null) { stmt.Parent = ssds; ssdssl.Add(stmt); } } ssds.ScopeStatementList = ssdssl.ToArray(); ssds.EndLocation = t.EndLocation; return ssds; case Continue: Step(); var cs = new ContinueStatement() { Location = t.Location, Parent = Parent }; if (laKind == (Identifier)) { Step(); cs.Identifier = t.Value; } else if(IsEOF) cs.IdentifierHash = DTokens.IncompleteIdHash; Expect(Semicolon); cs.EndLocation = t.EndLocation; return cs; case Break: Step(); var bs = new BreakStatement() { Location = t.Location, Parent = Parent }; if (laKind == (Identifier)) { Step(); bs.Identifier = t.Value; } else if(IsEOF) bs.IdentifierHash = DTokens.IncompleteIdHash; Expect(Semicolon); bs.EndLocation = t.EndLocation; return bs; case Return: Step(); var rs = new ReturnStatement() { Location = t.Location, Parent = Parent }; if (laKind != (Semicolon)) rs.ReturnExpression = Expression(Scope); Expect(Semicolon); rs.EndLocation = t.EndLocation; return rs; case Goto: Step(); var gs = new GotoStatement() { Location = t.Location, Parent = Parent }; switch(laKind) { case Identifier: Step(); gs.StmtType = GotoStatement.GotoStmtType.Identifier; gs.LabelIdentifier = t.Value; break; case Default: Step(); gs.StmtType = GotoStatement.GotoStmtType.Default; break; case Case: Step(); gs.StmtType = GotoStatement.GotoStmtType.Case; if (laKind != (Semicolon)) gs.CaseExpression = Expression(Scope); break; default: if (IsEOF) gs.LabelIdentifierHash = DTokens.IncompleteIdHash; break; } Expect(Semicolon); gs.EndLocation = t.EndLocation; return gs; case With: Step(); var wS = new WithStatement() { Location = t.Location, Parent = Parent }; if(Expect(OpenParenthesis)) { // Symbol wS.WithExpression = Expression(Scope); Expect(CloseParenthesis); if(!IsEOF) wS.ScopedStatement = Statement(Scope: Scope, Parent: wS); } wS.EndLocation = t.EndLocation; return wS; case Synchronized: Step(); var syncS = new SynchronizedStatement() { Location = t.Location, Parent = Parent }; if (laKind == (OpenParenthesis)) { Step(); syncS.SyncExpression = Expression(Scope); Expect(CloseParenthesis); } if(!IsEOF) syncS.ScopedStatement = Statement(Scope: Scope, Parent: syncS); syncS.EndLocation = t.EndLocation; return syncS; case Try: Step(); var ts = new TryStatement() { Location = t.Location, Parent = Parent }; ts.ScopedStatement = Statement(Scope: Scope, Parent: ts); if (!(laKind == (Catch) || laKind == (Finally))) SemErr(Catch, "At least one catch or a finally block expected!"); var catches = new List<TryStatement.CatchStatement>(); // Catches while (laKind == (Catch)) { Step(); var c = new TryStatement.CatchStatement() { Location = t.Location, Parent = ts }; // CatchParameter if (laKind == (OpenParenthesis)) { Step(); if (laKind == CloseParenthesis || IsEOF) { SemErr(CloseParenthesis, "Catch parameter expected, not ')'"); Step(); } else { var catchVar = new DVariable { Parent = Scope, Location = t.Location }; Lexer.PushLookAheadBackup(); catchVar.Type = BasicType(); if (laKind == CloseParenthesis) { Lexer.RestoreLookAheadBackup(); catchVar.Type = new IdentifierDeclaration("Exception"); } else Lexer.PopLookAheadBackup(); if (Expect(Identifier)) { catchVar.Name = t.Value; catchVar.NameLocation = t.Location; Expect(CloseParenthesis); } else if(IsEOF) catchVar.NameHash = DTokens.IncompleteIdHash; catchVar.EndLocation = t.EndLocation; c.CatchParameter = catchVar; } } if(!IsEOF) c.ScopedStatement = Statement(Scope: Scope, Parent: c); c.EndLocation = t.EndLocation; catches.Add(c); } if (catches.Count > 0) ts.Catches = catches.ToArray(); if (laKind == (Finally)) { Step(); var f = new TryStatement.FinallyStatement() { Location = t.Location, Parent = Parent }; f.ScopedStatement = Statement(); f.EndLocation = t.EndLocation; ts.FinallyStmt = f; } ts.EndLocation = t.EndLocation; return ts; case Throw: Step(); var ths = new ThrowStatement() { Location = t.Location, Parent = Parent }; ths.ThrowExpression = Expression(Scope); Expect(Semicolon); ths.EndLocation = t.EndLocation; return ths; case DTokens.Scope: Step(); if (laKind == OpenParenthesis) { var s = new ScopeGuardStatement() { Location = t.Location, Parent = Parent }; Step(); if (Expect(Identifier) && t.Value != null) // exit, failure, success s.GuardedScope = t.Value.ToLower(); else if (IsEOF) s.GuardedScope = DTokens.IncompleteId; Expect(CloseParenthesis); s.ScopedStatement = Statement(Scope: Scope, Parent: s); s.EndLocation = t.EndLocation; return s; } else PushAttribute(new Modifier(DTokens.Scope), false); goto default; case Asm: return ParseAsmStatement(Scope, Parent); case Pragma: var ps = new PragmaStatement { Location = la.Location }; ps.Pragma = _Pragma(); ps.Parent = Parent; ps.ScopedStatement = Statement(Scope: Scope, Parent: ps); ps.EndLocation = t.EndLocation; return ps; case Mixin: if (Peek(1).Kind == OpenParenthesis) { OverPeekBrackets(OpenParenthesis); if (Lexer.CurrentPeekToken.Kind != Semicolon) return ExpressionStatement(Scope, Parent); return MixinDeclaration(Scope, Parent); } else { var tmx = TemplateMixin(Scope, Parent); if (tmx.MixinId == null) return tmx; else return new DeclarationStatement { Declarations = new[] { new NamedTemplateMixinNode(tmx) }, Parent = Parent }; } case Assert: var isStatic = laKind == Static; AssertStatement asS; if (isStatic) { Step(); asS = new StaticAssertStatement { Location = la.Location, Parent = Parent }; } else asS = new AssertStatement() { Location = la.Location, Parent = Parent }; Step(); if (Expect(OpenParenthesis)) { asS.AssertedExpression = Expression(Scope); Expect(CloseParenthesis); Expect(Semicolon); } asS.EndLocation = t.EndLocation; return asS; case Volatile: Step(); var vs = new VolatileStatement() { Location = t.Location, Parent = Parent }; vs.ScopedStatement = Statement(Scope: Scope, Parent: vs); vs.EndLocation = t.EndLocation; return vs; case Import: if(laKind == Static) Step(); // Will be handled in ImportDeclaration return ImportDeclaration(Scope); case Enum: case Alias: case Typedef: var ds = new DeclarationStatement() { Location = la.Location, Parent = Parent, ParentNode = Scope }; ds.Declarations = Declaration(Scope); ds.EndLocation = t.EndLocation; return ds; default: if (IsClassLike(laKind) || (IsBasicType(laKind) && Lexer.CurrentPeekToken.Kind != Dot) || IsModifier(laKind)) goto case Typedef; if (IsAssignExpression()) return ExpressionStatement(Scope, Parent); goto case Typedef; } }
/// <summary> /// Array ctor. /// </summary> /// <param name="accessedItem">0 - the array's length-1; -1 when adding the item is wished.</param> public ArrayPointer(DVariable accessedArray, ArrayType arrayType, int accessedItem) : base(new MemberSymbol(accessedArray, arrayType, null)) { ItemNumber = accessedItem; }
/// <summary> /// Adds init, sizeof, alignof, mangleof, stringof to the completion list /// </summary> public static void AddGenericProperties(ISemantic rr, ICompletionDataGenerator cdg, INode relatedNode = null, bool DontAddInitProperty = false) { if (!DontAddInitProperty) { var prop_Init = new DVariable(); if (relatedNode != null) prop_Init.AssignFrom(relatedNode); // Override the initializer variable's name and description prop_Init.Name = "init"; prop_Init.Description = "A type's or variable's static initializer expression"; cdg.Add(prop_Init); } CreateArtificialProperties(GenericProps, cdg); }
public override ISymbolValue this[DVariable n] { get { if (n == null) throw new ArgumentNullException("There must be a valid variable node given in order to retrieve its value"); if (n.IsConst) { // .. resolve it's pre-compile time value and make the returned value the given argument var val = Evaluation.EvaluateValue(n.Initializer, this); // If it's null, then the initializer is null - which is equal to e.g. 0 or null !; if (val != null) return val; } throw new ArgumentException(n+" must have a constant initializer"); } set { throw new NotImplementedException(); } }
// Associative Arrays' properties have to be inserted manually static void CreateArtificialProperties(StaticProperty[] Properties, ICompletionDataGenerator cdg, ITypeDeclaration DefaultPropType = null) { foreach (var prop in Properties) { var p = new DVariable() { Name = prop.Name, Description = prop.Description, Type = prop.OverrideType != null ? prop.OverrideType : DefaultPropType }; cdg.Add(p); } }
public abstract ISymbolValue this[DVariable variable] { get; set; }
DVariable Argument(ref char c, out AbstractType parType) { bool scoped; if(scoped = (c == 'M')) c = (char)r.Read(); //TODO: Handle scoped var par = new DVariable{ Attributes = new List<DAttribute>() }; if(c == 'J' || c == 'K' ||c == 'L') { switch (c) { case 'J': par.Attributes.Add (new Modifier (DTokens.Out)); break; case 'K': par.Attributes.Add (new Modifier (DTokens.Ref)); break; case 'L': par.Attributes.Add (new Modifier (DTokens.Lazy)); break; } c = (char)r.Read(); } parType = Type(c); par.Type = DTypeToTypeDeclVisitor.GenerateTypeDecl(parType); return par; }
INode[] AliasDeclaration(IBlockNode Scope) { Step(); // _t is just a synthetic node which holds possible following attributes var _t = new DVariable(); ApplyAttributes(_t); _t.Description = GetComments(); List<INode> decls; // AliasThis if ((laKind == Identifier && Lexer.CurrentPeekToken.Kind == This) || (laKind == This && Lexer.CurrentPeekToken.Kind == Assign)) return new[]{AliasThisDeclaration(_t, Scope)}; // AliasInitializerList else if(laKind == Identifier && (Lexer.CurrentPeekToken.Kind == Assign || (Lexer.CurrentPeekToken.Kind == OpenParenthesis && OverPeekBrackets(OpenParenthesis) && Lexer.CurrentPeekToken.Kind == Assign))) { decls = new List<INode>(); do{ if(laKind == Comma) Step(); if(!Expect(Identifier)) break; var dv = new DVariable{ IsAlias = true, Attributes = _t.Attributes, Description = _t.Description, Name = t.Value, NameLocation = t.Location, Location = t.Location, Parent = Scope }; if(laKind == OpenParenthesis){ var ep = new EponymousTemplate(); ep.AssignFrom(dv); dv = ep; TemplateParameterList(ep); } if(Expect(Assign)) { Lexer.PushLookAheadBackup(); var wkTypeParsingBackup = AllowWeakTypeParsing; AllowWeakTypeParsing = true; dv.Type = Type(); AllowWeakTypeParsing = wkTypeParsingBackup; if(!(laKind == Comma || laKind == Semicolon)) { Lexer.RestoreLookAheadBackup(); dv.Initializer = AssignExpression(Scope); } else Lexer.PopLookAheadBackup(); } decls.Add(dv); } while(laKind == Comma); Expect(Semicolon); decls[decls.Count-1].Description += CheckForPostSemicolonComment(); return decls.ToArray(); } // alias BasicType Declarator decls=Decl(Scope, laKind != Identifier || Lexer.CurrentPeekToken.Kind != OpenParenthesis ? null : new Modifier(DTokens.Alias)); if(decls!=null){ foreach (var n in decls) { var dv = n as DVariable; if (dv != null) { if (n.NameHash == DTokens.IncompleteIdHash && n.Type == null) // 'alias |' shall trigger completion, 'alias int |' not n.NameHash = 0; dv.Attributes.AddRange (_t.Attributes); dv.IsAlias = true; } } decls[decls.Count-1].Description += CheckForPostSemicolonComment(); return decls.ToArray (); } return null; }