Mercurial > projects > dang
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]; + } +} +