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 .
23 #include <basic/sberrors.hxx>
24 #include <basic/sbmod.hxx>
25 #include <comphelper/SetFlagContextHelper.hxx>
28 SbiExpression::SbiExpression( SbiParser
* p
, SbiExprType t
,
29 SbiExprMode eMode
, const KeywordSymbolInfo
* pKeywordSymbolInfo
)
32 bBased
= bError
= bByVal
= bBracket
= false;
36 pExpr
= (t
!= SbSTDEXPR
) ? Term( pKeywordSymbolInfo
) : Boolean();
39 pExpr
->Optimize(pParser
);
41 if( t
== SbLVALUE
&& !pExpr
->IsLvalue() )
43 p
->Error( ERRCODE_BASIC_LVALUE_EXPECTED
);
45 if( t
== SbOPERAND
&& !IsVariable() )
47 p
->Error( ERRCODE_BASIC_VAR_EXPECTED
);
51 SbiExpression::SbiExpression( SbiParser
* p
, double n
, SbxDataType t
)
54 bBased
= bError
= bByVal
= bBracket
= false;
57 m_eMode
= EXPRMODE_STANDARD
;
58 pExpr
= std::make_unique
<SbiExprNode
>( n
, t
);
59 pExpr
->Optimize(pParser
);
62 SbiExpression::SbiExpression( SbiParser
* p
, const SbiSymDef
& r
, SbiExprListPtr pPar
)
65 bBased
= bError
= bByVal
= bBracket
= false;
68 m_eMode
= EXPRMODE_STANDARD
;
69 pExpr
= std::make_unique
<SbiExprNode
>( r
, SbxVARIANT
, std::move(pPar
) );
72 SbiExpression::~SbiExpression() { }
74 // reading in a complete identifier
75 // an identifier has the following form:
76 // name[(Parameter)][.Name[(parameter)]]...
77 // structure elements are coupled via the element pNext,
78 // so that they're not in the tree.
80 // Are there parameters without brackets following? This may be a number,
81 // a string, a symbol or also a comma (if the 1st parameter is missing)
83 static bool DoParametersFollow( SbiParser
* p
, SbiExprType eCurExpr
, SbiToken eTok
)
89 // but only if similar to CALL!
90 if( !p
->WhiteSpace() || eCurExpr
!= SbSYMBOL
)
94 if ( eTok
== NUMBER
|| eTok
== MINUS
|| eTok
== FIXSTRING
||
95 eTok
== SYMBOL
|| eTok
== COMMA
|| eTok
== DOT
|| eTok
== NOT
|| eTok
== BYVAL
)
99 else // check for default params with reserved names ( e.g. names of tokens )
101 SbiTokenizer
tokens( *static_cast<SbiTokenizer
*>(p
) );
102 // Urk the Next() / Peek() semantics are... weird
104 if ( tokens
.Peek() == ASSIGN
)
112 // definition of a new symbol
114 static SbiSymDef
* AddSym ( SbiToken eTok
, SbiSymPool
& rPool
, SbiExprType eCurExpr
,
115 const OUString
& rName
, SbxDataType eType
, const SbiExprList
* pPar
)
118 // A= is not a procedure
119 bool bHasType
= ( eTok
== EQ
|| eTok
== DOT
);
120 if( ( !bHasType
&& eCurExpr
== SbSYMBOL
) || pPar
)
122 // so this is a procedure
123 // the correct pool should be found out, as
124 // procs must always get into a public pool
125 SbiSymPool
* pPool
= &rPool
;
126 if( pPool
->GetScope() != SbPUBLIC
)
128 pPool
= &rPool
.GetParser()->aPublics
;
130 SbiProcDef
* pProc
= pPool
->AddProc( rName
);
132 // special treatment for Colls like Documents(1)
133 if( eCurExpr
== SbSTDEXPR
)
138 pDef
->SetType( bHasType
? eType
: SbxEMPTY
);
141 // generate dummy parameters
142 for( sal_Int32 n
= 1; n
<= pPar
->GetSize(); n
++ )
144 OUString aPar
= "PAR" + OUString::number( n
);
145 pProc
->GetParams().AddSym( aPar
);
151 // or a normal symbol
152 pDef
= rPool
.AddSym( rName
);
153 pDef
->SetType( eType
);
158 // currently even keywords are allowed (because of Dflt properties of the same name)
160 std::unique_ptr
<SbiExprNode
> SbiExpression::Term( const KeywordSymbolInfo
* pKeywordSymbolInfo
)
162 if( pParser
->Peek() == DOT
)
164 SbiExprNode
* pWithVar
= pParser
->GetWithVar();
165 // #26608: get to the node-chain's end to pass the correct object
166 SbiSymDef
* pDef
= pWithVar
? pWithVar
->GetRealVar() : nullptr;
167 std::unique_ptr
<SbiExprNode
> pNd
;
174 pNd
= ObjTerm( *pDef
);
177 pNd
->SetWithParent( pWithVar
);
182 pParser
->Error( ERRCODE_BASIC_UNEXPECTED
, DOT
);
183 pNd
= std::make_unique
<SbiExprNode
>( 1.0, SbxDOUBLE
);
188 SbiToken eTok
= (pKeywordSymbolInfo
== nullptr) ? pParser
->Next() : SYMBOL
;
189 // memorize the parsing's begin
190 pParser
->LockColumn();
191 OUString
aSym( (pKeywordSymbolInfo
== nullptr) ? pParser
->GetSym() : pKeywordSymbolInfo
->m_aKeywordSymbol
);
192 SbxDataType eType
= (pKeywordSymbolInfo
== nullptr) ? pParser
->GetType() : pKeywordSymbolInfo
->m_eSbxDataType
;
194 std::unique_ptr
<SbiExprListVector
> pvMoreParLcl
;
195 // are there parameters following?
196 SbiToken eNextTok
= pParser
->Peek();
197 // is it a known parameter?
198 // create a string constant then, which will be recognized
199 // in the SbiParameters-ctor and is continued to be handled
200 if( eNextTok
== ASSIGN
)
202 pParser
->UnlockColumn();
203 return std::make_unique
<SbiExprNode
>( aSym
);
205 // no keywords allowed from here on!
206 if( SbiTokenizer::IsKwd( eTok
)
207 && (!pParser
->IsCompatible() || eTok
!= INPUT
) )
209 pParser
->Error( ERRCODE_BASIC_SYNTAX
);
214 if( DoParametersFollow( pParser
, eCurExpr
, eTok
) )
216 bool bStandaloneExpression
= (m_eMode
== EXPRMODE_STANDALONE
);
217 pPar
= SbiExprList::ParseParameters( pParser
, bStandaloneExpression
);
218 bError
= bError
|| !pPar
->IsValid();
220 bBracket
= pPar
->IsBracket();
221 eTok
= pParser
->Peek();
223 // i75443 check for additional sets of parameters
224 while( eTok
== LPAREN
)
226 if( pvMoreParLcl
== nullptr )
228 pvMoreParLcl
.reset(new SbiExprListVector
);
230 SbiExprListPtr pAddPar
= SbiExprList::ParseParameters( pParser
);
231 bError
= bError
|| !pAddPar
->IsValid();
232 pvMoreParLcl
->push_back( std::move(pAddPar
) );
233 eTok
= pParser
->Peek();
236 // It might be an object part, if . or ! is following.
237 // In case of . the variable must already be defined;
238 // it's an object, if pDef is NULL after the search.
239 bool bObj
= ( ( eTok
== DOT
|| eTok
== EXCLAM
)
240 && !pParser
->WhiteSpace() );
243 bBracket
= false; // Now the bracket for the first term is obsolete
244 if( eType
== SbxVARIANT
)
250 // Name%. really does not work!
251 pParser
->Error( ERRCODE_BASIC_BAD_DECLARATION
, aSym
);
256 SbiSymDef
* pDef
= pParser
->pPool
->Find( aSym
);
259 // Part of the Runtime-Library?
260 // from 31.3.1996: swapped out to parser-method
261 // (is also needed in SbiParser::DefVar() in DIM.CXX)
262 pDef
= pParser
->CheckRTLForSym( aSym
, eType
);
264 // #i109184: Check if symbol is or later will be defined inside module
265 SbModule
& rMod
= pParser
->aGen
.GetModule();
266 if( rMod
.FindMethod( aSym
, SbxClassType::DontCare
) )
277 pDef
= AddSym( eTok
, *pParser
->pPool
, eCurExpr
, aSym
, eType
, pPar
.get() );
278 // Looks like this is a local ( but undefined variable )
279 // if it is in a static procedure then make this Symbol
281 if ( !bObj
&& pParser
->pProc
&& pParser
->pProc
->IsStatic() )
289 SbiConstDef
* pConst
= pDef
->GetConstDef();
293 pvMoreParLcl
.reset();
294 if( pConst
->GetType() == SbxSTRING
)
296 return std::make_unique
<SbiExprNode
>( pConst
->GetString() );
300 return std::make_unique
<SbiExprNode
>( pConst
->GetValue(), pConst
->GetType() );
304 // 0 parameters come up to ()
305 if( pDef
->GetDims() )
307 if( pPar
&& pPar
->GetSize() && pPar
->GetSize() != pDef
->GetDims() )
309 pParser
->Error( ERRCODE_BASIC_WRONG_DIMS
);
312 if( pDef
->IsDefinedAs() )
314 SbxDataType eDefType
= pDef
->GetType();
315 // #119187 Only error if types conflict
316 if( eType
>= SbxINTEGER
&& eType
<= SbxSTRING
&& eType
!= eDefType
)
318 // How? Define with AS first and take a Suffix then?
319 pParser
->Error( ERRCODE_BASIC_BAD_DECLARATION
, aSym
);
322 else if ( eType
== SbxVARIANT
)
324 // if there's nothing named, take the type of the entry,
325 // but only if the var hasn't been defined with AS XXX
326 // so that we catch n% = 5 : print n
330 // checking type of variables:
331 // is there named anything different in the scanner?
332 // That's OK for methods!
333 if( eType
!= SbxVARIANT
&& // Variant takes everything
334 eType
!= pDef
->GetType() &&
335 !pDef
->GetProcDef() )
337 // maybe pDef describes an object that so far has only been
338 // recognized as SbxVARIANT - then change type of pDef
339 // from 16.12.95 (similar cases possible perhaps?!?)
340 if( eType
== SbxOBJECT
&& pDef
->GetType() == SbxVARIANT
)
342 pDef
->SetType( SbxOBJECT
);
346 pParser
->Error( ERRCODE_BASIC_BAD_DECLARATION
, aSym
);
351 auto pNd
= std::make_unique
<SbiExprNode
>( *pDef
, eType
);
354 pPar
= SbiExprList::ParseParameters( pParser
,false,false );
356 pNd
->aVar
.pPar
= pPar
.release();
357 pNd
->aVar
.pvMorePar
= pvMoreParLcl
.release();
360 // from 8.1.95: Object may also be of the type SbxVARIANT
361 if( pDef
->GetType() == SbxVARIANT
)
362 pDef
->SetType( SbxOBJECT
);
363 // if we scan something with point,
364 // the type must be SbxOBJECT
365 if( pDef
->GetType() != SbxOBJECT
&& pDef
->GetType() != SbxVARIANT
)
367 // defer error until runtime if in vba mode
368 if ( !pParser
->IsVBASupportOn() )
370 pParser
->Error( ERRCODE_BASIC_BAD_DECLARATION
, aSym
);
376 pNd
->aVar
.pNext
= ObjTerm( *pDef
).release();
380 pParser
->UnlockColumn();
384 // construction of an object term. A term of this kind is part
385 // of an expression that begins with an object variable.
387 std::unique_ptr
<SbiExprNode
> SbiExpression::ObjTerm( SbiSymDef
& rObj
)
390 SbiToken eTok
= pParser
->Next();
391 if( eTok
!= SYMBOL
&& !SbiTokenizer::IsKwd( eTok
) && !SbiTokenizer::IsExtra( eTok
) )
393 // #66745 Some operators can also be allowed
394 // as identifiers, important for StarOne
395 if( eTok
!= MOD
&& eTok
!= NOT
&& eTok
!= AND
&& eTok
!= OR
&&
396 eTok
!= XOR
&& eTok
!= EQV
&& eTok
!= IMP
&& eTok
!= IS
)
398 pParser
->Error( ERRCODE_BASIC_VAR_EXPECTED
);
407 OUString
aSym( pParser
->GetSym() );
408 SbxDataType eType
= pParser
->GetType();
410 SbiExprListVector
* pvMoreParLcl
= nullptr;
411 eTok
= pParser
->Peek();
413 if( DoParametersFollow( pParser
, eCurExpr
, eTok
) )
415 pPar
= SbiExprList::ParseParameters( pParser
, false/*bStandaloneExpression*/ );
416 bError
= bError
|| !pPar
->IsValid();
417 eTok
= pParser
->Peek();
419 // i109624 check for additional sets of parameters
420 while( eTok
== LPAREN
)
422 if( pvMoreParLcl
== nullptr )
424 pvMoreParLcl
= new SbiExprListVector
;
426 SbiExprListPtr pAddPar
= SbiExprList::ParseParameters( pParser
);
427 bError
= bError
|| !pPar
->IsValid();
428 pvMoreParLcl
->push_back( std::move(pAddPar
) );
429 eTok
= pParser
->Peek();
432 bool bObj
= ( ( eTok
== DOT
|| eTok
== EXCLAM
) && !pParser
->WhiteSpace() );
435 if( eType
== SbxVARIANT
)
441 // Name%. does really not work!
442 pParser
->Error( ERRCODE_BASIC_BAD_DECLARATION
, aSym
);
447 // an object's symbol pool is always PUBLIC
448 SbiSymPool
& rPool
= rObj
.GetPool();
449 rPool
.SetScope( SbPUBLIC
);
450 SbiSymDef
* pDef
= rPool
.Find( aSym
);
453 pDef
= AddSym( eTok
, rPool
, eCurExpr
, aSym
, eType
, pPar
.get() );
454 pDef
->SetType( eType
);
457 auto pNd
= std::make_unique
<SbiExprNode
>( *pDef
, eType
);
458 pNd
->aVar
.pPar
= pPar
.release();
459 pNd
->aVar
.pvMorePar
= pvMoreParLcl
;
462 if( pDef
->GetType() == SbxVARIANT
)
464 pDef
->SetType( SbxOBJECT
);
466 if( pDef
->GetType() != SbxOBJECT
)
468 pParser
->Error( ERRCODE_BASIC_BAD_DECLARATION
, aSym
);
473 pNd
->aVar
.pNext
= ObjTerm( *pDef
).release();
480 // an operand can be:
483 // structure elements
486 // bracketed expressions
488 std::unique_ptr
<SbiExprNode
> SbiExpression::Operand( bool bUsedForTypeOf
)
490 std::unique_ptr
<SbiExprNode
> pRes
;
493 switch( SbiToken eTok
= pParser
->Peek() )
497 // process something like "IF Not r Is Nothing Then .."
498 if( !bUsedForTypeOf
&& pParser
->IsVBASupportOn() && pParser
->Peek() == IS
)
500 eTok
= pParser
->Next();
501 pRes
= std::make_unique
<SbiExprNode
>( std::move(pRes
), eTok
, Like() );
505 pRes
= Term(); break;
511 pRes
= std::make_unique
<SbiExprNode
>( pParser
->GetDbl(), pParser
->GetType() );
515 pRes
= std::make_unique
<SbiExprNode
>( pParser
->GetSym() ); break;
518 if( nParenLevel
== 0 && m_eMode
== EXPRMODE_LPAREN_PENDING
&& pParser
->Peek() == RPAREN
)
520 m_eMode
= EXPRMODE_EMPTY_PAREN
;
521 pRes
= std::make_unique
<SbiExprNode
>(); // Dummy node
527 if( pParser
->Peek() != RPAREN
)
529 // If there was a LPARAM, it does not belong to the expression
530 if( nParenLevel
== 1 && m_eMode
== EXPRMODE_LPAREN_PENDING
)
532 m_eMode
= EXPRMODE_LPAREN_NOT_NEEDED
;
536 pParser
->Error( ERRCODE_BASIC_BAD_BRACKETS
);
542 if( nParenLevel
== 1 && m_eMode
== EXPRMODE_LPAREN_PENDING
)
544 SbiToken eTokAfterRParen
= pParser
->Peek();
545 if( eTokAfterRParen
== EQ
|| eTokAfterRParen
== LPAREN
|| eTokAfterRParen
== DOT
)
547 m_eMode
= EXPRMODE_ARRAY_OR_OBJECT
;
551 m_eMode
= EXPRMODE_STANDARD
;
558 // keywords here are OK at the moment!
559 if( SbiTokenizer::IsKwd( eTok
) )
566 pRes
= std::make_unique
<SbiExprNode
>( 1.0, SbxDOUBLE
);
567 pParser
->Error( ERRCODE_BASIC_UNEXPECTED
, eTok
);
574 std::unique_ptr
<SbiExprNode
> SbiExpression::Unary()
576 std::unique_ptr
<SbiExprNode
> pNd
;
577 SbiToken eTok
= pParser
->Peek();
583 pNd
= std::make_unique
<SbiExprNode
>( Unary(), eTok
, nullptr );
586 if( pParser
->IsVBASupportOn() )
593 pNd
= std::make_unique
<SbiExprNode
>( Unary(), eTok
, nullptr );
603 std::unique_ptr
<SbiExprNode
> pObjNode
= Operand( true/*bUsedForTypeOf*/ );
604 pParser
->TestToken( IS
);
605 SbiSymDef
* pTypeDef
= new SbiSymDef( OUString() );
606 pParser
->TypeDecl( *pTypeDef
, true );
607 pNd
= std::make_unique
<SbiExprNode
>( std::move(pObjNode
), pTypeDef
->GetTypeId() );
613 SbiSymDef
* pTypeDef
= new SbiSymDef( OUString() );
614 pParser
->TypeDecl( *pTypeDef
, true );
615 pNd
= std::make_unique
<SbiExprNode
>( pTypeDef
->GetTypeId() );
624 std::unique_ptr
<SbiExprNode
> SbiExpression::Exp()
626 std::unique_ptr
<SbiExprNode
> pNd
= Unary();
627 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
629 while( pParser
->Peek() == EXPON
)
631 SbiToken eTok
= pParser
->Next();
632 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, Unary() );
638 std::unique_ptr
<SbiExprNode
> SbiExpression::MulDiv()
640 std::unique_ptr
<SbiExprNode
> pNd
= Exp();
641 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
645 SbiToken eTok
= pParser
->Peek();
646 if( eTok
!= MUL
&& eTok
!= DIV
)
650 eTok
= pParser
->Next();
651 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, Exp() );
657 std::unique_ptr
<SbiExprNode
> SbiExpression::IntDiv()
659 std::unique_ptr
<SbiExprNode
> pNd
= MulDiv();
660 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
662 while( pParser
->Peek() == IDIV
)
664 SbiToken eTok
= pParser
->Next();
665 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, MulDiv() );
671 std::unique_ptr
<SbiExprNode
> SbiExpression::Mod()
673 std::unique_ptr
<SbiExprNode
> pNd
= IntDiv();
674 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
676 while( pParser
->Peek() == MOD
)
678 SbiToken eTok
= pParser
->Next();
679 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, IntDiv() );
685 std::unique_ptr
<SbiExprNode
> SbiExpression::AddSub()
687 std::unique_ptr
<SbiExprNode
> pNd
= Mod();
688 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
692 SbiToken eTok
= pParser
->Peek();
693 if( eTok
!= PLUS
&& eTok
!= MINUS
)
697 eTok
= pParser
->Next();
698 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, Mod() );
704 std::unique_ptr
<SbiExprNode
> SbiExpression::Cat()
706 std::unique_ptr
<SbiExprNode
> pNd
= AddSub();
707 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
711 SbiToken eTok
= pParser
->Peek();
716 eTok
= pParser
->Next();
717 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, AddSub() );
723 std::unique_ptr
<SbiExprNode
> SbiExpression::Comp()
725 std::unique_ptr
<SbiExprNode
> pNd
= Cat();
726 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
731 SbiToken eTok
= pParser
->Peek();
732 if( m_eMode
== EXPRMODE_ARRAY_OR_OBJECT
)
736 if( eTok
!= EQ
&& eTok
!= NE
&& eTok
!= LT
&&
737 eTok
!= GT
&& eTok
!= LE
&& eTok
!= GE
)
741 eTok
= pParser
->Next();
742 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, Cat() );
750 std::unique_ptr
<SbiExprNode
> SbiExpression::VBA_Not()
752 std::unique_ptr
<SbiExprNode
> pNd
;
754 SbiToken eTok
= pParser
->Peek();
758 pNd
= std::make_unique
<SbiExprNode
>( VBA_Not(), eTok
, nullptr );
767 std::unique_ptr
<SbiExprNode
> SbiExpression::Like()
769 std::unique_ptr
<SbiExprNode
> pNd
= pParser
->IsVBASupportOn() ? VBA_Not() : Comp();
770 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
773 while( pParser
->Peek() == LIKE
)
775 SbiToken eTok
= pParser
->Next();
776 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, Comp() );
779 // multiple operands in a row does not work
780 if( nCount
> 1 && !pParser
->IsVBASupportOn() )
782 pParser
->Error( ERRCODE_BASIC_SYNTAX
);
789 std::unique_ptr
<SbiExprNode
> SbiExpression::Boolean()
791 std::unique_ptr
<SbiExprNode
> pNd
= Like();
792 if( m_eMode
!= EXPRMODE_EMPTY_PAREN
)
796 SbiToken eTok
= pParser
->Peek();
797 if( (eTok
!= AND
) && (eTok
!= OR
) &&
798 (eTok
!= XOR
) && (eTok
!= EQV
) &&
799 (eTok
!= IMP
) && (eTok
!= IS
) )
803 eTok
= pParser
->Next();
804 pNd
= std::make_unique
<SbiExprNode
>( std::move(pNd
), eTok
, Like() );
810 SbiConstExpression::SbiConstExpression( SbiParser
* p
) : SbiExpression( p
)
812 if( pExpr
->IsConstant() )
814 eType
= pExpr
->GetType();
815 if( pExpr
->IsNumber() )
822 aVal
= pExpr
->aStrVal
;
827 // #40204 special treatment for sal_Bool-constants
828 bool bIsBool
= false;
829 if( pExpr
->eNodeType
== SbxVARVAL
)
831 SbiSymDef
* pVarDef
= pExpr
->GetVar();
833 bool bBoolVal
= false;
834 if( pVarDef
->GetName().equalsIgnoreAsciiCase( "true" ) )
839 else if( pVarDef
->GetName().equalsIgnoreAsciiCase( "false" ) )
840 //else if( pVarDef->GetName().ICompare( "false" ) == COMPARE_EQUAL )
848 pExpr
= std::make_unique
<SbiExprNode
>( (bBoolVal
? SbxTRUE
: SbxFALSE
), SbxINTEGER
);
849 eType
= pExpr
->GetType();
856 pParser
->Error( ERRCODE_BASIC_SYNTAX
);
863 short SbiConstExpression::GetShortValue()
865 if( eType
== SbxSTRING
)
867 SbxVariableRef refConv
= new SbxVariable
;
868 refConv
->PutString( aVal
);
869 return refConv
->GetInteger();
885 pParser
->Error( ERRCODE_BASIC_OUT_OF_RANGE
);
887 else if( n
< SbxMININT
)
890 pParser
->Error( ERRCODE_BASIC_OUT_OF_RANGE
);
893 return static_cast<short>(n
);
898 SbiExprList::SbiExprList( )
905 SbiExprList::~SbiExprList() {}
907 SbiExpression
* SbiExprList::Get( size_t n
)
909 return aData
[n
].get();
912 void SbiExprList::addExpression( std::unique_ptr
<SbiExpression
>&& pExpr
)
914 aData
.push_back(std::move(pExpr
));
917 // the parameter list is completely parsed
918 // "procedurename()" is OK
919 // it's a function without parameters then
920 // i. e. you give an array as procedure parameter
922 // #i79918/#i80532: bConst has never been set to true
923 // -> reused as bStandaloneExpression
924 //SbiParameters::SbiParameters( SbiParser* p, sal_Bool bConst, sal_Bool bPar) :
925 SbiExprListPtr
SbiExprList::ParseParameters( SbiParser
* pParser
, bool bStandaloneExpression
, bool bPar
)
927 auto pExprList
= std::make_unique
<SbiExprList
>();
933 SbiToken eTok
= pParser
->Peek();
935 bool bAssumeExprLParenMode
= false;
936 bool bAssumeArrayMode
= false;
939 if( bStandaloneExpression
)
941 bAssumeExprLParenMode
= true;
945 pExprList
->bBracket
= true;
947 eTok
= pParser
->Peek();
952 if( ( pExprList
->bBracket
&& eTok
== RPAREN
) || SbiTokenizer::IsEoln( eTok
) )
960 // read in parameter table and lay down in correct order!
961 while( !pExprList
->bError
)
963 std::unique_ptr
<SbiExpression
> pExpr
;
967 pExpr
= std::make_unique
<SbiExpression
>( pParser
, 0, SbxEMPTY
);
969 // named arguments: either .name= or name:=
977 eTok
= pParser
->Peek();
980 if( bAssumeExprLParenMode
)
982 pExpr
= std::make_unique
<SbiExpression
>( pParser
, SbSTDEXPR
, EXPRMODE_LPAREN_PENDING
);
983 bAssumeExprLParenMode
= false;
985 SbiExprMode eModeAfter
= pExpr
->m_eMode
;
986 if( eModeAfter
== EXPRMODE_LPAREN_NOT_NEEDED
)
988 pExprList
->bBracket
= true;
990 else if( eModeAfter
== EXPRMODE_ARRAY_OR_OBJECT
)
992 // Expression "looks" like an array assignment
993 // a(...)[(...)] = ? or a(...).b(...)
994 // RPAREN is already parsed
995 pExprList
->bBracket
= true;
996 bAssumeArrayMode
= true;
999 else if( eModeAfter
== EXPRMODE_EMPTY_PAREN
)
1001 pExprList
->bBracket
= true;
1007 pExpr
= std::make_unique
<SbiExpression
>( pParser
);
1009 if( bByVal
&& pExpr
->IsLvalue() )
1013 if( !bAssumeArrayMode
)
1016 if( pParser
->Peek() == ASSIGN
)
1019 // SbiExpression::Term() has made as string out of it
1020 aName
= pExpr
->GetString();
1022 pExpr
= std::make_unique
<SbiExpression
>( pParser
);
1024 pExpr
->GetName() = aName
;
1027 pExprList
->bError
= pExprList
->bError
|| !pExpr
->IsValid();
1028 pExprList
->aData
.push_back(std::move(pExpr
));
1029 if( bAssumeArrayMode
)
1034 eTok
= pParser
->Peek();
1037 if( ( pExprList
->bBracket
&& eTok
== RPAREN
) || SbiTokenizer::IsEoln( eTok
) )
1040 if (SbiTokenizer::IsEoln(eTok
) && pExprList
->bBracket
)
1042 // tdf#106529: only fail here in strict mode (i.e. when compiled from IDE), and
1043 // allow legacy code with missing closing parenthesis when started e.g. from
1044 // extensions and event handlers
1045 if (comphelper::IsContextFlagActive("BasicStrict"))
1047 pParser
->Error(ERRCODE_BASIC_EXPECTED
, RPAREN
);
1048 pExprList
->bError
= true;
1053 pParser
->Error( pExprList
->bBracket
? ERRCODE_BASIC_BAD_BRACKETS
: ERRCODE_BASIC_EXPECTED
, COMMA
);
1054 pExprList
->bError
= true;
1059 eTok
= pParser
->Peek();
1060 if( ( pExprList
->bBracket
&& eTok
== RPAREN
) || SbiTokenizer::IsEoln( eTok
) )
1067 if( eTok
== RPAREN
)
1071 if( !pExprList
->bBracket
)
1073 pParser
->Error( ERRCODE_BASIC_BAD_BRACKETS
);
1074 pExprList
->bError
= true;
1077 pExprList
->nDim
= pExprList
->GetSize();
1081 // A list of array dimensions is parsed.
1083 SbiExprListPtr
SbiExprList::ParseDimList( SbiParser
* pParser
)
1085 auto pExprList
= std::make_unique
<SbiExprList
>();
1087 if( pParser
->Next() != LPAREN
)
1089 pParser
->Error( ERRCODE_BASIC_EXPECTED
, LPAREN
);
1090 pExprList
->bError
= true; return pExprList
;
1093 if( pParser
->Peek() != RPAREN
)
1098 auto pExpr1
= std::make_unique
<SbiExpression
>( pParser
);
1099 eTok
= pParser
->Next();
1102 auto pExpr2
= std::make_unique
<SbiExpression
>( pParser
);
1103 pExpr1
->ConvertToIntConstIfPossible();
1104 pExpr2
->ConvertToIntConstIfPossible();
1105 eTok
= pParser
->Next();
1106 pExprList
->bError
= pExprList
->bError
|| !pExpr1
->IsValid() || !pExpr2
->IsValid();
1107 pExprList
->aData
.push_back(std::move(pExpr1
));
1108 pExprList
->aData
.push_back(std::move(pExpr2
));
1113 pExpr1
->ConvertToIntConstIfPossible();
1114 pExprList
->bError
= pExprList
->bError
|| !pExpr1
->IsValid();
1115 pExprList
->aData
.push_back(std::move(pExpr1
));
1118 if( eTok
== RPAREN
) break;
1121 pParser
->Error( ERRCODE_BASIC_BAD_BRACKETS
);
1127 else pParser
->Next();
1131 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */