//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

//
// Definition of the in-memory high-level intermediate representation
// of shaders.  This is a tree that parser creates.
//
// Nodes in the tree are defined as a hierarchy of classes derived from 
// TIntermNode. Each is a node in a tree.  There is no preset branching factor;
// each node can have it's own type of list of children.
//

#ifndef __INTERMEDIATE_H
#define __INTERMEDIATE_H

#include "Common.h"
#include "Types.h"
#include "ConstantUnion.h"

//
// Operators used by the high-level (parse tree) representation.
//
enum TOperator {
    EOpNull,            // if in a node, should only mean a node is still being built
    EOpSequence,        // denotes a list of statements, or parameters, etc.
    EOpFunctionCall,    
    EOpFunction,        // For function definition
    EOpParameters,      // an aggregate listing the parameters to a function

    EOpDeclaration,
    EOpPrototype,

    //
    // Unary operators
    //

    EOpNegative,
    EOpLogicalNot,
    EOpVectorLogicalNot,
    EOpBitwiseNot,

    EOpPostIncrement,
    EOpPostDecrement,
    EOpPreIncrement,
    EOpPreDecrement,

    //
    // binary operations
    //

    EOpAdd,
    EOpSub,
    EOpMul,
    EOpDiv,
    EOpEqual,
    EOpNotEqual,
    EOpVectorEqual,
    EOpVectorNotEqual,
    EOpLessThan,
    EOpGreaterThan,
    EOpLessThanEqual,
    EOpGreaterThanEqual,
    EOpComma,

    EOpOuterProduct,
    EOpTranspose,
    EOpDeterminant,
    EOpInverse,

    EOpVectorTimesScalar,
    EOpVectorTimesMatrix,
    EOpMatrixTimesVector,
    EOpMatrixTimesScalar,

    EOpLogicalOr,
    EOpLogicalXor,
    EOpLogicalAnd,

    EOpIMod,
    EOpBitShiftLeft,
    EOpBitShiftRight,
    EOpBitwiseAnd,
    EOpBitwiseXor,
    EOpBitwiseOr,

    EOpIndexDirect,
    EOpIndexIndirect,
    EOpIndexDirectStruct,

    EOpVectorSwizzle,

    //
    // Built-in functions potentially mapped to operators
    //

    EOpRadians,
    EOpDegrees,
    EOpSin,
    EOpCos,
    EOpTan,
    EOpAsin,
    EOpAcos,
    EOpAtan,
    EOpSinh,
    EOpCosh,
    EOpTanh,
    EOpAsinh,
    EOpAcosh,
    EOpAtanh,

    EOpPow,
    EOpExp,
    EOpLog,
    EOpExp2,
    EOpLog2,
    EOpSqrt,
    EOpInverseSqrt,

    EOpAbs,
    EOpSign,
    EOpFloor,
    EOpTrunc,
    EOpRound,
    EOpRoundEven,
    EOpCeil,
    EOpFract,
    EOpMod,
    EOpMin,
    EOpMax,
    EOpClamp,
    EOpMix,
    EOpStep,
    EOpSmoothStep,
    EOpIsNan,
    EOpIsInf,
    EOpFloatBitsToInt,
    EOpFloatBitsToUint,
    EOpIntBitsToFloat,
    EOpUintBitsToFloat,
    EOpPackSnorm2x16,
    EOpPackUnorm2x16,
    EOpPackHalf2x16,
    EOpUnpackSnorm2x16,
    EOpUnpackUnorm2x16,
    EOpUnpackHalf2x16,

    EOpLength,
    EOpDistance,
    EOpDot,
    EOpCross,
    EOpNormalize,
    EOpFaceForward,
    EOpReflect,
    EOpRefract,

    EOpDFdx,            // Fragment only, OES_standard_derivatives extension
    EOpDFdy,            // Fragment only, OES_standard_derivatives extension
    EOpFwidth,          // Fragment only, OES_standard_derivatives extension

    EOpMatrixTimesMatrix,

    EOpAny,
    EOpAll,

    //
    // Branch
    //

    EOpKill,            // Fragment only
    EOpReturn,
    EOpBreak,
    EOpContinue,

    //
    // Constructors
    //

    EOpConstructInt,
    EOpConstructUInt,
    EOpConstructBool,
    EOpConstructFloat,
    EOpConstructVec2,
    EOpConstructVec3,
    EOpConstructVec4,
    EOpConstructBVec2,
    EOpConstructBVec3,
    EOpConstructBVec4,
    EOpConstructIVec2,
    EOpConstructIVec3,
    EOpConstructIVec4,
    EOpConstructUVec2,
    EOpConstructUVec3,
    EOpConstructUVec4,
    EOpConstructMat2,
    EOpConstructMat2x3,
    EOpConstructMat2x4,
    EOpConstructMat3x2,
    EOpConstructMat3,
    EOpConstructMat3x4,
    EOpConstructMat4x2,
    EOpConstructMat4x3,
    EOpConstructMat4,
    EOpConstructStruct,

    //
    // moves
    //

    EOpAssign,
    EOpInitialize,
    EOpAddAssign,
    EOpSubAssign,
    EOpMulAssign,
    EOpVectorTimesMatrixAssign,
    EOpVectorTimesScalarAssign,
    EOpMatrixTimesScalarAssign,
    EOpMatrixTimesMatrixAssign,
    EOpDivAssign,
    EOpIModAssign,
    EOpBitShiftLeftAssign,
    EOpBitShiftRightAssign,
    EOpBitwiseAndAssign,
    EOpBitwiseXorAssign,
    EOpBitwiseOrAssign
};

extern const char* getOperatorString(TOperator op);

class TIntermTraverser;
class TIntermAggregate;
class TIntermBinary;
class TIntermUnary;
class TIntermConstantUnion;
class TIntermSelection;
class TIntermTyped;
class TIntermSymbol;
class TIntermLoop;
class TIntermBranch;
class TInfoSink;

//
// Base class for the tree nodes
//
class TIntermNode {
public:
    POOL_ALLOCATOR_NEW_DELETE();

    TIntermNode() : line(0) {}

    TSourceLoc getLine() const { return line; }
    void setLine(TSourceLoc l) { line = l; }

    virtual void traverse(TIntermTraverser*) = 0;
    virtual TIntermTyped* getAsTyped() { return 0; }
    virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
    virtual TIntermAggregate* getAsAggregate() { return 0; }
    virtual TIntermBinary* getAsBinaryNode() { return 0; }
    virtual TIntermUnary* getAsUnaryNode() { return 0; }
    virtual TIntermSelection* getAsSelectionNode() { return 0; }
    virtual TIntermSymbol* getAsSymbolNode() { return 0; }
    virtual TIntermLoop* getAsLoopNode() { return 0; }
	virtual TIntermBranch* getAsBranchNode() { return 0; }
    virtual ~TIntermNode() { }

protected:
    TSourceLoc line;
};

//
// This is just to help yacc.
//
struct TIntermNodePair {
    TIntermNode* node1;
    TIntermNode* node2;
};

//
// Intermediate class for nodes that have a type.
//
class TIntermTyped : public TIntermNode {
public:
    TIntermTyped(const TType& t) : type(t)  { }
    virtual TIntermTyped* getAsTyped() { return this; }

    void setType(const TType& t) { type = t; }
    const TType& getType() const { return type; }
    TType* getTypePointer() { return &type; }

    TBasicType getBasicType() const { return type.getBasicType(); }
    TQualifier getQualifier() const { return type.getQualifier(); }
    TPrecision getPrecision() const { return type.getPrecision(); }
    int getNominalSize() const { return type.getNominalSize(); }
	int getSecondarySize() const { return type.getSecondarySize(); }
    
    bool isMatrix() const { return type.isMatrix(); }
    bool isArray()  const { return type.isArray(); }
    bool isVector() const { return type.isVector(); }
    bool isScalar() const { return type.isScalar(); }
    bool isScalarInt() const { return type.isScalarInt(); }
	bool isRegister() const { return type.isRegister(); }   // Fits in a 4-element register
	bool isStruct() const { return type.isStruct(); }
    const char* getBasicString() const { return type.getBasicString(); }
    const char* getQualifierString() const { return type.getQualifierString(); }
    TString getCompleteString() const { return type.getCompleteString(); }

	int totalRegisterCount() const { return type.totalRegisterCount(); }
	int elementRegisterCount() const { return type.elementRegisterCount(); }
	int getArraySize() const { return type.getArraySize(); }

protected:
    TType type;
};

//
// Handle for, do-while, and while loops.
//
enum TLoopType {
    ELoopFor,
    ELoopWhile,
    ELoopDoWhile
};

class TIntermLoop : public TIntermNode {
public:
    TIntermLoop(TLoopType aType,
                TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
                TIntermNode* aBody) :
            type(aType),
            init(aInit),
            cond(aCond),
            expr(aExpr),
            body(aBody),
            unrollFlag(false) { }

    virtual TIntermLoop* getAsLoopNode() { return this; }
    virtual void traverse(TIntermTraverser*);

    TLoopType getType() const { return type; }
    TIntermNode* getInit() { return init; }
    TIntermTyped* getCondition() { return cond; }
    TIntermTyped* getExpression() { return expr; }
    TIntermNode* getBody() { return body; }

    void setUnrollFlag(bool flag) { unrollFlag = flag; }
    bool getUnrollFlag() { return unrollFlag; }

protected:
    TLoopType type;
    TIntermNode* init;  // for-loop initialization
    TIntermTyped* cond; // loop exit condition
    TIntermTyped* expr; // for-loop expression
    TIntermNode* body;  // loop body

    bool unrollFlag; // Whether the loop should be unrolled or not.
};

//
// Handle break, continue, return, and kill.
//
class TIntermBranch : public TIntermNode {
public:
    TIntermBranch(TOperator op, TIntermTyped* e) :
            flowOp(op),
            expression(e) { }

	virtual TIntermBranch* getAsBranchNode() { return this; }
    virtual void traverse(TIntermTraverser*);

    TOperator getFlowOp() { return flowOp; }
    TIntermTyped* getExpression() { return expression; }

protected:
    TOperator flowOp;
    TIntermTyped* expression;  // non-zero except for "return exp;" statements
};

//
// Nodes that correspond to symbols or constants in the source code.
//
class TIntermSymbol : public TIntermTyped {
public:
    // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
    // per process globalpoolallocator, then it causes increased memory usage per compile
    // it is essential to use "symbol = sym" to assign to symbol
    TIntermSymbol(int i, const TString& sym, const TType& t) : 
            TIntermTyped(t), id(i)  { symbol = sym; } 

    int getId() const { return id; }
    const TString& getSymbol() const { return symbol; }

    void setId(int newId) { id = newId; }
    
    virtual void traverse(TIntermTraverser*);
    virtual TIntermSymbol* getAsSymbolNode() { return this; }

protected:
    int id;
    TString symbol;
};

class TIntermConstantUnion : public TIntermTyped {
public:
    TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }

    ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
    
    int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
    int getUConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getUConst() : 0; }
    float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
    bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }

    virtual TIntermConstantUnion* getAsConstantUnion()  { return this; }
    virtual void traverse(TIntermTraverser*);

    TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);

protected:
    ConstantUnion *unionArrayPointer;
};

//
// Intermediate class for node types that hold operators.
//
class TIntermOperator : public TIntermTyped {
public:
    TOperator getOp() const { return op; }
    void setOp(TOperator o) { op = o; }

    bool modifiesState() const;
    bool isConstructor() const;

protected:
    TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
    TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}   
    TOperator op;
};

//
// Nodes for all the basic binary math operators.
//
class TIntermBinary : public TIntermOperator {
public:
    TIntermBinary(TOperator o) : TIntermOperator(o) {}

    virtual TIntermBinary* getAsBinaryNode() { return this; }
    virtual void traverse(TIntermTraverser*);

    void setLeft(TIntermTyped* n) { left = n; }
    void setRight(TIntermTyped* n) { right = n; }
    TIntermTyped* getLeft() const { return left; }
    TIntermTyped* getRight() const { return right; }
    bool promote(TInfoSink&);

protected:
    TIntermTyped* left;
    TIntermTyped* right;
};

//
// Nodes for unary math operators.
//
class TIntermUnary : public TIntermOperator {
public:
    TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
    TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}

    virtual void traverse(TIntermTraverser*);
    virtual TIntermUnary* getAsUnaryNode() { return this; }

    void setOperand(TIntermTyped* o) { operand = o; }
    TIntermTyped* getOperand() { return operand; }    
    bool promote(TInfoSink&);

protected:
    TIntermTyped* operand;
};

typedef TVector<TIntermNode*> TIntermSequence;
typedef TVector<int> TQualifierList;

//
// Nodes that operate on an arbitrary sized set of children.
//
class TIntermAggregate : public TIntermOperator {
public:
    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0) { }
    TIntermAggregate(TOperator o) : TIntermOperator(o) { }
    ~TIntermAggregate() { }

    virtual TIntermAggregate* getAsAggregate() { return this; }
    virtual void traverse(TIntermTraverser*);

    TIntermSequence& getSequence() { return sequence; }

    void setName(const TString& n) { name = n; }
    const TString& getName() const { return name; }

    void setUserDefined() { userDefined = true; }
    bool isUserDefined() const { return userDefined; }

    void setOptimize(bool o) { optimize = o; }
    bool getOptimize() { return optimize; }
    void setDebug(bool d) { debug = d; }
    bool getDebug() { return debug; }

    void setEndLine(TSourceLoc line) { endLine = line; }
    TSourceLoc getEndLine() const { return endLine; }

protected:
    TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
    TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
    TIntermSequence sequence;
    TString name;
    bool userDefined; // used for user defined function names

    bool optimize;
    bool debug;
    TSourceLoc endLine;
};

//
// For if tests.  Simplified since there is no switch statement.
//
class TIntermSelection : public TIntermTyped {
public:
    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
            TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
            TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB)
	{
		this->type.setQualifier(EvqTemporary);
	}

    virtual void traverse(TIntermTraverser*);

    bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
    TIntermTyped* getCondition() const { return condition; }
    TIntermNode* getTrueBlock() const { return trueBlock; }
    TIntermNode* getFalseBlock() const { return falseBlock; }
    TIntermSelection* getAsSelectionNode() { return this; }

protected:
    TIntermTyped* condition;
    TIntermNode* trueBlock;
    TIntermNode* falseBlock;
};

enum Visit
{
    PreVisit,
    InVisit,
    PostVisit
};

//
// For traversing the tree.  User should derive from this, 
// put their traversal specific data in it, and then pass
// it to a Traverse method.
//
// When using this, just fill in the methods for nodes you want visited.
// Return false from a pre-visit to skip visiting that node's subtree.
//
class TIntermTraverser
{
public:
    POOL_ALLOCATOR_NEW_DELETE();
    TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) : 
            preVisit(preVisit),
            inVisit(inVisit),
            postVisit(postVisit),
            rightToLeft(rightToLeft),
            depth(0) {}
    virtual ~TIntermTraverser() {};

    virtual void visitSymbol(TIntermSymbol*) {}
    virtual void visitConstantUnion(TIntermConstantUnion*) {}
    virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
    virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
    virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
    virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
    virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
    virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}

    void incrementDepth() {depth++;}
    void decrementDepth() {depth--;}

    const bool preVisit;
    const bool inVisit;
    const bool postVisit;
    const bool rightToLeft;

protected:
    int depth;
};

#endif // __INTERMEDIATE_H
