/************************************************************** * * 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 FORMULA_TOKEN_HXX #define FORMULA_TOKEN_HXX #include #include #include #include "formula/opcode.hxx" //#include "refdata.hxx" //#include "scmatrix.hxx" #include "formula/intruref.hxx" #include #include "formula/IFunctionDescription.hxx" #include "formula/formuladllapi.h" namespace formula { enum StackVarEnum { svByte, svDouble, svString, svSingleRef, svDoubleRef, svMatrix, svIndex, svJump, svExternal, // Byte + String svFAP, // FormulaAutoPilot only, ever exported svJumpMatrix, // 2003-07-02 svRefList, // ocUnion result svEmptyCell, // Result is an empty cell, e.g. in LOOKUP() svMatrixCell, // Result is a matrix with bells and // whistles as needed for _the_ matrix // formula result. svHybridCell, // A temporary condition of a formula // cell during import, having a double // and/or string result and a formula // string to be compiled. svExternalSingleRef, svExternalDoubleRef, svExternalName, svSubroutine, // A token with a subroutine token array. svError, // error token svMissing = 0x70, // 0 or "" svSep, // separator, ocSep, ocOpen, ocClose svUnknown // unknown StackType }; #ifndef DBG_UTIL // save memory since compilers tend to int an enum typedef sal_uInt8 StackVar; #else // have enum names in debugger typedef StackVarEnum StackVar; #endif class FormulaToken; typedef SimpleIntrusiveReference< class FormulaToken > FormulaTokenRef; typedef SimpleIntrusiveReference< const class FormulaToken > FormulaConstTokenRef; class FormulaTokenArray; class FORMULA_DLLPUBLIC FormulaToken : public IFormulaToken { OpCode eOp; // not implemented, prevent usage FormulaToken(); FormulaToken& operator=( const FormulaToken& ); protected: const StackVar eType; // type of data mutable sal_uInt16 nRefCnt; // reference count public: FormulaToken( StackVar eTypeP,OpCode e = ocPush ) : eOp(e), eType( eTypeP ), nRefCnt(0) {} FormulaToken( const FormulaToken& r ) : IFormulaToken(), eOp(r.eOp), eType( r.eType ), nRefCnt(0) {} virtual ~FormulaToken(); inline void Delete() { delete this; } inline StackVar GetType() const { return eType; } sal_Bool IsFunction() const; // pure functions, no operators sal_Bool IsMatrixFunction() const; // if a function _always_ returns a Matrix sal_uInt8 GetParamCount() const; inline void IncRef() const { nRefCnt++; } inline void DecRef() const { if (!--nRefCnt) const_cast(this)->Delete(); } inline sal_uInt16 GetRef() const { return nRefCnt; } inline OpCode GetOpCode() const { return eOp; } /** Dummy methods to avoid switches and casts where possible, the real token classes have to overload the appropriate method[s]. The only methods valid anytime if not overloaded are: - GetByte() since this represents the count of parameters to a function which of course is 0 on non-functions. FormulaByteToken and ScExternal do overload it. - HasForceArray() since also this is only used for operators and functions and is 0 for other tokens. Any other non-overloaded method pops up an assertion. */ virtual sal_uInt8 GetByte() const; virtual void SetByte( sal_uInt8 n ); virtual bool HasForceArray() const; virtual void SetForceArray( bool b ); virtual double GetDouble() const; virtual double& GetDoubleAsReference(); virtual const String& GetString() const; virtual sal_uInt16 GetIndex() const; virtual void SetIndex( sal_uInt16 n ); virtual short* GetJump() const; virtual const String& GetExternal() const; virtual FormulaToken* GetFAPOrigToken() const; virtual sal_uInt16 GetError() const; virtual void SetError( sal_uInt16 ); virtual FormulaToken* Clone() const { return new FormulaToken(*this); } virtual sal_Bool Is3DRef() const; // reference with 3D flag set virtual sal_Bool TextEqual( const formula::FormulaToken& rToken ) const; virtual sal_Bool operator==( const FormulaToken& rToken ) const; virtual bool isFunction() const { return IsFunction(); } virtual sal_uInt32 getArgumentCount() const { return GetParamCount(); } /** This is dirty and only the compiler should use it! */ struct PrivateAccess { friend class FormulaCompiler; private: PrivateAccess() { } }; inline void NewOpCode( OpCode e, const PrivateAccess& ) { eOp = e; } static size_t GetStrLenBytes( xub_StrLen nLen ) { return nLen * sizeof(sal_Unicode); } static size_t GetStrLenBytes( const String& rStr ) { return GetStrLenBytes( rStr.Len() ); } }; class FORMULA_DLLPUBLIC FormulaByteToken : public FormulaToken { private: sal_uInt8 nByte; bool bHasForceArray; protected: FormulaByteToken( OpCode e, sal_uInt8 n, StackVar v, bool b ) : FormulaToken( v,e ), nByte( n ), bHasForceArray( b ) {} public: FormulaByteToken( OpCode e, sal_uInt8 n, bool b ) : FormulaToken( svByte,e ), nByte( n ), bHasForceArray( b ) {} FormulaByteToken( OpCode e, sal_uInt8 n ) : FormulaToken( svByte,e ), nByte( n ), bHasForceArray( false ) {} FormulaByteToken( OpCode e ) : FormulaToken( svByte,e ), nByte( 0 ), bHasForceArray( false ) {} FormulaByteToken( const FormulaByteToken& r ) : FormulaToken( r ), nByte( r.nByte ), bHasForceArray( r.bHasForceArray ) {} virtual FormulaToken* Clone() const { return new FormulaByteToken(*this); } virtual sal_uInt8 GetByte() const; virtual void SetByte( sal_uInt8 n ); virtual bool HasForceArray() const; virtual void SetForceArray( bool b ); virtual sal_Bool operator==( const FormulaToken& rToken ) const; DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaByteToken ) }; // A special token for the FormulaAutoPilot only. Keeps a reference pointer of // the token of which it was created for comparison. class FORMULA_DLLPUBLIC FormulaFAPToken : public FormulaByteToken { private: FormulaTokenRef pOrigToken; public: FormulaFAPToken( OpCode e, sal_uInt8 n, FormulaToken* p ) : FormulaByteToken( e, n, svFAP, false ), pOrigToken( p ) {} FormulaFAPToken( const FormulaFAPToken& r ) : FormulaByteToken( r ), pOrigToken( r.pOrigToken ) {} virtual FormulaToken* Clone() const { return new FormulaFAPToken(*this); } virtual FormulaToken* GetFAPOrigToken() const; virtual sal_Bool operator==( const FormulaToken& rToken ) const; }; class FORMULA_DLLPUBLIC FormulaDoubleToken : public FormulaToken { private: double fDouble; public: FormulaDoubleToken( double f ) : FormulaToken( svDouble ), fDouble( f ) {} FormulaDoubleToken( const FormulaDoubleToken& r ) : FormulaToken( r ), fDouble( r.fDouble ) {} virtual FormulaToken* Clone() const { return new FormulaDoubleToken(*this); } virtual double GetDouble() const; virtual double& GetDoubleAsReference(); virtual sal_Bool operator==( const FormulaToken& rToken ) const; DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaDoubleToken ) }; class FORMULA_DLLPUBLIC FormulaStringToken : public FormulaToken { private: String aString; public: FormulaStringToken( const String& r ) : FormulaToken( svString ), aString( r ) {} FormulaStringToken( const FormulaStringToken& r ) : FormulaToken( r ), aString( r.aString ) {} virtual FormulaToken* Clone() const { return new FormulaStringToken(*this); } virtual const String& GetString() const; virtual sal_Bool operator==( const FormulaToken& rToken ) const; DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaStringToken ) }; /** Identical to FormulaStringToken, but with explicit OpCode instead of implicit ocPush, and an optional sal_uInt8 for ocBad tokens. */ class FORMULA_DLLPUBLIC FormulaStringOpToken : public FormulaByteToken { private: String aString; public: FormulaStringOpToken( OpCode e, const String& r ) : FormulaByteToken( e, 0, svString, false ), aString( r ) {} FormulaStringOpToken( const FormulaStringOpToken& r ) : FormulaByteToken( r ), aString( r.aString ) {} virtual FormulaToken* Clone() const { return new FormulaStringOpToken(*this); } virtual const String& GetString() const; virtual sal_Bool operator==( const FormulaToken& rToken ) const; }; class FORMULA_DLLPUBLIC FormulaIndexToken : public FormulaToken { private: sal_uInt16 nIndex; public: FormulaIndexToken( OpCode e, sal_uInt16 n ) : FormulaToken( svIndex, e ), nIndex( n ) {} FormulaIndexToken( const FormulaIndexToken& r ) : FormulaToken( r ), nIndex( r.nIndex ) {} virtual FormulaToken* Clone() const { return new FormulaIndexToken(*this); } virtual sal_uInt16 GetIndex() const; virtual void SetIndex( sal_uInt16 n ); virtual sal_Bool operator==( const FormulaToken& rToken ) const; }; class FORMULA_DLLPUBLIC FormulaExternalToken : public FormulaToken { private: String aExternal; sal_uInt8 nByte; public: FormulaExternalToken( OpCode e, sal_uInt8 n, const String& r ) : FormulaToken( svExternal, e ), aExternal( r ), nByte( n ) {} FormulaExternalToken( OpCode e, const String& r ) : FormulaToken(svExternal, e ), aExternal( r ), nByte( 0 ) {} FormulaExternalToken( const FormulaExternalToken& r ) : FormulaToken( r ), aExternal( r.aExternal ), nByte( r.nByte ) {} virtual FormulaToken* Clone() const { return new FormulaExternalToken(*this); } virtual const String& GetExternal() const; virtual sal_uInt8 GetByte() const; virtual void SetByte( sal_uInt8 n ); virtual sal_Bool operator==( const FormulaToken& rToken ) const; }; class FORMULA_DLLPUBLIC FormulaMissingToken : public FormulaToken { public: FormulaMissingToken() : FormulaToken( svMissing,ocMissing ) {} FormulaMissingToken( const FormulaMissingToken& r ) : FormulaToken( r ) {} virtual FormulaToken* Clone() const { return new FormulaMissingToken(*this); } virtual double GetDouble() const; virtual const String& GetString() const; virtual sal_Bool operator==( const FormulaToken& rToken ) const; }; class FORMULA_DLLPUBLIC FormulaJumpToken : public FormulaToken { private: short* pJump; public: FormulaJumpToken( OpCode e, short* p ) : FormulaToken( formula::svJump , e) { pJump = new short[ p[0] + 1 ]; memcpy( pJump, p, (p[0] + 1) * sizeof(short) ); } FormulaJumpToken( const FormulaJumpToken& r ) : FormulaToken( r ) { pJump = new short[ r.pJump[0] + 1 ]; memcpy( pJump, r.pJump, (r.pJump[0] + 1) * sizeof(short) ); } virtual ~FormulaJumpToken(); virtual short* GetJump() const; virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; virtual FormulaToken* Clone() const { return new FormulaJumpToken(*this); } }; class FORMULA_DLLPUBLIC FormulaSubroutineToken : public FormulaToken { public: /** Takes ownership of pArray and deletes it upon destruction! */ FormulaSubroutineToken( const FormulaTokenArray* pArray ) : FormulaToken( svSubroutine, ocCall ), mpArray( pArray) {} FormulaSubroutineToken( const FormulaSubroutineToken& r ); virtual ~FormulaSubroutineToken(); virtual FormulaToken* Clone() const { return new FormulaSubroutineToken(*this); } virtual sal_Bool operator==( const FormulaToken& rToken ) const; const FormulaTokenArray* GetTokenArray() const; private: const FormulaTokenArray* mpArray; }; class FORMULA_DLLPUBLIC FormulaUnknownToken : public FormulaToken { public: FormulaUnknownToken( OpCode e ) : FormulaToken( svUnknown, e ) {} FormulaUnknownToken( const FormulaUnknownToken& r ) : FormulaToken( r ) {} virtual FormulaToken* Clone() const { return new FormulaUnknownToken(*this); } virtual sal_Bool operator==( const FormulaToken& rToken ) const; }; class FORMULA_DLLPUBLIC FormulaErrorToken : public FormulaToken { sal_uInt16 nError; public: FormulaErrorToken( sal_uInt16 nErr ) : FormulaToken( svError ), nError( nErr) {} FormulaErrorToken( const FormulaErrorToken& r ) : FormulaToken( r ), nError( r.nError) {} virtual FormulaToken* Clone() const { return new FormulaErrorToken(*this); } virtual sal_uInt16 GetError() const; virtual void SetError( sal_uInt16 nErr ); virtual sal_Bool operator==( const FormulaToken& rToken ) const; }; // ============================================================================= } // formula // ============================================================================= #endif