blob: e0b50d6e850e5a155702fdf432843f75d6dd992a [file] [log] [blame]
//===-- AST Operator Class --------------------------------------*- C++ -*-===//
//
// High Level Virtual Machine (HLVM)
//
// Copyright (C) 2006 Reid Spencer. All Rights Reserved.
//
// This software is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or (at
// your option) any later version.
//
// This software is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
// more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library in the file named LICENSE.txt; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301 USA
//
//===----------------------------------------------------------------------===//
/// @file hlvm/AST/Operator.h
/// @author Reid Spencer <reid@hlvm.org> (original author)
/// @date 2006/05/04
/// @since 0.1.0
/// @brief Declares the class hlvm::AST::Operator
//===----------------------------------------------------------------------===//
#ifndef HLVM_AST_OPERATOR_H
#define HLVM_AST_OPERATOR_H
#include <hlvm/AST/Node.h>
namespace hlvm
{
class Type;
class Bundle;
class Function;
class Block;
class LoopOp;
/// This class is the abstract base class in the Abstract Syntax Tree for all
/// operators. An Operator is an instruction to the virtual machine to take
/// some action. Operators form the content of a Block. As this is the base
/// class of all operators, the Operator class only provides the functionality
/// that is common to all operators: getting the number of operands
/// (getNumOperands), getting the Value of an operand (getOperand), and
/// setting
/// the Value of an operand (setOperand). Since Operand is a Value, this implies
/// two things: (1) Operators can be the operand of other operators and (2) eery
/// Operator has a type.
/// @see Value
/// @see Block
/// @brief AST Abstract Operator Node
class Operator : public Value
{
/// @name Constructors
/// @{
protected:
Operator(NodeIDs opID) : Value(opID) {}
virtual ~Operator();
/// @}
/// @name Accessors
/// @{
public:
/// Get the number of operands in this operator
virtual size_t getNumOperands() const = 0;
/// Get a specific operand of this operator.
virtual Operator* getOperand(unsigned opnum) const = 0;
/// Return the function containing this operator
Function* getContainingFunction() const;
/// Return the block containing this operator
Block* getContainingBlock() const;
/// Return the loop operator containing this operator. This can return
/// any of the loop constructs (Loop, While, Unless, etc.) so its result
/// type is Operator*.
Operator* getContainingLoop() const;
/// Determine if this is a classof some other type.
static inline bool classof(const Operator*) { return true; }
static inline bool classof(const Node* N) { return N->isOperator(); }
/// @}
/// @name Mutators
/// @{
public:
virtual void setOperand(unsigned opnum, Operator* oprnd) = 0;
/// @}
friend class AST;
};
/// This class provides an Abstract Syntax Tree base class for all Operators
/// that have no operands.
/// @brief AST Operator With No Operands
class NilaryOperator : public Operator
{
/// @name Constructors
/// @{
protected:
NilaryOperator(NodeIDs opID ) : Operator(opID) {}
virtual ~NilaryOperator();
/// @}
/// @name Accessors
/// @{
public:
virtual size_t getNumOperands() const;
virtual Operator* getOperand(unsigned opnum) const;
static inline bool classof(const NilaryOperator*) { return true; }
static inline bool classof(const Node* N) { return N->isNilaryOperator(); }
/// @}
/// @name Mutators
/// @{
public:
virtual void setOperand(unsigned opnum, Operator* oprnd);
protected:
virtual void insertChild(Node* child);
virtual void removeChild(Node* child);
/// @}
friend class AST;
};
/// This class provides an Abstract Syntax Tree base class for Operators that
/// take a single operand.
/// @brief AST Operator With One Operand
class UnaryOperator : public Operator
{
/// @name Constructors
/// @{
protected:
UnaryOperator(NodeIDs opID) : Operator(opID), op1(0) {}
virtual ~UnaryOperator();
/// @}
/// @name Accessors
/// @{
public:
Operator* getOperand() const { return op1; }
virtual size_t getNumOperands() const;
virtual Operator* getOperand(unsigned opnum) const;
static inline bool classof(const UnaryOperator*) { return true; }
static inline bool classof(const Node* N) { return N->isUnaryOperator(); }
/// @}
/// @name Mutators
/// @{
public:
virtual void setOperand(unsigned opnum, Operator* oprnd);
virtual void resolveTypeTo(const Type* from, const Type* to);
protected:
virtual void insertChild(Node* child);
virtual void removeChild(Node* child);
virtual void setOperand(Operator* oprnd) { op1 = oprnd; }
/// @}
/// @name Data
/// @{
protected:
Operator* op1;
/// @}
friend class AST;
};
/// This class provides an Abstract Syntax Tree base class for all operators
/// that have two operands. The operands may be of any Type.
/// @brief AST Operator With Two Operands
class BinaryOperator : public Operator
{
/// @name Constructors
/// @{
protected:
BinaryOperator(NodeIDs opID) : Operator(opID) { ops[0] = ops[1] = 0; }
virtual ~BinaryOperator();
/// @}
/// @name Accessors
/// @{
public:
virtual size_t getNumOperands() const;
virtual Operator* getOperand(unsigned opnum) const;
static inline bool classof(const BinaryOperator*) { return true; }
static inline bool classof(const Node* N) { return N->isBinaryOperator(); }
/// @}
/// @name Mutators
/// @{
public:
virtual void setOperand(unsigned opnum, Operator* oprnd);
virtual void resolveTypeTo(const Type* from, const Type* to);
protected:
virtual void insertChild(Node* child);
virtual void removeChild(Node* child);
/// @}
/// @name Data
/// @{
protected:
Operator* ops[2];
/// @}
friend class AST;
};
/// This class provides an Abstract Syntax Tree base class for all operators
/// that have three operands. The operands may be of any Type.
/// @brief AST Operator With Three Operands
class TernaryOperator : public Operator
{
/// @name Constructors
/// @{
protected:
TernaryOperator(NodeIDs opID) : Operator(opID)
{ ops[0] = ops[1] = ops[2] = 0; }
virtual ~TernaryOperator();
/// @}
/// @name Accessors
/// @{
public:
virtual size_t getNumOperands() const;
virtual Operator* getOperand(unsigned opnum) const;
static inline bool classof(const TernaryOperator*) { return true; }
static inline bool classof(const Node* N) { return N->isTernaryOperator(); }
/// @}
/// @name Mutators
/// @{
public:
virtual void setOperand(unsigned opnum, Operator* oprnd);
virtual void resolveTypeTo(const Type* from, const Type* to);
protected:
virtual void insertChild(Node* child);
virtual void removeChild(Node* child);
/// @}
/// @name Data
/// @{
protected:
Operator* ops[3];
/// @}
friend class AST;
};
/// This class provides an Abstract Syntax Tree base class for all operators
/// that have multiple operands. The operands may be of any Type. Although the
/// interface to this class permits any number of operands, in practice the
/// number of allowed operands for a given MultiOperator subclass is limited.
/// The subclass's insertChild and removeChild method overrides will enforce
/// the correct arity for that subclass.
/// @brief AST Operator With Multiple Operands
class MultiOperator : public Operator
{
/// @name Types
/// @{
public:
typedef std::vector<Operator*> OprndList;
typedef OprndList::iterator iterator;
typedef OprndList::const_iterator const_iterator;
/// @}
/// @name Constructors
/// @{
protected:
MultiOperator(NodeIDs opID) : Operator(opID), ops() {}
virtual ~MultiOperator();
/// @}
/// @name Accessors
/// @{
public:
virtual size_t getNumOperands() const;
virtual Operator* getOperand(unsigned opnum) const;
static inline bool classof(const MultiOperator*) { return true; }
static inline bool classof(const Node* N) { return N->isMultiOperator(); }
/// @}
/// @name Iterators
/// @{
public:
iterator begin() { return ops.begin(); }
const_iterator begin() const { return ops.begin(); }
iterator end () { return ops.end(); }
const_iterator end () const { return ops.end(); }
size_t size () const { return ops.size(); }
bool empty() const { return ops.empty(); }
Operator* front() { return ops.front(); }
const Operator* front() const { return ops.front(); }
Operator* back() { return ops.back(); }
const Operator* back() const { return ops.back(); }
/// @}
/// @name Mutators
/// @{
public:
virtual void setOperand(unsigned opnum, Operator* oprnd);
virtual void resolveTypeTo(const Type* from, const Type* to);
void addOperand(Operator* v) { v->setParent(this); }
void addOperands(const OprndList& new_ops);
protected:
virtual void insertChild(Node* child);
virtual void removeChild(Node* child);
/// @}
/// @name Data
/// @{
protected:
OprndList ops; ///< The operands of this Operator
/// @}
friend class AST;
};
} // end hlvm namespace
#endif