blob: 7d421cc0caa1cd6c608bd13506f7d897cb4b3982 [file] [log] [blame]
/**************************************************************
*
* 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