Mercurial > projects > dang
diff sema/Visitor.d @ 1:2168f4cb73f1
First push
author | johnsen@johnsen-desktop |
---|---|
date | Fri, 18 Apr 2008 02:01:38 +0200 |
parents | |
children | 2c5a8f4c254a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sema/Visitor.d Fri Apr 18 02:01:38 2008 +0200 @@ -0,0 +1,188 @@ +module sema.Visitor; + +import tango.io.Stdout; + +public +import ast.Decl, + ast.Stmt, + ast.Exp; + +import lexer.Token; + +class Visitor(FinalT = int, DeclT = FinalT, StmtT = DeclT, ExpT = StmtT) +{ +public: + FinalT visit(Decl[] decls) + { + foreach (decl; decls) + visitDecl(decl); + static if (is(FinalT == void)) + return; + else + return FinalT.init; + } + + DeclT visitDecl(Decl decl) + { + switch(decl.declType) + { + case DeclType.FuncDecl: + return visitFuncDecl(cast(FuncDecl)decl); + case DeclType.VarDecl: + return visitVarDecl(cast(VarDecl)decl); + default: + throw new Exception("Unknown declaration type"); + } + } + + StmtT visitStmt(Stmt stmt) + { + switch(stmt.stmtType) + { + case StmtType.Return: + return visitReturnStmt(cast(ReturnStmt)stmt); + case StmtType.Decl: + return visitDeclStmt(cast(DeclStmt)stmt); + case StmtType.Exp: + return visitExpStmt(cast(ExpStmt)stmt); + default: + throw new Exception("Unknown statement type"); + } + } + + ExpT visitExp(Exp exp) + { + switch(exp.expType) + { + case ExpType.Binary: + return visitBinaryExp(cast(BinaryExp)exp); + case ExpType.IntegerLit: + return visitIntegerLit(cast(IntegerLit)exp); + case ExpType.Negate: + return visitNegateExp(cast(NegateExp)exp); + case ExpType.AssignExp: + return visitAssignExp(cast(AssignExp)exp); + case ExpType.CallExp: + return visitCallExp(cast(CallExp)exp); + case ExpType.Identifier: + return visitIdentifier(cast(Identifier)exp); + default: + throw new Exception("Unknown expression type"); + } + } + + // Declarations: + DeclT visitVarDecl(VarDecl d) + { + visitExp(d.type); + visitExp(d.identifier); + if (d.init) + visitExp(d.init); + + static if (is(DeclT == void)) + return; + else + return DeclT.init; + } + + DeclT visitFuncDecl(FuncDecl f) + { + visitExp(f.type); + visitExp(f.identifier); + foreach (arg; f.funcArgs) + visitDecl(arg); + foreach (stmt; f.statements) + visitStmt(stmt); + + static if (is(DeclT == void)) + return; + else + return DeclT.init; + } + + // Statements: + StmtT visitReturnStmt(ReturnStmt s) + { + visitExp(s.exp); + static if (is(StmtT == void)) + return; + else + return StmtT.init; + } + + StmtT visitDeclStmt(DeclStmt d) + { + visitDecl(d.decl); + static if (is(StmtT == void)) + return; + else + return StmtT.init; + } + + StmtT visitExpStmt(ExpStmt s) + { + visitExp(s.exp); + static if (is(StmtT == void)) + return; + else + return StmtT.init; + } + + // Expressions: + ExpT visitAssignExp(AssignExp exp) + { + visitExp(exp.identifier); + visitExp(exp.exp); + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + + ExpT visitBinaryExp(BinaryExp exp) + { + visitExp(exp.left); + visitExp(exp.right); + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + + ExpT visitCallExp(CallExp exp) + { + visitExp(exp.exp); + foreach (arg; exp.args) + visitExp(arg); + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + + ExpT visitNegateExp(NegateExp exp) + { + visitExp(exp.exp); + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + + ExpT visitIntegerLit(IntegerLit exp) + { + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + + ExpT visitIdentifier(Identifier exp) + { + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } +} +