view sema/AstAction.d @ 78:ad956143dcdc new_gen

Parse and gen for dereferences
author Anders Halager <halager@gmail.com>
date Fri, 02 May 2008 16:38:31 +0200
parents 381975d76baf
children 81813366ef92
line wrap: on
line source

module sema.AstAction;

import Integer = tango.text.convert.Integer;

import lexer.Token;

import misc.Error;

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

public
import parser.Action;

/**
  This class implements the default actions for Dang, by building up an AST
  with the data needed in a compiler.
 */
class AstAction : Action
{
    // -- Declarations --
    override DeclT actOnDeclarator(ref Id type, ref Id id, ExprT init)
    {
        Exp exp = cast(Exp)init;
        if(type.tok.type == Tok.Struct)
            return new StructDecl(new Identifier(id.tok));
        else
            return new VarDecl(new Identifier(type.tok), new Identifier(id.tok), exp);
    }
    
    override void actOnStructMember(DeclT decl, ref Id type, ref Id name, ExprT init)
    {
        Exp exp = cast(Exp)init;
        StructDecl st = cast(StructDecl)decl;
        st.addMember(
                new Identifier(type.tok), 
                new Identifier(name.tok), 
                exp);
    }

    ExprT actOnMemberReference(ExprT lhs, Location op, Id member)
    {
        return new MemberReference(cast(Exp)lhs, new Identifier(member.tok));
    }

    override DeclT actOnStartOfFunctionDef(ref Id type, ref Id name)
    {
        return new FuncDecl(new Identifier(type.tok), new Identifier(name.tok));
    }

    override void addFuncArg(DeclT func, Id type, Id name)
    {
        FuncDecl fd = cast(FuncDecl)func;
        fd.addParam(new Identifier(type.tok), new Identifier(name.tok));
    }

    override DeclT actOnEndOfFunction(DeclT func, StmtT stmts)
    {
        FuncDecl fd = cast(FuncDecl)func;
        fd.setBody(cast(CompoundStatement)stmts);
        return fd;
    }

    // -- Statements --
    override StmtT actOnCompoundStmt(ref Token l, ref Token r, StmtT[] stmts)
    {
        Stmt[] statements = cast(Stmt[])stmts;
        return new CompoundStatement(statements.dup);
    }

    override StmtT actOnExprStmt(ExprT exp)
    {
        return new ExpStmt(cast(Exp)exp);
    }

    override StmtT actOnReturnStmt(ref Token loc, ExprT exp)
    {
        Exp e = cast(Exp)exp;
        auto res = new ReturnStmt;
        res.exp = e;
        return res;
    }

    override StmtT actOnIfStmt(ref Token ifTok, ExprT cond, StmtT thenBody,
                               ref Token elseTok, StmtT elseBody)
    {
        Exp c = cast(Exp)cond;
        Stmt t = cast(Stmt)thenBody;
        Stmt e = cast(Stmt)elseBody;
        return new IfStmt(c, t, e);
    }

    override StmtT actOnWhileStmt(ref Token tok, ExprT cond, StmtT whileBody)
    {
        Exp c = cast(Exp)cond;
        Stmt b = cast(Stmt)whileBody;
        return new WhileStmt(c, b);
    }

    override StmtT actOnDeclStmt(DeclT decl)
    {
        Decl d = cast(Decl)decl;
        return new DeclStmt(d);
    }

    // -- Expressions --
    override ExprT actOnNumericConstant(Token c)
    {
        return new IntegerLit(c);
    }

    override ExprT actOnIdentifierExp(Id id)
    {
        return new Identifier(id.tok);
    }

    override ExprT actOnBinaryOp(Operator op, ExprT l, ExprT r)
    {
        Exp left = cast(Exp)l;
        Exp right = cast(Exp)r;
        if (op == Operator.Assign)
            return new AssignExp(left, right);
        else
            return new BinaryExp(cast(BinaryExp.Operator)op, left, right);
    }

    override ExprT actOnUnaryOp(Token op, ExprT operand)
    {
        Exp target = cast(Exp)operand;
        if (op.type == Tok.Minus)
            return new NegateExp(target);
        if (op.type == Tok.Star)
            return new DerefExp(target);
        assert(0, "Only valid unary expressions are -x and *x");
    }

    override ExprT actOnCallExpr(ExprT fn, ref Token, ExprT[] args, ref Token)
    {
        Exp f = cast(Exp)fn;
        Exp[] arguments = cast(Exp[])args.dup;
        return new CallExp(f, arguments);
    }

    override ExprT actOnCastExpr(Id id, ExprT exp)
    {
        return new CastExp(new Identifier(id.tok), cast(Exp)exp );
    }
}