diff sema/BuildScopes.d @ 194:08f68d684047

Rename some files. Hopefully we can get a more iterative sema pass, that's a lot easier to "get startet with". Also added support for alias.
author Anders Johnsen <skabet@gmail.com>
date Tue, 29 Jul 2008 13:54:44 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sema/BuildScopes.d	Tue Jul 29 13:54:44 2008 +0200
@@ -0,0 +1,265 @@
+module sema.BuildScopes;
+
+import tango.io.Stdout,
+       tango.core.Array : find;
+
+import sema.Scope;
+
+import sema.Visitor;
+
+/**
+  Add scopes to everything, and add all identifiers that correspond to types.
+  Types/Symbols are added by ForwardReference.
+ **/
+class BuildScopes : Visitor!(void)
+{
+    static ModuleHandler mHandle;
+
+    static this()
+    {
+        mHandle = new ModuleHandler;
+    }
+
+    override void visit(Module[] modules)
+    {
+        foreach(m ; modules)
+            visitModule(m);
+    }
+
+    private void registerBasicTypeTo(char[] n, DType t, Scope sc, Module m)
+    {
+        sc.types[n] = t;
+        auto id = new Identifier(n);
+        id.env = sc;
+        auto decl = new DummyDecl();
+        auto sym = m.symbol.createMember(n, t, decl);
+        sym.decl = decl;
+        decl.sym = sym;
+        decl.env = sc;
+        sc.put(id.get, decl);
+    }
+
+    override void visitModule(Module m)
+    {
+        auto root = new Scope;
+        table ~= root;
+
+        m.symbol = new Symbol;
+
+        registerBasicTypeTo("void",     DType.Void, root, m);
+        registerBasicTypeTo("bool",     DType.Bool, root, m);
+        registerBasicTypeTo("byte",     DType.Byte, root, m);
+        registerBasicTypeTo("ubyte",    DType.UByte, root, m);
+        registerBasicTypeTo("short",    DType.Short, root, m);
+        registerBasicTypeTo("ushort",   DType.UShort, root, m);
+        registerBasicTypeTo("int",      DType.Int, root, m);
+        registerBasicTypeTo("uint",     DType.UInt, root, m);
+        registerBasicTypeTo("long",     DType.Long, root, m);
+        registerBasicTypeTo("ulong",    DType.ULong, root, m);
+
+        registerBasicTypeTo("char",     DType.Char, root, m);
+        registerBasicTypeTo("wchar",    DType.WChar, root, m);
+        registerBasicTypeTo("dchar",    DType.DChar, root, m);
+
+        registerBasicTypeTo("float",    DType.Float, root, m);
+        registerBasicTypeTo("double",   DType.Double, root, m);
+        registerBasicTypeTo("real",     DType.Real, root, m);
+
+        current().inModule = m;
+        current().mHandle = mHandle;
+        mHandle.add(m);
+        m.env = current();
+        super.visitModule(m);
+    }
+
+    override void visitDecl(Decl d)
+    {
+        d.env = current();
+        super.visitDecl(d);
+    }
+
+    override void visitImportDecl(ImportDecl i)
+    {
+        i.env.imports ~= i;
+        super.visitImportDecl(i);
+    }
+
+    override void visitStmt(Stmt s)
+    {
+        s.env = current();
+        s.stmtIndex = s.env.stmtIndex;
+        super.visitStmt(s);
+    }
+
+    override void visitExp(Exp e)
+    {
+        e.env = current();
+        e.stmtIndex = e.env.stmtIndex;
+        super.visitExp(e);
+    }
+
+    override void visitFuncDecl(FuncDecl d)
+    {
+        current().put(d.identifier.get, d);
+        d.env = current();
+        auto sc = push();
+
+        visitExp(d.returnType);
+        visitExp(d.identifier);
+        sc.parentFunction = d;
+        foreach (arg; d.funcArgs)
+            visitDecl(arg);
+        foreach (stmt; d.statements)
+        {
+            sc.currentStmtIndex++;
+            visitStmt(stmt);
+        }
+        pop(sc);
+    }
+
+    override void visitVarDecl(VarDecl d)
+    {
+        if (d.init)
+            visitExp(d.init);
+
+        if (need_push > 0 && current().parentFunction !is null) {
+            push();
+            --need_push;
+        }
+
+        if(d.identifier)
+        {
+            auto sc = current();
+            sc.put(d.identifier.get, d);
+            d.env = sc;
+            visitExp(d.varType);
+            visitExp(d.identifier);
+        }
+    }
+
+    override void visitStructDecl(StructDecl s)
+    {
+        auto sc = current();
+        sc.put(s.identifier.get, s);
+        s.env = sc;
+        auto type = new DStruct(s.identifier);
+
+        sc.types[s.identifier.get] = type;
+
+        sc = push();
+        super.visitStructDecl(s);
+        pop(sc);
+    }
+
+    override void visitClassDecl(ClassDecl s)
+    {
+        auto sc = current();
+        sc.put(s.identifier.get, s);
+        s.env = sc;
+        auto type = new DClass(s.identifier);
+
+        sc.types[s.identifier.get] = type;
+
+        sc = push();
+        super.visitClassDecl(s);
+        pop(sc);
+    }
+
+    override void visitInterfaceDecl(InterfaceDecl s)
+    {
+        auto sc = current();
+        sc.put(s.identifier.get, s);
+        s.env = sc;
+        auto type = new DInterface(s.identifier);
+
+        sc.types[s.identifier.get] = type;
+
+        sc = push();
+        super.visitInterfaceDecl(s);
+        pop(sc);
+    }
+    
+    override void visitAliasDecl(AliasDecl a)
+    {
+        a.env = current();
+//        auto decl = cast(VarDecl)a.decl;
+//        auto sc = current();
+//        super.visitDecl(a.decl);
+    }
+
+    override void visitDeclStmt(DeclStmt d)
+    {
+        ++need_push;
+        super.visitDeclStmt(d);
+    }
+    private uint need_push = 0;
+
+    override void visitIfStmt(IfStmt s)
+    {
+        s.env = current();
+        visitExp(s.cond);
+        auto sc = push();
+        visitStmt(s.then_body);
+        pop(sc);
+
+        if (s.else_body !is null)
+        {
+            sc = push();
+            visitStmt(s.else_body);
+            pop(sc);
+        }
+    }
+
+    override void visitWhileStmt(WhileStmt s)
+    {
+        s.env = current();
+        auto sc = push();
+        super.visitWhileStmt(s);
+        pop(sc);
+    }
+
+    override void visitForStmt(ForStmt s)
+    {
+        s.env = current();
+        auto sc = push();
+        super.visitForStmt(s);
+        pop(sc);
+    }
+
+    override void visitCompoundStmt(CompoundStatement s)
+    {
+        s.env = current();
+        auto sc = push();
+        super.visitCompoundStmt(s);
+        pop(sc);
+    }
+
+private:
+    Scope[] table;
+
+    Scope push()
+    {
+        auto sc = new Scope(current());
+        table ~= sc;
+        return sc;
+    }
+
+    Scope pop(Scope sc = null)
+    {
+        if (sc !is null)
+        {
+            table.length = table.find(sc);
+            return sc;
+        }
+
+        auto res = table[$ - 1];
+        table.length = table.length - 1;
+        return res;
+    }
+
+    Scope current()
+    {
+        return table[$ - 1];
+    }
+}
+