1*e1f63238SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*e1f63238SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*e1f63238SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*e1f63238SAndrew Rist * distributed with this work for additional information 6*e1f63238SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*e1f63238SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*e1f63238SAndrew Rist * "License"); you may not use this file except in compliance 9*e1f63238SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*e1f63238SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*e1f63238SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*e1f63238SAndrew Rist * software distributed under the License is distributed on an 15*e1f63238SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*e1f63238SAndrew Rist * KIND, either express or implied. See the License for the 17*e1f63238SAndrew Rist * specific language governing permissions and limitations 18*e1f63238SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*e1f63238SAndrew Rist *************************************************************/ 21*e1f63238SAndrew Rist 22*e1f63238SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_basic.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "sbcomp.hxx" 28cdf0e10cSrcweir #include <basic/sbx.hxx> // w.g. ...IMPL_REF(...sbxvariable) 29cdf0e10cSrcweir #include "expr.hxx" 30cdf0e10cSrcweir 31cdf0e10cSrcweir /*************************************************************************** 32cdf0e10cSrcweir |* 33cdf0e10cSrcweir |* SbiExpression 34cdf0e10cSrcweir |* 35cdf0e10cSrcweir ***************************************************************************/ 36cdf0e10cSrcweir 37cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, SbiExprType t, 38cdf0e10cSrcweir SbiExprMode eMode, const KeywordSymbolInfo* pKeywordSymbolInfo ) 39cdf0e10cSrcweir { 40cdf0e10cSrcweir pParser = p; 41cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 42cdf0e10cSrcweir nParenLevel = 0; 43cdf0e10cSrcweir eCurExpr = t; 44cdf0e10cSrcweir m_eMode = eMode; 45cdf0e10cSrcweir pNext = NULL; 46cdf0e10cSrcweir pExpr = (t != SbSTDEXPR ) ? Term( pKeywordSymbolInfo ) : Boolean(); 47cdf0e10cSrcweir if( t != SbSYMBOL ) 48cdf0e10cSrcweir pExpr->Optimize(); 49cdf0e10cSrcweir if( t == SbLVALUE && !pExpr->IsLvalue() ) 50cdf0e10cSrcweir p->Error( SbERR_LVALUE_EXPECTED ); 51cdf0e10cSrcweir if( t == SbOPERAND && !IsVariable() ) 52cdf0e10cSrcweir p->Error( SbERR_VAR_EXPECTED ); 53cdf0e10cSrcweir } 54cdf0e10cSrcweir 55cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, double n, SbxDataType t ) 56cdf0e10cSrcweir { 57cdf0e10cSrcweir pParser = p; 58cdf0e10cSrcweir eCurExpr = SbOPERAND; 59cdf0e10cSrcweir pNext = NULL; 60cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 61cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, n, t ); 62cdf0e10cSrcweir pExpr->Optimize(); 63cdf0e10cSrcweir } 64cdf0e10cSrcweir 65cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, const String& r ) 66cdf0e10cSrcweir { 67cdf0e10cSrcweir pParser = p; 68cdf0e10cSrcweir pNext = NULL; 69cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 70cdf0e10cSrcweir eCurExpr = SbOPERAND; 71cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, r ); 72cdf0e10cSrcweir } 73cdf0e10cSrcweir 74cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, const SbiSymDef& r, SbiExprList* pPar ) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir pParser = p; 77cdf0e10cSrcweir pNext = NULL; 78cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 79cdf0e10cSrcweir eCurExpr = SbOPERAND; 80cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, r, SbxVARIANT, pPar ); 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir SbiExpression::SbiExpression( SbiParser* p, SbiToken t ) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir pParser = p; 86cdf0e10cSrcweir pNext = NULL; 87cdf0e10cSrcweir bError = bByVal = bBased = bBracket = sal_False; 88cdf0e10cSrcweir eCurExpr = SbOPERAND; 89cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, NULL, t, NULL ); 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir SbiExpression::~SbiExpression() 93cdf0e10cSrcweir { 94cdf0e10cSrcweir delete pExpr; 95cdf0e10cSrcweir } 96cdf0e10cSrcweir 97cdf0e10cSrcweir // Einlesen eines kompletten Bezeichners 98cdf0e10cSrcweir // Ein Bezeichner hat folgende Form: 99cdf0e10cSrcweir // name[(Parameter)][.Name[(parameter)]]... 100cdf0e10cSrcweir // Strukturelemente werden ueber das Element pNext verkoppelt, 101cdf0e10cSrcweir // damit sie nicht im Baum stehen. 102cdf0e10cSrcweir 103cdf0e10cSrcweir // Folgen Parameter ohne Klammer? Dies kann eine Zahl, ein String, 104cdf0e10cSrcweir // ein Symbol oder auch ein Komma sein (wenn der 1. Parameter fehlt) 105cdf0e10cSrcweir 106cdf0e10cSrcweir static sal_Bool DoParametersFollow( SbiParser* p, SbiExprType eCurExpr, SbiToken eTok ) 107cdf0e10cSrcweir { 108cdf0e10cSrcweir if( eTok == LPAREN ) 109cdf0e10cSrcweir return sal_True; 110cdf0e10cSrcweir // Aber nur, wenn CALL-aehnlich! 111cdf0e10cSrcweir if( !p->WhiteSpace() || eCurExpr != SbSYMBOL ) 112cdf0e10cSrcweir return sal_False; 113cdf0e10cSrcweir if ( eTok == NUMBER || eTok == MINUS || eTok == FIXSTRING 114cdf0e10cSrcweir || eTok == SYMBOL || eTok == COMMA || eTok == DOT || eTok == NOT || eTok == BYVAL ) 115cdf0e10cSrcweir { 116cdf0e10cSrcweir return sal_True; 117cdf0e10cSrcweir } 118cdf0e10cSrcweir else // check for default params with reserved names ( e.g. names of tokens ) 119cdf0e10cSrcweir { 120cdf0e10cSrcweir SbiTokenizer tokens( *(SbiTokenizer*)p ); 121cdf0e10cSrcweir // Urk the Next() / Peek() symantics are... weird 122cdf0e10cSrcweir tokens.Next(); 123cdf0e10cSrcweir if ( tokens.Peek() == ASSIGN ) 124cdf0e10cSrcweir return sal_True; 125cdf0e10cSrcweir } 126cdf0e10cSrcweir return sal_False; 127cdf0e10cSrcweir } 128cdf0e10cSrcweir 129cdf0e10cSrcweir // Definition eines neuen Symbols 130cdf0e10cSrcweir 131cdf0e10cSrcweir static SbiSymDef* AddSym 132cdf0e10cSrcweir ( SbiToken eTok, SbiSymPool& rPool, SbiExprType eCurExpr, 133cdf0e10cSrcweir const String& rName, SbxDataType eType, SbiParameters* pPar ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir SbiSymDef* pDef; 136cdf0e10cSrcweir // A= ist keine Prozedur 137cdf0e10cSrcweir sal_Bool bHasType = sal_Bool( eTok == EQ || eTok == DOT ); 138cdf0e10cSrcweir if( ( !bHasType && eCurExpr == SbSYMBOL ) || pPar ) 139cdf0e10cSrcweir { 140cdf0e10cSrcweir // Dies ist also eine Prozedur 141cdf0e10cSrcweir // da suche man doch den richtigen Pool raus, da Procs 142cdf0e10cSrcweir // immer in einem Public-Pool landen muessen 143cdf0e10cSrcweir SbiSymPool* pPool = &rPool; 144cdf0e10cSrcweir if( pPool->GetScope() != SbPUBLIC ) 145cdf0e10cSrcweir pPool = &rPool.GetParser()->aPublics; 146cdf0e10cSrcweir SbiProcDef* pProc = pPool->AddProc( rName ); 147cdf0e10cSrcweir 148cdf0e10cSrcweir // Sonderbehandlung fuer Colls wie Documents(1) 149cdf0e10cSrcweir if( eCurExpr == SbSTDEXPR ) 150cdf0e10cSrcweir bHasType = sal_True; 151cdf0e10cSrcweir 152cdf0e10cSrcweir pDef = pProc; 153cdf0e10cSrcweir pDef->SetType( bHasType ? eType : SbxEMPTY ); 154cdf0e10cSrcweir if( pPar ) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir // Dummy-Parameter generieren 157cdf0e10cSrcweir sal_uInt16 n = 1; 158cdf0e10cSrcweir for( short i = 0; i < pPar->GetSize(); i++ ) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir String aPar = String::CreateFromAscii( "PAR" ); 161cdf0e10cSrcweir aPar += ++n; 162cdf0e10cSrcweir pProc->GetParams().AddSym( aPar ); 163cdf0e10cSrcweir } 164cdf0e10cSrcweir } 165cdf0e10cSrcweir } 166cdf0e10cSrcweir else 167cdf0e10cSrcweir { 168cdf0e10cSrcweir // oder ein normales Symbol 169cdf0e10cSrcweir pDef = rPool.AddSym( rName ); 170cdf0e10cSrcweir pDef->SetType( eType ); 171cdf0e10cSrcweir } 172cdf0e10cSrcweir return pDef; 173cdf0e10cSrcweir } 174cdf0e10cSrcweir 175cdf0e10cSrcweir // Zur Zeit sind sogar Keywords zugelassen (wg. gleichnamiger Dflt-Properties) 176cdf0e10cSrcweir 177cdf0e10cSrcweir SbiExprNode* SbiExpression::Term( const KeywordSymbolInfo* pKeywordSymbolInfo ) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir if( pParser->Peek() == DOT ) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir // eine WITH-Variable 182cdf0e10cSrcweir SbiExprNode* pWithVar = pParser->GetWithVar(); 183cdf0e10cSrcweir // #26608: Ans Ende der Node-Kette gehen, um richtiges Objekt zu uebergeben 184cdf0e10cSrcweir SbiSymDef* pDef = pWithVar ? pWithVar->GetRealVar() : NULL; 185cdf0e10cSrcweir SbiExprNode* pNd = NULL; 186cdf0e10cSrcweir if( !pDef ) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir pParser->Next(); 189cdf0e10cSrcweir } 190cdf0e10cSrcweir else 191cdf0e10cSrcweir { 192cdf0e10cSrcweir pNd = ObjTerm( *pDef ); 193cdf0e10cSrcweir if( pNd ) 194cdf0e10cSrcweir pNd->SetWithParent( pWithVar ); 195cdf0e10cSrcweir } 196cdf0e10cSrcweir if( !pNd ) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir pParser->Error( SbERR_UNEXPECTED, DOT ); 199cdf0e10cSrcweir pNd = new SbiExprNode( pParser, 1.0, SbxDOUBLE ); 200cdf0e10cSrcweir } 201cdf0e10cSrcweir return pNd; 202cdf0e10cSrcweir } 203cdf0e10cSrcweir 204cdf0e10cSrcweir SbiToken eTok = (pKeywordSymbolInfo == NULL) ? pParser->Next() : pKeywordSymbolInfo->m_eTok; 205cdf0e10cSrcweir // Anfang des Parsings merken 206cdf0e10cSrcweir pParser->LockColumn(); 207cdf0e10cSrcweir String aSym( (pKeywordSymbolInfo == NULL) ? pParser->GetSym() : pKeywordSymbolInfo->m_aKeywordSymbol ); 208cdf0e10cSrcweir SbxDataType eType = (pKeywordSymbolInfo == NULL) ? pParser->GetType() : pKeywordSymbolInfo->m_eSbxDataType; 209cdf0e10cSrcweir SbiParameters* pPar = NULL; 210cdf0e10cSrcweir SbiExprListVector* pvMoreParLcl = NULL; 211cdf0e10cSrcweir // Folgen Parameter? 212cdf0e10cSrcweir SbiToken eNextTok = pParser->Peek(); 213cdf0e10cSrcweir // Ist es ein benannter Parameter? 214cdf0e10cSrcweir // Dann einfach eine Stringkonstante erzeugen. Diese wird 215cdf0e10cSrcweir // im SbiParameters-ctor erkannt und weiterverarbeitet 216cdf0e10cSrcweir if( eNextTok == ASSIGN ) 217cdf0e10cSrcweir { 218cdf0e10cSrcweir pParser->UnlockColumn(); 219cdf0e10cSrcweir return new SbiExprNode( pParser, aSym ); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir // ab hier sind keine Keywords zugelassen! 222cdf0e10cSrcweir if( pParser->IsKwd( eTok ) ) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir if( pParser->IsCompatible() && eTok == INPUT ) 225cdf0e10cSrcweir { 226cdf0e10cSrcweir eTok = SYMBOL; 227cdf0e10cSrcweir } 228cdf0e10cSrcweir else 229cdf0e10cSrcweir { 230cdf0e10cSrcweir pParser->Error( SbERR_SYNTAX ); 231cdf0e10cSrcweir bError = sal_True; 232cdf0e10cSrcweir } 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235cdf0e10cSrcweir if( DoParametersFollow( pParser, eCurExpr, eTok = eNextTok ) ) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir bool bStandaloneExpression = (m_eMode == EXPRMODE_STANDALONE); 238cdf0e10cSrcweir pPar = new SbiParameters( pParser, bStandaloneExpression ); 239cdf0e10cSrcweir bError |= !pPar->IsValid(); 240cdf0e10cSrcweir if( !bError ) 241cdf0e10cSrcweir bBracket = pPar->IsBracket(); 242cdf0e10cSrcweir eTok = pParser->Peek(); 243cdf0e10cSrcweir 244cdf0e10cSrcweir // i75443 check for additional sets of parameters 245cdf0e10cSrcweir while( eTok == LPAREN ) 246cdf0e10cSrcweir { 247cdf0e10cSrcweir if( pvMoreParLcl == NULL ) 248cdf0e10cSrcweir pvMoreParLcl = new SbiExprListVector(); 249cdf0e10cSrcweir SbiParameters* pAddPar = new SbiParameters( pParser ); 250cdf0e10cSrcweir pvMoreParLcl->push_back( pAddPar ); 251cdf0e10cSrcweir bError |= !pPar->IsValid(); 252cdf0e10cSrcweir eTok = pParser->Peek(); 253cdf0e10cSrcweir } 254cdf0e10cSrcweir } 255cdf0e10cSrcweir // Es koennte ein Objektteil sein, wenn . oder ! folgt 256cdf0e10cSrcweir // Bei . muss aber die Variable bereits definiert sein; wenn pDef 257cdf0e10cSrcweir // nach der Suche NULL ist, isses ein Objekt! 258cdf0e10cSrcweir sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM ) 259cdf0e10cSrcweir && !pParser->WhiteSpace() ); 260cdf0e10cSrcweir if( bObj ) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir bBracket = sal_False; // Now the bracket for the first term is obsolete 263cdf0e10cSrcweir if( eType == SbxVARIANT ) 264cdf0e10cSrcweir eType = SbxOBJECT; 265cdf0e10cSrcweir else 266cdf0e10cSrcweir { 267cdf0e10cSrcweir // Name%. geht wirklich nicht! 268cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 269cdf0e10cSrcweir bError = sal_True; 270cdf0e10cSrcweir } 271cdf0e10cSrcweir } 272cdf0e10cSrcweir // Suche: 273cdf0e10cSrcweir SbiSymDef* pDef = pParser->pPool->Find( aSym ); 274cdf0e10cSrcweir if( !pDef ) 275cdf0e10cSrcweir { 276cdf0e10cSrcweir // Teil der Runtime-Library? 277cdf0e10cSrcweir // AB 31.3.1996: In Parser-Methode ausgelagert 278cdf0e10cSrcweir // (wird auch in SbiParser::DefVar() in DIM.CXX benoetigt) 279cdf0e10cSrcweir pDef = pParser->CheckRTLForSym( aSym, eType ); 280cdf0e10cSrcweir 281cdf0e10cSrcweir // #i109184: Check if symbol is or later will be defined inside module 282cdf0e10cSrcweir SbModule& rMod = pParser->aGen.GetModule(); 283cdf0e10cSrcweir SbxArray* pModMethods = rMod.GetMethods(); 284cdf0e10cSrcweir if( pModMethods->Find( aSym, SbxCLASS_DONTCARE ) ) 285cdf0e10cSrcweir pDef = NULL; 286cdf0e10cSrcweir } 287cdf0e10cSrcweir if( !pDef ) 288cdf0e10cSrcweir { 289cdf0e10cSrcweir // Falls ein Punkt angegeben war, isses Teil eines Objekts, 290cdf0e10cSrcweir // also muss der Returnwert ein Objekt sein 291cdf0e10cSrcweir if( bObj ) 292cdf0e10cSrcweir eType = SbxOBJECT; 293cdf0e10cSrcweir pDef = AddSym( eTok, *pParser->pPool, eCurExpr, aSym, eType, pPar ); 294cdf0e10cSrcweir // Looks like this is a local ( but undefined variable ) 295cdf0e10cSrcweir // if it is in a static procedure then make this Symbol 296cdf0e10cSrcweir // static 297cdf0e10cSrcweir if ( !bObj && pParser->pProc && pParser->pProc->IsStatic() ) 298cdf0e10cSrcweir pDef->SetStatic(); 299cdf0e10cSrcweir } 300cdf0e10cSrcweir else 301cdf0e10cSrcweir { 302cdf0e10cSrcweir 303cdf0e10cSrcweir // Symbol ist bereits definiert. 304cdf0e10cSrcweir // Ist es eine Konstante? 305cdf0e10cSrcweir SbiConstDef* pConst = pDef->GetConstDef(); 306cdf0e10cSrcweir if( pConst ) 307cdf0e10cSrcweir { 308cdf0e10cSrcweir if( pConst->GetType() == SbxSTRING ) 309cdf0e10cSrcweir return new SbiExprNode( pParser, pConst->GetString() ); 310cdf0e10cSrcweir else 311cdf0e10cSrcweir return new SbiExprNode( pParser, pConst->GetValue(), pConst->GetType() ); 312cdf0e10cSrcweir } 313cdf0e10cSrcweir // Hat es Dimensionen, 314cdf0e10cSrcweir // und sind auch Parameter angegeben? 315cdf0e10cSrcweir // (Wobei 0 Parameter () entsprechen) 316cdf0e10cSrcweir if( pDef->GetDims() ) 317cdf0e10cSrcweir { 318cdf0e10cSrcweir if( pPar && pPar->GetSize() && pPar->GetSize() != pDef->GetDims() ) 319cdf0e10cSrcweir pParser->Error( SbERR_WRONG_DIMS ); 320cdf0e10cSrcweir } 321cdf0e10cSrcweir if( pDef->IsDefinedAs() ) 322cdf0e10cSrcweir { 323cdf0e10cSrcweir SbxDataType eDefType = pDef->GetType(); 324cdf0e10cSrcweir // #119187 Only error if types conflict 325cdf0e10cSrcweir if( eType >= SbxINTEGER && eType <= SbxSTRING && eType != eDefType ) 326cdf0e10cSrcweir { 327cdf0e10cSrcweir // Wie? Erst mit AS definieren und dann einen Suffix nehmen? 328cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 329cdf0e10cSrcweir bError = sal_True; 330cdf0e10cSrcweir } 331cdf0e10cSrcweir else if ( eType == SbxVARIANT ) 332cdf0e10cSrcweir // Falls nix angegeben, den Typ des Eintrags nehmen 333cdf0e10cSrcweir // aber nur, wenn die Var nicht mit AS XXX definiert ist 334cdf0e10cSrcweir // damit erwischen wir n% = 5 : print n 335cdf0e10cSrcweir eType = eDefType; 336cdf0e10cSrcweir } 337cdf0e10cSrcweir // Typcheck bei Variablen: 338cdf0e10cSrcweir // ist explizit im Scanner etwas anderes angegeben? 339cdf0e10cSrcweir // Bei Methoden ist dies OK! 340cdf0e10cSrcweir if( eType != SbxVARIANT && // Variant nimmt alles 341cdf0e10cSrcweir eType != pDef->GetType() && 342cdf0e10cSrcweir !pDef->GetProcDef() ) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir // Es kann sein, dass pDef ein Objekt beschreibt, das bisher 345cdf0e10cSrcweir // nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern 346cdf0e10cSrcweir // AB, 16.12.95 (Vielleicht noch aehnliche Faelle moeglich ?!?) 347cdf0e10cSrcweir if( eType == SbxOBJECT && pDef->GetType() == SbxVARIANT ) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir pDef->SetType( SbxOBJECT ); 350cdf0e10cSrcweir } 351cdf0e10cSrcweir else 352cdf0e10cSrcweir { 353cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 354cdf0e10cSrcweir bError = sal_True; 355cdf0e10cSrcweir } 356cdf0e10cSrcweir } 357cdf0e10cSrcweir } 358cdf0e10cSrcweir SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType ); 359cdf0e10cSrcweir if( !pPar ) 360cdf0e10cSrcweir pPar = new SbiParameters( pParser,sal_False,sal_False ); 361cdf0e10cSrcweir pNd->aVar.pPar = pPar; 362cdf0e10cSrcweir pNd->aVar.pvMorePar = pvMoreParLcl; 363cdf0e10cSrcweir if( bObj ) 364cdf0e10cSrcweir { 365cdf0e10cSrcweir // AB, 8.1.95: Objekt kann auch vom Typ SbxVARIANT sein 366cdf0e10cSrcweir if( pDef->GetType() == SbxVARIANT ) 367cdf0e10cSrcweir pDef->SetType( SbxOBJECT ); 368cdf0e10cSrcweir // Falls wir etwas mit Punkt einscannen, muss der 369cdf0e10cSrcweir // Typ SbxOBJECT sein 370cdf0e10cSrcweir if( pDef->GetType() != SbxOBJECT && pDef->GetType() != SbxVARIANT ) 371cdf0e10cSrcweir { 372cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 373cdf0e10cSrcweir bError = sal_True; 374cdf0e10cSrcweir } 375cdf0e10cSrcweir if( !bError ) 376cdf0e10cSrcweir pNd->aVar.pNext = ObjTerm( *pDef ); 377cdf0e10cSrcweir } 378cdf0e10cSrcweir // Merken der Spalte 1 wieder freigeben 379cdf0e10cSrcweir pParser->UnlockColumn(); 380cdf0e10cSrcweir return pNd; 381cdf0e10cSrcweir } 382cdf0e10cSrcweir 383cdf0e10cSrcweir // Aufbau eines Objekt-Terms. Ein derartiger Term ist Teil 384cdf0e10cSrcweir // eines Ausdrucks, der mit einer Objektvariablen beginnt. 385cdf0e10cSrcweir 386cdf0e10cSrcweir SbiExprNode* SbiExpression::ObjTerm( SbiSymDef& rObj ) 387cdf0e10cSrcweir { 388cdf0e10cSrcweir pParser->Next(); 389cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 390cdf0e10cSrcweir if( eTok != SYMBOL && !pParser->IsKwd( eTok ) && !pParser->IsExtra( eTok ) ) 391cdf0e10cSrcweir { 392cdf0e10cSrcweir // #66745 Einige Operatoren koennen in diesem Kontext auch 393cdf0e10cSrcweir // als Identifier zugelassen werden, wichtig fuer StarOne 394cdf0e10cSrcweir if( eTok != MOD && eTok != NOT && eTok != AND && eTok != OR && 395cdf0e10cSrcweir eTok != XOR && eTok != EQV && eTok != IMP && eTok != IS ) 396cdf0e10cSrcweir { 397cdf0e10cSrcweir pParser->Error( SbERR_VAR_EXPECTED ); 398cdf0e10cSrcweir bError = sal_True; 399cdf0e10cSrcweir } 400cdf0e10cSrcweir } 401cdf0e10cSrcweir /* #118410 Allow type for Class methods and RTL object, e.g. RTL.Chr$(97) 402cdf0e10cSrcweir else 403cdf0e10cSrcweir { 404cdf0e10cSrcweir if( pParser->GetType() != SbxVARIANT ) 405cdf0e10cSrcweir pParser->Error( SbERR_SYNTAX ), bError = sal_True; 406cdf0e10cSrcweir } 407cdf0e10cSrcweir */ 408cdf0e10cSrcweir if( bError ) 409cdf0e10cSrcweir return NULL; 410cdf0e10cSrcweir 411cdf0e10cSrcweir String aSym( pParser->GetSym() ); 412cdf0e10cSrcweir SbxDataType eType = pParser->GetType(); 413cdf0e10cSrcweir SbiParameters* pPar = NULL; 414cdf0e10cSrcweir SbiExprListVector* pvMoreParLcl = NULL; 415cdf0e10cSrcweir eTok = pParser->Peek(); 416cdf0e10cSrcweir // Parameter? 417cdf0e10cSrcweir if( DoParametersFollow( pParser, eCurExpr, eTok ) ) 418cdf0e10cSrcweir { 419cdf0e10cSrcweir bool bStandaloneExpression = false; 420cdf0e10cSrcweir pPar = new SbiParameters( pParser, bStandaloneExpression ); 421cdf0e10cSrcweir bError |= !pPar->IsValid(); 422cdf0e10cSrcweir eTok = pParser->Peek(); 423cdf0e10cSrcweir 424cdf0e10cSrcweir // i109624 check for additional sets of parameters 425cdf0e10cSrcweir while( eTok == LPAREN ) 426cdf0e10cSrcweir { 427cdf0e10cSrcweir if( pvMoreParLcl == NULL ) 428cdf0e10cSrcweir pvMoreParLcl = new SbiExprListVector(); 429cdf0e10cSrcweir SbiParameters* pAddPar = new SbiParameters( pParser ); 430cdf0e10cSrcweir pvMoreParLcl->push_back( pAddPar ); 431cdf0e10cSrcweir bError |= !pPar->IsValid(); 432cdf0e10cSrcweir eTok = pParser->Peek(); 433cdf0e10cSrcweir } 434cdf0e10cSrcweir 435cdf0e10cSrcweir } 436cdf0e10cSrcweir sal_Bool bObj = sal_Bool( ( eTok == DOT || eTok == EXCLAM ) && !pParser->WhiteSpace() ); 437cdf0e10cSrcweir if( bObj ) 438cdf0e10cSrcweir { 439cdf0e10cSrcweir if( eType == SbxVARIANT ) 440cdf0e10cSrcweir eType = SbxOBJECT; 441cdf0e10cSrcweir else 442cdf0e10cSrcweir { 443cdf0e10cSrcweir // Name%. geht wirklich nicht! 444cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 445cdf0e10cSrcweir bError = sal_True; 446cdf0e10cSrcweir } 447cdf0e10cSrcweir } 448cdf0e10cSrcweir 449cdf0e10cSrcweir // Der Symbol-Pool eines Objekts ist immer PUBLIC 450cdf0e10cSrcweir SbiSymPool& rPool = rObj.GetPool(); 451cdf0e10cSrcweir rPool.SetScope( SbPUBLIC ); 452cdf0e10cSrcweir SbiSymDef* pDef = rPool.Find( aSym ); 453cdf0e10cSrcweir if( !pDef ) 454cdf0e10cSrcweir { 455cdf0e10cSrcweir pDef = AddSym( eTok, rPool, eCurExpr, aSym, eType, pPar ); 456cdf0e10cSrcweir pDef->SetType( eType ); 457cdf0e10cSrcweir } 458cdf0e10cSrcweir 459cdf0e10cSrcweir SbiExprNode* pNd = new SbiExprNode( pParser, *pDef, eType ); 460cdf0e10cSrcweir pNd->aVar.pPar = pPar; 461cdf0e10cSrcweir pNd->aVar.pvMorePar = pvMoreParLcl; 462cdf0e10cSrcweir if( bObj ) 463cdf0e10cSrcweir { 464cdf0e10cSrcweir // Falls wir etwas mit Punkt einscannen, muss der 465cdf0e10cSrcweir // Typ SbxOBJECT sein 466cdf0e10cSrcweir 467cdf0e10cSrcweir // AB, 3.1.96 468cdf0e10cSrcweir // Es kann sein, dass pDef ein Objekt beschreibt, das bisher 469cdf0e10cSrcweir // nur als SbxVARIANT erkannt wurde, dann Typ von pDef aendern 470cdf0e10cSrcweir if( pDef->GetType() == SbxVARIANT ) 471cdf0e10cSrcweir pDef->SetType( SbxOBJECT ); 472cdf0e10cSrcweir 473cdf0e10cSrcweir if( pDef->GetType() != SbxOBJECT ) 474cdf0e10cSrcweir { 475cdf0e10cSrcweir pParser->Error( SbERR_BAD_DECLARATION, aSym ); 476cdf0e10cSrcweir bError = sal_True; 477cdf0e10cSrcweir } 478cdf0e10cSrcweir if( !bError ) 479cdf0e10cSrcweir { 480cdf0e10cSrcweir pNd->aVar.pNext = ObjTerm( *pDef ); 481cdf0e10cSrcweir pNd->eType = eType; 482cdf0e10cSrcweir } 483cdf0e10cSrcweir } 484cdf0e10cSrcweir return pNd; 485cdf0e10cSrcweir } 486cdf0e10cSrcweir 487cdf0e10cSrcweir // Als Operanden kommen in Betracht: 488cdf0e10cSrcweir // Konstante 489cdf0e10cSrcweir // skalare Variable 490cdf0e10cSrcweir // Strukturelemente 491cdf0e10cSrcweir // Array-Elemente 492cdf0e10cSrcweir // Funktionen 493cdf0e10cSrcweir // geklammerte Ausdruecke 494cdf0e10cSrcweir 495cdf0e10cSrcweir SbiExprNode* SbiExpression::Operand( bool bUsedForTypeOf ) 496cdf0e10cSrcweir { 497cdf0e10cSrcweir SbiExprNode *pRes; 498cdf0e10cSrcweir SbiToken eTok; 499cdf0e10cSrcweir 500cdf0e10cSrcweir // Operand testen: 501cdf0e10cSrcweir switch( eTok = pParser->Peek() ) 502cdf0e10cSrcweir { 503cdf0e10cSrcweir case SYMBOL: 504cdf0e10cSrcweir pRes = Term(); 505cdf0e10cSrcweir // process something like "IF Not r Is Nothing Then .." 506cdf0e10cSrcweir if( !bUsedForTypeOf && pParser->IsVBASupportOn() && pParser->Peek() == IS ) 507cdf0e10cSrcweir { 508cdf0e10cSrcweir eTok = pParser->Next(); 509cdf0e10cSrcweir pRes = new SbiExprNode( pParser, pRes, eTok, Like() ); 510cdf0e10cSrcweir } 511cdf0e10cSrcweir break; 512cdf0e10cSrcweir case DOT: // .with 513cdf0e10cSrcweir pRes = Term(); break; 514cdf0e10cSrcweir case NUMBER: 515cdf0e10cSrcweir pParser->Next(); 516cdf0e10cSrcweir pRes = new SbiExprNode( pParser, pParser->GetDbl(), pParser->GetType() ); 517cdf0e10cSrcweir break; 518cdf0e10cSrcweir case FIXSTRING: 519cdf0e10cSrcweir pParser->Next(); 520cdf0e10cSrcweir pRes = new SbiExprNode( pParser, pParser->GetSym() ); break; 521cdf0e10cSrcweir case LPAREN: 522cdf0e10cSrcweir pParser->Next(); 523cdf0e10cSrcweir if( nParenLevel == 0 && m_eMode == EXPRMODE_LPAREN_PENDING && pParser->Peek() == RPAREN ) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir m_eMode = EXPRMODE_EMPTY_PAREN; 526cdf0e10cSrcweir pRes = new SbiExprNode(); // Dummy node 527cdf0e10cSrcweir pParser->Next(); 528cdf0e10cSrcweir break; 529cdf0e10cSrcweir } 530cdf0e10cSrcweir nParenLevel++; 531cdf0e10cSrcweir pRes = Boolean(); 532cdf0e10cSrcweir if( pParser->Peek() != RPAREN ) 533cdf0e10cSrcweir { 534cdf0e10cSrcweir // If there was a LPARAM, it does not belong to the expression 535cdf0e10cSrcweir if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING ) 536cdf0e10cSrcweir m_eMode = EXPRMODE_LPAREN_NOT_NEEDED; 537cdf0e10cSrcweir else 538cdf0e10cSrcweir pParser->Error( SbERR_BAD_BRACKETS ); 539cdf0e10cSrcweir } 540cdf0e10cSrcweir else 541cdf0e10cSrcweir { 542cdf0e10cSrcweir pParser->Next(); 543cdf0e10cSrcweir if( nParenLevel == 1 && m_eMode == EXPRMODE_LPAREN_PENDING ) 544cdf0e10cSrcweir { 545cdf0e10cSrcweir SbiToken eTokAfterRParen = pParser->Peek(); 546cdf0e10cSrcweir if( eTokAfterRParen == EQ || eTokAfterRParen == LPAREN || eTokAfterRParen == DOT ) 547cdf0e10cSrcweir m_eMode = EXPRMODE_ARRAY_OR_OBJECT; 548cdf0e10cSrcweir else 549cdf0e10cSrcweir m_eMode = EXPRMODE_STANDARD; 550cdf0e10cSrcweir } 551cdf0e10cSrcweir } 552cdf0e10cSrcweir nParenLevel--; 553cdf0e10cSrcweir pRes->bComposite = sal_True; 554cdf0e10cSrcweir break; 555cdf0e10cSrcweir default: 556cdf0e10cSrcweir // Zur Zeit sind Keywords hier OK! 557cdf0e10cSrcweir if( pParser->IsKwd( eTok ) ) 558cdf0e10cSrcweir pRes = Term(); 559cdf0e10cSrcweir else 560cdf0e10cSrcweir { 561cdf0e10cSrcweir pParser->Next(); 562cdf0e10cSrcweir pRes = new SbiExprNode( pParser, 1.0, SbxDOUBLE ); // bei Fehlern 563cdf0e10cSrcweir pParser->Error( SbERR_UNEXPECTED, eTok ); 564cdf0e10cSrcweir } 565cdf0e10cSrcweir } 566cdf0e10cSrcweir return pRes; 567cdf0e10cSrcweir } 568cdf0e10cSrcweir 569cdf0e10cSrcweir SbiExprNode* SbiExpression::Unary() 570cdf0e10cSrcweir { 571cdf0e10cSrcweir SbiExprNode* pNd; 572cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 573cdf0e10cSrcweir switch( eTok ) 574cdf0e10cSrcweir { 575cdf0e10cSrcweir case MINUS: 576cdf0e10cSrcweir eTok = NEG; 577cdf0e10cSrcweir pParser->Next(); 578cdf0e10cSrcweir pNd = new SbiExprNode( pParser, Unary(), eTok, NULL ); 579cdf0e10cSrcweir break; 580cdf0e10cSrcweir case NOT: 581cdf0e10cSrcweir if( pParser->IsVBASupportOn() ) 582cdf0e10cSrcweir { 583cdf0e10cSrcweir pNd = Operand(); 584cdf0e10cSrcweir } 585cdf0e10cSrcweir else 586cdf0e10cSrcweir { 587cdf0e10cSrcweir pParser->Next(); 588cdf0e10cSrcweir pNd = new SbiExprNode( pParser, Unary(), eTok, NULL ); 589cdf0e10cSrcweir } 590cdf0e10cSrcweir break; 591cdf0e10cSrcweir case PLUS: 592cdf0e10cSrcweir pParser->Next(); 593cdf0e10cSrcweir pNd = Unary(); 594cdf0e10cSrcweir break; 595cdf0e10cSrcweir case TYPEOF: 596cdf0e10cSrcweir { 597cdf0e10cSrcweir pParser->Next(); 598cdf0e10cSrcweir bool bUsedForTypeOf = true; 599cdf0e10cSrcweir SbiExprNode* pObjNode = Operand( bUsedForTypeOf ); 600cdf0e10cSrcweir pParser->TestToken( IS ); 601cdf0e10cSrcweir String aDummy; 602cdf0e10cSrcweir SbiSymDef* pTypeDef = new SbiSymDef( aDummy ); 603cdf0e10cSrcweir pParser->TypeDecl( *pTypeDef, sal_True ); 604cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pObjNode, pTypeDef->GetTypeId() ); 605cdf0e10cSrcweir break; 606cdf0e10cSrcweir } 607cdf0e10cSrcweir case NEW: 608cdf0e10cSrcweir { 609cdf0e10cSrcweir pParser->Next(); 610cdf0e10cSrcweir String aStr; 611cdf0e10cSrcweir SbiSymDef* pTypeDef = new SbiSymDef( aStr ); 612cdf0e10cSrcweir pParser->TypeDecl( *pTypeDef, sal_True ); 613cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pTypeDef->GetTypeId() ); 614cdf0e10cSrcweir break; 615cdf0e10cSrcweir } 616cdf0e10cSrcweir default: 617cdf0e10cSrcweir pNd = Operand(); 618cdf0e10cSrcweir } 619cdf0e10cSrcweir return pNd; 620cdf0e10cSrcweir } 621cdf0e10cSrcweir 622cdf0e10cSrcweir SbiExprNode* SbiExpression::Exp() 623cdf0e10cSrcweir { 624cdf0e10cSrcweir SbiExprNode* pNd = Unary(); 625cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 626cdf0e10cSrcweir { 627cdf0e10cSrcweir while( pParser->Peek() == EXPON ) { 628cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 629cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Unary() ); 630cdf0e10cSrcweir } 631cdf0e10cSrcweir } 632cdf0e10cSrcweir return pNd; 633cdf0e10cSrcweir } 634cdf0e10cSrcweir 635cdf0e10cSrcweir SbiExprNode* SbiExpression::MulDiv() 636cdf0e10cSrcweir { 637cdf0e10cSrcweir SbiExprNode* pNd = Exp(); 638cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 639cdf0e10cSrcweir { 640cdf0e10cSrcweir for( ;; ) 641cdf0e10cSrcweir { 642cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 643cdf0e10cSrcweir if( eTok != MUL && eTok != DIV ) 644cdf0e10cSrcweir break; 645cdf0e10cSrcweir eTok = pParser->Next(); 646cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Exp() ); 647cdf0e10cSrcweir } 648cdf0e10cSrcweir } 649cdf0e10cSrcweir return pNd; 650cdf0e10cSrcweir } 651cdf0e10cSrcweir 652cdf0e10cSrcweir SbiExprNode* SbiExpression::IntDiv() 653cdf0e10cSrcweir { 654cdf0e10cSrcweir SbiExprNode* pNd = MulDiv(); 655cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 656cdf0e10cSrcweir { 657cdf0e10cSrcweir while( pParser->Peek() == IDIV ) { 658cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 659cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, MulDiv() ); 660cdf0e10cSrcweir } 661cdf0e10cSrcweir } 662cdf0e10cSrcweir return pNd; 663cdf0e10cSrcweir } 664cdf0e10cSrcweir 665cdf0e10cSrcweir SbiExprNode* SbiExpression::Mod() 666cdf0e10cSrcweir { 667cdf0e10cSrcweir SbiExprNode* pNd = IntDiv(); 668cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 669cdf0e10cSrcweir { 670cdf0e10cSrcweir while( pParser->Peek() == MOD ) { 671cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 672cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, IntDiv() ); 673cdf0e10cSrcweir } 674cdf0e10cSrcweir } 675cdf0e10cSrcweir return pNd; 676cdf0e10cSrcweir } 677cdf0e10cSrcweir 678cdf0e10cSrcweir SbiExprNode* SbiExpression::AddSub() 679cdf0e10cSrcweir { 680cdf0e10cSrcweir SbiExprNode* pNd = Mod(); 681cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 682cdf0e10cSrcweir { 683cdf0e10cSrcweir for( ;; ) 684cdf0e10cSrcweir { 685cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 686cdf0e10cSrcweir if( eTok != PLUS && eTok != MINUS ) 687cdf0e10cSrcweir break; 688cdf0e10cSrcweir eTok = pParser->Next(); 689cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Mod() ); 690cdf0e10cSrcweir } 691cdf0e10cSrcweir } 692cdf0e10cSrcweir return pNd; 693cdf0e10cSrcweir } 694cdf0e10cSrcweir 695cdf0e10cSrcweir SbiExprNode* SbiExpression::Cat() 696cdf0e10cSrcweir { 697cdf0e10cSrcweir SbiExprNode* pNd = AddSub(); 698cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 699cdf0e10cSrcweir { 700cdf0e10cSrcweir for( ;; ) 701cdf0e10cSrcweir { 702cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 703cdf0e10cSrcweir if( eTok != CAT ) 704cdf0e10cSrcweir break; 705cdf0e10cSrcweir eTok = pParser->Next(); 706cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, AddSub() ); 707cdf0e10cSrcweir } 708cdf0e10cSrcweir } 709cdf0e10cSrcweir return pNd; 710cdf0e10cSrcweir } 711cdf0e10cSrcweir 712cdf0e10cSrcweir SbiExprNode* SbiExpression::Comp() 713cdf0e10cSrcweir { 714cdf0e10cSrcweir SbiExprNode* pNd = Cat(); 715cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 716cdf0e10cSrcweir { 717cdf0e10cSrcweir short nCount = 0; 718cdf0e10cSrcweir for( ;; ) 719cdf0e10cSrcweir { 720cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 721cdf0e10cSrcweir if( m_eMode == EXPRMODE_ARRAY_OR_OBJECT ) 722cdf0e10cSrcweir break; 723cdf0e10cSrcweir if( eTok != EQ && eTok != NE && eTok != LT 724cdf0e10cSrcweir && eTok != GT && eTok != LE && eTok != GE ) 725cdf0e10cSrcweir break; 726cdf0e10cSrcweir eTok = pParser->Next(); 727cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Cat() ); 728cdf0e10cSrcweir nCount++; 729cdf0e10cSrcweir } 730cdf0e10cSrcweir } 731cdf0e10cSrcweir return pNd; 732cdf0e10cSrcweir } 733cdf0e10cSrcweir 734cdf0e10cSrcweir SbiExprNode* SbiExpression::VBA_Not() 735cdf0e10cSrcweir { 736cdf0e10cSrcweir SbiExprNode* pNd = NULL; 737cdf0e10cSrcweir 738cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 739cdf0e10cSrcweir if( eTok == NOT ) 740cdf0e10cSrcweir { 741cdf0e10cSrcweir pParser->Next(); 742cdf0e10cSrcweir pNd = new SbiExprNode( pParser, VBA_Not(), eTok, NULL ); 743cdf0e10cSrcweir } 744cdf0e10cSrcweir else 745cdf0e10cSrcweir { 746cdf0e10cSrcweir pNd = Comp(); 747cdf0e10cSrcweir } 748cdf0e10cSrcweir return pNd; 749cdf0e10cSrcweir } 750cdf0e10cSrcweir 751cdf0e10cSrcweir SbiExprNode* SbiExpression::Like() 752cdf0e10cSrcweir { 753cdf0e10cSrcweir SbiExprNode* pNd = pParser->IsVBASupportOn() ? VBA_Not() : Comp(); 754cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 755cdf0e10cSrcweir { 756cdf0e10cSrcweir short nCount = 0; 757cdf0e10cSrcweir while( pParser->Peek() == LIKE ) { 758cdf0e10cSrcweir SbiToken eTok = pParser->Next(); 759cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Comp() ), nCount++; 760cdf0e10cSrcweir } 761cdf0e10cSrcweir // Mehrere Operatoren hintereinander gehen nicht 762cdf0e10cSrcweir if( nCount > 1 ) 763cdf0e10cSrcweir { 764cdf0e10cSrcweir pParser->Error( SbERR_SYNTAX ); 765cdf0e10cSrcweir bError = sal_True; 766cdf0e10cSrcweir } 767cdf0e10cSrcweir } 768cdf0e10cSrcweir return pNd; 769cdf0e10cSrcweir } 770cdf0e10cSrcweir 771cdf0e10cSrcweir SbiExprNode* SbiExpression::Boolean() 772cdf0e10cSrcweir { 773cdf0e10cSrcweir SbiExprNode* pNd = Like(); 774cdf0e10cSrcweir if( m_eMode != EXPRMODE_EMPTY_PAREN ) 775cdf0e10cSrcweir { 776cdf0e10cSrcweir for( ;; ) 777cdf0e10cSrcweir { 778cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 779cdf0e10cSrcweir if( eTok != AND && eTok != OR && eTok != XOR 780cdf0e10cSrcweir && eTok != EQV && eTok != IMP && eTok != IS ) 781cdf0e10cSrcweir break; 782cdf0e10cSrcweir eTok = pParser->Next(); 783cdf0e10cSrcweir pNd = new SbiExprNode( pParser, pNd, eTok, Like() ); 784cdf0e10cSrcweir } 785cdf0e10cSrcweir } 786cdf0e10cSrcweir return pNd; 787cdf0e10cSrcweir } 788cdf0e10cSrcweir 789cdf0e10cSrcweir /*************************************************************************** 790cdf0e10cSrcweir |* 791cdf0e10cSrcweir |* SbiConstExpression 792cdf0e10cSrcweir |* 793cdf0e10cSrcweir ***************************************************************************/ 794cdf0e10cSrcweir 795cdf0e10cSrcweir // Parsing einer Expression, die sich zu einer numerischen 796cdf0e10cSrcweir // Konstanten verarbeiten laesst. 797cdf0e10cSrcweir 798cdf0e10cSrcweir SbiConstExpression::SbiConstExpression( SbiParser* p ) : SbiExpression( p ) 799cdf0e10cSrcweir { 800cdf0e10cSrcweir if( pExpr->IsConstant() ) 801cdf0e10cSrcweir { 802cdf0e10cSrcweir eType = pExpr->GetType(); 803cdf0e10cSrcweir if( pExpr->IsNumber() ) 804cdf0e10cSrcweir { 805cdf0e10cSrcweir nVal = pExpr->nVal; 806cdf0e10cSrcweir } 807cdf0e10cSrcweir else 808cdf0e10cSrcweir { 809cdf0e10cSrcweir nVal = 0; 810cdf0e10cSrcweir aVal = pExpr->aStrVal; 811cdf0e10cSrcweir } 812cdf0e10cSrcweir } 813cdf0e10cSrcweir else 814cdf0e10cSrcweir { 815cdf0e10cSrcweir // #40204 Spezialbehandlung fuer sal_Bool-Konstanten 816cdf0e10cSrcweir sal_Bool bIsBool = sal_False; 817cdf0e10cSrcweir if( pExpr->eNodeType == SbxVARVAL ) 818cdf0e10cSrcweir { 819cdf0e10cSrcweir SbiSymDef* pVarDef = pExpr->GetVar(); 820cdf0e10cSrcweir 821cdf0e10cSrcweir // Ist es eine sal_Bool-Konstante? 822cdf0e10cSrcweir sal_Bool bBoolVal = sal_False; 823cdf0e10cSrcweir if( pVarDef->GetName().EqualsIgnoreCaseAscii( "true" ) ) 824cdf0e10cSrcweir //if( pVarDef->GetName().ICompare( "true" ) == COMPARE_EQUAL ) 825cdf0e10cSrcweir { 826cdf0e10cSrcweir bIsBool = sal_True; 827cdf0e10cSrcweir bBoolVal = sal_True; 828cdf0e10cSrcweir } 829cdf0e10cSrcweir else if( pVarDef->GetName().EqualsIgnoreCaseAscii( "false" ) ) 830cdf0e10cSrcweir //else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL ) 831cdf0e10cSrcweir { 832cdf0e10cSrcweir bIsBool = sal_True; 833cdf0e10cSrcweir bBoolVal = sal_False; 834cdf0e10cSrcweir } 835cdf0e10cSrcweir 836cdf0e10cSrcweir // Wenn es ein sal_Bool ist, Node austauschen 837cdf0e10cSrcweir if( bIsBool ) 838cdf0e10cSrcweir { 839cdf0e10cSrcweir delete pExpr; 840cdf0e10cSrcweir pExpr = new SbiExprNode( pParser, (bBoolVal ? SbxTRUE : SbxFALSE), SbxINTEGER ); 841cdf0e10cSrcweir eType = pExpr->GetType(); 842cdf0e10cSrcweir nVal = pExpr->nVal; 843cdf0e10cSrcweir } 844cdf0e10cSrcweir } 845cdf0e10cSrcweir 846cdf0e10cSrcweir if( !bIsBool ) 847cdf0e10cSrcweir { 848cdf0e10cSrcweir pParser->Error( SbERR_SYNTAX ); 849cdf0e10cSrcweir eType = SbxDOUBLE; 850cdf0e10cSrcweir nVal = 0; 851cdf0e10cSrcweir } 852cdf0e10cSrcweir } 853cdf0e10cSrcweir } 854cdf0e10cSrcweir 855cdf0e10cSrcweir short SbiConstExpression::GetShortValue() 856cdf0e10cSrcweir { 857cdf0e10cSrcweir if( eType == SbxSTRING ) 858cdf0e10cSrcweir { 859cdf0e10cSrcweir SbxVariableRef refConv = new SbxVariable; 860cdf0e10cSrcweir refConv->PutString( aVal ); 861cdf0e10cSrcweir return refConv->GetInteger(); 862cdf0e10cSrcweir } 863cdf0e10cSrcweir else 864cdf0e10cSrcweir { 865cdf0e10cSrcweir double n = nVal; 866cdf0e10cSrcweir if( n > 0 ) n += .5; else n -= .5; 867cdf0e10cSrcweir if( n > SbxMAXINT ) n = SbxMAXINT, pParser->Error( SbERR_OUT_OF_RANGE ); 868cdf0e10cSrcweir else 869cdf0e10cSrcweir if( n < SbxMININT ) n = SbxMININT, pParser->Error( SbERR_OUT_OF_RANGE ); 870cdf0e10cSrcweir return (short) n; 871cdf0e10cSrcweir } 872cdf0e10cSrcweir } 873cdf0e10cSrcweir 874cdf0e10cSrcweir 875cdf0e10cSrcweir /*************************************************************************** 876cdf0e10cSrcweir |* 877cdf0e10cSrcweir |* SbiExprList 878cdf0e10cSrcweir |* 879cdf0e10cSrcweir ***************************************************************************/ 880cdf0e10cSrcweir 881cdf0e10cSrcweir SbiExprList::SbiExprList( SbiParser* p ) 882cdf0e10cSrcweir { 883cdf0e10cSrcweir pParser = p; 884cdf0e10cSrcweir pFirst = NULL; 885cdf0e10cSrcweir nExpr = 886cdf0e10cSrcweir nDim = 0; 887cdf0e10cSrcweir bError = 888cdf0e10cSrcweir bBracket = sal_False; 889cdf0e10cSrcweir } 890cdf0e10cSrcweir 891cdf0e10cSrcweir SbiExprList::~SbiExprList() 892cdf0e10cSrcweir { 893cdf0e10cSrcweir SbiExpression* p = pFirst; 894cdf0e10cSrcweir while( p ) 895cdf0e10cSrcweir { 896cdf0e10cSrcweir SbiExpression* q = p->pNext; 897cdf0e10cSrcweir delete p; 898cdf0e10cSrcweir p = q; 899cdf0e10cSrcweir } 900cdf0e10cSrcweir } 901cdf0e10cSrcweir 902cdf0e10cSrcweir // Parameter anfordern (ab 0) 903cdf0e10cSrcweir 904cdf0e10cSrcweir SbiExpression* SbiExprList::Get( short n ) 905cdf0e10cSrcweir { 906cdf0e10cSrcweir SbiExpression* p = pFirst; 907cdf0e10cSrcweir while( n-- && p ) 908cdf0e10cSrcweir p = p->pNext; 909cdf0e10cSrcweir return p; 910cdf0e10cSrcweir } 911cdf0e10cSrcweir 912cdf0e10cSrcweir void SbiExprList::addExpression( SbiExpression* pExpr ) 913cdf0e10cSrcweir { 914cdf0e10cSrcweir SbiExpression* p = pFirst; 915cdf0e10cSrcweir while( p && p->pNext ) 916cdf0e10cSrcweir p = p->pNext; 917cdf0e10cSrcweir 918cdf0e10cSrcweir p->pNext = pExpr; 919cdf0e10cSrcweir } 920cdf0e10cSrcweir 921cdf0e10cSrcweir 922cdf0e10cSrcweir /*************************************************************************** 923cdf0e10cSrcweir |* 924cdf0e10cSrcweir |* SbiParameters 925cdf0e10cSrcweir |* 926cdf0e10cSrcweir ***************************************************************************/ 927cdf0e10cSrcweir 928cdf0e10cSrcweir // Parsender Konstruktor: 929cdf0e10cSrcweir // Die Parameterliste wird komplett geparst. 930cdf0e10cSrcweir // "Prozedurname()" ist OK. 931cdf0e10cSrcweir // Dann handelt es sich um eine Funktion ohne Parameter 932cdf0e10cSrcweir // respektive um die Angabe eines Arrays als Prozedurparameter. 933cdf0e10cSrcweir 934cdf0e10cSrcweir // #i79918/#i80532: bConst has never been set to true 935cdf0e10cSrcweir // -> reused as bStandaloneExpression 936cdf0e10cSrcweir //SbiParameters::SbiParameters( SbiParser* p, sal_Bool bConst, sal_Bool bPar) : 937cdf0e10cSrcweir SbiParameters::SbiParameters( SbiParser* p, sal_Bool bStandaloneExpression, sal_Bool bPar) : 938cdf0e10cSrcweir SbiExprList( p ) 939cdf0e10cSrcweir { 940cdf0e10cSrcweir if( !bPar ) 941cdf0e10cSrcweir return; 942cdf0e10cSrcweir 943cdf0e10cSrcweir SbiExpression *pExpr; 944cdf0e10cSrcweir SbiToken eTok = pParser->Peek(); 945cdf0e10cSrcweir 946cdf0e10cSrcweir // evtl. Klammer auf weg: 947cdf0e10cSrcweir bool bAssumeExprLParenMode = false; 948cdf0e10cSrcweir bool bAssumeArrayMode = false; 949cdf0e10cSrcweir if( eTok == LPAREN ) 950cdf0e10cSrcweir { 951cdf0e10cSrcweir if( bStandaloneExpression ) 952cdf0e10cSrcweir { 953cdf0e10cSrcweir bAssumeExprLParenMode = true; 954cdf0e10cSrcweir } 955cdf0e10cSrcweir else 956cdf0e10cSrcweir { 957cdf0e10cSrcweir bBracket = sal_True; 958cdf0e10cSrcweir pParser->Next(); 959cdf0e10cSrcweir eTok = pParser->Peek(); 960cdf0e10cSrcweir } 961cdf0e10cSrcweir } 962cdf0e10cSrcweir 963cdf0e10cSrcweir // Ende-Test 964cdf0e10cSrcweir if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) ) 965cdf0e10cSrcweir { 966cdf0e10cSrcweir if( eTok == RPAREN ) 967cdf0e10cSrcweir pParser->Next(); 968cdf0e10cSrcweir return; 969cdf0e10cSrcweir } 970cdf0e10cSrcweir // Parametertabelle einlesen und in richtiger Folge ablegen! 971cdf0e10cSrcweir SbiExpression* pLast = NULL; 972cdf0e10cSrcweir String aName; 973cdf0e10cSrcweir while( !bError ) 974cdf0e10cSrcweir { 975cdf0e10cSrcweir aName.Erase(); 976cdf0e10cSrcweir // Fehlendes Argument 977cdf0e10cSrcweir if( eTok == COMMA ) 978cdf0e10cSrcweir { 979cdf0e10cSrcweir pExpr = new SbiExpression( pParser, 0, SbxEMPTY ); 980cdf0e10cSrcweir //if( bConst ) 981cdf0e10cSrcweir // pParser->Error( SbERR_SYNTAX ), bError = sal_True; 982cdf0e10cSrcweir } 983cdf0e10cSrcweir // Benannte Argumente: entweder .name= oder name:= 984cdf0e10cSrcweir else 985cdf0e10cSrcweir { 986cdf0e10cSrcweir bool bByVal = false; 987cdf0e10cSrcweir if( eTok == BYVAL ) 988cdf0e10cSrcweir { 989cdf0e10cSrcweir bByVal = true; 990cdf0e10cSrcweir pParser->Next(); 991cdf0e10cSrcweir eTok = pParser->Peek(); 992cdf0e10cSrcweir } 993cdf0e10cSrcweir 994cdf0e10cSrcweir if( bAssumeExprLParenMode ) 995cdf0e10cSrcweir { 996cdf0e10cSrcweir pExpr = new SbiExpression( pParser, SbSTDEXPR, EXPRMODE_LPAREN_PENDING ); 997cdf0e10cSrcweir bAssumeExprLParenMode = sal_False; 998cdf0e10cSrcweir 999cdf0e10cSrcweir SbiExprMode eModeAfter = pExpr->m_eMode; 1000cdf0e10cSrcweir if( eModeAfter == EXPRMODE_LPAREN_NOT_NEEDED ) 1001cdf0e10cSrcweir { 1002cdf0e10cSrcweir bBracket = sal_True; 1003cdf0e10cSrcweir } 1004cdf0e10cSrcweir else if( eModeAfter == EXPRMODE_ARRAY_OR_OBJECT ) 1005cdf0e10cSrcweir { 1006cdf0e10cSrcweir // Expression "looks" like an array assignment 1007cdf0e10cSrcweir // a(...)[(...)] = ? or a(...).b(...) 1008cdf0e10cSrcweir // RPAREN is already parsed 1009cdf0e10cSrcweir bBracket = sal_True; 1010cdf0e10cSrcweir bAssumeArrayMode = true; 1011cdf0e10cSrcweir eTok = NIL; 1012cdf0e10cSrcweir } 1013cdf0e10cSrcweir else if( eModeAfter == EXPRMODE_EMPTY_PAREN ) 1014cdf0e10cSrcweir { 1015cdf0e10cSrcweir bBracket = sal_True; 1016cdf0e10cSrcweir delete pExpr; 1017cdf0e10cSrcweir if( bByVal ) 1018cdf0e10cSrcweir pParser->Error( SbERR_LVALUE_EXPECTED ); 1019cdf0e10cSrcweir return; 1020cdf0e10cSrcweir } 1021cdf0e10cSrcweir } 1022cdf0e10cSrcweir else 1023cdf0e10cSrcweir pExpr = new SbiExpression( pParser ); 1024cdf0e10cSrcweir 1025cdf0e10cSrcweir if( bByVal && pExpr->IsLvalue() ) 1026cdf0e10cSrcweir pExpr->SetByVal(); 1027cdf0e10cSrcweir 1028cdf0e10cSrcweir //pExpr = bConst ? new SbiConstExpression( pParser ) 1029cdf0e10cSrcweir // : new SbiExpression( pParser ); 1030cdf0e10cSrcweir if( !bAssumeArrayMode ) 1031cdf0e10cSrcweir { 1032cdf0e10cSrcweir if( pParser->Peek() == ASSIGN ) 1033cdf0e10cSrcweir { 1034cdf0e10cSrcweir // VBA mode: name:= 1035cdf0e10cSrcweir // SbiExpression::Term() hat einen String daraus gemacht 1036cdf0e10cSrcweir aName = pExpr->GetString(); 1037cdf0e10cSrcweir delete pExpr; 1038cdf0e10cSrcweir pParser->Next(); 1039cdf0e10cSrcweir pExpr = new SbiExpression( pParser ); 1040cdf0e10cSrcweir //if( bConst ) 1041cdf0e10cSrcweir // pParser->Error( SbERR_SYNTAX ), bError = sal_True; 1042cdf0e10cSrcweir } 1043cdf0e10cSrcweir pExpr->GetName() = aName; 1044cdf0e10cSrcweir } 1045cdf0e10cSrcweir } 1046cdf0e10cSrcweir pExpr->pNext = NULL; 1047cdf0e10cSrcweir if( !pLast ) 1048cdf0e10cSrcweir pFirst = pLast = pExpr; 1049cdf0e10cSrcweir else 1050cdf0e10cSrcweir pLast->pNext = pExpr, pLast = pExpr; 1051cdf0e10cSrcweir nExpr++; 1052cdf0e10cSrcweir bError |= !pExpr->IsValid(); 1053cdf0e10cSrcweir 1054cdf0e10cSrcweir if( bAssumeArrayMode ) 1055cdf0e10cSrcweir break; 1056cdf0e10cSrcweir 1057cdf0e10cSrcweir // Naechstes Element? 1058cdf0e10cSrcweir eTok = pParser->Peek(); 1059cdf0e10cSrcweir if( eTok != COMMA ) 1060cdf0e10cSrcweir { 1061cdf0e10cSrcweir if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) ) 1062cdf0e10cSrcweir break; 1063cdf0e10cSrcweir pParser->Error( bBracket 1064cdf0e10cSrcweir ? SbERR_BAD_BRACKETS 1065cdf0e10cSrcweir : SbERR_EXPECTED, COMMA ); 1066cdf0e10cSrcweir bError = sal_True; 1067cdf0e10cSrcweir } 1068cdf0e10cSrcweir else 1069cdf0e10cSrcweir { 1070cdf0e10cSrcweir pParser->Next(); 1071cdf0e10cSrcweir eTok = pParser->Peek(); 1072cdf0e10cSrcweir if( ( bBracket && eTok == RPAREN ) || pParser->IsEoln( eTok ) ) 1073cdf0e10cSrcweir break; 1074cdf0e10cSrcweir } 1075cdf0e10cSrcweir } 1076cdf0e10cSrcweir // Schliessende Klammer 1077cdf0e10cSrcweir if( eTok == RPAREN ) 1078cdf0e10cSrcweir { 1079cdf0e10cSrcweir pParser->Next(); 1080cdf0e10cSrcweir pParser->Peek(); 1081cdf0e10cSrcweir if( !bBracket ) 1082cdf0e10cSrcweir { 1083cdf0e10cSrcweir pParser->Error( SbERR_BAD_BRACKETS ); 1084cdf0e10cSrcweir bError = sal_True; 1085cdf0e10cSrcweir } 1086cdf0e10cSrcweir } 1087cdf0e10cSrcweir nDim = nExpr; 1088cdf0e10cSrcweir } 1089cdf0e10cSrcweir 1090cdf0e10cSrcweir /*************************************************************************** 1091cdf0e10cSrcweir |* 1092cdf0e10cSrcweir |* SbiDimList 1093cdf0e10cSrcweir |* 1094cdf0e10cSrcweir ***************************************************************************/ 1095cdf0e10cSrcweir 1096cdf0e10cSrcweir // Parsender Konstruktor: 1097cdf0e10cSrcweir // Eine Liste von Array-Dimensionen wird geparst. Die Ausdruecke werden 1098cdf0e10cSrcweir // auf numerisch getestet. Das bCONST-Bit wird gesetzt, wenn alle Ausdruecke 1099cdf0e10cSrcweir // Integer-Konstanten sind. 1100cdf0e10cSrcweir 1101cdf0e10cSrcweir SbiDimList::SbiDimList( SbiParser* p ) : SbiExprList( p ) 1102cdf0e10cSrcweir { 1103cdf0e10cSrcweir bConst = sal_True; 1104cdf0e10cSrcweir 1105cdf0e10cSrcweir if( pParser->Next() != LPAREN ) 1106cdf0e10cSrcweir { 1107cdf0e10cSrcweir pParser->Error( SbERR_EXPECTED, LPAREN ); 1108cdf0e10cSrcweir bError = sal_True; return; 1109cdf0e10cSrcweir } 1110cdf0e10cSrcweir 1111cdf0e10cSrcweir if( pParser->Peek() != RPAREN ) 1112cdf0e10cSrcweir { 1113cdf0e10cSrcweir SbiExpression *pExpr1, *pExpr2, *pLast = NULL; 1114cdf0e10cSrcweir SbiToken eTok; 1115cdf0e10cSrcweir for( ;; ) 1116cdf0e10cSrcweir { 1117cdf0e10cSrcweir pExpr1 = new SbiExpression( pParser ); 1118cdf0e10cSrcweir eTok = pParser->Next(); 1119cdf0e10cSrcweir if( eTok == TO ) 1120cdf0e10cSrcweir { 1121cdf0e10cSrcweir pExpr2 = new SbiExpression( pParser ); 1122cdf0e10cSrcweir eTok = pParser->Next(); 1123cdf0e10cSrcweir bConst &= pExpr1->IsIntConstant() & pExpr2->IsIntConstant(); 1124cdf0e10cSrcweir bError |= !pExpr1->IsValid(); 1125cdf0e10cSrcweir bError |= !pExpr2->IsValid(); 1126cdf0e10cSrcweir pExpr1->pNext = pExpr2; 1127cdf0e10cSrcweir if( !pLast ) 1128cdf0e10cSrcweir pFirst = pExpr1; 1129cdf0e10cSrcweir else 1130cdf0e10cSrcweir pLast->pNext = pExpr1; 1131cdf0e10cSrcweir pLast = pExpr2; 1132cdf0e10cSrcweir nExpr += 2; 1133cdf0e10cSrcweir } 1134cdf0e10cSrcweir else 1135cdf0e10cSrcweir { 1136cdf0e10cSrcweir // Nur eine Dim-Angabe 1137cdf0e10cSrcweir pExpr1->SetBased(); 1138cdf0e10cSrcweir pExpr1->pNext = NULL; 1139cdf0e10cSrcweir bConst &= pExpr1->IsIntConstant(); 1140cdf0e10cSrcweir bError |= !pExpr1->IsValid(); 1141cdf0e10cSrcweir if( !pLast ) 1142cdf0e10cSrcweir pFirst = pLast = pExpr1; 1143cdf0e10cSrcweir else 1144cdf0e10cSrcweir pLast->pNext = pExpr1, pLast = pExpr1; 1145cdf0e10cSrcweir nExpr++; 1146cdf0e10cSrcweir } 1147cdf0e10cSrcweir nDim++; 1148cdf0e10cSrcweir if( eTok == RPAREN ) break; 1149cdf0e10cSrcweir if( eTok != COMMA ) 1150cdf0e10cSrcweir { 1151cdf0e10cSrcweir pParser->Error( SbERR_BAD_BRACKETS ); 1152cdf0e10cSrcweir pParser->Next(); 1153cdf0e10cSrcweir break; 1154cdf0e10cSrcweir } 1155cdf0e10cSrcweir } 1156cdf0e10cSrcweir } 1157cdf0e10cSrcweir else pParser->Next(); 1158cdf0e10cSrcweir } 1159cdf0e10cSrcweir 1160