1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_FORMULA_TOKEN_HXX
21 #define INCLUDED_FORMULA_TOKEN_HXX
23 #include <sal/config.h>
29 #include <formula/formuladllapi.h>
30 #include <formula/IFunctionDescription.hxx>
31 #include <formula/opcode.hxx>
32 #include <formula/types.hxx>
33 #include <formula/paramclass.hxx>
34 #include <osl/interlck.h>
35 #include <rtl/ustring.hxx>
36 #include <sal/types.h>
37 #include <svl/sharedstring.hxx>
41 struct ScComplexRefData
;
42 struct ScSingleRefData
;
43 enum class FormulaError
: sal_uInt16
;
48 enum StackVar
: sal_uInt8
58 svExternal
, // Byte + String
59 svFAP
, // FormulaAutoPilot only, ever exported
61 svRefList
, // ocUnion result
62 svEmptyCell
, // Result is an empty cell, e.g. in LOOKUP()
64 svMatrixCell
, // Result is a matrix with bells and
65 // whistles as needed for _the_ matrix
68 svHybridCell
, // A temporary condition of a formula
69 // cell during import, having a double
70 // and/or string result and a formula
71 // string to be compiled.
78 svError
, // error token
80 svSep
, // separator, ocSep, ocOpen, ocClose
81 svUnknown
// unknown StackType
84 // Only to be used for debugging output. No guarantee of stability of the
87 // Turn this into an operator<< when StackVar becomes a scoped enum
89 inline std::string
StackVarEnumToString(StackVar
const e
)
93 case svByte
: return "Byte";
94 case svDouble
: return "Double";
95 case svString
: return "String";
96 case svSingleRef
: return "SingleRef";
97 case svDoubleRef
: return "DoubleRef";
98 case svMatrix
: return "Matrix";
99 case svIndex
: return "Index";
100 case svJump
: return "Jump";
101 case svExternal
: return "External";
102 case svFAP
: return "FAP";
103 case svJumpMatrix
: return "JumpMatrix";
104 case svRefList
: return "RefList";
105 case svEmptyCell
: return "EmptyCell";
106 case svMatrixCell
: return "MatrixCell";
107 case svHybridCell
: return "HybridCell";
108 case svExternalSingleRef
: return "ExternalSingleRef";
109 case svExternalDoubleRef
: return "ExternalDoubleRef";
110 case svExternalName
: return "ExternalName";
111 case svSingleVectorRef
: return "SingleVectorRef";
112 case svDoubleVectorRef
: return "DoubleVectorRef";
113 case svError
: return "Error";
114 case svMissing
: return "Missing";
115 case svSep
: return "Sep";
116 case svUnknown
: return "Unknown";
118 std::ostringstream os
;
119 os
<< static_cast<int>(e
);
123 class FORMULA_DLLPUBLIC FormulaToken
126 const StackVar eType
; // type of data
127 mutable oslInterlockedCount mnRefCnt
; // reference count
129 FormulaToken
& operator=( const FormulaToken
& ) = delete;
131 FormulaToken( StackVar eTypeP
,OpCode e
= ocPush
);
132 FormulaToken( const FormulaToken
& r
);
134 virtual ~FormulaToken();
136 void Delete() { delete this; }
137 void DeleteIfZeroRef() { if (mnRefCnt
== 0) delete this; }
138 StackVar
GetType() const { return eType
; }
139 bool IsFunction() const; // pure functions, no operators
141 bool IsExternalRef() const;
144 sal_uInt8
GetParamCount() const;
148 osl_atomic_increment(&mnRefCnt
);
153 if (!osl_atomic_decrement(&mnRefCnt
))
154 const_cast<FormulaToken
*>(this)->Delete();
157 oslInterlockedCount
GetRef() const { return mnRefCnt
; }
158 OpCode
GetOpCode() const { return eOp
; }
160 bool IsInForceArray() const;
163 Dummy methods to avoid switches and casts where possible,
164 the real token classes have to override the appropriate method[s].
165 The only methods valid anytime if not overridden are:
167 - GetByte() since this represents the count of parameters to a function
168 which of course is 0 on non-functions. FormulaByteToken and ScExternal do
171 - GetInForceArray() since also this is only used for operators and
172 functions and is ParamClass::Unknown for other tokens.
174 Any other non-overridden method pops up an assertion.
177 virtual sal_uInt8
GetByte() const;
178 virtual void SetByte( sal_uInt8 n
);
179 virtual ParamClass
GetInForceArray() const;
180 virtual void SetInForceArray( ParamClass c
);
181 virtual double GetDouble() const;
182 virtual double& GetDoubleAsReference();
183 virtual sal_Int16
GetDoubleType() const;
184 virtual void SetDoubleType( sal_Int16 nType
);
185 virtual svl::SharedString
GetString() const;
186 virtual void SetString( const svl::SharedString
& rStr
);
187 virtual sal_uInt16
GetIndex() const;
188 virtual void SetIndex( sal_uInt16 n
);
189 virtual sal_Int16
GetSheet() const;
190 virtual void SetSheet( sal_Int16 n
);
191 virtual short* GetJump() const;
192 virtual const OUString
& GetExternal() const;
193 virtual FormulaToken
* GetFAPOrigToken() const;
194 virtual FormulaError
GetError() const;
195 virtual void SetError( FormulaError
);
197 virtual const ScSingleRefData
* GetSingleRef() const;
198 virtual ScSingleRefData
* GetSingleRef();
199 virtual const ScComplexRefData
* GetDoubleRef() const;
200 virtual ScComplexRefData
* GetDoubleRef();
201 virtual const ScSingleRefData
* GetSingleRef2() const;
202 virtual ScSingleRefData
* GetSingleRef2();
203 virtual const ScMatrix
* GetMatrix() const;
204 virtual ScMatrix
* GetMatrix();
205 virtual ScJumpMatrix
* GetJumpMatrix() const;
206 virtual const std::vector
<ScComplexRefData
>* GetRefList() const;
207 virtual std::vector
<ScComplexRefData
>* GetRefList();
209 virtual FormulaToken
* Clone() const { return new FormulaToken(*this); }
211 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const;
212 virtual bool operator==( const FormulaToken
& rToken
) const;
214 /** This is dirty and only the compiler should use it! */
215 struct PrivateAccess
{ friend class FormulaCompiler
; private: PrivateAccess() { } };
216 void NewOpCode( OpCode e
, const PrivateAccess
& ) { eOp
= e
; }
219 inline void intrusive_ptr_add_ref(const FormulaToken
* p
)
224 inline void intrusive_ptr_release(const FormulaToken
* p
)
229 class FORMULA_DLLPUBLIC FormulaByteToken
: public FormulaToken
233 ParamClass eInForceArray
;
235 FormulaByteToken( OpCode e
, sal_uInt8 n
, StackVar v
, ParamClass c
) :
236 FormulaToken( v
,e
), nByte( n
),
237 eInForceArray( c
) {}
239 FormulaByteToken( OpCode e
, sal_uInt8 n
, ParamClass c
) :
240 FormulaToken( svByte
,e
), nByte( n
),
241 eInForceArray( c
) {}
242 FormulaByteToken( OpCode e
, sal_uInt8 n
) :
243 FormulaToken( svByte
,e
), nByte( n
),
244 eInForceArray( ParamClass::Unknown
) {}
245 FormulaByteToken( OpCode e
) :
246 FormulaToken( svByte
,e
), nByte( 0 ),
247 eInForceArray( ParamClass::Unknown
) {}
248 FormulaByteToken( const FormulaByteToken
& r
) :
249 FormulaToken( r
), nByte( r
.nByte
),
250 eInForceArray( r
.eInForceArray
) {}
252 virtual FormulaToken
* Clone() const override
{ return new FormulaByteToken(*this); }
253 virtual sal_uInt8
GetByte() const override
;
254 virtual void SetByte( sal_uInt8 n
) override
;
255 virtual ParamClass
GetInForceArray() const override
;
256 virtual void SetInForceArray( ParamClass c
) override
;
257 virtual bool operator==( const FormulaToken
& rToken
) const override
;
261 // A special token for the FormulaAutoPilot only. Keeps a reference pointer of
262 // the token of which it was created for comparison.
263 class FORMULA_DLLPUBLIC FormulaFAPToken
: public FormulaByteToken
266 FormulaTokenRef pOrigToken
;
268 FormulaFAPToken( OpCode e
, sal_uInt8 n
, FormulaToken
* p
) :
269 FormulaByteToken( e
, n
, svFAP
, ParamClass::Unknown
),
271 FormulaFAPToken( const FormulaFAPToken
& r
) :
272 FormulaByteToken( r
), pOrigToken( r
.pOrigToken
) {}
274 virtual FormulaToken
* Clone() const override
{ return new FormulaFAPToken(*this); }
275 virtual FormulaToken
* GetFAPOrigToken() const override
;
276 virtual bool operator==( const FormulaToken
& rToken
) const override
;
279 class FORMULA_DLLPUBLIC FormulaDoubleToken
: public FormulaToken
284 FormulaDoubleToken( double f
) :
285 FormulaToken( svDouble
), fDouble( f
) {}
286 FormulaDoubleToken( const FormulaDoubleToken
& r
) :
287 FormulaToken( r
), fDouble( r
.fDouble
) {}
289 virtual FormulaToken
* Clone() const override
{ return new FormulaDoubleToken(*this); }
290 virtual double GetDouble() const override
;
291 virtual double& GetDoubleAsReference() override
;
292 virtual sal_Int16
GetDoubleType() const override
; ///< always returns 0 for "not typed"
293 virtual bool operator==( const FormulaToken
& rToken
) const override
;
296 class FORMULA_DLLPUBLIC FormulaTypedDoubleToken
: public FormulaDoubleToken
299 sal_Int16 mnType
; /**< Can hold, for example, a value
300 of SvNumFormatType, or by
304 FormulaTypedDoubleToken( double f
, sal_Int16 nType
) :
305 FormulaDoubleToken( f
), mnType( nType
) {}
306 FormulaTypedDoubleToken( const FormulaTypedDoubleToken
& r
) :
307 FormulaDoubleToken( r
), mnType( r
.mnType
) {}
309 virtual FormulaToken
* Clone() const override
{ return new FormulaTypedDoubleToken(*this); }
310 virtual sal_Int16
GetDoubleType() const override
;
311 virtual void SetDoubleType( sal_Int16 nType
) override
;
312 virtual bool operator==( const FormulaToken
& rToken
) const override
;
316 class FORMULA_DLLPUBLIC FormulaStringToken
: public FormulaToken
318 svl::SharedString maString
;
320 FormulaStringToken( const svl::SharedString
& r
);
321 FormulaStringToken( const FormulaStringToken
& r
);
323 virtual FormulaToken
* Clone() const override
;
324 virtual svl::SharedString
GetString() const override
;
325 virtual void SetString( const svl::SharedString
& rStr
) override
;
326 virtual bool operator==( const FormulaToken
& rToken
) const override
;
330 /** Identical to FormulaStringToken, but with explicit OpCode instead of implicit
331 ocPush, and an optional sal_uInt8 for ocBad tokens. */
332 class FORMULA_DLLPUBLIC FormulaStringOpToken
: public FormulaByteToken
334 svl::SharedString maString
;
336 FormulaStringOpToken( OpCode e
, const svl::SharedString
& r
);
337 FormulaStringOpToken( const FormulaStringOpToken
& r
);
339 virtual FormulaToken
* Clone() const override
;
340 virtual svl::SharedString
GetString() const override
;
341 virtual void SetString( const svl::SharedString
& rStr
) override
;
342 virtual bool operator==( const FormulaToken
& rToken
) const override
;
345 class FORMULA_DLLPUBLIC FormulaIndexToken
: public FormulaToken
351 FormulaIndexToken( OpCode e
, sal_uInt16 n
, sal_Int16 nSheet
= -1 ) :
352 FormulaToken( svIndex
, e
), nIndex( n
), mnSheet( nSheet
) {}
353 FormulaIndexToken( const FormulaIndexToken
& r
) :
354 FormulaToken( r
), nIndex( r
.nIndex
), mnSheet( r
.mnSheet
) {}
356 virtual FormulaToken
* Clone() const override
{ return new FormulaIndexToken(*this); }
357 virtual sal_uInt16
GetIndex() const override
;
358 virtual void SetIndex( sal_uInt16 n
) override
;
359 virtual sal_Int16
GetSheet() const override
;
360 virtual void SetSheet( sal_Int16 n
) override
;
361 virtual bool operator==( const FormulaToken
& rToken
) const override
;
365 class FORMULA_DLLPUBLIC FormulaExternalToken
: public FormulaToken
371 FormulaExternalToken( OpCode e
, sal_uInt8 n
, const OUString
& r
) :
372 FormulaToken( svExternal
, e
), aExternal( r
),
374 FormulaExternalToken( OpCode e
, const OUString
& r
) :
375 FormulaToken(svExternal
, e
), aExternal( r
),
377 FormulaExternalToken( const FormulaExternalToken
& r
) :
378 FormulaToken( r
), aExternal( r
.aExternal
),
381 virtual FormulaToken
* Clone() const override
{ return new FormulaExternalToken(*this); }
382 virtual const OUString
& GetExternal() const override
;
383 virtual sal_uInt8
GetByte() const override
;
384 virtual void SetByte( sal_uInt8 n
) override
;
385 virtual bool operator==( const FormulaToken
& rToken
) const override
;
389 class FORMULA_DLLPUBLIC FormulaMissingToken
: public FormulaToken
392 FormulaMissingToken() :
393 FormulaToken( svMissing
,ocMissing
) {}
394 FormulaMissingToken( const FormulaMissingToken
& r
) :
397 virtual FormulaToken
* Clone() const override
{ return new FormulaMissingToken(*this); }
398 virtual double GetDouble() const override
;
399 virtual svl::SharedString
GetString() const override
;
400 virtual bool operator==( const FormulaToken
& rToken
) const override
;
403 class FORMULA_DLLPUBLIC FormulaJumpToken
: public FormulaToken
406 std::unique_ptr
<short[]>
408 ParamClass eInForceArray
;
410 FormulaJumpToken( OpCode e
, short const * p
) :
411 FormulaToken( formula::svJump
, e
),
412 eInForceArray( ParamClass::Unknown
)
414 pJump
.reset( new short[ p
[0] + 1 ] );
415 memcpy( pJump
.get(), p
, (p
[0] + 1) * sizeof(short) );
417 FormulaJumpToken( const FormulaJumpToken
& r
) :
419 eInForceArray( r
.eInForceArray
)
421 pJump
.reset( new short[ r
.pJump
[0] + 1 ] );
422 memcpy( pJump
.get(), r
.pJump
.get(), (r
.pJump
[0] + 1) * sizeof(short) );
424 virtual ~FormulaJumpToken() override
;
425 virtual short* GetJump() const override
;
426 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
427 virtual FormulaToken
* Clone() const override
{ return new FormulaJumpToken(*this); }
428 virtual ParamClass
GetInForceArray() const override
;
429 virtual void SetInForceArray( ParamClass c
) override
;
433 class FORMULA_DLLPUBLIC FormulaUnknownToken
: public FormulaToken
436 FormulaUnknownToken( OpCode e
) :
437 FormulaToken( svUnknown
, e
) {}
438 FormulaUnknownToken( const FormulaUnknownToken
& r
) :
441 virtual FormulaToken
* Clone() const override
{ return new FormulaUnknownToken(*this); }
442 virtual bool operator==( const FormulaToken
& rToken
) const override
;
446 class FORMULA_DLLPUBLIC FormulaErrorToken
: public FormulaToken
450 FormulaErrorToken( FormulaError nErr
) :
451 FormulaToken( svError
), nError( nErr
) {}
452 FormulaErrorToken( const FormulaErrorToken
& r
) :
453 FormulaToken( r
), nError( r
.nError
) {}
455 virtual FormulaToken
* Clone() const override
{ return new FormulaErrorToken(*this); }
456 virtual FormulaError
GetError() const override
;
457 virtual void SetError( FormulaError nErr
) override
;
458 virtual bool operator==( const FormulaToken
& rToken
) const override
;
467 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */