view gen/LuaGen.d @ 1:2168f4cb73f1

First push
author johnsen@johnsen-desktop
date Fri, 18 Apr 2008 02:01:38 +0200
parents
children 69464d465284
line wrap: on
line source

module gen.LuaGen;

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

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

import lexer.Token;

class LuaGen
{
public:
    this()
    {
    }
    
    void gen(Decl[] decls)
    {

        foreach(decl ; decls)
                genDecl(decl);
        printBeginLine("main()");
        printEndLine;
    }

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

                printBeginLine("function ");
                genIdentifier(funcDecl.identifier);
                print("(");
                foreach(i, funcArg ; funcDecl.funcArgs)
                {
                    genIdentifier(funcArg.identifier);
                    if(i+1 < funcDecl.funcArgs.length)
                        print(", ");
                }
                printEndLine(")");
                indent;
                foreach(stmt ; funcDecl.statements)
                {
                    genStmt(stmt);
                }
                dedent;
                printBeginLine("end");
                printEndLine();
                break;

            case DeclType.VarDecl:
                genVarDecl(cast(VarDecl)decl);

            default:
        }
    }

    void genStmt(Stmt stmt)
    {
        switch(stmt.stmtType)
        {
            case StmtType.Return:
                auto ret = cast(ReturnStmt)stmt;
                printBeginLine("return ");
                genExpression(ret.exp);
                printEndLine();
                break;
            case StmtType.Decl:
                auto declStmt = cast(DeclStmt)stmt;
                genDecl(declStmt.decl);
                break;
            case StmtType.Exp:
                auto expStmt = cast(ExpStmt)stmt;
                printBeginLine();
                genExpression(expStmt.exp);
                printEndLine();
                break;

        }
    }

    void genVarDecl(VarDecl decl)
    {
        printBeginLine("local ");
        genIdentifier(decl.identifier);
        if(decl.init)
        {
            print(" = ");
            genExpression(decl.init);
        }
        printEndLine();

    }

    void genExpression(Exp exp)
    {
        switch(exp.expType)
        {
            case ExpType.Binary:
                auto binaryExp = cast(BinaryExp)exp;
                genExpression(binaryExp.left);
                print(" " ~ [binaryExp.op] ~ " ");
                genExpression(binaryExp.right);
                break;
            case ExpType.IntegerLit:
                auto integetLit = cast(IntegerLit)exp;
                auto t = integetLit.token;
                print(t.get);
                break;
            case ExpType.Negate:
                auto negateExp = cast(NegateExp)exp;
                print("-(");
                genExpression(negateExp.exp);
                print(")");
                break;
            case ExpType.AssignExp:
                auto assignExp = cast(AssignExp)exp;
                genIdentifier(assignExp.identifier);
                print(" = ");
                genExpression(assignExp.exp);
                break;
            case ExpType.CallExp:
                auto callExp = cast(CallExp)exp;
                genExpression(callExp.exp);
                print("(");
                foreach(i, arg ; callExp.args)
                {
                    genExpression(arg);
                    if(i+1 < callExp.args.length)
                        print(", ");
                }
                print(")");
                break;
            case ExpType.Identifier:
                auto identifier = cast(Identifier)exp;
                print(identifier.token.get);
                break;
        }

    }

    void genIdentifier(Identifier identifier)
    {
        print(identifier.token.get);
    }

    void indent()
    {
        tabIndex ~= tabType;
    }

    void dedent()
    {
        tabIndex = tabIndex[0 .. $-tabType.length];
    }

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

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

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

private:
    char[] tabIndex;
    const char[] tabType = "    "; // 4 spaces
}