Mercurial > projects > dang
view sema/SymbolTableBuilder.d @ 45:9bc660cbdbec new_gen
If statements are back
Also fixed a bug in the codegen preventing return in the else branch, now
it is optional.
Also found an issue with the way we are generating our llvm from ifs - it
doesn't mean anything but the code looks ugly.
if (cond_1)
if (cond_2)
statement;
return 0;
Becomes:
br cond_1, then, merge
then:
br cond_2 then2, merge2
merge:
ret 0
then2:
statements
merge2:
br merge
This is because we use appendBasicBlock on the function
author | Anders Halager <halager@gmail.com> |
---|---|
date | Wed, 23 Apr 2008 16:43:42 +0200 |
parents | 495188f9078e |
children | da551f90e03f |
line wrap: on
line source
module sema.SymbolTableBuilder; import tango.io.Stdout, tango.core.Array : find; public import sema.SymbolTable; import sema.Visitor; class SymbolTableBuilder : 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); } override void visitDecl(Decl d) { d.env = current(); super.visitDecl(d); } override void visitStmt(Stmt s) { s.env = current(); super.visitStmt(s); } override void visitExp(Exp e) { e.env = current(); super.visitExp(e); } override void visitFuncDecl(FuncDecl d) { auto sym = current().add(d.identifier); auto sc = push(); sym.type = typeOf(d.type, sc); visitExp(d.type); visitExp(d.identifier); d.env = current(); sc.parentFunction = sym; foreach (arg; d.funcArgs) visitDecl(arg); foreach (stmt; d.statements) visitStmt(stmt); pop(sc); } override void visitVarDecl(VarDecl d) { if (d.init) visitExp(d.init); if (need_push > 0) { push(); --need_push; } auto sc = current(); auto sym = sc.add(d.identifier); sym.type = typeOf(d.type, sc); d.env = sc; visitExp(d.type); visitExp(d.identifier); } override void visitStructDecl(StructDecl s) { auto sc = current(); auto sym = sc.add(s.identifier); DType[char[]] types; foreach(varDecl ; s.vars) { types[varDecl.identifier.get] = typeOf(varDecl.type, sc); } auto type = new DStruct(s.identifier); type.setMembers(types); sc.types[s.identifier.get] = type; sym.type = type; s.env = sc; super.visitStructDecl(s); } 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]; } DType typeOf(Identifier id, Scope sc) { return sc.findType(id); /* if (auto type = id.get in types) return *type; DType res = new DType(id); types[id.get] = res; return res;*/ } DType[char[]] types; }