import std.d.lexer; import std.d.ast; import std.stdio; template tagAndAccept(string tagName) { immutable tagAndAccept = `output.writeln("<` ~ tagName ~ `>");` ~ tagName ~ `.accept(this);` ~ `output.writeln("");`; } class XMLPrinter : ASTVisitor { override void visit(AddExpression addExpression) { output.writeln(""); output.writeln(""); addExpression.left.accept(this); output.writeln(""); if (addExpression.right !is null) { output.writeln(""); addExpression.right.accept(this); output.writeln(""); } output.writeln(""); } override void visit(AliasDeclaration aliasDeclaration) { mixin (tagAndAccept!"aliasDeclaration"); } override void visit(AliasInitializer aliasInitializer) { mixin (tagAndAccept!"aliasInitializer"); } override void visit(AliasThisDeclaration aliasThisDeclaration) { mixin (tagAndAccept!"aliasThisDeclaration"); } override void visit(AlignAttribute alignAttribute) { output.writeln(""); } override void visit(AndAndExpression andAndExpression) { output.writeln(""); output.writeln(""); andAndExpression.left.accept(this); output.writeln(""); if (andAndExpression.right !is null) { output.writeln(""); andAndExpression.right.accept(this); output.writeln(""); } output.writeln(""); } override void visit(AndExpression andExpression) { output.writeln(""); output.writeln(""); andExpression.left.accept(this); output.writeln(""); if (andExpression.right !is null) { output.writeln(""); andExpression.right.accept(this); output.writeln(""); } output.writeln(""); } override void visit(ArgumentList argumentList) { mixin (tagAndAccept!"argumentList"); } override void visit(Arguments arguments) { mixin (tagAndAccept!"arguments"); } override void visit(ArrayInitializer arrayInitializer) { mixin (tagAndAccept!"arrayInitializer"); } override void visit(ArrayLiteral arrayLiteral) { mixin (tagAndAccept!"arrayLiteral"); } override void visit(ArrayMemberInitialization arrayMemberInitialization) { mixin (tagAndAccept!"arrayMemberInitialization"); } override void visit(AssertExpression assertExpression) { output.writeln(""); output.writeln(""); assertExpression.assertion.accept(this); output.writeln(""); if (assertExpression.message !is null) { output.writeln(""); assertExpression.message.accept(this); output.writeln(""); } output.writeln(""); } override void visit(AssignExpression assignExpression) { if (assignExpression.assignExpression is null) output.writeln(""); else output.writeln(""); assignExpression.accept(this); output.writeln(""); } override void visit(AssocArrayLiteral assocArrayLiteral) { mixin (tagAndAccept!"assocArrayLiteral"); } override void visit(AtAttribute atAttribute) { output.writeln(""); if (atAttribute.identifier.type == TokenType.invalid) atAttribute.accept(this); else output.writeln("", atAttribute.identifier.value, ""); output.writeln(""); } override void visit(Attribute attribute) { output.writeln(""); if (attribute.attribute == TokenType.invalid) attribute.accept(this); else output.writeln(getTokenValue(attribute.attribute)); output.writeln(""); } override void visit(AttributeDeclaration attributeDeclaration) { assert (attributeDeclaration !is null); mixin (tagAndAccept!"attributeDeclaration"); } override void visit(AutoDeclaration autoDec) { output.writeln(""); for (size_t i = 0; i < autoDec.identifiers.length; i++) { output.writeln(""); output.writeln("", autoDec.identifiers[i].value, ""); visit(autoDec.initializers[i]); output.writeln(""); } output.writeln(""); } override void visit(BlockStatement blockStatement) { output.writeln(""); blockStatement.accept(this); output.writeln(""); } override void visit(BodyStatement bodyStatement) { output.writeln(""); bodyStatement.accept(this); output.writeln(""); } override void visit(BreakStatement breakStatement) { if (breakStatement.label.type == TokenType.invalid) output.writeln(""); else output.writeln(""); } override void visit(BaseClass baseClass) { mixin (tagAndAccept!"baseClass"); } override void visit(BaseClassList baseClassList) { mixin (tagAndAccept!"baseClassList"); } override void visit(CaseRangeStatement caseRangeStatement) { output.writeln(""); output.writeln(""); visit(caseRangeStatement.low); output.writeln(""); output.writeln(""); visit(caseRangeStatement.high); output.writeln(""); if (caseRangeStatement.declarationsAndStatements !is null) visit(caseRangeStatement.declarationsAndStatements); output.writeln(""); } override void visit(CaseStatement caseStatement) { mixin (tagAndAccept!"caseStatement"); } override void visit(CastExpression castExpression) { mixin (tagAndAccept!"castExpression"); } override void visit(CastQualifier castQualifier) { mixin (tagAndAccept!"castQualifier"); } override void visit(Catches catches) { mixin (tagAndAccept!"catches"); } override void visit(Catch catch_) { output.writeln(""); catch_.accept(this); output.writeln(""); } override void visit(ClassDeclaration classDec) { output.writeln(""); output.writeln("", classDec.name.value, ""); classDec.accept(this); output.writeln(""); } override void visit(CmpExpression cmpExpression) { mixin (tagAndAccept!"cmpExpression"); } override void visit(CompileCondition compileCondition) { mixin (tagAndAccept!"compileCondition"); } override void visit(ConditionalDeclaration conditionalDeclaration) { output.writeln(""); visit(conditionalDeclaration.compileCondition); output.writeln(""); visit(conditionalDeclaration.trueDeclaration); output.writeln(""); if (conditionalDeclaration.falseDeclaration !is null) { output.writeln(""); visit(conditionalDeclaration.falseDeclaration); output.writeln(""); } output.writeln(""); } override void visit(ConditionalStatement conditionalStatement) { output.writeln(""); visit(conditionalStatement.compileCondition); output.writeln(""); visit(conditionalStatement.trueStatement); output.writeln(""); if (conditionalStatement.falseStatement !is null) { output.writeln(""); visit(conditionalStatement.falseStatement); output.writeln(""); } output.writeln(""); } override void visit(Constraint constraint) { output.writeln(""); constraint.accept(this); output.writeln(""); } override void visit(Constructor constructor) { mixin (tagAndAccept!"constructor"); } override void visit(ContinueStatement continueStatement) { if (continueStatement.label.type == TokenType.invalid) output.writeln(""); else output.writeln(""); } override void visit(DebugCondition debugCondition) { if (debugCondition.identifierOrInteger.type == TokenType.invalid) output.writeln(""); else output.writeln(""); } override void visit(DebugSpecification debugSpecification) { if (debugSpecification.identifierOrInteger.type == TokenType.invalid) output.writeln(""); else output.writeln(""); } override void visit(Declaration declaration) { mixin (tagAndAccept!"declaration"); } override void visit(DeclarationsAndStatements declarationsAndStatements) { mixin (tagAndAccept!"declarationsAndStatements"); } override void visit(DeclarationOrStatement declarationOrStatement) { mixin (tagAndAccept!"declarationOrStatement"); } override void visit(Declarator declarator) { output.writeln(""); output.writeln("", declarator.name.value, ""); declarator.accept(this); output.writeln(""); } override void visit(DefaultStatement defaultStatement) { mixin (tagAndAccept!"defaultStatement"); } override void visit(DeleteExpression deleteExpression) { mixin (tagAndAccept!"deleteExpression"); } override void visit(DeleteStatement deleteStatement) { mixin (tagAndAccept!"deleteStatement"); } override void visit(Deprecated deprecated_) { if (deprecated_.assignExpression !is null) { output.writeln(""); deprecated_.accept(this); output.writeln(""); } else output.writeln(""); } override void visit(Destructor destructor) { mixin (tagAndAccept!"destructor"); } override void visit(DoStatement doStatement) { mixin (tagAndAccept!"doStatement"); } override void visit(EnumBody enumBody) { mixin (tagAndAccept!"enumBody"); } override void visit(EnumDeclaration enumDec) { output.writeln(""); if (enumDec.name.type == TokenType.identifier) output.writeln("", enumDec.name.value, ""); enumDec.accept(this); output.writeln(""); } override void visit(EnumMember enumMem) { output.writeln(""); enumMem.accept(this); output.writeln(""); } override void visit(EqualExpression equalExpression) { output.writeln(""); output.writeln(""); visit(equalExpression.left); output.writeln(""); output.writeln(""); visit(equalExpression.right); output.writeln(""); output.writeln(""); } override void visit(Expression expression) { output.writeln(""); expression.accept(this); output.writeln(""); } override void visit(ExpressionStatement expressionStatement) { output.writeln(""); expressionStatement.accept(this); output.writeln(""); } override void visit(FinalSwitchStatement finalSwitchStatement) { output.writeln(""); finalSwitchStatement.accept(this); output.writeln(""); } override void visit(Finally finally_) { output.writeln(""); finally_.accept(this); output.writeln(""); } override void visit(ForStatement forStatement) { output.writeln(""); // TODO forStatement.accept(this); output.writeln(""); } /*************************************************************************** * BOOKMARK **************************************************************************/ override void visit(Module mod) { output.writeln(""); mod.accept(this); output.writeln(""); } override void visit(ModuleDeclaration modDec) { output.writeln(""); modDec.accept(this); output.writeln(""); } override void visit(IdentifierChain chain) { output.writeln(""); chain.accept(this); output.writeln(""); } override void visit(IdentifierList list) { output.writeln(""); list.accept(this); output.writeln(""); } override void visit(FunctionBody functionBody) { mixin (tagAndAccept!"functionBody"); } override void visit(FunctionDeclaration functionDec) { output.writeln(""); output.writeln("", functionDec.name.value, ""); functionDec.accept(this); output.writeln(""); } override void visit(ImportDeclaration importDeclaration) { mixin (tagAndAccept!"importDeclaration"); } override void visit(InterfaceDeclaration interfaceDec) { output.writeln(""); output.writeln("", interfaceDec.name.value, ""); interfaceDec.accept(this); output.writeln(""); } override void visit(Parameters parameters) { mixin (tagAndAccept!"parameters"); } override void visit(Parameter param) { output.writeln(""); if (param.name.type == TokenType.identifier) output.writeln("", param.name.value, ""); foreach (attribute; param.parameterAttributes) { output.writeln("", getTokenValue(attribute), ""); } param.accept(this); if (param.vararg) output.writeln(""); output.writeln(""); } override void visit(StructDeclaration structDec) { output.writeln(""); output.writeln("", structDec.name.value, ""); structDec.accept(this); output.writeln(""); } override void visit(Token token) { string tagName; with (TokenType) switch (token.type) { case identifier: tagName = "identifier"; break; case doubleLiteral: tagName = "doubleLiteral"; break; case idoubleLiteral: tagName = "idoubleLiteral"; break; case floatLiteral: tagName = "floatLiteral"; break; case ifloatLiteral: tagName = "ifloatLiteral"; break; case intLiteral: tagName = "intLiteral"; break; case uintLiteral: tagName = "uintLiteral"; break; case longLiteral: tagName = "longLiteral"; break; case ulongLiteral: tagName = "ulongLiteral"; break; case realLiteral: tagName = "realLiteral"; break; case irealLiteral: tagName = "irealLiteral"; break; case characterLiteral: tagName = "characterLiteral"; break; case stringLiteral: tagName = "stringLiteral"; break; case dstringLiteral: tagName = "dstringLiteral"; break; case wstringLiteral: tagName = "wstringLiteral"; break; default: tagName = "token"; } output.writeln("<", tagName, ">"); } override void visit(Type type) { output.writeln(""); type.accept(this); output.writeln(""); } override void visit(Unittest unittest_) { output.writeln(""); unittest_.accept(this); output.writeln(""); } override void visit(VariableDeclaration variableDeclaration) { mixin (tagAndAccept!"variableDeclaration") } alias ASTVisitor.visit visit; File output; }