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