view ast/Exp.d @ 56:4ae365eff712 new_gen

Now return types works for structs... Also, simplyfing in AST have been startet - but still messy. This update is a little messy...
author Anders Johnsen <skabet@gmail.com>
date Mon, 28 Apr 2008 21:40:00 +0200
parents 79cb0afafabe
children fc62c5296a1c
line wrap: on
line source

module ast.Exp;

import tango.text.Util : jhash;
import tango.io.Stdout;

import ast.Decl,
       ast.Stmt;

import lexer.Token;

import sema.SymbolTable;

enum ExpType
{
    Binary,
    Negate,
    IntegerLit,
    MemberReference,
    ArrayLookup,
    Identifier,
    AssignExp,
    CallExp,
}

class Exp
{
    this(ExpType expType) 
    {
        this.expType = expType;
    }

    ExpType expType;
    Scope env;
    int stmtIndex;

    Exp simplify()
    {
        return this;
    }
}

class CallExp : Exp
{
    this(Exp exp, Exp[] args)
    {
        super(ExpType.CallExp);
        this.exp = exp;
        this.args = args;
    }

    Exp exp;
    Exp[] args;
    bool sret = false;


    Exp simplify()
    {
        auto call = cast(Identifier)exp;
        FuncDecl f = env.parentFunction;
        auto i = new Identifier("temp.var");
        i.env = f.env;
        f.env.add(i);
        f.env.find(i).type = f.env.find(call).type;
        auto var = new VarDecl(f.type, i, null);
        Exp[] args; 
        args ~= i;
        args ~= this.args;
        auto callExp = new CallExp(exp, args);
        callExp.env = f.env;
//        auto ass = new AssignExp(i, callExp);
        var.env = f.env;
//        ass.env = f.env;
        auto stmtVar = new DeclStmt(var);
        auto stmtCall = new ExpStmt(callExp);
        Stmt[] stmts;
        foreach( index, s ; f.statements)
        {
            if(stmtIndex == index)
            {
                stmts ~= stmtVar;
                stmts ~= stmtCall;
            }
            stmts ~= s;
        }
        f.statements = stmts;
        callExp.sret = true;

        return i;
    }
}

class AssignExp : Exp
{
    this(Exp identifier, Exp exp)
    {
        super(ExpType.AssignExp);
        this.identifier = identifier;
        this.exp = exp;
    }
    Exp simplify()
    {
        identifier = identifier.simplify;
        exp = exp.simplify;

        return this;
    }

    Exp identifier;
    Exp exp;
}

class BinaryExp : Exp
{
    public enum Operator
    {
        Assign,

        Eq, Ne,

        Lt, Le,
        Gt, Ge,

        Add, Sub,
        Mul, Div, Mod,
    }

    this(Operator op, Exp left, Exp right)
    {
        super(ExpType.Binary);
        this.op = op;
        this.left = left;
        this.right = right;
    }

    char[] resultType()
    {
        if (op >= Operator.Eq && op <= Operator.Ge)
            return "bool";
        return null;
    }
    Exp simplify()
    {
        left = left.simplify;
        right = right.simplify;
        return this;
    }

    Operator op;
    Exp left, right;
}

class NegateExp : Exp
{
    this(Exp exp)
    {
        super(ExpType.Negate);
        this.exp = exp;
    }
    Exp simplify()
    {
        exp = exp.simplify;
        return this;
    }

    public Exp exp;
}

class IntegerLit : Exp
{
    this(Token t)
    {
        super(ExpType.IntegerLit);
        this.token = t;
    }
    Exp simplify()
    {
        return this;
    }

    Token token;
}

class MemberReference : Exp
{
    this(Exp target, Identifier child)
    {
        super(ExpType.MemberReference);
        this.target = target;
        this.child = child;
    }
    Exp simplify()
    {
        child.simplify;
        target = target.simplify;
        return this;
    }

    Identifier child;
    Exp target;
}

class ArrayLookup : Exp
{
    this(Exp target, IntegerLit pos)
    {
        super(ExpType.ArrayLookup);
        this.target = target;
        this.pos = pos;
    }

    Exp simplify()
    {
        target = target.simplify;
        pos.simplify;
        return this;
    }

    Exp target;
    IntegerLit pos;
}

class Identifier : Exp
{
    this(Token t)
    {
        super(ExpType.Identifier);
        this.token = t;
        name = t.get;
    }

    this(char[] name)
    {
        super(ExpType.Identifier);
        this.name = name;
    }

    char[] get()
    {
        return name;
    }

    hash_t toHash()
    {
        return jhash(name);
    }

    int opCmp(Object o)
    {
        if (auto id = cast(Identifier)o)
            return typeid(char[]).compare(&name, &id.name);
        return 0;
    }

    int opEquals(Object o)
    {
        if (auto id = cast(Identifier)o)
            return typeid(char[]).equals(&name, &id.name);
        return 0;
    }

    Exp simplify()
    {
        return this;
    }

    Token token;
    char[] name;
}