view tools/AstPrinter.d @ 88:eb5b2c719a39 new_gen

Major change to locations, tokens and expressions. A location (now SourceLocation or SLoc) is only 32 bit in size - disadvantage is that it can't find its own text. You have to go through the new SourceManager to do that. This has caused changes to a lot of stuff and removal of DataSource and the old Location Additionally Exp has gotten some location stuff, so we can give proper error messages. Not in Decl and Stmt yet, but thats coming too.
author Anders Halager <halager@gmail.com>
date Sun, 04 May 2008 18:13:46 +0200
parents 81813366ef92
children 48bb2287c035
line wrap: on
line source

module tools.AstPrinter;

import tango.io.Stdout;

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

import basic.SourceManager;

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

    this(SourceManager sm)
    {

        this.sm = sm;
    }

    void print(Decl[] decls)
    {
        foreach(decl ; 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;
}