view tools/AstPrinter.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 fea8d61a2451
line wrap: on
line source

module tools.AstPrinter;

import tango.io.Stdout;

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

import basic.SourceManager;

class AstPrinter
{
    const char[] tabType = "    "; // 4 spaces

    this(SourceManager sm)
    {

        this.sm = sm;
    }

    void print(Module m)
    {
        foreach(decl ; m.decls)
        {
            printDecl(decl);
        }
    }

    void printDecl(Decl decl)
    {
        switch(decl.declType)
        {
            case DeclType.FuncDecl:
                auto funcDecl = cast(FuncDecl)decl;
                printBeginLine();
                printIdentifier(funcDecl.returnType);
                space;
                printIdentifier(funcDecl.identifier);
                printFuncArgs(funcDecl);
                printOpenBrace();
                foreach(stmt ; funcDecl.statements)
                    printStatement(stmt);
                printCloseBrace();
                break;

            case DeclType.VarDecl:
                auto varDecl = cast(VarDecl)decl;
                printBeginLine();
                printExp(varDecl.varType);
                space;
                printExp(varDecl.identifier);
                if(varDecl.init)
                {
                    print(" = ");
                    printExp(varDecl.init);
                }
                printEndLine(";");
                break;

            case DeclType.StructDecl:
                auto structDecl = cast(StructDecl)decl;
                printBeginLine("struct ");
                printIdentifier(structDecl.identifier);
                printEndLine;
                printOpenBrace;
                foreach( var ; structDecl.vars)
                    printDecl(var);
                printCloseBrace;
                break;
        }
    }

    void printStatement(Stmt stmt)
    {
        switch(stmt.stmtType)
        {
            case StmtType.Return:
                auto ret = cast(ReturnStmt)stmt;
                printBeginLine("return");
                if(ret.exp)
                {
                    space;
                    printExp(ret.exp);
                }
                printEndLine(";");
                break;
            case StmtType.Decl:
                auto declStmt = cast(DeclStmt)stmt;
                printDecl(declStmt.decl);
                break;
            case StmtType.Exp:
                auto expStmt = cast(ExpStmt)stmt;
                printBeginLine();
                printExp(expStmt.exp);
                printEndLine(";");
                break;

        }
    }

    void printExp(Exp exp)
    {
        switch(exp.expType)
        {
            case ExpType.Binary:
                auto binaryExp = cast(BinaryExp)exp;
                print("(");
                printExp(binaryExp.left);
                print(" " ~ binaryExp.getOp[binaryExp.op] ~ " ");
                printExp(binaryExp.right);
                print(")");
                break;
            case ExpType.IntegerLit:
                auto integetLit = cast(IntegerLit)exp;
                print(integetLit.get);
                break;
            case ExpType.Negate:
                auto negateExp = cast(NegateExp)exp;
                print("-");
                printExp(negateExp.exp);
                break;
            case ExpType.Deref:
                auto derefExp = cast(DerefExp)exp;
                print("*");
                printExp(derefExp.exp);
                break;
            case ExpType.AssignExp:
                auto assignExp = cast(AssignExp)exp;
                printExp(assignExp.identifier);
                print(" = ");
                printExp(assignExp.exp);
                break;
            case ExpType.MemberReference:
                auto mrExp = cast(MemberReference)exp;
                printExp(mrExp.target);
                print(".");
                printIdentifier(mrExp.child);
                break;
            case ExpType.Identifier:
                auto iden = cast(Identifier)exp;
                printIdentifier(iden);
                break;
            case ExpType.PointerIdentifier:
                auto iden = cast(PointerIdentifier)exp;
                printExp(iden.pointerOf);
                print("*");
                break;
            case ExpType.CallExp:
                auto callExp = cast(CallExp)exp;
                printExp(callExp.exp);
                print("(");
                foreach(i, e; callExp.args)
                {
                    printExp(e);
                    if(i+1 < callExp.args.length)
                        print(", ");
                }
                print(")");
                break;
            case ExpType.CastExp:
                auto castExp = cast(CastExp)exp;
                print("cast");
                print("(");
                printExp(castExp.castType);
                print(")");
                printExp(castExp.exp);
                break;
        }
        
    }

    void printFuncArgs(FuncDecl decl)
    {
        print("(");
     
        foreach(i, d; decl.funcArgs)
        {
            printIdentifier(d.varType);
            if(i == 0 && decl.sret)
                print("*");
            space;
            printIdentifier(d.identifier);
            if(i+1 < decl.funcArgs.length)
                print(",");
        }

        printEndLine(")");
    }

    void printIdentifier(Identifier identifier)
    {
        print(identifier.get);
    }

    void printOpenBrace()
    {
        printEndLine(tabIndex~"{");
        tabIndex ~= tabType;
    }

    void printCloseBrace()
    {
        tabIndex = tabIndex[0 .. $-tabType.length];
        printEndLine(tabIndex~"}");
    }

    void printBeginLine(char[] line = "")
    {
        Stdout(tabIndex~line);
    }

    void printEndLine(char[] line = "")
    {
        Stdout(line).newline;
    }

    void print(char[] line)
    {
        Stdout(line);
    }

    void space()
    {
        print(" ");
    }
private:
    SourceManager sm;
    char[] tabIndex;
}