Mercurial > projects > dang
diff sema/ScopeBuilder.d @ 92:771ac63898e2 new_gen
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Mon, 05 May 2008 18:44:20 +0200 |
parents | sema/SymbolTableBuilder.d@29f486ccc203 |
children | 621cedba53ea |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sema/ScopeBuilder.d Mon May 05 18:44:20 2008 +0200 @@ -0,0 +1,227 @@ +module sema.ScopeBuilder; + +import tango.io.Stdout, + tango.core.Array : find; + +public +import sema.Scope; + +import sema.Visitor, + basic.SmallArray; + +class ForwardReference : Visitor!(void) +{ + override void visit(Decl[] decls) + { + foreach (decl; decls) + visitDecl(decl); + } + + override void visitFuncDecl(FuncDecl d) + { + visitExp(d.returnType); + visitExp(d.identifier); + foreach (arg; d.funcArgs) + visitDecl(arg); + foreach (stmt; d.statements) + visitStmt(stmt); + + auto sym = d.env.find(d.identifier); + sym.type = d.type; + } + + override void visitVarDecl(VarDecl d) + { + visitExp(d.varType); + visitExp(d.identifier); + + if (d.init) + visitExp(d.init); + + d.env.find(d.identifier).type = typeOf(d.varType, d.env); + } + + override void visitStructDecl(StructDecl s) + { + DType[char[]] types; + + auto st = s.env.types[s.identifier.get].asStruct; + foreach(varDecl ; s.vars) + st.addMember(typeOf(varDecl.varType, varDecl.env), varDecl.identifier.get); + + super.visitStructDecl(s); + } + + DType typeOf(Identifier id, Scope sc) + { + if(auto i = cast(PointerIdentifier)id) + return (typeOf(i.pointerOf, sc)).getPointerTo(); + if(auto i = cast(ArrayIdentifier)id) + return typeOf(i.arrayOf, sc).getAsArray(i.size); + return sc.findType(id); + } +} + +class ScopeBuilder : Visitor!(void) +{ + this() + { + table ~= new Scope; + table[0].types["void"] = DType.Void; + table[0].types["bool"] = DType.Bool; + table[0].types["byte"] = DType.Byte; + table[0].types["ubyte"] = DType.UByte; + table[0].types["short"] = DType.Short; + table[0].types["ushort"] = DType.UShort; + table[0].types["int"] = DType.Int; + table[0].types["uint"] = DType.UInt; + table[0].types["long"] = DType.Long; + table[0].types["ulong"] = DType.ULong; + } + + override void visit(Decl[] decls) + { + foreach (decl; decls) + visitDecl(decl); + auto fr = new ForwardReference(); + fr.visit(decls); + } + + override void visitDecl(Decl d) + { + d.env = current(); + super.visitDecl(d); + } + + 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) + { + auto sym = current().add(d.identifier); + auto sc = push(); + + visitExp(d.returnType); + visitExp(d.identifier); + d.env = current(); + 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; + } + + auto sc = current(); + auto sym = sc.add(d.identifier); + d.env = sc; + visitExp(d.varType); + visitExp(d.identifier); + } + + override void visitStructDecl(StructDecl s) + { + auto sc = current(); + auto sym = sc.add(s.identifier); + s.env = sc; + auto type = new DStruct(s.identifier); + + sc.types[s.identifier.get] = type; + + sc = push(); + super.visitStructDecl(s); + pop(sc); + } + + 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 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]; + } +} +