view tools/DotPrinter.d @ 94:48bb2287c035 new_gen

Added Modules. Right now it's very simple - will grow with time and need.
author Anders Johnsen <skabet@gmail.com>
date Tue, 06 May 2008 16:24:14 +0200
parents eb5b2c719a39
children
line wrap: on
line source

module tools.DotPrinter;

import tango.io.Stdout,
       Int = tango.text.convert.Integer;

import ast.Module,
       ast.Decl,
       ast.Stmt,
       ast.Exp;

class DotPrinter
{
    this()
    {
    }

    private char[][void*] identifiers;
    private int current_id = 0;

    void print(Module m)
    {
        Stdout("digraph {").newline;
        foreach(decl ; m.decls)
        {
            printDecl(decl);
        }
        Stdout("}").newline;
    }

    void printDecl(Decl decl)
    {
        switch(decl.declType)
        {
            case DeclType.FuncDecl:
                FuncDecl funcDecl = cast(FuncDecl)decl;

                //printIdentifier(funcDecl.identifier);
                //printFuncArgs(funcDecl.funcArgs);
                Stdout(dotId(decl))(` [label="function`);
                Stdout(`\n name: `)(text(funcDecl.identifier));
                Stdout(`\n return type: `)(text(funcDecl.returnType));
                Stdout(`", shape=box, fillcolor=lightblue, style=filled]`);
                Stdout.newline;
                //Stdout(`"`);
                foreach(stmt ; funcDecl.statements)
                    printStatement(dotId(decl), stmt);
                break;

            case DeclType.VarDecl:
                VarDecl varDecl = cast(VarDecl)decl;

                //printIdentifier(funcDecl.identifier);
                //printFuncArgs(funcDecl.funcArgs);
                Stdout(dotId(decl))(` [label="var`);
                Stdout(`\n name: `)(text(varDecl.identifier));
                Stdout(`\n type: `)(text(varDecl.varType));
                Stdout(`"]`).newline;

                if (varDecl.init !is null)
                    printExpression(dotId(decl), varDecl.init);
                break;
        }
    }

    void printStatement(char[] parent, Stmt stmt)
    {
        auto id = dotId(stmt);
        switch (stmt.stmtType)
        {
            case StmtType.Stmt:
                Stdout(id)(` [label="Statement"]`).newline;
                Stdout(parent)(` -> `)(id).newline;
                break;

            case StmtType.Decl:
                Stdout(id)(` [label="Decl"]`).newline;
                Stdout(parent)(` -> `)(id).newline;
                auto decl = (cast(DeclStmt)stmt).decl;
                printDecl(decl);
                Stdout(id)(` -> `)(dotId(decl)).newline;
                break;

            case StmtType.Return:
                Stdout(id)(` [label="Return"]`).newline;
                Stdout(parent)(` -> `)(id).newline;
                printExpression(id, (cast(ReturnStmt)stmt).exp);
                break;

            case StmtType.Exp:
                Stdout(parent)(` -> `)(id).newline;
                printExpression(id, (cast(ExpStmt)stmt).exp);
                break;
        }
    }

    void printExpression(char[] parent, Exp exp)
    {
        auto id = dotId(exp);

        switch(exp.expType)
        {
            case ExpType.Binary:
                auto bin = cast(BinaryExp)exp;
                Stdout(id)(` [label="`)(bin.op)(`"]`).newline;
                printExpression(id, bin.left);
                printExpression(id, bin.right);
                break;

            case ExpType.Negate:
                auto neg = cast(NegateExp)exp;
                Stdout(id)(` [label="Negate"]`).newline;
                printExpression(id, neg.exp);
                break;

            case ExpType.IntegerLit:
                auto e = cast(IntegerLit)exp;
                Stdout(id)(` [label="`)(text(e.get))(`"]`).newline;
                break;
        
            case ExpType.Identifier:
                auto e = cast(Identifier)exp;
                Stdout(id)(` [label="`)(text(e))(`"]`).newline;
                break;

            case ExpType.AssignExp:
                auto ass = cast(AssignExp)exp;
                Stdout(parent)(` [label="Assign"]`).newline;
//                Stdout(id)(` [label="`)(text(ass.identifier))(`"]`).newline;
                printExpression(parent, ass.exp);
                break;

            case ExpType.CallExp:
                break;
        }
        Stdout(parent)(` -> `)(id).newline;
    }

    char[] dotId(Decl d) { return dotId(cast(void*)d); }
    char[] dotId(Stmt s) { return dotId(cast(void*)s); }
    char[] dotId(Exp e)  { return dotId(cast(void*)e); }

    char[] dotId(void* o)
    {
        auto id = o in identifiers;
        if (id is null)
        {
            ++current_id;
            identifiers[o] = Int.toString(current_id);
            id = o in identifiers;
        }
        return *id;
    }

    char[] text(Identifier identifier)
    {
        return identifier.get;
    }
    char[] text(char[] t)
    {
        return t;
    }
}