view sema/SymbolTableBuilder.d @ 11:642c6a998fd9

Support for while statements and fixed scope for if
author Anders Halager <halager@gmail.com>
date Fri, 18 Apr 2008 13:45:39 +0200
parents ae5bbe4e7fd6
children a51bdf15a33d
line wrap: on
line source

module sema.SymbolTableBuilder;

import tango.io.Stdout;

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

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

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

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

    override void visitWhileStmt(WhileStmt s)
    {
        s.env = current();
        push();
        super.visitWhileStmt(s);
        pop();
    }

private:
    Scope[] table;

    void push()
    {
        table ~= new Scope(current());
    }

    Scope pop()
    {
        auto res = table[$ - 1];
        table.length = table.length - 1;
        return res;
    }

    Scope current()
    {
        return table[$ - 1];
    }
}