Mercurial > projects > dil
diff src/dil/ast/DefaultVisitor.d @ 806:bcb74c9b895c
Moved out files in the trunk folder to the root.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 09 Mar 2008 00:12:19 +0100 |
parents | trunk/src/dil/ast/DefaultVisitor.d@9e6c6bb73e5f |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dil/ast/DefaultVisitor.d Sun Mar 09 00:12:19 2008 +0100 @@ -0,0 +1,375 @@ +/++ + Author: Aziz Köksal + License: GPL3 ++/ +module dil.ast.DefaultVisitor; + +import dil.ast.Visitor; + +import dil.ast.Node; +import dil.ast.Declarations, + dil.ast.Expressions, + dil.ast.Statements, + dil.ast.Types, + dil.ast.Parameters; +import common; + +/// This huge template function, when instantiated for a certain node class, +/// generates a body of calls to visit() on the subnodes. +returnType!(T.stringof) visitDefault(T)(T t) +{ + assert(t !is null, "node passed to visitDefault() is null"); + //Stdout(t).newline; + + alias t d, s, e, n; // Variable aliases of t. + + static if (is(T : Declaration)) + { + alias T D; + static if (is(D == CompoundDeclaration)) + foreach (decl; d.decls) + visitD(decl); + //EmptyDeclaration, + //IllegalDeclaration, + //ModuleDeclaration have no subnodes. + static if (is(D == AliasDeclaration) || + is(D == TypedefDeclaration)) + visitD(d.decl); + static if (is(D == EnumDeclaration)) + { + d.baseType && visitT(d.baseType); + foreach (member; d.members) + visitD(member); + } + static if (is(D == EnumMemberDeclaration)) + d.value && visitE(d.value); + static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration)) + { +// visitN(d.tparams); + foreach (base; d.bases) + visitT(base); + d.decls && visitD(d.decls); + } + static if (is(D == StructDeclaration) || is(D == UnionDeclaration)) +// visitN(d.tparams), + d.decls && visitD(d.decls); + static if (is(D == ConstructorDeclaration)) + visitN(d.params), visitS(d.funcBody); + static if (is(D == StaticConstructorDeclaration) || + is(D == DestructorDeclaration) || + is(D == StaticDestructorDeclaration) || + is(D == InvariantDeclaration) || + is(D == UnittestDeclaration)) + visitS(d.funcBody); + static if (is(D == FunctionDeclaration)) + visitT(d.returnType), +// visitN(d.tparams), + visitN(d.params), + visitS(d.funcBody); + static if (is(D == VariablesDeclaration)) + { + d.typeNode && visitT(d.typeNode); + foreach(init; d.inits) + init && visitE(init); + } + static if (is(D == DebugDeclaration) || is(D == VersionDeclaration)) + d.decls && visitD(d.decls), + d.elseDecls && visitD(d.elseDecls); + static if (is(D == StaticIfDeclaration)) + visitE(d.condition), + visitD(d.ifDecls), + d.elseDecls && visitD(d.elseDecls); + static if (is(D == StaticAssertDeclaration)) + visitE(d.condition), + d.message && visitE(d.message); + static if (is(D == TemplateDeclaration)) + visitN(d.tparams), + visitD(d.decls); + static if (is(D == NewDeclaration) || is(D == DeleteDeclaration)) + visitN(d.params), + visitS(d.funcBody); + static if (is(D == ProtectionDeclaration) || + is(D == StorageClassDeclaration) || + is(D == LinkageDeclaration) || + is(D == AlignDeclaration)) + visitD(d.decls); + static if (is(D == PragmaDeclaration)) + { + foreach (arg; d.args) + visitE(arg); + visitD(d.decls); + } + static if (is(D == MixinDeclaration)) + d.templateExpr ? visitE(d.templateExpr) : visitE(d.argument); + } + else + static if (is(T : Expression)) + { + alias T E; + static if (is(E == IllegalExpression)) + {} + else + static if (is(E == CondExpression)) + visitE(e.condition), visitE(e.lhs), visitE(e.rhs); + else + static if (is(E : BinaryExpression)) + visitE(e.lhs), visitE(e.rhs); + else + static if (is(E : UnaryExpression)) + { + static if (is(E == CastExpression)) + visitT(e.type); + visitE(e.e); // Visit member in base class UnaryExpression. + static if (is(E == IndexExpression)) + foreach (arg; e.args) + visitE(arg); + static if (is(E == SliceExpression)) + e.left && (visitE(e.left), visitE(e.right)); + static if (is(E == AsmPostBracketExpression)) + visitE(e.e2); + } + else + { + static if (is(E == NewExpression)) + { + foreach (arg; e.newArgs) + visitE(arg); + visitT(e.type); + foreach (arg; e.ctorArgs) + visitE(arg); + } + static if (is(E == NewAnonClassExpression)) + { + foreach (arg; e.newArgs) + visitE(arg); + foreach (base; e.bases) + visitT(base); + foreach (arg; e.ctorArgs) + visitE(arg); + visitD(e.decls); + } + static if (is(E == AsmBracketExpression)) + visitE(e.e); + static if (is(E == TemplateInstanceExpression)) + e.targs && visitN(e.targs); + static if (is(E == ArrayLiteralExpression)) + foreach (value; e.values) + visitE(value); + static if (is(E == AArrayLiteralExpression)) + foreach (i, key; e.keys) + visitE(key), visitE(e.values[i]); + static if (is(E == AssertExpression)) + visitE(e.expr), e.msg && visitE(e.msg); + static if (is(E == MixinExpression) || + is(E == ImportExpression)) + visitE(e.expr); + static if (is(E == TypeofExpression) || + is(E == TypeDotIdExpression) || + is(E == TypeidExpression)) + visitT(e.type); + static if (is(E == IsExpression)) + visitT(e.type), e.specType && visitT(e.specType), + e.tparams && visitN(e.tparams); + static if (is(E == FunctionLiteralExpression)) + e.returnType && visitT(e.returnType), + e.params && visitN(e.params), + visitS(e.funcBody); + static if (is(E == ParenExpression)) + visitE(e.next); + static if (is(E == TraitsExpression)) + visitN(e.targs); + // VoidInitializer has no subnodes. + static if (is(E == ArrayInitExpression)) + foreach (i, key; e.keys) + key && visitE(key), visitE(e.values[i]); + static if (is(E == StructInitExpression)) + foreach (value; e.values) + visitE(value); + } + } + else + static if (is(T : Statement)) + { + alias T S; + static if (is(S == CompoundStatement)) + foreach (stmnt; s.stmnts) + visitS(stmnt); + //IllegalStatement has no subnodes. + static if (is(S == FuncBodyStatement)) + s.funcBody && visitS(s.funcBody), + s.inBody && visitS(s.inBody), + s.outBody && visitS(s.outBody); + static if (is(S == ScopeStatement) || is(S == LabeledStatement)) + visitS(s.s); + static if (is(S == ExpressionStatement)) + visitE(s.e); + static if (is(S == DeclarationStatement)) + visitD(s.decl); + static if (is(S == IfStatement)) + { + s.variable ? cast(Node)visitS(s.variable) : visitE(s.condition); + visitS(s.ifBody), s.elseBody && visitS(s.elseBody); + } + static if (is(S == WhileStatement)) + visitE(s.condition), visitS(s.whileBody); + static if (is(S == DoWhileStatement)) + visitS(s.doBody), visitE(s.condition); + static if (is(S == ForStatement)) + s.init && visitS(s.init), + s.condition && visitE(s.condition), + s.increment && visitE(s.increment), + visitS(s.forBody); + static if (is(S == ForeachStatement)) + visitN(s.params), visitE(s.aggregate), visitS(s.forBody); + static if (is(S == ForeachRangeStatement)) + visitN(s.params), visitE(s.lower), visitE(s.upper), visitS(s.forBody); + static if (is(S == SwitchStatement)) + visitE(s.condition), visitS(s.switchBody); + static if (is(S == CaseStatement)) + { + foreach (value; s.values) + visitE(value); + visitS(s.caseBody); + } + static if (is(S == DefaultStatement)) + visitS(s.defaultBody); + //ContinueStatement, + //BreakStatement have no subnodes. + static if (is(S == ReturnStatement)) + s.e && visitE(s.e); + static if (is(S == GotoStatement)) + s.caseExpr && visitE(s.caseExpr); + static if (is(S == WithStatement)) + visitE(s.e), visitS(s.withBody); + static if (is(S == SynchronizedStatement)) + s.e && visitE(s.e), visitS(s.syncBody); + static if (is(S == TryStatement)) + { + visitS(s.tryBody); + foreach (catchBody; s.catchBodies) + visitS(catchBody); + s.finallyBody && visitS(s.finallyBody); + } + static if (is(S == CatchStatement)) + s.param && visitN(s.param), visitS(s.catchBody); + static if (is(S == FinallyStatement)) + visitS(s.finallyBody); + static if (is(S == ScopeGuardStatement)) + visitS(s.scopeBody); + static if (is(S == ThrowStatement)) + visitE(s.e); + static if (is(S == VolatileStatement)) + s.volatileBody && visitS(s.volatileBody); + static if (is(S == AsmBlockStatement)) + visitS(s.statements); + static if (is(S == AsmStatement)) + foreach (op; s.operands) + visitE(op); + //AsmAlignStatement, + //IllegalAsmStatement have no subnodes. + static if (is(S == PragmaStatement)) + { + foreach (arg; s.args) + visitE(arg); + visitS(s.pragmaBody); + } + static if (is(S == MixinStatement)) + visitE(s.templateExpr); + static if (is(S == StaticIfStatement)) + visitE(s.condition), visitS(s.ifBody), s.elseBody && visitS(s.elseBody); + static if (is(S == StaticAssertStatement)) + visitE(s.condition), s.message && visitE(s.message); + static if (is(S == DebugStatement) || is(S == VersionStatement)) + visitS(s.mainBody), s.elseBody && visitS(s.elseBody); + } + else + static if (is(T : TypeNode)) + { + //IllegalType, + //IntegralType, + //ModuleScopeType, + //IdentifierType have no subnodes. + static if (is(T == QualifiedType)) + visitT(t.lhs), visitT(t.rhs); + static if (is(T == TypeofType)) + visitE(t.e); + static if (is(T == TemplateInstanceType)) + t.targs && visitN(t.targs); + static if (is(T == PointerType)) + visitT(t.next); + static if (is(T == ArrayType)) + { + visitT(t.next); + if (t.assocType) + visitT(t.assocType); + else if (t.e1) + visitE(t.e1), t.e2 && visitE(t.e2); + } + static if (is(T == FunctionType) || is(T == DelegateType)) + visitT(t.returnType), visitN(t.params); + static if (is(T == CFuncPointerType)) + visitT(t.next), t.params && visitN(t.params); + static if (is(T == BaseClassType) || + is(T == ConstType) || + is(T == InvariantType)) + visitT(t.next); + } + else + static if (is(T == Parameter)) + { + n.type && visitT(n.type); + n.defValue && visitE(n.defValue); + } + else + static if (is(T == Parameters) || + is(T == TemplateParameters) || + is(T == TemplateArguments)) + { + foreach (node; n.children) + visitN(node); + } + else + static if (is(T : TemplateParameter)) + { + static if (is(N == TemplateAliasParameter) || + is(N == TemplateTypeParameter) || + is(N == TemplateThisParameter)) + n.specType && visitN(n.specType), + n.defType && visitN(n.defType); + static if (is(N == TemplateValueParameter)) + visitT(n.valueType), + n.specValue && visitN(n.specValue), + n.defValue && visitN(n.defValue); + //TemplateTupleParameter has no subnodes. + } + else + static assert(0, "Missing default visit method for: "~typeof(t).stringof); + return t; +} + +/// Generates the default visit methods. +/// +/// E.g: +/// --- +/// private mixin .visitDefault!(ClassDeclaration) _ClassDeclaration; +/// override returnType!("ClassDeclaration") visit(ClassDeclaration node) +/// { return _ClassDeclaration.visitDefault(node); } +/// --- +char[] generateDefaultVisitMethods() +{ + char[] text; + foreach (className; g_classNames) + text ~= "private mixin .visitDefault!("~className~") _"~className~";\n" + "override returnType!(\""~className~"\") visit("~className~" node)" + "{return _"~className~".visitDefault(node);}\n"; + return text; +} +// pragma(msg, generateDefaultVisitMethods()); + +/// This class provides default methods for +/// traversing nodes and their sub-nodes. +class DefaultVisitor : Visitor +{ + // Comment out if too many errors are shown. + mixin(generateDefaultVisitMethods()); +}