summaryrefslogtreecommitdiffstats
path: root/basic/source/inc/expr.hxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--basic/source/inc/expr.hxx227
1 files changed, 227 insertions, 0 deletions
diff --git a/basic/source/inc/expr.hxx b/basic/source/inc/expr.hxx
new file mode 100644
index 000000000..d5130c39d
--- /dev/null
+++ b/basic/source/inc/expr.hxx
@@ -0,0 +1,227 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <memory>
+
+#include "opcodes.hxx"
+#include "token.hxx"
+#include <vector>
+
+class SbiExprNode;
+class SbiExpression;
+class SbiExprList;
+class SbiParser;
+class SbiCodeGen;
+class SbiSymDef;
+class SbiProcDef;
+
+
+typedef std::unique_ptr<SbiExprList> SbiExprListPtr;
+typedef std::vector<SbiExprListPtr> SbiExprListVector;
+
+struct SbVar {
+ SbiExprNode* pNext; // next element (for structures)
+ SbiSymDef* pDef; // symbol definition
+ SbiExprList* pPar; // optional parameters (is deleted)
+ SbiExprListVector* pvMorePar; // Array of arrays foo(pPar)(avMorePar[0])(avMorePar[1])...
+};
+
+struct KeywordSymbolInfo
+{
+ OUString m_aKeywordSymbol;
+ SbxDataType m_eSbxDataType;
+};
+
+enum SbiExprType { // expression types:
+ SbSTDEXPR, // normal expression
+ SbLVALUE, // any lValue
+ SbSYMBOL, // any composite symbol
+ SbOPERAND // variable/function
+};
+
+enum SbiExprMode { // Expression context:
+ EXPRMODE_STANDARD, // default
+ EXPRMODE_STANDALONE, // a param1, param2 OR a( param1, param2 ) = 42
+ EXPRMODE_LPAREN_PENDING, // start of parameter list with bracket, special handling
+ EXPRMODE_LPAREN_NOT_NEEDED, // pending LPAREN has not been used
+ EXPRMODE_ARRAY_OR_OBJECT, // '=' or '(' or '.' found after ')' on ParenLevel 0, stopping
+ // expression, assuming array syntax a(...)[(...)] = ?
+ // or a(...).b(...)
+ EXPRMODE_EMPTY_PAREN // It turned out that the paren don't contain anything: a()
+};
+
+enum SbiNodeType {
+ SbxNUMVAL, // nVal = value
+ SbxSTRVAL, // aStrVal = value, before #i59791/#i45570: nStringId = value
+ SbxVARVAL, // aVar = value
+ SbxTYPEOF, // TypeOf ObjExpr Is Type
+ SbxNODE, // Node
+ SbxNEW, // new <type> expression
+ SbxDUMMY
+};
+
+enum RecursiveMode
+{
+ UNDEFINED,
+ FORCE_CALL,
+ PREVENT_CALL
+};
+
+class SbiExprNode final { // operators (and operands)
+ friend class SbiExpression;
+ friend class SbiConstExpression;
+ union {
+ sal_uInt16 nTypeStrId; // pooled String-ID, #i59791/#i45570 Now only for TypeOf
+ double nVal; // numeric value
+ SbVar aVar; // or variable
+ };
+ OUString aStrVal; // #i59791/#i45570 Store string directly
+ std::unique_ptr<SbiExprNode> pLeft; // left branch
+ std::unique_ptr<SbiExprNode> pRight; // right branch (NULL for unary ops)
+ SbiExprNode* pWithParent; // node, whose member is "this per with"
+ SbiNodeType eNodeType;
+ SbxDataType eType;
+ SbiToken eTok;
+ bool bError; // true: error
+ void FoldConstants(SbiParser*);
+ void FoldConstantsBinaryNode(SbiParser*);
+ void FoldConstantsUnaryNode(SbiParser*);
+ void CollectBits(); // converting numbers to strings
+ bool IsOperand() const
+ { return eNodeType != SbxNODE && eNodeType != SbxTYPEOF && eNodeType != SbxNEW; }
+ bool IsNumber() const;
+ bool IsLvalue() const; // true, if usable as Lvalue
+ void GenElement( SbiCodeGen&, SbiOpcode );
+
+public:
+ SbiExprNode();
+ SbiExprNode( double, SbxDataType );
+ SbiExprNode( OUString );
+ SbiExprNode( const SbiSymDef&, SbxDataType, SbiExprListPtr = nullptr );
+ SbiExprNode( std::unique_ptr<SbiExprNode>, SbiToken, std::unique_ptr<SbiExprNode> );
+ SbiExprNode( std::unique_ptr<SbiExprNode>, sal_uInt16 ); // #120061 TypeOf
+ SbiExprNode( sal_uInt16 ); // new <type>
+ ~SbiExprNode();
+
+ bool IsValid() const { return !bError; }
+ bool IsConstant() const // true: constant operand
+ { return eNodeType == SbxSTRVAL || eNodeType == SbxNUMVAL; }
+ void ConvertToIntConstIfPossible();
+ bool IsVariable() const;
+
+ void SetWithParent( SbiExprNode* p ) { pWithParent = p; }
+
+ SbxDataType GetType() const { return eType; }
+ void SetType( SbxDataType eTp ) { eType = eTp; }
+ SbiNodeType GetNodeType() const { return eNodeType; }
+ SbiSymDef* GetVar();
+ SbiSymDef* GetRealVar(); // last variable in x.y.z
+ SbiExprNode* GetRealNode(); // last node in x.y.z
+ const OUString& GetString() const { return aStrVal; }
+ short GetNumber() const { return static_cast<short>(nVal); }
+ SbiExprList* GetParameters() { return aVar.pPar; }
+
+ void Optimize(SbiParser*); // tree matching
+
+ void Gen( SbiCodeGen& rGen, RecursiveMode eRecMode = UNDEFINED ); // giving out a node
+};
+
+class SbiExpression {
+ friend class SbiExprList;
+protected:
+ OUString aArgName;
+ SbiParser* pParser;
+ std::unique_ptr<SbiExprNode> pExpr; // expression tree
+ SbiExprType eCurExpr; // type of expression
+ SbiExprMode m_eMode; // expression context
+ bool bBased = false; // true: easy DIM-part (+BASE)
+ bool bError = false;
+ bool bByVal = false; // true: ByVal-Parameter
+ bool bBracket = false; // true: Parameter list with brackets
+ sal_uInt16 nParenLevel = 0;
+ std::unique_ptr<SbiExprNode> Term( const KeywordSymbolInfo* pKeywordSymbolInfo = nullptr );
+ std::unique_ptr<SbiExprNode> ObjTerm( SbiSymDef& );
+ std::unique_ptr<SbiExprNode> Operand( bool bUsedForTypeOf = false );
+ std::unique_ptr<SbiExprNode> Unary();
+ std::unique_ptr<SbiExprNode> Exp();
+ std::unique_ptr<SbiExprNode> MulDiv();
+ std::unique_ptr<SbiExprNode> IntDiv();
+ std::unique_ptr<SbiExprNode> Mod();
+ std::unique_ptr<SbiExprNode> AddSub();
+ std::unique_ptr<SbiExprNode> Cat();
+ std::unique_ptr<SbiExprNode> Like();
+ std::unique_ptr<SbiExprNode> VBA_Not();
+ std::unique_ptr<SbiExprNode> Comp();
+ std::unique_ptr<SbiExprNode> Boolean();
+public:
+ SbiExpression( SbiParser*, SbiExprType = SbSTDEXPR,
+ SbiExprMode eMode = EXPRMODE_STANDARD, const KeywordSymbolInfo* pKeywordSymbolInfo = nullptr ); // parsing Ctor
+ SbiExpression( SbiParser*, double, SbxDataType );
+ SbiExpression( SbiParser*, const SbiSymDef&, SbiExprListPtr = nullptr );
+ ~SbiExpression();
+ OUString& GetName() { return aArgName; }
+ void SetBased() { bBased = true; }
+ bool IsBased() const { return bBased; }
+ void SetByVal() { bByVal = true; }
+ bool IsBracket() const { return bBracket; }
+ bool IsValid() const { return pExpr->IsValid(); }
+ bool IsVariable() const { return pExpr->IsVariable(); }
+ bool IsLvalue() const { return pExpr->IsLvalue(); }
+ void ConvertToIntConstIfPossible() { pExpr->ConvertToIntConstIfPossible(); }
+ const OUString& GetString() const { return pExpr->GetString(); }
+ SbiSymDef* GetRealVar() { return pExpr->GetRealVar(); }
+ SbiExprNode* GetExprNode() { return pExpr.get(); }
+ SbxDataType GetType() const { return pExpr->GetType(); }
+ void Gen( RecursiveMode eRecMode = UNDEFINED );
+};
+
+class SbiConstExpression : public SbiExpression {
+ double nVal;
+ OUString aVal;
+ SbxDataType eType;
+public: // numeric constant
+ SbiConstExpression( SbiParser* );
+ SbxDataType GetType() const { return eType; }
+ const OUString& GetString() const { return aVal; }
+ double GetValue() const { return nVal; }
+ short GetShortValue();
+};
+
+class SbiExprList final { // class for parameters and dims
+ std::vector<std::unique_ptr<SbiExpression>> aData;
+ short nDim;
+ bool bError;
+ bool bBracket;
+public:
+ SbiExprList();
+ ~SbiExprList();
+ static SbiExprListPtr ParseParameters(SbiParser*, bool bStandaloneExpression = false, bool bPar = true);
+ static SbiExprListPtr ParseDimList( SbiParser* );
+ bool IsBracket() const { return bBracket; }
+ bool IsValid() const { return !bError; }
+ short GetSize() const { return aData.size(); }
+ short GetDims() const { return nDim; }
+ SbiExpression* Get( size_t );
+ void Gen( SbiCodeGen& rGen); // code generation
+ void addExpression( std::unique_ptr<SbiExpression>&& pExpr );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */