1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #pragma once
21 
22 #include <memory>
23 
24 #include "opcodes.hxx"
25 #include "token.hxx"
26 #include <vector>
27 
28 class SbiExprNode;
29 class SbiExpression;
30 class SbiExprList;
31 class SbiParser;
32 class SbiCodeGen;
33 class SbiSymDef;
34 class SbiProcDef;
35 
36 
37 typedef std::unique_ptr<SbiExprList> SbiExprListPtr;
38 typedef std::vector<SbiExprListPtr> SbiExprListVector;
39 
40 struct SbVar {
41     SbiExprNode*        pNext;      // next element (for structures)
42     SbiSymDef*          pDef;       // symbol definition
43     SbiExprList*        pPar;       // optional parameters (is deleted)
44     SbiExprListVector*  pvMorePar;  // Array of arrays foo(pPar)(avMorePar[0])(avMorePar[1])...
45 };
46 
47 struct KeywordSymbolInfo
48 {
49     OUString m_aKeywordSymbol;
50     SbxDataType     m_eSbxDataType;
51 };
52 
53 enum SbiExprType {                  // expression types:
54     SbSTDEXPR,                      // normal expression
55     SbLVALUE,                       // any lValue
56     SbSYMBOL,                       // any composite symbol
57     SbOPERAND                       // variable/function
58 };
59 
60 enum SbiExprMode {                  // Expression context:
61     EXPRMODE_STANDARD,              // default
62     EXPRMODE_STANDALONE,            // a param1, param2 OR a( param1, param2 ) = 42
63     EXPRMODE_LPAREN_PENDING,        // start of parameter list with bracket, special handling
64     EXPRMODE_LPAREN_NOT_NEEDED,     // pending LPAREN has not been used
65     EXPRMODE_ARRAY_OR_OBJECT,       // '=' or '(' or '.' found after ')' on ParenLevel 0, stopping
66                                     // expression, assuming array syntax a(...)[(...)] = ?
67                                     // or a(...).b(...)
68     EXPRMODE_EMPTY_PAREN            // It turned out that the paren don't contain anything: a()
69 };
70 
71 enum SbiNodeType {
72     SbxNUMVAL,                      // nVal = value
73     SbxSTRVAL,                      // aStrVal = value, before #i59791/#i45570: nStringId = value
74     SbxVARVAL,                      // aVar = value
75     SbxTYPEOF,                      // TypeOf ObjExpr Is Type
76     SbxNODE,                        // Node
77     SbxNEW,                         // new <type> expression
78     SbxDUMMY
79 };
80 
81 enum RecursiveMode
82 {
83     UNDEFINED,
84     FORCE_CALL,
85     PREVENT_CALL
86 };
87 
88 class SbiExprNode final {           // operators (and operands)
89     friend class SbiExpression;
90     friend class SbiConstExpression;
91     union {
92         sal_uInt16 nTypeStrId;          // pooled String-ID, #i59791/#i45570 Now only for TypeOf
93         double nVal;                // numeric value
94         SbVar  aVar;                // or variable
95     };
96     OUString aStrVal;               // #i59791/#i45570 Store string directly
97     std::unique_ptr<SbiExprNode> pLeft; // left branch
98     std::unique_ptr<SbiExprNode> pRight; // right branch (NULL for unary ops)
99     SbiExprNode* pWithParent;       // node, whose member is "this per with"
100     SbiNodeType  eNodeType;
101     SbxDataType eType;
102     SbiToken     eTok;
103     bool  bError;                   // true: error
104     void  FoldConstants(SbiParser*);
105     void  FoldConstantsBinaryNode(SbiParser*);
106     void  FoldConstantsUnaryNode(SbiParser*);
107     void  CollectBits();            // converting numbers to strings
IsOperand() const108     bool  IsOperand() const
109         { return eNodeType != SbxNODE && eNodeType != SbxTYPEOF && eNodeType != SbxNEW; }
110     bool  IsNumber() const;
111     bool  IsLvalue() const;        // true, if usable as Lvalue
112     void  GenElement( SbiCodeGen&, SbiOpcode );
113 
114 public:
115     SbiExprNode();
116     SbiExprNode( double, SbxDataType );
117     SbiExprNode( const OUString& );
118     SbiExprNode( const SbiSymDef&, SbxDataType, SbiExprListPtr = nullptr );
119     SbiExprNode( std::unique_ptr<SbiExprNode>, SbiToken, std::unique_ptr<SbiExprNode> );
120     SbiExprNode( std::unique_ptr<SbiExprNode>, sal_uInt16 );    // #120061 TypeOf
121     SbiExprNode( sal_uInt16 );                  // new <type>
122     ~SbiExprNode();
123 
IsValid() const124     bool IsValid() const               { return !bError; }
IsConstant() const125     bool IsConstant() const           // true: constant operand
126         { return eNodeType == SbxSTRVAL || eNodeType == SbxNUMVAL; }
127     void ConvertToIntConstIfPossible();
128     bool IsVariable() const;
129 
SetWithParent(SbiExprNode * p)130     void SetWithParent( SbiExprNode* p )    { pWithParent = p; }
131 
GetType() const132     SbxDataType GetType() const     { return eType; }
SetType(SbxDataType eTp)133     void SetType( SbxDataType eTp ) { eType = eTp; }
GetNodeType() const134     SbiNodeType GetNodeType() const { return eNodeType; }
135     SbiSymDef* GetVar();
136     SbiSymDef* GetRealVar();        // last variable in x.y.z
137     SbiExprNode* GetRealNode();     // last node in x.y.z
GetString() const138     const OUString& GetString() const { return aStrVal; }
GetNumber() const139     short GetNumber() const         { return static_cast<short>(nVal); }
GetParameters()140     SbiExprList* GetParameters()    { return aVar.pPar; }
141 
142     void Optimize(SbiParser*);                // tree matching
143 
144     void Gen( SbiCodeGen& rGen, RecursiveMode eRecMode = UNDEFINED ); // giving out a node
145 };
146 
147 class SbiExpression {
148     friend class SbiExprList;
149 protected:
150     OUString      aArgName;
151     SbiParser*    pParser;
152     std::unique_ptr<SbiExprNode>   pExpr; // expression tree
153     SbiExprType   eCurExpr;         // type of expression
154     SbiExprMode   m_eMode;          // expression context
155     bool          bBased = false;   // true: easy DIM-part (+BASE)
156     bool          bError = false;
157     bool          bByVal = false;   // true: ByVal-Parameter
158     bool          bBracket = false; // true: Parameter list with brackets
159     sal_uInt16        nParenLevel = 0;
160     std::unique_ptr<SbiExprNode> Term( const KeywordSymbolInfo* pKeywordSymbolInfo = nullptr );
161     std::unique_ptr<SbiExprNode> ObjTerm( SbiSymDef& );
162     std::unique_ptr<SbiExprNode> Operand( bool bUsedForTypeOf = false );
163     std::unique_ptr<SbiExprNode> Unary();
164     std::unique_ptr<SbiExprNode> Exp();
165     std::unique_ptr<SbiExprNode> MulDiv();
166     std::unique_ptr<SbiExprNode> IntDiv();
167     std::unique_ptr<SbiExprNode> Mod();
168     std::unique_ptr<SbiExprNode> AddSub();
169     std::unique_ptr<SbiExprNode> Cat();
170     std::unique_ptr<SbiExprNode> Like();
171     std::unique_ptr<SbiExprNode> VBA_Not();
172     std::unique_ptr<SbiExprNode> Comp();
173     std::unique_ptr<SbiExprNode> Boolean();
174 public:
175     SbiExpression( SbiParser*, SbiExprType = SbSTDEXPR,
176         SbiExprMode eMode = EXPRMODE_STANDARD, const KeywordSymbolInfo* pKeywordSymbolInfo = nullptr ); // parsing Ctor
177     SbiExpression( SbiParser*, double, SbxDataType );
178     SbiExpression( SbiParser*, const SbiSymDef&, SbiExprListPtr = nullptr );
179    ~SbiExpression();
GetName()180     OUString& GetName()             { return aArgName;            }
SetBased()181     void SetBased()                 { bBased = true;              }
IsBased() const182     bool IsBased() const            { return bBased;              }
SetByVal()183     void SetByVal()                 { bByVal = true;              }
IsBracket() const184     bool IsBracket() const          { return bBracket;            }
IsValid() const185     bool IsValid() const            { return pExpr->IsValid();    }
IsVariable() const186     bool IsVariable() const         { return pExpr->IsVariable(); }
IsLvalue() const187     bool IsLvalue() const           { return pExpr->IsLvalue();   }
ConvertToIntConstIfPossible()188     void ConvertToIntConstIfPossible() { pExpr->ConvertToIntConstIfPossible();     }
GetString() const189     const OUString& GetString() const { return pExpr->GetString();  }
GetRealVar()190     SbiSymDef* GetRealVar()         { return pExpr->GetRealVar(); }
GetExprNode()191     SbiExprNode* GetExprNode()      { return pExpr.get();         }
GetType() const192     SbxDataType GetType() const     { return pExpr->GetType();    }
193     void Gen( RecursiveMode eRecMode = UNDEFINED );
194 };
195 
196 class SbiConstExpression : public SbiExpression {
197     double nVal;
198     OUString aVal;
199     SbxDataType eType;
200 public:                             // numeric constant
201     SbiConstExpression( SbiParser* );
GetType() const202     SbxDataType GetType() const { return eType; }
GetString() const203     const OUString& GetString() const { return aVal; }
GetValue() const204     double GetValue() const { return nVal; }
205     short GetShortValue();
206 };
207 
208 class SbiExprList final {            // class for parameters and dims
209     std::vector<std::unique_ptr<SbiExpression>> aData;
210     short nDim;
211     bool  bError;
212     bool  bBracket;
213 public:
214     SbiExprList();
215     ~SbiExprList();
216     static SbiExprListPtr ParseParameters(SbiParser*, bool bStandaloneExpression = false, bool bPar = true);
217     static SbiExprListPtr ParseDimList( SbiParser* );
IsBracket() const218     bool  IsBracket() const         { return bBracket;        }
IsValid() const219     bool  IsValid() const           { return !bError; }
GetSize() const220     short GetSize() const           { return aData.size();    }
GetDims() const221     short GetDims() const           { return nDim;            }
222     SbiExpression* Get( size_t );
223     void  Gen( SbiCodeGen& rGen);                    // code generation
224     void addExpression( std::unique_ptr<SbiExpression>&& pExpr  );
225 };
226 
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
228