/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 *************************************************************/



#ifndef _EXPR_HXX
#define _EXPR_HXX

#include "opcodes.hxx"
#include "token.hxx"

class SbiExprNode;
class SbiExpression;
class SbiExprList;
class SbiDimList;
class SbiParameters;
class SbiParser;
class SbiCodeGen;
class SbiSymDef;
class SbiProcDef;


#include <vector>
typedef ::std::vector<SbiExprList*> SbiExprListVector;

struct SbVar {                      // Variablen-Element:
	SbiExprNode*        pNext;		// Weiteres Element (bei Strukturen)
	SbiSymDef*          pDef;		// Symboldefinition
	SbiExprList*        pPar;		// optionale Parameter (wird geloescht)
	SbiExprListVector*  pvMorePar;  // Array of arrays foo(pPar)(avMorePar[0])(avMorePar[1])...
};

struct KeywordSymbolInfo
{
	String			m_aKeywordSymbol;
	SbxDataType		m_eSbxDataType;
	SbiToken		m_eTok;
};

enum SbiExprType {					// Expression-Typen:
	SbSTDEXPR,                      // normaler Ausdruck
	SbLVALUE,                       // beliebiger lValue
	SbSYMBOL,                       // beliebiges zusammengesetztes Symbol
	SbOPERAND						// Variable/Funktion
};

enum SbiExprMode {					// Expression context:
	EXPRMODE_STANDARD,              // default
	EXPRMODE_STANDALONE,            // a param1, param2 OR a( param1, param2 ) = 42
	EXPRMODE_LPAREN_PENDING,        // start of parameter list with bracket, special handling
	EXPRMODE_LPAREN_NOT_NEEDED,     // pending LPAREN has not been used
	EXPRMODE_ARRAY_OR_OBJECT,       // '=' or '(' or '.' found after ')' on ParenLevel 0, stopping
									// expression, assuming array syntax a(...)[(...)] = ?
									// or a(...).b(...)
	EXPRMODE_EMPTY_PAREN            // It turned out that the paren don't contain anything: a()
};

enum SbiNodeType {
	SbxNUMVAL,                      // nVal = Wert
	SbxSTRVAL,                      // aStrVal = Wert, before #i59791/#i45570: nStringId = Wert
	SbxVARVAL,                      // aVar = Wert
	SbxTYPEOF,                      // TypeOf ObjExpr Is Type
	SbxNODE,						// Node
	SbxNEW,							// new <type> expression
	SbxDUMMY
};

enum RecursiveMode
{
	UNDEFINED,
	FORCE_CALL,
	PREVENT_CALL
};

class SbiExprNode {                  // Operatoren (und Operanden)
	friend class SbiExpression;
	friend class SbiConstExpression;
	union {
		sal_uInt16 nTypeStrId; 	     	// gepoolter String-ID, #i59791/#i45570 Now only for TypeOf
		double nVal;                // numerischer Wert
		SbVar  aVar;                // oder Variable
	};
	String aStrVal;					// #i59791/#i45570 Store string directly
	SbiExprNode* pLeft;             // linker Zweig
	SbiExprNode* pRight;            // rechter Zweig (NULL bei unaeren Ops)
	SbiExprNode* pWithParent;       // Knoten, dessen Member this per with ist
	SbiCodeGen*  pGen; 				// Code-Generator
	SbiNodeType  eNodeType;         // Art des Nodes
	SbxDataType eType;              // aktueller Datentyp
	SbiToken     eTok;              // Token des Operators
	sal_Bool  bComposite;				// sal_True: Zusammengesetzter Ausdruck
	sal_Bool  bError; 	                // sal_True: Fehlerhaft
	void  FoldConstants();          // Constant Folding durchfuehren
	void  CollectBits();            // Umwandeln von Zahlen in Strings
	sal_Bool  IsOperand()               // sal_True, wenn Operand
		{ return sal_Bool( eNodeType != SbxNODE && eNodeType != SbxTYPEOF && eNodeType != SbxNEW ); }
	sal_Bool  IsTypeOf()
		{ return sal_Bool( eNodeType == SbxTYPEOF ); }
	sal_Bool  IsNew()
		{ return sal_Bool( eNodeType == SbxNEW ); }
	sal_Bool  IsNumber();               // sal_True bei Zahlen
	sal_Bool  IsString();               // sal_True bei Strings
	sal_Bool  IsLvalue();               // sal_True, falls als Lvalue verwendbar
	void  GenElement( SbiOpcode );  // Element
	void  BaseInit( SbiParser* p );	// Hilfsfunktion fuer Ctor, AB 17.12.95
public:
	SbiExprNode( void );
	SbiExprNode( SbiParser*, double, SbxDataType );
	SbiExprNode( SbiParser*, const String& );
	SbiExprNode( SbiParser*, const SbiSymDef&, SbxDataType, SbiExprList* = NULL );
	SbiExprNode( SbiParser*, SbiExprNode*, SbiToken, SbiExprNode* );
	SbiExprNode( SbiParser*, SbiExprNode*, sal_uInt16 );	// #120061 TypeOf
	SbiExprNode( SbiParser*, sal_uInt16 );					// new <type>
	virtual ~SbiExprNode();

	sal_Bool IsValid()                  { return sal_Bool( !bError ); }
	sal_Bool IsConstant()               // sal_True bei konstantem Operanden
		{ return sal_Bool( eNodeType == SbxSTRVAL || eNodeType == SbxNUMVAL ); }
	sal_Bool IsIntConst();              // sal_True bei Integer-Konstanten
	sal_Bool IsVariable();              // sal_True, wenn Variable

	SbiExprNode* GetWithParent()			{ return pWithParent; }
	void SetWithParent( SbiExprNode* p )	{ pWithParent = p; }

	SbxDataType GetType()           { return eType; }
	void SetType( SbxDataType eTp )	{ eType = eTp; }
	SbiNodeType GetNodeType()       { return eNodeType; }
	SbiSymDef* GetVar();			// Variable (falls vorhanden)
	SbiSymDef* GetRealVar();		// letzte Variable in x.y.z
	SbiExprNode* GetRealNode();		// letzter Knoten in x.y.z
	short GetDepth();               // Tiefe eines Baumes berechnen
	const String& GetString() 		{ return aStrVal; }
	short GetNumber() 				{ return (short)nVal; }
	SbiExprList* GetParameters()	{ return aVar.pPar; }
	SbiExprListVector* GetMoreParameters()	{ return aVar.pvMorePar; }

	void Optimize();                // Baumabgleich

	void Gen( RecursiveMode eRecMode = UNDEFINED );	// Ausgabe eines Nodes
};

class SbiExpression {                // der Ausdruck:
	friend class SbiExprList;
	friend class SbiParameters;
	friend class SbiDimList;
protected:
	String 		  aArgName;         // Name fuer bananntes Argument
	SbiParser* 	  pParser;			// fuer Fehlermeldungen, Parsing
	SbiExpression* pNext;            // Link bei Parameterlisten
	SbiExprNode*   pExpr;            // Der Expression-Baum
	SbiExprType	  eCurExpr;			// Art des Ausdrucks
	SbiExprMode   m_eMode;			// Expression context
	sal_Bool  		  bBased;			// sal_True: einfacher DIM-Teil (+BASE)
	sal_Bool          bError;           // sal_True: Fehler
	sal_Bool          bByVal;           // sal_True: ByVal-Parameter
	sal_Bool          bBracket;         // sal_True: Parameter list with brackets
	sal_uInt16        nParenLevel;
	SbiExprNode* Term( const KeywordSymbolInfo* pKeywordSymbolInfo = NULL );
	SbiExprNode* ObjTerm( SbiSymDef& );
	SbiExprNode* Operand( bool bUsedForTypeOf = false );
	SbiExprNode* Unary();
	SbiExprNode* Exp();
	SbiExprNode* MulDiv();
	SbiExprNode* IntDiv();
	SbiExprNode* Mod();
	SbiExprNode* AddSub();
	SbiExprNode* Cat();
	SbiExprNode* Like();
	SbiExprNode* VBA_Not();
	SbiExprNode* Comp();
	SbiExprNode* Boolean();
public:
	SbiExpression( SbiParser*, SbiExprType = SbSTDEXPR,
		SbiExprMode eMode = EXPRMODE_STANDARD, const KeywordSymbolInfo* pKeywordSymbolInfo = NULL ); // Parsender Ctor
	SbiExpression( SbiParser*, const String& );
	SbiExpression( SbiParser*, double, SbxDataType = SbxDOUBLE );
	SbiExpression( SbiParser*, const SbiSymDef&, SbiExprList* = NULL );
	SbiExpression( SbiParser*, SbiToken );        // Spezial-Expr mit Spezial-Tokens
   ~SbiExpression();
	String& GetName()               { return aArgName;            }
	void SetBased()					{ bBased = sal_True; 			  }
	sal_Bool IsBased()					{ return bBased; 			  }
	void SetByVal()                 { bByVal = sal_True;              }
	sal_Bool IsByVal()                  { return bByVal;              }
	sal_Bool IsBracket()                { return bBracket;            }
	sal_Bool IsValid()                  { return pExpr->IsValid();    }
	sal_Bool IsConstant()               { return pExpr->IsConstant(); }
	sal_Bool IsVariable()               { return pExpr->IsVariable(); }
	sal_Bool IsLvalue()                 { return pExpr->IsLvalue();   }
	sal_Bool IsIntConstant()            { return pExpr->IsIntConst(); }
	const String& GetString()       { return pExpr->GetString();  }
	SbiSymDef* GetVar()             { return pExpr->GetVar();     }
	SbiSymDef* GetRealVar()         { return pExpr->GetRealVar(); }
	SbiExprNode* GetExprNode()		{ return pExpr; }
	SbxDataType GetType()           { return pExpr->GetType();    }
	void SetType( SbxDataType eType){ pExpr->eType = eType;       }
	void Gen( RecursiveMode eRecMode = UNDEFINED );	// Ausgabe eines Nodes
};

class SbiConstExpression : public SbiExpression {
	double nVal;
	String aVal;
	SbxDataType eType;
public:                             // numerische Konstante
	SbiConstExpression( SbiParser* );
	SbxDataType GetType() { return eType; }
	const String& GetString() { return aVal; }
	double GetValue() { return nVal; }
	short GetShortValue();
};

class SbiExprList {                  // Basisklasse fuer Parameter und Dims
protected:
	SbiParser* pParser;				// Parser
	SbiExpression* pFirst;          // Expressions
	short nExpr;                    // Anzahl Expressions
	short nDim;						// Anzahl Dimensionen
	sal_Bool  bError;                   // sal_True: Fehler
	sal_Bool  bBracket;                 // sal_True: Klammern
public:
	SbiExprList( SbiParser* );
	virtual ~SbiExprList();
	sal_Bool  IsBracket()               { return bBracket;        }
	sal_Bool  IsValid()                 { return sal_Bool( !bError ); }
	short GetSize()                 { return nExpr;           }
	short GetDims()                 { return nDim;     		  }
	SbiExpression* Get( short );
	sal_Bool  Test( const SbiProcDef& );	// Parameter-Checks
	void  Gen();                    // Code-Erzeugung
	void addExpression( SbiExpression* pExpr );
};

class SbiParameters : public SbiExprList {
public:
	SbiParameters( SbiParser*, sal_Bool bConst = sal_False, sal_Bool bPar = sal_True);// parsender Ctor
};

class SbiDimList : public SbiExprList {
	sal_Bool  bConst;                   // sal_True: Alles sind Integer-Konstanten
public:
	SbiDimList( SbiParser* );         // Parsender Ctor
	sal_Bool  IsConstant()              { return bConst; }
};

#endif
