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;
+    }
+}
+