// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// 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,
	EOpInvariantDeclaration, // Specialized declarations for attributing invariance
	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,
	EOpIndexDirectInterfaceBlock,

	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,
	EOpModf,
	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 TOperator TypeToConstructorOperator(const TType &type);
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;
class TIntermSwitch;
class TIntermCase;

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

	TIntermNode()
	{
		// TODO: Move this to TSourceLoc constructor
		// after getting rid of TPublicType.
		line.first_file = line.last_file = 0;
		line.first_line = line.last_line = 0;
	}

	const TSourceLoc& getLine() const { return line; }
	void setLine(const 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 TIntermSwitch *getAsSwitchNode() { return 0; }
	virtual TIntermCase *getAsCaseNode() { 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; }

	virtual 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 isInterfaceBlock() const { return type.isInterfaceBlock(); }
	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 blockRegisterCount(bool samplersOnly) const { return samplersOnly ? type.totalSamplerRegisterCount() : type.blockRegisterCount(); }
	int elementRegisterCount() const { return type.elementRegisterCount(); }
	int registerSize() const { return type.registerSize(); }
	int getArraySize() const { return type.getArraySize(); }

	static TIntermTyped *CreateIndexNode(int index);
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)
	{
		getTypePointer()->setQualifier(EvqConstExpr);
	}

	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; }

	// Previous union pointer freed on pool deallocation.
	void replaceConstantUnion(ConstantUnion *safeConstantUnion) { unionArrayPointer = safeConstantUnion; }

	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 setType(const TType &t) override
	{
		type = t;

		if(left->getQualifier() == EvqConstExpr && right->getQualifier() == EvqConstExpr)
		{
			type.setQualifier(EvqConstExpr);
		}
	}

	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) {}

	void setType(const TType &t) override
	{
		type = t;

		if(operand->getQualifier() == EvqConstExpr)
		{
			type.setQualifier(EvqConstExpr);
		}
	}

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

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

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, 0, 0, 0 }; }
	TIntermAggregate(TOperator o) : TIntermOperator(o), userDefined(false) { endLine = { 0, 0, 0, 0 }; }
	~TIntermAggregate() { }

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

	TIntermSequence& getSequence() { return sequence; }

	void setType(const TType &t) override
	{
		type = t;

		if(op != EOpFunctionCall)
		{
			for(TIntermNode *node : sequence)
			{
				if(!node->getAsTyped() || node->getAsTyped()->getQualifier() != EvqConstExpr)
				{
					return;
				}
			}

			type.setQualifier(EvqConstExpr);
		}
	}

	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(const TSourceLoc& line) { endLine = line; }
	const TSourceLoc& getEndLine() const { return endLine; }

	bool isConstantFoldable()
	{
		for(TIntermNode *node : sequence)
		{
			if(!node->getAsConstantUnion() || !node->getAsConstantUnion()->getUnionArrayPointer())
			{
				return false;
			}
		}

		return true;
	}

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;
};

//
// Switch statement.
//
class TIntermSwitch : public TIntermNode
{
public:
	TIntermSwitch(TIntermTyped *init, TIntermAggregate *statementList)
		: TIntermNode(), mInit(init), mStatementList(statementList)
	{}

	void traverse(TIntermTraverser *it);

	TIntermSwitch *getAsSwitchNode() { return this; }

	TIntermTyped *getInit() { return mInit; }
	TIntermAggregate *getStatementList() { return mStatementList; }
	void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; }

protected:
	TIntermTyped *mInit;
	TIntermAggregate *mStatementList;
};

//
// Case label.
//
class TIntermCase : public TIntermNode
{
public:
	TIntermCase(TIntermTyped *condition)
		: TIntermNode(), mCondition(condition)
	{}

	void traverse(TIntermTraverser *it);

	TIntermCase *getAsCaseNode() { return this; }

	bool hasCondition() const { return mCondition != nullptr; }
	TIntermTyped *getCondition() const { return mCondition; }

protected:
	TIntermTyped *mCondition;
};

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),
			mDepth(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;}
	virtual bool visitSwitch(Visit, TIntermSwitch*) { return true; }
	virtual bool visitCase(Visit, TIntermCase*) { return true; }

	void incrementDepth(TIntermNode *current)
	{
		mDepth++;
		mPath.push_back(current);
	}

	void decrementDepth()
	{
		mDepth--;
		mPath.pop_back();
	}

	TIntermNode *getParentNode()
	{
		return mPath.size() == 0 ? nullptr : mPath.back();
	}

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

protected:
	int mDepth;

	// All the nodes from root to the current node's parent during traversing.
	TVector<TIntermNode *> mPath;

private:
	struct ParentBlock
	{
		ParentBlock(TIntermAggregate *nodeIn, TIntermSequence::size_type posIn)
		: node(nodeIn), pos(posIn)
		{}

		TIntermAggregate *node;
		TIntermSequence::size_type pos;
	};
	// All the code blocks from the root to the current node's parent during traversal.
	std::vector<ParentBlock> mParentBlockStack;
};

#endif // __INTERMEDIATE_H
