view src/ast/Expr.d @ 209:42e663451371

Renamed some of the actions. Declarations now have it's own action.
author Anders Johnsen <skabet@gmail.com>
date Tue, 12 Aug 2008 19:05:17 +0200
parents d3c148ca429b
children
line wrap: on
line source

module ast.Expr;

/**
  The base class for all Expressions.
  */
class Expr
{
    /// Get the type of the Expr
    Object getType() 
    {
        assert(0, "Unimplemented");
        return null;
    }

    /// Set the type of the Expr
    void setType(Object type) 
    {
        assert(0, "Unimplemented");
    }

    /// Returns true if the Expr can be compile-time evaluated.
    bool isConstantExpr() { return false; }

    NumberLiteral asNumberLiteral() { return null; }
    bool isNumberLiteral() { return false; }

    StringLiteral asStringLiteral() { return null; }
    bool isStringLiteral() { return false; }

    ArrayLiteral asArrayLiteral() { return null; }
    bool isArrayLiteral() { return false; }

    AssignExp asAssignExp() { return null; }
    bool isAssignExp() { return false; }

    BinaryExp asBinaryExp() { return null; }
    bool isBinaryExp() { return false; }

    NegateExp asNegateExp() { return null; }
    bool isNegateExp() { return false; }

    DerefExp asDerefExp() { return null; }
    bool isDerefExp() { return false; }

    AddressOfExp asAddressOfExp() { return null; }
    bool isAddressOfExp() { return false; }

    IndexExp asIndexExp() { return null; }
    bool isIndexExp() { return false; }

    Identifier asIdentifier() { return null; }
    bool isIdentifier() { return false; }

    Member asMember() { return null; }
    bool isMember() { return false; }

private:
/// FIXME: Add DType? here
}

/**
  NumberLiteral
  */
/// FIXME: Should there be an IntegerLiteral and FloatLiteral instead?
class NumberLiteral : Expr
{
    override bool isConstantExpr() { return true; }

    override NumberLiteral asNumberLiteral() { return this; }
    override bool isNumberLiteral() { return true; }
}

/**
  StringLiteral
  */
class StringLiteral : Expr
{
    override bool isConstantExpr() { return true; }

    override StringLiteral asStringLiteral() { return this; }
    override bool isStringLiteral() { return true; }
}

/**
  ArrayLiteral
  */
class ArrayLiteral : Expr
{
    /// Return the arguments for the ArrayLiteral
    Expr[] getArguments() { return arguments; }

    /// Return a given argument for the ArrayLiteral
    Expr getArgument(int index) { return arguments[index]; }

    /// Get the count of arguments for the ArrayLiteral
    int getArgumentCount() { return arguments.length; }

    override bool isConstantExpr() 
    {
        /**
          If all the arguments to the ArrayLiteral is an constant Expr, then
          this ArrayLiteral can be considered an constant Expr aswell.
          */
        // FIXME: consider if it should save the result
        foreach (arg; arguments)
            if (!arg.isConstantExpr())
                return false;
        return true; 
    }

    override ArrayLiteral asArrayLiteral() { return this; }
    override bool isArrayLiteral() { return true; }

private:
    Expr[] arguments;
}

/**
  The AssignExp expression contains two expression, a left and a right side, 
  left being a lvalue, right being a rvalue. 

  If the right side ain't the same type as the left type, the right side will
  try to be promoted through an implicit cast. If this failes, an error must
  be given.
  */
class AssignExp : Expr
{
    override AssignExp asAssignExp() { return this; }
    override bool isAssignExp() { return true; }

private:
    Expr left, right;
}

/**
  BinaryExp
  */
class BinaryExp : Expr
{
    override BinaryExp asBinaryExp() { return this; }
    override bool isBinaryExp() { return true; }

private:
    Expr left, right;
}

/**
  NegateExp
  */
class NegateExp : Expr
{
    override NegateExp asNegateExp() { return this; }
    override bool isNegateExp() { return true; }

private:
    Expr expr;
}

/**
  DerefExp
  */
class DerefExp : Expr
{
    override DerefExp asDerefExp() { return this; }
    override bool isDerefExp() { return true; }
}

/**
  AddressOfExp
  */
class AddressOfExp : Expr
{
    override AddressOfExp asAddressOfExp() { return this; }
    override bool isAddressOfExp() { return true; }
}

/**
  IndexExp
  */
class IndexExp : Expr
{
    override IndexExp asIndexExp() { return this; }
    override bool isIndexExp() { return true; }
}

/**
  Identifier
  */
class Identifier : Expr
{
    override Identifier asIdentifier() { return this; }
    override bool isIdentifier() { return true; }
}

/**
  Member
  */
class Member : Expr
{
    override Member asMember() { return this; }
    override bool isMember() { return true; }
}