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("` ~ tagName ~ `>");`;
}
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, ">", 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;
}