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_BASIC_SOURCE_INC_EXPR_HXX
21 #define INCLUDED_BASIC_SOURCE_INC_EXPR_HXX
25 #include "opcodes.hxx"
38 typedef std::unique_ptr
<SbiExprList
> SbiExprListPtr
;
39 typedef std::vector
<SbiExprListPtr
> SbiExprListVector
;
42 SbiExprNode
* pNext
; // next element (for structures)
43 SbiSymDef
* pDef
; // symbol definition
44 SbiExprList
* pPar
; // optional parameters (is deleted)
45 SbiExprListVector
* pvMorePar
; // Array of arrays foo(pPar)(avMorePar[0])(avMorePar[1])...
48 struct KeywordSymbolInfo
50 OUString m_aKeywordSymbol
;
51 SbxDataType m_eSbxDataType
;
54 enum SbiExprType
{ // expression types:
55 SbSTDEXPR
, // normal expression
56 SbLVALUE
, // any lValue
57 SbSYMBOL
, // any composite symbol
58 SbOPERAND
// variable/function
61 enum SbiExprMode
{ // Expression context:
62 EXPRMODE_STANDARD
, // default
63 EXPRMODE_STANDALONE
, // a param1, param2 OR a( param1, param2 ) = 42
64 EXPRMODE_LPAREN_PENDING
, // start of parameter list with bracket, special handling
65 EXPRMODE_LPAREN_NOT_NEEDED
, // pending LPAREN has not been used
66 EXPRMODE_ARRAY_OR_OBJECT
, // '=' or '(' or '.' found after ')' on ParenLevel 0, stopping
67 // expression, assuming array syntax a(...)[(...)] = ?
69 EXPRMODE_EMPTY_PAREN
// It turned out that the paren don't contain anything: a()
73 SbxNUMVAL
, // nVal = value
74 SbxSTRVAL
, // aStrVal = value, before #i59791/#i45570: nStringId = value
75 SbxVARVAL
, // aVar = value
76 SbxTYPEOF
, // TypeOf ObjExpr Is Type
78 SbxNEW
, // new <type> expression
89 class SbiExprNode final
{ // operators (and operands)
90 friend class SbiExpression
;
91 friend class SbiConstExpression
;
93 sal_uInt16 nTypeStrId
; // pooled String-ID, #i59791/#i45570 Now only for TypeOf
94 double nVal
; // numeric value
95 SbVar aVar
; // or variable
97 OUString aStrVal
; // #i59791/#i45570 Store string directly
98 std::unique_ptr
<SbiExprNode
> pLeft
; // left branch
99 std::unique_ptr
<SbiExprNode
> pRight
; // right branch (NULL for unary ops)
100 SbiExprNode
* pWithParent
; // node, whose member is "this per with"
101 SbiNodeType eNodeType
;
104 bool bError
; // true: error
105 void FoldConstants(SbiParser
*);
106 void FoldConstantsBinaryNode(SbiParser
*);
107 void FoldConstantsUnaryNode(SbiParser
*);
108 void CollectBits(); // converting numbers to strings
109 bool IsOperand() const
110 { return eNodeType
!= SbxNODE
&& eNodeType
!= SbxTYPEOF
&& eNodeType
!= SbxNEW
; }
111 bool IsNumber() const;
112 bool IsLvalue() const; // true, if usable as Lvalue
113 void GenElement( SbiCodeGen
&, SbiOpcode
);
117 SbiExprNode( double, SbxDataType
);
118 SbiExprNode( const OUString
& );
119 SbiExprNode( const SbiSymDef
&, SbxDataType
, SbiExprListPtr
= nullptr );
120 SbiExprNode( std::unique_ptr
<SbiExprNode
>, SbiToken
, std::unique_ptr
<SbiExprNode
> );
121 SbiExprNode( std::unique_ptr
<SbiExprNode
>, sal_uInt16
); // #120061 TypeOf
122 SbiExprNode( sal_uInt16
); // new <type>
125 bool IsValid() const { return !bError
; }
126 bool IsConstant() const // true: constant operand
127 { return eNodeType
== SbxSTRVAL
|| eNodeType
== SbxNUMVAL
; }
128 void ConvertToIntConstIfPossible();
129 bool IsVariable() const;
131 void SetWithParent( SbiExprNode
* p
) { pWithParent
= p
; }
133 SbxDataType
GetType() const { return eType
; }
134 void SetType( SbxDataType eTp
) { eType
= eTp
; }
135 SbiNodeType
GetNodeType() const { return eNodeType
; }
137 SbiSymDef
* GetRealVar(); // last variable in x.y.z
138 SbiExprNode
* GetRealNode(); // last node in x.y.z
139 const OUString
& GetString() const { return aStrVal
; }
140 short GetNumber() const { return static_cast<short>(nVal
); }
141 SbiExprList
* GetParameters() { return aVar
.pPar
; }
143 void Optimize(SbiParser
*); // tree matching
145 void Gen( SbiCodeGen
& rGen
, RecursiveMode eRecMode
= UNDEFINED
); // giving out a node
148 class SbiExpression
{
149 friend class SbiExprList
;
153 std::unique_ptr
<SbiExprNode
> pExpr
; // expression tree
154 SbiExprType eCurExpr
; // type of expression
155 SbiExprMode m_eMode
; // expression context
156 bool bBased
; // true: easy DIM-part (+BASE)
158 bool bByVal
; // true: ByVal-Parameter
159 bool bBracket
; // true: Parameter list with brackets
160 sal_uInt16 nParenLevel
;
161 std::unique_ptr
<SbiExprNode
> Term( const KeywordSymbolInfo
* pKeywordSymbolInfo
= nullptr );
162 std::unique_ptr
<SbiExprNode
> ObjTerm( SbiSymDef
& );
163 std::unique_ptr
<SbiExprNode
> Operand( bool bUsedForTypeOf
= false );
164 std::unique_ptr
<SbiExprNode
> Unary();
165 std::unique_ptr
<SbiExprNode
> Exp();
166 std::unique_ptr
<SbiExprNode
> MulDiv();
167 std::unique_ptr
<SbiExprNode
> IntDiv();
168 std::unique_ptr
<SbiExprNode
> Mod();
169 std::unique_ptr
<SbiExprNode
> AddSub();
170 std::unique_ptr
<SbiExprNode
> Cat();
171 std::unique_ptr
<SbiExprNode
> Like();
172 std::unique_ptr
<SbiExprNode
> VBA_Not();
173 std::unique_ptr
<SbiExprNode
> Comp();
174 std::unique_ptr
<SbiExprNode
> Boolean();
176 SbiExpression( SbiParser
*, SbiExprType
= SbSTDEXPR
,
177 SbiExprMode eMode
= EXPRMODE_STANDARD
, const KeywordSymbolInfo
* pKeywordSymbolInfo
= nullptr ); // parsing Ctor
178 SbiExpression( SbiParser
*, double, SbxDataType
);
179 SbiExpression( SbiParser
*, const SbiSymDef
&, SbiExprListPtr
= nullptr );
181 OUString
& GetName() { return aArgName
; }
182 void SetBased() { bBased
= true; }
183 bool IsBased() const { return bBased
; }
184 void SetByVal() { bByVal
= true; }
185 bool IsBracket() const { return bBracket
; }
186 bool IsValid() const { return pExpr
->IsValid(); }
187 bool IsVariable() const { return pExpr
->IsVariable(); }
188 bool IsLvalue() const { return pExpr
->IsLvalue(); }
189 void ConvertToIntConstIfPossible() { pExpr
->ConvertToIntConstIfPossible(); }
190 const OUString
& GetString() const { return pExpr
->GetString(); }
191 SbiSymDef
* GetRealVar() { return pExpr
->GetRealVar(); }
192 SbiExprNode
* GetExprNode() { return pExpr
.get(); }
193 SbxDataType
GetType() const { return pExpr
->GetType(); }
194 void Gen( RecursiveMode eRecMode
= UNDEFINED
);
197 class SbiConstExpression
: public SbiExpression
{
201 public: // numeric constant
202 SbiConstExpression( SbiParser
* );
203 SbxDataType
GetType() const { return eType
; }
204 const OUString
& GetString() const { return aVal
; }
205 double GetValue() const { return nVal
; }
206 short GetShortValue();
209 class SbiExprList final
{ // class for parameters and dims
210 std::vector
<std::unique_ptr
<SbiExpression
>> aData
;
217 static SbiExprListPtr
ParseParameters(SbiParser
*, bool bStandaloneExpression
= false, bool bPar
= true);
218 static SbiExprListPtr
ParseDimList( SbiParser
* );
219 bool IsBracket() const { return bBracket
; }
220 bool IsValid() const { return !bError
; }
221 short GetSize() const { return aData
.size(); }
222 short GetDims() const { return nDim
; }
223 SbiExpression
* Get( size_t );
224 void Gen( SbiCodeGen
& rGen
); // code generation
225 void addExpression( std::unique_ptr
<SbiExpression
>&& pExpr
);
230 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */