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