Mercurial > projects > dang
view sema/ScopeBuilder.d @ 103:09b4d74cb3f5 new_gen
Parsing char, wchar and dchar as basic types.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Thu, 08 May 2008 10:54:29 +0200 |
parents | cd066f3b539a |
children | 189c049cbfcc |
line wrap: on
line source
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(Module[] modules) { this.modules = modules; super.visit(modules); } override void visitFuncDecl(FuncDecl d) { visitExp(d.returnType); visitExp(d.identifier); foreach (arg; d.funcArgs) visitDecl(arg); foreach (stmt; d.statements) visitStmt(stmt); d.env.find(d.identifier).setType(d.type); } override void visitVarDecl(VarDecl d) { visitExp(d.varType); visitExp(d.identifier); if (d.init) visitExp(d.init); d.env.find(d.identifier).setType( typeOf(d.varType, d.env) ); } override void visitStructDecl(StructDecl s) { DType[char[]] types; auto st = s.env.types[s.identifier.get].asStruct; foreach(decl ; s.decls) if(auto varDecl = cast(VarDecl)decl) 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); } Module[] modules; } class ScopeBuilder : Visitor!(void) { static ModuleHandler mHandle; static this() { mHandle = new ModuleHandler; } this() { } override void visit(Module[] modules) { foreach(m ; modules) visitModule(m); auto fr = new ForwardReference(); fr.visit(modules); } override void visitModule(Module m) { table ~= new Scope; table[table.length-1].types["void"] = DType.Void; table[table.length-1].types["bool"] = DType.Bool; table[table.length-1].types["byte"] = DType.Byte; table[table.length-1].types["ubyte"] = DType.UByte; table[table.length-1].types["short"] = DType.Short; table[table.length-1].types["ushort"] = DType.UShort; table[table.length-1].types["int"] = DType.Int; table[table.length-1].types["uint"] = DType.UInt; table[table.length-1].types["long"] = DType.Long; table[table.length-1].types["ulong"] = DType.ULong; table[table.length-1].types["char"] = DType.Char; table[table.length-1].types["wchar"] = DType.WChar; table[table.length-1].types["dchar"] = DType.DChar; 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().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(); sc.add(d.identifier); d.env = sc; visitExp(d.varType); visitExp(d.identifier); } override void visitStructDecl(StructDecl s) { auto sc = current(); 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]; } }