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/opcode.hxx>
31 #include <formula/types.hxx>
32 #include <formula/paramclass.hxx>
33 #include <osl/interlck.h>
34 #include <rtl/ustring.hxx>
35 #include <sal/types.h>
36 #include <svl/sharedstring.hxx>
40 struct ScComplexRefData
;
41 struct ScSingleRefData
;
42 enum class FormulaError
: sal_uInt16
;
47 enum StackVar
: sal_uInt8
57 svExternal
, // Byte + String
58 svFAP
, // FormulaAutoPilot only, ever exported
60 svRefList
, // ocUnion result
61 svEmptyCell
, // Result is an empty cell, e.g. in LOOKUP()
63 svMatrixCell
, // Result is a matrix with bells and
64 // whistles as needed for _the_ matrix
67 svHybridCell
, // A temporary condition of a formula
68 // cell during import, having a double
69 // and/or string result and a formula
70 // string to be compiled.
77 svError
, // error token
79 svSep
, // separator, ocSep, ocOpen, ocClose
80 svUnknown
// unknown StackType
83 // Only to be used for debugging output. No guarantee of stability of the
86 // Turn this into an operator<< when StackVar becomes a scoped enum
88 inline std::string
StackVarEnumToString(StackVar
const e
)
92 case svByte
: return "Byte";
93 case svDouble
: return "Double";
94 case svString
: return "String";
95 case svSingleRef
: return "SingleRef";
96 case svDoubleRef
: return "DoubleRef";
97 case svMatrix
: return "Matrix";
98 case svIndex
: return "Index";
99 case svJump
: return "Jump";
100 case svExternal
: return "External";
101 case svFAP
: return "FAP";
102 case svJumpMatrix
: return "JumpMatrix";
103 case svRefList
: return "RefList";
104 case svEmptyCell
: return "EmptyCell";
105 case svMatrixCell
: return "MatrixCell";
106 case svHybridCell
: return "HybridCell";
107 case svExternalSingleRef
: return "ExternalSingleRef";
108 case svExternalDoubleRef
: return "ExternalDoubleRef";
109 case svExternalName
: return "ExternalName";
110 case svSingleVectorRef
: return "SingleVectorRef";
111 case svDoubleVectorRef
: return "DoubleVectorRef";
112 case svError
: return "Error";
113 case svMissing
: return "Missing";
114 case svSep
: return "Sep";
115 case svUnknown
: return "Unknown";
117 std::ostringstream os
;
118 os
<< static_cast<int>(e
);
122 class FORMULA_DLLPUBLIC FormulaToken
125 const StackVar eType
; // type of data
126 mutable oslInterlockedCount mnRefCnt
; // reference count
128 FormulaToken
& operator=( const FormulaToken
& ) = delete;
130 FormulaToken( StackVar eTypeP
,OpCode e
= ocPush
);
131 FormulaToken( const FormulaToken
& r
);
133 virtual ~FormulaToken();
135 void Delete() { delete this; }
136 void DeleteIfZeroRef() { if (mnRefCnt
== 0) delete this; }
137 StackVar
GetType() const { return eType
; }
138 bool IsFunction() const; // pure functions, no operators
140 bool IsExternalRef() const;
143 sal_uInt8
GetParamCount() const;
147 osl_atomic_increment(&mnRefCnt
);
152 if (!osl_atomic_decrement(&mnRefCnt
))
153 const_cast<FormulaToken
*>(this)->Delete();
156 oslInterlockedCount
GetRef() const { return mnRefCnt
; }
157 OpCode
GetOpCode() const { return eOp
; }
159 bool IsInForceArray() const;
162 Dummy methods to avoid switches and casts where possible,
163 the real token classes have to override the appropriate method[s].
164 The only methods valid anytime if not overridden are:
166 - GetByte() since this represents the count of parameters to a function
167 which of course is 0 on non-functions. FormulaByteToken and ScExternal do
170 - GetInForceArray() since also this is only used for operators and
171 functions and is ParamClass::Unknown for other tokens.
173 Any other non-overridden method pops up an assertion.
176 virtual sal_uInt8
GetByte() const;
177 virtual void SetByte( sal_uInt8 n
);
178 virtual ParamClass
GetInForceArray() const;
179 virtual void SetInForceArray( ParamClass c
);
180 virtual double GetDouble() const;
181 virtual double& GetDoubleAsReference();
182 virtual sal_Int16
GetDoubleType() const;
183 virtual void SetDoubleType( sal_Int16 nType
);
184 virtual svl::SharedString
GetString() const;
185 virtual void SetString( const svl::SharedString
& rStr
);
186 virtual sal_uInt16
GetIndex() const;
187 virtual void SetIndex( sal_uInt16 n
);
188 virtual sal_Int16
GetSheet() const;
189 virtual void SetSheet( sal_Int16 n
);
190 virtual short* GetJump() const;
191 virtual const OUString
& GetExternal() const;
192 virtual FormulaToken
* GetFAPOrigToken() const;
193 virtual FormulaError
GetError() const;
194 virtual void SetError( FormulaError
);
196 virtual const ScSingleRefData
* GetSingleRef() const;
197 virtual ScSingleRefData
* GetSingleRef();
198 virtual const ScComplexRefData
* GetDoubleRef() const;
199 virtual ScComplexRefData
* GetDoubleRef();
200 virtual const ScSingleRefData
* GetSingleRef2() const;
201 virtual ScSingleRefData
* GetSingleRef2();
202 virtual const ScMatrix
* GetMatrix() const;
203 virtual ScMatrix
* GetMatrix();
204 virtual ScJumpMatrix
* GetJumpMatrix() const;
205 virtual const std::vector
<ScComplexRefData
>* GetRefList() const;
206 virtual std::vector
<ScComplexRefData
>* GetRefList();
208 virtual FormulaToken
* Clone() const { return new FormulaToken(*this); }
210 virtual bool TextEqual( const formula::FormulaToken
& rToken
) const;
211 virtual bool operator==( const FormulaToken
& rToken
) const;
213 /** This is dirty and only the compiler should use it! */
214 struct PrivateAccess
{ friend class FormulaCompiler
; private: PrivateAccess() { } };
215 void NewOpCode( OpCode e
, const PrivateAccess
& ) { eOp
= e
; }
218 inline void intrusive_ptr_add_ref(const FormulaToken
* p
)
223 inline void intrusive_ptr_release(const FormulaToken
* p
)
228 class FORMULA_DLLPUBLIC FormulaByteToken
: public FormulaToken
232 ParamClass eInForceArray
;
234 FormulaByteToken( OpCode e
, sal_uInt8 n
, StackVar v
, ParamClass c
) :
235 FormulaToken( v
,e
), nByte( n
),
236 eInForceArray( c
) {}
238 FormulaByteToken( OpCode e
, sal_uInt8 n
, ParamClass c
) :
239 FormulaToken( svByte
,e
), nByte( n
),
240 eInForceArray( c
) {}
241 FormulaByteToken( OpCode e
, sal_uInt8 n
) :
242 FormulaToken( svByte
,e
), nByte( n
),
243 eInForceArray( ParamClass::Unknown
) {}
244 FormulaByteToken( OpCode e
) :
245 FormulaToken( svByte
,e
), nByte( 0 ),
246 eInForceArray( ParamClass::Unknown
) {}
247 FormulaByteToken( const FormulaByteToken
& r
) :
248 FormulaToken( r
), nByte( r
.nByte
),
249 eInForceArray( r
.eInForceArray
) {}
251 virtual FormulaToken
* Clone() const override
{ return new FormulaByteToken(*this); }
252 virtual sal_uInt8
GetByte() const override
;
253 virtual void SetByte( sal_uInt8 n
) override
;
254 virtual ParamClass
GetInForceArray() const override
;
255 virtual void SetInForceArray( ParamClass c
) override
;
256 virtual bool operator==( const FormulaToken
& rToken
) const override
;
260 // A special token for the FormulaAutoPilot only. Keeps a reference pointer of
261 // the token of which it was created for comparison.
262 class FORMULA_DLLPUBLIC FormulaFAPToken final
: public FormulaByteToken
265 FormulaTokenRef pOrigToken
;
267 FormulaFAPToken( OpCode e
, sal_uInt8 n
, FormulaToken
* p
) :
268 FormulaByteToken( e
, n
, svFAP
, ParamClass::Unknown
),
270 FormulaFAPToken( const FormulaFAPToken
& r
) :
271 FormulaByteToken( r
), pOrigToken( r
.pOrigToken
) {}
273 virtual FormulaToken
* Clone() const override
{ return new FormulaFAPToken(*this); }
274 virtual FormulaToken
* GetFAPOrigToken() const override
;
275 virtual bool operator==( const FormulaToken
& rToken
) const override
;
278 class FORMULA_DLLPUBLIC FormulaDoubleToken
: public FormulaToken
283 FormulaDoubleToken( double f
) :
284 FormulaToken( svDouble
), fDouble( f
) {}
285 FormulaDoubleToken( const FormulaDoubleToken
& r
) :
286 FormulaToken( r
), fDouble( r
.fDouble
) {}
288 virtual FormulaToken
* Clone() const override
{ return new FormulaDoubleToken(*this); }
289 virtual double GetDouble() const override
;
290 virtual double& GetDoubleAsReference() override
;
291 virtual sal_Int16
GetDoubleType() const override
; ///< always returns 0 for "not typed"
292 virtual bool operator==( const FormulaToken
& rToken
) const override
;
295 class FORMULA_DLLPUBLIC FormulaTypedDoubleToken final
: public FormulaDoubleToken
298 sal_Int16 mnType
; /**< Can hold, for example, a value
299 of SvNumFormatType, or by
303 FormulaTypedDoubleToken( double f
, sal_Int16 nType
) :
304 FormulaDoubleToken( f
), mnType( nType
) {}
305 FormulaTypedDoubleToken( const FormulaTypedDoubleToken
& r
) :
306 FormulaDoubleToken( r
), mnType( r
.mnType
) {}
308 virtual FormulaToken
* Clone() const override
{ return new FormulaTypedDoubleToken(*this); }
309 virtual sal_Int16
GetDoubleType() const override
;
310 virtual void SetDoubleType( sal_Int16 nType
) override
;
311 virtual bool operator==( const FormulaToken
& rToken
) const override
;
315 class FORMULA_DLLPUBLIC FormulaStringToken final
: public FormulaToken
317 svl::SharedString maString
;
319 FormulaStringToken( const svl::SharedString
& r
);
320 FormulaStringToken( const FormulaStringToken
& r
);
322 virtual FormulaToken
* Clone() const override
;
323 virtual svl::SharedString
GetString() const override
;
324 virtual void SetString( const svl::SharedString
& rStr
) override
;
325 virtual bool operator==( const FormulaToken
& rToken
) const override
;
329 /** Identical to FormulaStringToken, but with explicit OpCode instead of implicit
330 ocPush, and an optional sal_uInt8 for ocBad tokens. */
331 class FORMULA_DLLPUBLIC FormulaStringOpToken final
: public FormulaByteToken
333 svl::SharedString maString
;
335 FormulaStringOpToken( OpCode e
, const svl::SharedString
& r
);
336 FormulaStringOpToken( const FormulaStringOpToken
& r
);
338 virtual FormulaToken
* Clone() const override
;
339 virtual svl::SharedString
GetString() const override
;
340 virtual void SetString( const svl::SharedString
& rStr
) override
;
341 virtual bool operator==( const FormulaToken
& rToken
) const override
;
344 class FORMULA_DLLPUBLIC FormulaIndexToken final
: public FormulaToken
350 FormulaIndexToken( OpCode e
, sal_uInt16 n
, sal_Int16 nSheet
= -1 ) :
351 FormulaToken( svIndex
, e
), nIndex( n
), mnSheet( nSheet
) {}
352 FormulaIndexToken( const FormulaIndexToken
& r
) :
353 FormulaToken( r
), nIndex( r
.nIndex
), mnSheet( r
.mnSheet
) {}
355 virtual FormulaToken
* Clone() const override
{ return new FormulaIndexToken(*this); }
356 virtual sal_uInt16
GetIndex() const override
;
357 virtual void SetIndex( sal_uInt16 n
) override
;
358 virtual sal_Int16
GetSheet() const override
;
359 virtual void SetSheet( sal_Int16 n
) override
;
360 virtual bool operator==( const FormulaToken
& rToken
) const override
;
364 class FORMULA_DLLPUBLIC FormulaExternalToken final
: public FormulaToken
370 FormulaExternalToken( OpCode e
, sal_uInt8 n
, const OUString
& r
) :
371 FormulaToken( svExternal
, e
), aExternal( r
),
373 FormulaExternalToken( OpCode e
, const OUString
& r
) :
374 FormulaToken(svExternal
, e
), aExternal( r
),
376 FormulaExternalToken( const FormulaExternalToken
& r
) :
377 FormulaToken( r
), aExternal( r
.aExternal
),
380 virtual FormulaToken
* Clone() const override
{ return new FormulaExternalToken(*this); }
381 virtual const OUString
& GetExternal() const override
;
382 virtual sal_uInt8
GetByte() const override
;
383 virtual void SetByte( sal_uInt8 n
) override
;
384 virtual bool operator==( const FormulaToken
& rToken
) const override
;
388 class FORMULA_DLLPUBLIC FormulaMissingToken final
: public FormulaToken
391 FormulaMissingToken() :
392 FormulaToken( svMissing
,ocMissing
) {}
393 FormulaMissingToken( const FormulaMissingToken
& r
) :
396 virtual FormulaToken
* Clone() const override
{ return new FormulaMissingToken(*this); }
397 virtual double GetDouble() const override
;
398 virtual svl::SharedString
GetString() const override
;
399 virtual bool operator==( const FormulaToken
& rToken
) const override
;
402 class FORMULA_DLLPUBLIC FormulaJumpToken final
: public FormulaToken
405 std::unique_ptr
<short[]>
407 ParamClass eInForceArray
;
409 FormulaJumpToken( OpCode e
, short const * p
) :
410 FormulaToken( formula::svJump
, e
),
411 eInForceArray( ParamClass::Unknown
)
413 pJump
.reset( new short[ p
[0] + 1 ] );
414 memcpy( pJump
.get(), p
, (p
[0] + 1) * sizeof(short) );
416 FormulaJumpToken( const FormulaJumpToken
& r
) :
418 eInForceArray( r
.eInForceArray
)
420 pJump
.reset( new short[ r
.pJump
[0] + 1 ] );
421 memcpy( pJump
.get(), r
.pJump
.get(), (r
.pJump
[0] + 1) * sizeof(short) );
423 virtual ~FormulaJumpToken() override
;
424 virtual short* GetJump() const override
;
425 virtual bool operator==( const formula::FormulaToken
& rToken
) const override
;
426 virtual FormulaToken
* Clone() const override
{ return new FormulaJumpToken(*this); }
427 virtual ParamClass
GetInForceArray() const override
;
428 virtual void SetInForceArray( ParamClass c
) override
;
432 class FORMULA_DLLPUBLIC FormulaUnknownToken final
: public FormulaToken
435 FormulaUnknownToken( OpCode e
) :
436 FormulaToken( svUnknown
, e
) {}
437 FormulaUnknownToken( const FormulaUnknownToken
& r
) :
440 virtual FormulaToken
* Clone() const override
{ return new FormulaUnknownToken(*this); }
441 virtual bool operator==( const FormulaToken
& rToken
) const override
;
445 class FORMULA_DLLPUBLIC FormulaErrorToken final
: public FormulaToken
449 FormulaErrorToken( FormulaError nErr
) :
450 FormulaToken( svError
), nError( nErr
) {}
451 FormulaErrorToken( const FormulaErrorToken
& r
) :
452 FormulaToken( r
), nError( r
.nError
) {}
454 virtual FormulaToken
* Clone() const override
{ return new FormulaErrorToken(*this); }
455 virtual FormulaError
GetError() const override
;
456 virtual void SetError( FormulaError nErr
) override
;
457 virtual bool operator==( const FormulaToken
& rToken
) const override
;
466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */