diff --git a/astprinter.d b/astprinter.d index 7dd03c5..f6c2d47 100644 --- a/astprinter.d +++ b/astprinter.d @@ -1179,8 +1179,21 @@ class XMLPrinter : ASTVisitor mixin (tagAndAccept!"templateArguments"); } + override void visit (EponymousTemplateDeclaration eponymousTemplateDeclaration) + { + mixin (tagAndAccept!"eponymousTemplateDeclaration"); + } + override void visit(TemplateDeclaration templateDeclaration) { + if (templateDeclaration.eponymousTemplateDeclaration !is null) + { + output.writeln(""); + visit(templateDeclaration.eponymousTemplateDeclaration); + output.writeln(""); + return; + } + output.writeln(""); output.writeln("", templateDeclaration.name.value, ""); diff --git a/stdx/d/ast.d b/stdx/d/ast.d index babb016..db470e6 100644 --- a/stdx/d/ast.d +++ b/stdx/d/ast.d @@ -101,6 +101,7 @@ public: /** */ void visit(EnumBody enumBody) { enumBody.accept(this); } /** */ void visit(EnumDeclaration enumDeclaration) { enumDeclaration.accept(this); } /** */ void visit(EnumMember enumMember) { enumMember.accept(this); } + /** */ void visit(EponymousTemplateDeclaration eponymousTemplateDeclaration) { eponymousTemplateDeclaration.accept(this); } /** */ void visit(EqualExpression equalExpression) { equalExpression.accept(this); } /** */ void visit(Expression expression) { expression.accept(this); } /** */ void visit(ExpressionNode expressionNode) { expressionNode.accept(this); } @@ -1126,6 +1127,19 @@ public: /** */ AssignExpression assignExpression; } +/// +class EponymousTemplateDeclaration : ASTNode +{ +public: + override void accept(ASTVisitor visitor) + { + mixin (visitIfNotNull!(name, templateParameters, assignExpression)); + } + /** */ Token name; + /** */ TemplateParameters templateParameters; + /** */ AssignExpression assignExpression; +} + /// class EqualExpression : ExpressionNode { @@ -2354,12 +2368,13 @@ public: override void accept(ASTVisitor visitor) { mixin (visitIfNotNull!(name, templateParameters, constraint, - declarations)); + declarations, eponymousTemplateDeclaration)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ Declaration[] declarations; + /** */ EponymousTemplateDeclaration eponymousTemplateDeclaration; } /// diff --git a/stdx/d/parser.d b/stdx/d/parser.d index 160ba61..84e84eb 100644 --- a/stdx/d/parser.d +++ b/stdx/d/parser.d @@ -1666,6 +1666,8 @@ class ClassFour(A, B) if (someTest()) : Super {}}c; if (node.destructor is null) return null; break; case enum_: + if (startsWith(TokenType.enum_, TokenType.identifier, TokenType.lParen)) + goto case template_; node.enumDeclaration = parseEnumDeclaration(); if (node.enumDeclaration is null) return null; break; @@ -4890,13 +4892,19 @@ q{(int a, ...) * Parses a TemplateDeclaration * * $(GRAMMAR $(RULEDEF templateDeclaration): - * $(LITERAL 'template') $(LITERAL Identifier) $(RULE templateParameters) $(RULE constraint)? $(LITERAL '{') $(RULE declaration)* $(LITERAL '}') + * $(LITERAL 'template') $(LITERAL Identifier) $(RULE templateParameters) $(RULE constraint)? $(LITERAL '{') $(RULE declaration)* $(LITERAL '}') + * | $(RULE eponymousTemplateDeclaration) * ;) */ TemplateDeclaration parseTemplateDeclaration() { mixin(traceEnterAndExit!(__FUNCTION__)); auto node = new TemplateDeclaration; + if (currentIs(TokenType.enum_)) + { + node.eponymousTemplateDeclaration = parseEponymousTemplateDeclaration(); + return node; + } expect(TokenType.template_); auto ident = expect(TokenType.identifier); if (ident is null) return null; @@ -4915,6 +4923,28 @@ q{(int a, ...) return node; } + /** + * Parses an EponymousTemplateDeclaration + * + * $(GRAMMAR $(RULEDEF eponymousTemplateDeclaration): + * $(LITERAL 'enum') $(LITERAL Identifier) $(RULE templateParameters) $(LITERAL '=') $(RULE assignExpression) $(LITERAL ';') + * ;) + */ + EponymousTemplateDeclaration parseEponymousTemplateDeclaration() + { + mixin(traceEnterAndExit!(__FUNCTION__)); + auto node = new EponymousTemplateDeclaration; + expect(TokenType.enum_); + auto ident = expect(TokenType.identifier); + if (ident is null) return null; + node.name = *ident; + node.templateParameters = parseTemplateParameters(); + expect(TokenType.assign); + node.assignExpression = parseAssignExpression(); + expect(TokenType.semicolon); + return node; + } + /** * Parses a TemplateInstance * @@ -6173,6 +6203,8 @@ protected: return false; else if (peekIs(TokenType.identifier)) { + if (startsWith(TokenType.enum_, TokenType.identifier, TokenType.lParen)) + return false; auto b = setBookmark(); scope(exit) goToBookmark(b); advance();