view sema/SymbolTableBuilder.d @ 22:e331e4e816e4

now handling structs to some extend
author johnsen@johnsen-laptop
date Fri, 18 Apr 2008 23:45:45 +0200
parents a51bdf15a33d
children 2d28b21faad6
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;
    }

    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);
        sym.type = d.type;
        visitExp(d.type);
        visitExp(d.identifier);
        d.env = current();
        auto sc = push();
        sc.parentFunction = sym;
        foreach (arg; d.funcArgs)
            visitDecl(arg);
        foreach (stmt; d.statements)
            visitStmt(stmt);
        pop(sc);
    }

    override void visitVarDecl(VarDecl d)
    {
        auto sc = current();
        auto sym = sc.add(d.identifier);
        sym.type = d.type;
        super.visitVarDecl(d);
    }

    override void visitStructDecl(StructDecl s)
    {
        auto sc = current();
        auto sym = sc.add(s.identifier);
//        sym.type = Tok.Struct;
        super.visitStructDecl(s);
    }

    override void visitDeclStmt(DeclStmt d)
    {
        super.visitDeclStmt(d);
        push();
    }

    override void visitIfStmt(IfStmt s)
    {
        s.env = current();
        visitExp(s.cond);
        auto sc = push();
        foreach (stmt; s.then_body)
            visitStmt(stmt);
        pop(sc);

        sc = push();
        foreach (stmt; s.else_body)
            visitStmt(stmt);
        pop(sc);
    }

    override void visitWhileStmt(WhileStmt s)
    {
        s.env = current();
        auto sc = push();
        super.visitWhileStmt(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];
    }
}