LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/basic/source/comp - dim.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 294 682 43.1 %
Date: 2013-07-09 Functions: 9 19 47.4 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include <basic/sbx.hxx>
      21             : #include "sbcomp.hxx"
      22             : #include "sbunoobj.hxx"
      23             : 
      24             : 
      25             : SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
      26             : 
      27             : // Declaration of a variable
      28             : // If there are errors it will be parsed up to the comma or the newline.
      29             : // Return-value: a new instance, which were inserted and then deleted.
      30             : // Array-Indexex were returned as SbiDimList
      31             : 
      32        1064 : SbiSymDef* SbiParser::VarDecl( SbiDimList** ppDim, bool bStatic, bool bConst )
      33             : {
      34        1064 :     bool bWithEvents = false;
      35        1064 :     if( Peek() == WITHEVENTS )
      36             :     {
      37           0 :         Next();
      38           0 :         bWithEvents = true;
      39             :     }
      40        1064 :     if( !TestSymbol() ) return NULL;
      41        1064 :     SbxDataType t = eScanType;
      42        1064 :     SbiSymDef* pDef = bConst ? new SbiConstDef( aSym ) : new SbiSymDef( aSym );
      43        1064 :     SbiDimList* pDim = NULL;
      44             :     // Brackets?
      45        1064 :     if( Peek() == LPAREN )
      46             :     {
      47          44 :         pDim = new SbiDimList( this );
      48          44 :         if( !pDim->GetDims() )
      49          19 :             pDef->SetWithBrackets();
      50             :     }
      51        1064 :     pDef->SetType( t );
      52        1064 :     if( bStatic )
      53           0 :         pDef->SetStatic();
      54        1064 :     if( bWithEvents )
      55           0 :         pDef->SetWithEvents();
      56        1064 :     TypeDecl( *pDef );
      57        1064 :     if( !ppDim && pDim )
      58             :     {
      59           0 :         if(pDim->GetDims() )
      60           0 :             Error( SbERR_EXPECTED, "()" );
      61           0 :         delete pDim;
      62             :     }
      63        1064 :     else if( ppDim )
      64         857 :         *ppDim = pDim;
      65        1064 :     return pDef;
      66             : }
      67             : 
      68             : // Resolving of a AS-Type-Declaration
      69             : // The data type were inserted into the handed over variable
      70             : 
      71        1450 : void SbiParser::TypeDecl( SbiSymDef& rDef, bool bAsNewAlreadyParsed )
      72             : {
      73        1450 :     SbxDataType eType = rDef.GetType();
      74        1450 :     if( bAsNewAlreadyParsed || Peek() == AS )
      75             :     {
      76         958 :         short nSize = 0;
      77         958 :         if( !bAsNewAlreadyParsed )
      78         958 :             Next();
      79         958 :         rDef.SetDefinedAs();
      80         958 :         SbiToken eTok = Next();
      81         958 :         if( !bAsNewAlreadyParsed && eTok == NEW )
      82             :         {
      83          28 :             rDef.SetNew();
      84          28 :             eTok = Next();
      85             :         }
      86         958 :         switch( eTok )
      87             :         {
      88             :             case ANY:
      89           0 :                 if( rDef.IsNew() )
      90           0 :                     Error( SbERR_SYNTAX );
      91           0 :                 eType = SbxVARIANT; break;
      92             :             case TINTEGER:
      93             :             case TLONG:
      94             :             case TSINGLE:
      95             :             case TDOUBLE:
      96             :             case TCURRENCY:
      97             :             case TDATE:
      98             :             case TSTRING:
      99             :             case TOBJECT:
     100             :             case _ERROR_:
     101             :             case TBOOLEAN:
     102             :             case TVARIANT:
     103             :             case TBYTE:
     104         823 :                 if( rDef.IsNew() )
     105           0 :                     Error( SbERR_SYNTAX );
     106         823 :                 eType = (eTok==TBYTE) ? SbxBYTE : SbxDataType( eTok - TINTEGER + SbxINTEGER );
     107         823 :                 if( eType == SbxSTRING )
     108             :                 {
     109             :                     // STRING*n ?
     110         438 :                     if( Peek() == MUL )
     111             :                     {       // fixed size!
     112           0 :                         Next();
     113           0 :                         SbiConstExpression aSize( this );
     114           0 :                         nSize = aSize.GetShortValue();
     115           0 :                         if( nSize < 0 || (bVBASupportOn && nSize <= 0) )
     116           0 :                             Error( SbERR_OUT_OF_RANGE );
     117             :                         else
     118           0 :                             rDef.SetFixedStringLength( nSize );
     119             :                     }
     120             :                 }
     121         823 :                 break;
     122             :             case SYMBOL: // can only be a TYPE or a object class!
     123         121 :                 if( eScanType != SbxVARIANT )
     124           0 :                     Error( SbERR_SYNTAX );
     125             :                 else
     126             :                 {
     127         121 :                     OUString aCompleteName = aSym;
     128             : 
     129             :                     // #52709 DIM AS NEW for Uno with full-qualified name
     130         121 :                     if( Peek() == DOT )
     131             :                     {
     132          15 :                         OUString aDotStr( '.' );
     133          15 :                         while( Peek() == DOT )
     134             :                         {
     135          57 :                             aCompleteName += aDotStr;
     136          57 :                             Next();
     137          57 :                             SbiToken ePeekTok = Peek();
     138          57 :                             if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) )
     139             :                             {
     140          57 :                                 Next();
     141          57 :                                 aCompleteName += aSym;
     142             :                             }
     143             :                             else
     144             :                             {
     145           0 :                                 Next();
     146           0 :                                 Error( SbERR_UNEXPECTED, SYMBOL );
     147           0 :                                 break;
     148             :                             }
     149          15 :                         }
     150             :                     }
     151         106 :                     else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) || ( IsVBASupportOn() && VBAConstantHelper::instance().isVBAConstantType( aCompleteName ) ) )
     152             :                     {
     153           0 :                         eType = SbxLONG;
     154           0 :                         break;
     155             :                     }
     156             : 
     157             :                     // Take over in the string pool
     158         121 :                     rDef.SetTypeId( aGblStrings.Add( aCompleteName ) );
     159             : 
     160         121 :                     if( rDef.IsNew() && pProc == NULL )
     161           0 :                         aRequiredTypes.push_back( aCompleteName );
     162             :                 }
     163         121 :                 eType = SbxOBJECT;
     164         121 :                 break;
     165             :             case FIXSTRING: // new syntax for complex UNO types
     166          14 :                 rDef.SetTypeId( aGblStrings.Add( aSym ) );
     167          14 :                 eType = SbxOBJECT;
     168          14 :                 break;
     169             :             default:
     170           0 :                 Error( SbERR_UNEXPECTED, eTok );
     171           0 :                 Next();
     172             :         }
     173             :         // The variable could have been declared with a suffix
     174         958 :         if( rDef.GetType() != SbxVARIANT )
     175             :         {
     176         135 :             if( rDef.GetType() != eType )
     177           0 :                 Error( SbERR_VAR_DEFINED, rDef.GetName() );
     178         135 :             else if( eType == SbxSTRING && rDef.GetLen() != nSize )
     179           0 :                 Error( SbERR_VAR_DEFINED, rDef.GetName() );
     180             :         }
     181         958 :         rDef.SetType( eType );
     182         958 :         rDef.SetLen( nSize );
     183             :     }
     184        1450 : }
     185             : 
     186             : // Here variables, arrays and structures were definied.
     187             : // DIM/PRIVATE/PUBLIC/GLOBAL
     188             : 
     189         788 : void SbiParser::Dim()
     190             : {
     191         788 :     DefVar( _DIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : false );
     192         788 : }
     193             : 
     194         789 : void SbiParser::DefVar( SbiOpcode eOp, bool bStatic )
     195             : {
     196         789 :     SbiSymPool* pOldPool = pPool;
     197         789 :     bool bSwitchPool = false;
     198         789 :     bool bPersistantGlobal = false;
     199         789 :     SbiToken eFirstTok = eCurTok;
     200         789 :     if( pProc && ( eCurTok == GLOBAL || eCurTok == PUBLIC || eCurTok == PRIVATE ) )
     201           0 :         Error( SbERR_NOT_IN_SUBR, eCurTok );
     202         789 :     if( eCurTok == PUBLIC || eCurTok == GLOBAL )
     203             :     {
     204          86 :         bSwitchPool = true;     // at the right moment switch to the global pool
     205          86 :         if( eCurTok == GLOBAL )
     206          64 :             bPersistantGlobal = true;
     207             :     }
     208             :     // behavior in VBA is that a module scope variable's lifetime is
     209             :     // tied to the document. e.g. a module scope variable is global
     210         789 :        if(  GetBasic()->IsDocBasic() && bVBASupportOn && !pProc )
     211         145 :         bPersistantGlobal = true;
     212             :     // PRIVATE is a synonymous for DIM
     213             :     // _CONST_?
     214         789 :     bool bConst = false;
     215         789 :     if( eCurTok == _CONST_ )
     216          30 :         bConst = true;
     217         759 :     else if( Peek() == _CONST_ )
     218          44 :         Next(), bConst = true;
     219             : 
     220             :     // #110004 It can also be a sub/function
     221        1476 :     if( !bConst && (eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ||
     222        1374 :                     eCurTok == STATIC || eCurTok == ENUM || eCurTok == DECLARE || eCurTok == TYPE) )
     223             :     {
     224             :         // Next token is read here, because !bConst
     225          28 :         bool bPrivate = ( eFirstTok == PRIVATE );
     226             : 
     227          28 :         if( eCurTok == STATIC )
     228             :         {
     229           0 :             Next();
     230           0 :             DefStatic( bPrivate );
     231             :         }
     232          28 :         else if( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY )
     233             :         {
     234             :             // End global chain if necessary (not done in
     235             :             // SbiParser::Parse() under these conditions
     236          28 :             if( bNewGblDefs && nGblChain == 0 )
     237             :             {
     238           0 :                 nGblChain = aGen.Gen( _JUMP, 0 );
     239           0 :                 bNewGblDefs = false;
     240             :             }
     241          28 :             Next();
     242          28 :             DefProc( false, bPrivate );
     243          56 :             return;
     244             :         }
     245           0 :         else if( eCurTok == ENUM )
     246             :         {
     247           0 :             Next();
     248           0 :             DefEnum( bPrivate );
     249           0 :             return;
     250             :         }
     251           0 :         else if( eCurTok == DECLARE )
     252             :         {
     253           0 :             Next();
     254           0 :             DefDeclare( bPrivate );
     255           0 :             return;
     256             :         }
     257             :         // #i109049
     258           0 :         else if( eCurTok == TYPE )
     259             :         {
     260           0 :             Next();
     261           0 :             DefType( bPrivate );
     262           0 :             return;
     263             :         }
     264             :     }
     265             : 
     266             : #ifdef SHARED
     267             : #define tmpSHARED
     268             : #undef SHARED
     269             : #endif
     270             :     // SHARED were ignored
     271         761 :     if( Peek() == SHARED ) Next();
     272             : #ifdef tmpSHARED
     273             : #define SHARED
     274             : #undef tmpSHARED
     275             : #endif
     276             :     // PRESERVE only at REDIM
     277         761 :     if( Peek() == PRESERVE )
     278             :     {
     279           0 :         Next();
     280           0 :         if( eOp == _REDIM )
     281           0 :             eOp = _REDIMP;
     282             :         else
     283           0 :             Error( SbERR_UNEXPECTED, eCurTok );
     284             :     }
     285             :     SbiSymDef* pDef;
     286             :     SbiDimList* pDim;
     287             : 
     288             :     // #40689, Statics -> Modul-Initialising, skip in Sub
     289         761 :     sal_uInt32 nEndOfStaticLbl = 0;
     290         761 :     if( !bVBASupportOn && bStatic )
     291             :     {
     292           0 :         nEndOfStaticLbl = aGen.Gen( _JUMP, 0 );
     293           0 :         aGen.Statement();   // catch up on static here
     294             :     }
     295             : 
     296         761 :     bool bDefined = false;
     297        1618 :     while( ( pDef = VarDecl( &pDim, bStatic, bConst ) ) != NULL )
     298             :     {
     299         857 :         EnableErrors();
     300             :         // search variable:
     301         857 :         if( bSwitchPool )
     302         139 :             pPool = &aGlobals;
     303         857 :         SbiSymDef* pOld = pPool->Find( pDef->GetName() );
     304             :         // search also in the Runtime-Library
     305         857 :         bool bRtlSym = false;
     306         857 :         if( !pOld )
     307             :         {
     308         852 :             pOld = CheckRTLForSym( pDef->GetName(), SbxVARIANT );
     309         852 :             if( pOld )
     310           1 :                 bRtlSym = true;
     311             :         }
     312         857 :         if( pOld && !(eOp == _REDIM || eOp == _REDIMP) )
     313             :         {
     314           5 :             if( pDef->GetScope() == SbLOCAL && pOld->GetScope() != SbLOCAL )
     315           5 :                 pOld = NULL;
     316             :         }
     317         857 :         if( pOld )
     318             :         {
     319           1 :             bDefined = true;
     320             :             // always an error at a RTL-S
     321           1 :             if( !bRtlSym && (eOp == _REDIM || eOp == _REDIMP) )
     322             :             {
     323             :                 // compare the attributes at a REDIM
     324             :                 SbxDataType eDefType;
     325           1 :                 bool bError_ = false;
     326           1 :                 if( pOld->IsStatic() )
     327             :                 {
     328           0 :                     bError_ = true;
     329             :                 }
     330           1 :                 else if( pOld->GetType() != ( eDefType = pDef->GetType() ) )
     331             :                 {
     332           0 :                     if( !( eDefType == SbxVARIANT && !pDef->IsDefinedAs() ) )
     333           0 :                         bError_ = true;
     334             :                 }
     335           1 :                 if( bError_ )
     336           0 :                     Error( SbERR_VAR_DEFINED, pDef->GetName() );
     337             :             }
     338             :             else
     339           0 :                 Error( SbERR_VAR_DEFINED, pDef->GetName() );
     340           1 :             delete pDef; pDef = pOld;
     341             :         }
     342             :         else
     343         856 :             pPool->Add( pDef );
     344             : 
     345             :         // #36374: Create the variable in front of the distinction IsNew()
     346             :         // Otherwise error at Dim Identifier As New Type and option explicit
     347        2570 :         if( !bDefined && !(eOp == _REDIM || eOp == _REDIMP)
     348        1713 :                       && ( !bConst || pDef->GetScope() == SbGLOBAL ) )
     349             :         {
     350             :             // Declare variable or global constant
     351             :             SbiOpcode eOp2;
     352         820 :             switch ( pDef->GetScope() )
     353             :             {
     354         139 :                 case SbGLOBAL:  eOp2 = bPersistantGlobal ? _GLOBAL_P : _GLOBAL;
     355         139 :                                 goto global;
     356         121 :                 case SbPUBLIC:  eOp2 = bPersistantGlobal ? _PUBLIC_P : _PUBLIC;
     357             :                                 // #40689, no own Opcode anymore
     358         121 :                                 if( bVBASupportOn && bStatic )
     359             :                                 {
     360           0 :                                     eOp2 = _STATIC;
     361           0 :                                     break;
     362             :                                 }
     363         260 :                 global:         aGen.BackChain( nGblChain );
     364         260 :                                 nGblChain = 0;
     365         260 :                                 bGblDefs = bNewGblDefs = true;
     366         260 :                                 break;
     367         560 :                 default:        eOp2 = _LOCAL;
     368             :             }
     369         820 :             sal_uInt32 nOpnd2 = sal::static_int_cast< sal_uInt16 >( pDef->GetType() );
     370         820 :             if( pDef->IsWithEvents() )
     371           0 :                 nOpnd2 |= SBX_TYPE_WITH_EVENTS_FLAG;
     372             : 
     373         820 :             if( bCompatible && pDef->IsNew() )
     374           1 :                 nOpnd2 |= SBX_TYPE_DIM_AS_NEW_FLAG;
     375             : 
     376         820 :             short nFixedStringLength = pDef->GetFixedStringLength();
     377         820 :             if( nFixedStringLength >= 0 )
     378           0 :                 nOpnd2 |= (SBX_FIXED_LEN_STRING_FLAG + (sal_uInt32(nFixedStringLength) << 17));     // len = all bits above 0x10000
     379             : 
     380         820 :             if( pDim != NULL && pDim->GetDims() > 0 )
     381          24 :                 nOpnd2 |= SBX_TYPE_VAR_TO_DIM_FLAG;
     382             : 
     383         820 :             aGen.Gen( eOp2, pDef->GetId(), nOpnd2 );
     384             :         }
     385             : 
     386             :         // Initialising for self-defined daty types
     387             :         // and per NEW created variable
     388        1714 :         if( pDef->GetType() == SbxOBJECT
     389         857 :          && pDef->GetTypeId() )
     390             :         {
     391         130 :             if( !bCompatible && !pDef->IsNew() )
     392             :             {
     393           0 :                 OUString aTypeName( aGblStrings.Find( pDef->GetTypeId() ) );
     394           0 :                 if( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) == NULL )
     395             :                 {
     396           0 :                     Error( SbERR_UNDEF_TYPE, aTypeName );
     397           0 :                 }
     398             :             }
     399             : 
     400         130 :             if( bConst )
     401             :             {
     402           0 :                 Error( SbERR_SYNTAX );
     403             :             }
     404             : 
     405         130 :             if( pDim )
     406             :             {
     407           4 :                 if( eOp == _REDIMP )
     408             :                 {
     409           0 :                     SbiExpression aExpr( this, *pDef, NULL );
     410           0 :                     aExpr.Gen();
     411           0 :                     aGen.Gen( _REDIMP_ERASE );
     412             : 
     413           0 :                     pDef->SetDims( pDim->GetDims() );
     414           0 :                     SbiExpression aExpr2( this, *pDef, pDim );
     415           0 :                     aExpr2.Gen();
     416           0 :                     aGen.Gen( _DCREATE_REDIMP, pDef->GetId(), pDef->GetTypeId() );
     417             :                 }
     418             :                 else
     419             :                 {
     420           4 :                     pDef->SetDims( pDim->GetDims() );
     421           4 :                     SbiExpression aExpr( this, *pDef, pDim );
     422           4 :                     aExpr.Gen();
     423           4 :                     aGen.Gen( _DCREATE, pDef->GetId(), pDef->GetTypeId() );
     424             :                 }
     425             :             }
     426             :             else
     427             :             {
     428         126 :                 SbiExpression aExpr( this, *pDef );
     429         126 :                 aExpr.Gen();
     430         126 :                 SbiOpcode eOp_ = pDef->IsNew() ? _CREATE : _TCREATE;
     431         126 :                 aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() );
     432         126 :                 if ( bVBASupportOn )
     433         103 :                     aGen.Gen( _VBASET );
     434             :                 else
     435          23 :                     aGen.Gen( _SET );
     436             :             }
     437             :         }
     438             :         else
     439             :         {
     440         727 :             if( bConst )
     441             :             {
     442             :                 // Definition of the constants
     443         125 :                 if( pDim )
     444             :                 {
     445           0 :                     Error( SbERR_SYNTAX );
     446           0 :                     delete pDim;
     447             :                 }
     448         125 :                 SbiExpression aVar( this, *pDef );
     449         125 :                 if( !TestToken( EQ ) )
     450           0 :                     goto MyBreak;   // (see below)
     451         250 :                 SbiConstExpression aExpr( this );
     452         125 :                 if( !bDefined && aExpr.IsValid() )
     453             :                 {
     454         125 :                     if( pDef->GetScope() == SbGLOBAL )
     455             :                     {
     456             :                         // Create code only for the global constant!
     457          89 :                         aVar.Gen();
     458          89 :                         aExpr.Gen();
     459          89 :                         aGen.Gen( _PUTC );
     460             :                     }
     461         125 :                     SbiConstDef* pConst = pDef->GetConstDef();
     462         125 :                     if( aExpr.GetType() == SbxSTRING )
     463          64 :                         pConst->Set( aExpr.GetString() );
     464             :                     else
     465          61 :                         pConst->Set( aExpr.GetValue(), aExpr.GetType() );
     466         125 :                 }
     467             :             }
     468         602 :             else if( pDim )
     469             :             {
     470             :                 // Dimension the variable
     471             :                 // Delete the var at REDIM beforehand
     472          40 :                 if( eOp == _REDIM )
     473             :                 {
     474           1 :                     SbiExpression aExpr( this, *pDef, NULL );
     475           1 :                     aExpr.Gen();
     476           1 :                     if ( bVBASupportOn )
     477             :                         // delete the array but
     478             :                         // clear the variable ( this
     479             :                         // allows the processing of
     480             :                         // the param to happen as normal without errors ( ordinary ERASE just clears the array )
     481           1 :                         aGen.Gen( _ERASE_CLEAR );
     482             :                     else
     483           0 :                         aGen.Gen( _ERASE );
     484             :                 }
     485          39 :                 else if( eOp == _REDIMP )
     486             :                 {
     487           0 :                     SbiExpression aExpr( this, *pDef, NULL );
     488           0 :                     aExpr.Gen();
     489           0 :                     aGen.Gen( _REDIMP_ERASE );
     490             :                 }
     491          40 :                 pDef->SetDims( pDim->GetDims() );
     492          40 :                 if( bPersistantGlobal )
     493           2 :                     pDef->SetGlobal( sal_True );
     494          40 :                 SbiExpression aExpr( this, *pDef, pDim );
     495          40 :                 aExpr.Gen();
     496          40 :                 pDef->SetGlobal( sal_False );
     497          40 :                 aGen.Gen( (eOp == _STATIC) ? _DIM : eOp );
     498             :             }
     499             :         }
     500         857 :         if( !TestComma() )
     501         761 :             goto MyBreak;
     502             : 
     503             :         // Implementation of bSwitchPool (see above): pPool must not be set to &aGlobals
     504             :         // at the VarDecl-Call.
     505             :         // Apart from that the behavior should be absolutely identical,
     506             :         // i.e., pPool had to be reset always at the end of the loop.
     507             :         // also at a break
     508          96 :         pPool = pOldPool;
     509          96 :         continue;       // Skip MyBreak
     510             :     MyBreak:
     511         761 :         pPool = pOldPool;
     512         761 :         break;
     513             :     }
     514             : 
     515             :     // #40689, finalize the jump over statics declarations
     516         761 :     if( !bVBASupportOn && bStatic )
     517             :     {
     518             :         // maintain the global chain
     519           0 :         nGblChain = aGen.Gen( _JUMP, 0 );
     520           0 :         bGblDefs = bNewGblDefs = true;
     521             : 
     522             :         // Register for Sub a jump to the end of statics
     523           0 :         aGen.BackChain( nEndOfStaticLbl );
     524             :     }
     525             : 
     526             : }
     527             : 
     528             : // Here were Arrays redimensioned.
     529             : 
     530           1 : void SbiParser::ReDim()
     531             : {
     532           1 :     DefVar( _REDIM, (  pProc && bVBASupportOn ) ? pProc->IsStatic() : false );
     533           1 : }
     534             : 
     535             : // ERASE array, ...
     536             : 
     537           0 : void SbiParser::Erase()
     538             : {
     539           0 :     while( !bAbort )
     540             :     {
     541           0 :         SbiExpression aExpr( this, SbLVALUE );
     542           0 :         aExpr.Gen();
     543           0 :         aGen.Gen( _ERASE );
     544           0 :         if( !TestComma() ) break;
     545           0 :     }
     546           0 : }
     547             : 
     548             : // Declaration of a data type
     549             : 
     550           0 : void SbiParser::Type()
     551             : {
     552           0 :     DefType( false );
     553           0 : }
     554             : 
     555           0 : void SbiParser::DefType( bool bPrivate )
     556             : {
     557             :     // TODO: Use bPrivate
     558             :     (void)bPrivate;
     559             : 
     560             :     // Read the new Token lesen. It had to be a symbol
     561           0 :     if (!TestSymbol())
     562           0 :         return;
     563             : 
     564           0 :     if (rTypeArray->Find(aSym,SbxCLASS_OBJECT))
     565             :     {
     566           0 :         Error( SbERR_VAR_DEFINED, aSym );
     567           0 :         return;
     568             :     }
     569             : 
     570           0 :     SbxObject *pType = new SbxObject(aSym);
     571             : 
     572             :     SbiSymDef* pElem;
     573           0 :     SbiDimList* pDim = NULL;
     574           0 :     bool bDone = false;
     575             : 
     576           0 :     while( !bDone && !IsEof() )
     577             :     {
     578           0 :         switch( Peek() )
     579             :         {
     580             :             case ENDTYPE :
     581           0 :                 pElem = NULL;
     582           0 :                 bDone = true;
     583           0 :                 Next();
     584           0 :             break;
     585             : 
     586             :             case EOLN :
     587             :             case REM :
     588           0 :                 pElem = NULL;
     589           0 :                 Next();
     590           0 :             break;
     591             : 
     592             :             default:
     593           0 :                 pElem = VarDecl(&pDim, false, false);
     594           0 :                 if( !pElem )
     595           0 :                     bDone = true;   // Error occurred
     596             :         }
     597           0 :         if( pElem )
     598             :         {
     599           0 :             SbxArray *pTypeMembers = pType->GetProperties();
     600           0 :             OUString aElemName = pElem->GetName();
     601           0 :             if( pTypeMembers->Find( aElemName, SbxCLASS_DONTCARE) )
     602             :             {
     603           0 :                 Error (SbERR_VAR_DEFINED);
     604             :             }
     605             :             else
     606             :             {
     607           0 :                 SbxDataType eElemType = pElem->GetType();
     608           0 :                 SbxProperty *pTypeElem = new SbxProperty( aElemName, eElemType );
     609           0 :                 if( pDim )
     610             :                 {
     611           0 :                     SbxDimArray* pArray = new SbxDimArray( pElem->GetType() );
     612           0 :                     if ( pDim->GetSize() )
     613             :                     {
     614             :                         // Dimension the target array
     615             : 
     616           0 :                         for ( short i=0; i<pDim->GetSize();++i )
     617             :                         {
     618           0 :                             sal_Int32 lb = nBase;
     619           0 :                             SbiExprNode* pNode =  pDim->Get(i)->GetExprNode();
     620           0 :                             sal_Int32 ub = pNode->GetNumber();
     621           0 :                             if ( !pDim->Get( i )->IsBased() ) // each dim is low/up
     622             :                             {
     623           0 :                                 if (  ++i >= pDim->GetSize() ) // trouble
     624           0 :                                     StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
     625           0 :                                 pNode =  pDim->Get(i)->GetExprNode();
     626           0 :                                 lb = ub;
     627           0 :                                 ub = pNode->GetNumber();
     628             :                             }
     629           0 :                             else if ( !bCompatible )
     630           0 :                                 ub += nBase;
     631           0 :                             pArray->AddDim32( lb, ub );
     632             :                         }
     633           0 :                         pArray->setHasFixedSize( true );
     634             :                     }
     635             :                     else
     636           0 :                         pArray->unoAddDim( 0, -1 ); // variant array
     637           0 :                     sal_uInt16 nSavFlags = pTypeElem->GetFlags();
     638             :                     // need to reset the FIXED flag
     639             :                     // when calling PutObject ( because the type will not match Object )
     640           0 :                     pTypeElem->ResetFlag( SBX_FIXED );
     641           0 :                     pTypeElem->PutObject( pArray );
     642           0 :                     pTypeElem->SetFlags( nSavFlags );
     643             :                 }
     644             :                 // Nested user type?
     645           0 :                 if( eElemType == SbxOBJECT )
     646             :                 {
     647           0 :                     sal_uInt16 nElemTypeId = pElem->GetTypeId();
     648           0 :                     if( nElemTypeId != 0 )
     649             :                     {
     650           0 :                         OUString aTypeName( aGblStrings.Find( nElemTypeId ) );
     651           0 :                         SbxObject* pTypeObj = static_cast< SbxObject* >( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) );
     652           0 :                         if( pTypeObj != NULL )
     653             :                         {
     654           0 :                             SbxObject* pCloneObj = cloneTypeObjectImpl( *pTypeObj );
     655           0 :                             pTypeElem->PutObject( pCloneObj );
     656           0 :                         }
     657             :                     }
     658             :                 }
     659           0 :                 pTypeMembers->Insert( pTypeElem, pTypeMembers->Count() );
     660             :             }
     661           0 :             delete pDim, pDim = NULL;
     662           0 :             delete pElem;
     663             :         }
     664             :     }
     665             : 
     666           0 :     pType->Remove( OUString("Name"), SbxCLASS_DONTCARE );
     667           0 :     pType->Remove( OUString("Parent"), SbxCLASS_DONTCARE );
     668             : 
     669           0 :     rTypeArray->Insert (pType,rTypeArray->Count());
     670             : }
     671             : 
     672             : 
     673             : // Declaration of Enum type
     674             : 
     675           0 : void SbiParser::Enum()
     676             : {
     677           0 :     DefEnum( false );
     678           0 : }
     679             : 
     680           0 : void SbiParser::DefEnum( bool bPrivate )
     681             : {
     682             :     // Read a the new Token. It had to be a symbol
     683           0 :     if (!TestSymbol())
     684           0 :         return;
     685             : 
     686           0 :     OUString aEnumName = aSym;
     687           0 :     if( rEnumArray->Find(aEnumName,SbxCLASS_OBJECT) )
     688             :     {
     689           0 :         Error( SbERR_VAR_DEFINED, aSym );
     690           0 :         return;
     691             :     }
     692             : 
     693           0 :     SbxObject *pEnum = new SbxObject( aEnumName );
     694           0 :     if( bPrivate )
     695             :     {
     696           0 :         pEnum->SetFlag( SBX_PRIVATE );
     697             :     }
     698             :     SbiSymDef* pElem;
     699             :     SbiDimList* pDim;
     700           0 :     bool bDone = false;
     701             : 
     702             :     // Starting with -1 to make first default value 0 after ++
     703           0 :     sal_Int32 nCurrentEnumValue = -1;
     704           0 :     while( !bDone && !IsEof() )
     705             :     {
     706           0 :         switch( Peek() )
     707             :         {
     708             :             case ENDENUM :
     709           0 :                 pElem = NULL;
     710           0 :                 bDone = true;
     711           0 :                 Next();
     712           0 :             break;
     713             : 
     714             :             case EOLN :
     715             :             case REM :
     716           0 :                 pElem = NULL;
     717           0 :                 Next();
     718           0 :             break;
     719             : 
     720             :             default:
     721             :             {
     722             :                 // TODO: Check existing!
     723           0 :                 bool bDefined = false;
     724             : 
     725           0 :                 pDim = NULL;
     726           0 :                 pElem = VarDecl( &pDim, false, true );
     727           0 :                 if( !pElem )
     728             :                 {
     729           0 :                     bDone = true;   // Error occurred
     730           0 :                     break;
     731             :                 }
     732           0 :                 else if( pDim )
     733             :                 {
     734           0 :                     delete pDim;
     735           0 :                     Error( SbERR_SYNTAX );
     736           0 :                     bDone = true;   // Error occurred
     737           0 :                     break;
     738             :                 }
     739             : 
     740           0 :                 SbiExpression aVar( this, *pElem );
     741           0 :                 if( Peek() == EQ )
     742             :                 {
     743           0 :                     Next();
     744             : 
     745           0 :                     SbiConstExpression aExpr( this );
     746           0 :                     if( !bDefined && aExpr.IsValid() )
     747             :                     {
     748           0 :                         SbxVariableRef xConvertVar = new SbxVariable();
     749           0 :                         if( aExpr.GetType() == SbxSTRING )
     750           0 :                             xConvertVar->PutString( aExpr.GetString() );
     751             :                         else
     752           0 :                             xConvertVar->PutDouble( aExpr.GetValue() );
     753             : 
     754           0 :                         nCurrentEnumValue = xConvertVar->GetLong();
     755           0 :                     }
     756             :                 }
     757             :                 else
     758           0 :                     nCurrentEnumValue++;
     759             : 
     760           0 :                 SbiSymPool* pPoolToUse = bPrivate ? pPool : &aGlobals;
     761             : 
     762           0 :                 SbiSymDef* pOld = pPoolToUse->Find( pElem->GetName() );
     763           0 :                 if( pOld )
     764             :                 {
     765           0 :                     Error( SbERR_VAR_DEFINED, pElem->GetName() );
     766           0 :                     bDone = true;   // Error occurred
     767           0 :                     break;
     768             :                 }
     769             : 
     770           0 :                 pPool->Add( pElem );
     771             : 
     772           0 :                 if( !bPrivate )
     773             :                 {
     774           0 :                     SbiOpcode eOp = _GLOBAL;
     775           0 :                     aGen.BackChain( nGblChain );
     776           0 :                     nGblChain = 0;
     777           0 :                     bGblDefs = bNewGblDefs = true;
     778             :                     aGen.Gen(
     779           0 :                         eOp, pElem->GetId(),
     780           0 :                         sal::static_int_cast< sal_uInt16 >( pElem->GetType() ) );
     781             : 
     782           0 :                     aVar.Gen();
     783           0 :                     sal_uInt16 nStringId = aGen.GetParser()->aGblStrings.Add( nCurrentEnumValue, SbxLONG );
     784           0 :                     aGen.Gen( _NUMBER, nStringId );
     785           0 :                     aGen.Gen( _PUTC );
     786             :                 }
     787             : 
     788           0 :                 SbiConstDef* pConst = pElem->GetConstDef();
     789           0 :                 pConst->Set( nCurrentEnumValue, SbxLONG );
     790             :             }
     791             :         }
     792           0 :         if( pElem )
     793             :         {
     794           0 :             SbxArray *pEnumMembers = pEnum->GetProperties();
     795           0 :             SbxProperty *pEnumElem = new SbxProperty( pElem->GetName(), SbxLONG );
     796           0 :             pEnumElem->PutLong( nCurrentEnumValue );
     797           0 :             pEnumElem->ResetFlag( SBX_WRITE );
     798           0 :             pEnumElem->SetFlag( SBX_CONST );
     799           0 :             pEnumMembers->Insert( pEnumElem, pEnumMembers->Count() );
     800             :         }
     801             :     }
     802             : 
     803           0 :     pEnum->Remove( OUString("Name"), SbxCLASS_DONTCARE );
     804           0 :     pEnum->Remove( OUString("Parent"), SbxCLASS_DONTCARE );
     805             : 
     806           0 :     rEnumArray->Insert( pEnum, rEnumArray->Count() );
     807             : }
     808             : 
     809             : 
     810             : // Procedure-Declaration
     811             : // the first Token is already read in (SUB/FUNCTION)
     812             : // xxx Name [LIB "name"[ALIAS "name"]][(Parameter)][AS TYPE]
     813             : 
     814         386 : SbiProcDef* SbiParser::ProcDecl( bool bDecl )
     815             : {
     816         386 :     bool bFunc = ( eCurTok == FUNCTION );
     817         386 :     bool bProp = ( eCurTok == GET || eCurTok == SET || eCurTok == LET );
     818         386 :     if( !TestSymbol() ) return NULL;
     819         386 :     OUString aName( aSym );
     820         386 :     SbxDataType eType = eScanType;
     821         386 :     SbiProcDef* pDef = new SbiProcDef( this, aName, true );
     822         386 :     pDef->SetType( eType );
     823         386 :     if( Peek() == _CDECL_ )
     824             :     {
     825           0 :         Next(); pDef->SetCdecl();
     826             :     }
     827         386 :     if( Peek() == LIB )
     828             :     {
     829           0 :         Next();
     830           0 :         if( Next() == FIXSTRING )
     831             :         {
     832           0 :             pDef->GetLib() = aSym;
     833             :         }
     834             :         else
     835             :         {
     836           0 :             Error( SbERR_SYNTAX );
     837             :         }
     838             :     }
     839         386 :     if( Peek() == ALIAS )
     840             :     {
     841           0 :         Next();
     842           0 :         if( Next() == FIXSTRING )
     843             :         {
     844           0 :             pDef->GetAlias() = aSym;
     845             :         }
     846             :         else
     847             :         {
     848           0 :             Error( SbERR_SYNTAX );
     849             :         }
     850             :     }
     851         386 :     if( !bDecl )
     852             :     {
     853             :         // CDECL, LIB and ALIAS are invalid
     854         386 :         if( !pDef->GetLib().isEmpty() )
     855             :         {
     856           0 :             Error( SbERR_UNEXPECTED, LIB );
     857             :         }
     858         386 :         if( !pDef->GetAlias().isEmpty() )
     859             :         {
     860           0 :             Error( SbERR_UNEXPECTED, ALIAS );
     861             :         }
     862         386 :         if( pDef->IsCdecl() )
     863             :         {
     864           0 :             Error( SbERR_UNEXPECTED, _CDECL_ );
     865             :         }
     866         386 :         pDef->SetCdecl( false );
     867         386 :         pDef->GetLib() = "";
     868         386 :         pDef->GetAlias() = "";
     869             :     }
     870           0 :     else if( pDef->GetLib().isEmpty() )
     871             :     {
     872             :         // ALIAS and CDECL only together with LIB
     873           0 :         if( !pDef->GetAlias().isEmpty() )
     874             :         {
     875           0 :             Error( SbERR_UNEXPECTED, ALIAS );
     876             :         }
     877           0 :         if( pDef->IsCdecl() )
     878             :         {
     879           0 :             Error( SbERR_UNEXPECTED, _CDECL_ );
     880             :         }
     881           0 :         pDef->SetCdecl( false );
     882           0 :         pDef->GetAlias() = "";
     883             :     }
     884             :     // Brackets?
     885         386 :     if( Peek() == LPAREN )
     886             :     {
     887         344 :         Next();
     888         344 :         if( Peek() == RPAREN )
     889             :         {
     890         252 :             Next();
     891             :         }
     892             :         else
     893             :         {
     894             :             for(;;)
     895             :             {
     896         207 :                 bool bByVal = false;
     897         207 :                 bool bOptional = false;
     898         207 :                 bool bParamArray = false;
     899         458 :                 while( Peek() == BYVAL || Peek() == BYREF || Peek() == _OPTIONAL_ )
     900             :                 {
     901          44 :                     if( Peek() == BYVAL )
     902             :                     {
     903           4 :                         bByVal = true;
     904             :                     }
     905          40 :                     else if ( Peek() == BYREF )
     906             :                     {
     907           0 :                         bByVal = false;
     908             :                     }
     909          40 :                     else if ( Peek() == _OPTIONAL_ )
     910             :                     {
     911          40 :                         bOptional = true;
     912             :                     }
     913          44 :                     Next();
     914             :                 }
     915         207 :                 if( bCompatible && Peek() == PARAMARRAY )
     916             :                 {
     917           0 :                     if( bByVal || bOptional )
     918             :                     {
     919           0 :                         Error( SbERR_UNEXPECTED, PARAMARRAY );
     920             :                     }
     921           0 :                     Next();
     922           0 :                     bParamArray = true;
     923             :                 }
     924         207 :                 SbiSymDef* pPar = VarDecl( NULL, false, false );
     925         207 :                 if( !pPar )
     926             :                 {
     927           0 :                     break;
     928             :                 }
     929         207 :                 if( bByVal )
     930             :                 {
     931           4 :                     pPar->SetByVal();
     932             :                 }
     933         207 :                 if( bOptional )
     934             :                 {
     935          40 :                     pPar->SetOptional();
     936             :                 }
     937         207 :                 if( bParamArray )
     938             :                 {
     939           0 :                     pPar->SetParamArray();
     940             :                 }
     941         207 :                 pDef->GetParams().Add( pPar );
     942         207 :                 SbiToken eTok = Next();
     943         207 :                 if( eTok != COMMA && eTok != RPAREN )
     944             :                 {
     945           0 :                     bool bError2 = true;
     946           0 :                     if( bOptional && bCompatible && eTok == EQ )
     947             :                     {
     948           0 :                         SbiConstExpression* pDefaultExpr = new SbiConstExpression( this );
     949           0 :                         SbxDataType eType2 = pDefaultExpr->GetType();
     950             : 
     951             :                         sal_uInt16 nStringId;
     952           0 :                         if( eType2 == SbxSTRING )
     953             :                         {
     954           0 :                             nStringId = aGblStrings.Add( pDefaultExpr->GetString() );
     955             :                         }
     956             :                         else
     957             :                         {
     958           0 :                             nStringId = aGblStrings.Add( pDefaultExpr->GetValue(), eType2 );
     959             :                         }
     960           0 :                         pPar->SetDefaultId( nStringId );
     961           0 :                         delete pDefaultExpr;
     962             : 
     963           0 :                         eTok = Next();
     964           0 :                         if( eTok == COMMA || eTok == RPAREN )
     965             :                         {
     966           0 :                             bError2 = false;
     967             :                         }
     968             :                     }
     969           0 :                     if( bError2 )
     970             :                     {
     971           0 :                         Error( SbERR_EXPECTED, RPAREN );
     972           0 :                         break;
     973             :                     }
     974             :                 }
     975         207 :                 if( eTok == RPAREN )
     976             :                 {
     977          92 :                     break;
     978             :                 }
     979         115 :             }
     980             :         }
     981             :     }
     982         386 :     TypeDecl( *pDef );
     983         386 :     if( eType != SbxVARIANT && pDef->GetType() != eType )
     984             :     {
     985           0 :         Error( SbERR_BAD_DECLARATION, aName );
     986             :     }
     987         386 :     if( pDef->GetType() == SbxVARIANT && !( bFunc || bProp ) )
     988             :     {
     989         262 :         pDef->SetType( SbxEMPTY );
     990             :     }
     991         386 :     return pDef;
     992             : }
     993             : 
     994             : // DECLARE
     995             : 
     996           0 : void SbiParser::Declare()
     997             : {
     998           0 :     DefDeclare( false );
     999           0 : }
    1000             : 
    1001           0 : void SbiParser::DefDeclare( bool bPrivate )
    1002             : {
    1003           0 :     Next();
    1004           0 :     if( eCurTok != SUB && eCurTok != FUNCTION )
    1005             :     {
    1006           0 :       Error( SbERR_UNEXPECTED, eCurTok );
    1007             :     }
    1008             :     else
    1009             :     {
    1010           0 :         bool bFunction = (eCurTok == FUNCTION);
    1011             : 
    1012           0 :         SbiProcDef* pDef = ProcDecl( true );
    1013           0 :         if( pDef )
    1014             :         {
    1015           0 :             if( pDef->GetLib().isEmpty() )
    1016             :             {
    1017           0 :                 Error( SbERR_EXPECTED, LIB );
    1018             :             }
    1019             :             // Is it already there?
    1020           0 :             SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
    1021           0 :             if( pOld )
    1022             :             {
    1023           0 :                 SbiProcDef* p = pOld->GetProcDef();
    1024           0 :                 if( !p )
    1025             :                 {
    1026             :                     // Declared as a variable
    1027           0 :                     Error( SbERR_BAD_DECLARATION, pDef->GetName() );
    1028           0 :                     delete pDef;
    1029           0 :                     pDef = NULL;
    1030             :                 }
    1031             :                 else
    1032             :                 {
    1033           0 :                     pDef->Match( p );
    1034             :                 }
    1035             :             }
    1036             :             else
    1037             :             {
    1038           0 :                 aPublics.Add( pDef );
    1039             :             }
    1040           0 :             if ( pDef )
    1041             :             {
    1042           0 :                 pDef->SetPublic( !bPrivate );
    1043             : 
    1044             :                 // New declare handling
    1045           0 :                 if( !pDef->GetLib().isEmpty())
    1046             :                 {
    1047           0 :                     if( bNewGblDefs && nGblChain == 0 )
    1048             :                     {
    1049           0 :                         nGblChain = aGen.Gen( _JUMP, 0 );
    1050           0 :                         bNewGblDefs = false;
    1051             :                     }
    1052             : 
    1053           0 :                     sal_uInt16 nSavLine = nLine;
    1054           0 :                     aGen.Statement();
    1055           0 :                     pDef->Define();
    1056           0 :                     pDef->SetLine1( nSavLine );
    1057           0 :                     pDef->SetLine2( nSavLine );
    1058             : 
    1059           0 :                     SbiSymPool& rPool = pDef->GetParams();
    1060           0 :                     sal_uInt16 nParCount = rPool.GetSize();
    1061             : 
    1062           0 :                     SbxDataType eType = pDef->GetType();
    1063           0 :                     if( bFunction )
    1064             :                     {
    1065           0 :                         aGen.Gen( _PARAM, 0, sal::static_int_cast< sal_uInt16 >( eType ) );
    1066             :                     }
    1067           0 :                     if( nParCount > 1 )
    1068             :                     {
    1069           0 :                         aGen.Gen( _ARGC );
    1070             : 
    1071           0 :                         for( sal_uInt16 i = 1 ; i < nParCount ; ++i )
    1072             :                         {
    1073           0 :                             SbiSymDef* pParDef = rPool.Get( i );
    1074           0 :                             SbxDataType eParType = pParDef->GetType();
    1075             : 
    1076           0 :                             aGen.Gen( _PARAM, i, sal::static_int_cast< sal_uInt16 >( eParType ) );
    1077           0 :                             aGen.Gen( _ARGV );
    1078             : 
    1079           0 :                             sal_uInt16 nTyp = sal::static_int_cast< sal_uInt16 >( pParDef->GetType() );
    1080           0 :                             if( pParDef->IsByVal() )
    1081             :                             {
    1082             :                                 // Reset to avoid additional byval in call to wrapper function
    1083           0 :                                 pParDef->SetByVal( sal_False );
    1084           0 :                                 nTyp |= 0x8000;
    1085             :                             }
    1086           0 :                             aGen.Gen( _ARGTYP, nTyp );
    1087             :                         }
    1088             :                     }
    1089             : 
    1090           0 :                     aGen.Gen( _LIB, aGblStrings.Add( pDef->GetLib() ) );
    1091             : 
    1092           0 :                     SbiOpcode eOp = pDef->IsCdecl() ? _CALLC : _CALL;
    1093           0 :                     sal_uInt16 nId = pDef->GetId();
    1094           0 :                     if( !pDef->GetAlias().isEmpty() )
    1095             :                     {
    1096           0 :                         nId = ( nId & 0x8000 ) | aGblStrings.Add( pDef->GetAlias() );
    1097             :                     }
    1098           0 :                     if( nParCount > 1 )
    1099             :                     {
    1100           0 :                         nId |= 0x8000;
    1101             :                     }
    1102           0 :                     aGen.Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( eType ) );
    1103             : 
    1104           0 :                     if( bFunction )
    1105             :                     {
    1106           0 :                         aGen.Gen( _PUT );
    1107             :                     }
    1108           0 :                     aGen.Gen( _LEAVE );
    1109             :                 }
    1110             :             }
    1111             :         }
    1112             :     }
    1113           0 : }
    1114             : 
    1115           0 : void SbiParser::Attribute()
    1116             : {
    1117             :     // TODO: Need to implement the method as an attributed object.
    1118           0 :     while( Next() != EQ )
    1119             :     {
    1120           0 :         if( Next() != DOT)
    1121             :         {
    1122           0 :             break;
    1123             :         }
    1124             :     }
    1125             : 
    1126           0 :     if( eCurTok != EQ )
    1127             :     {
    1128           0 :         Error( SbERR_SYNTAX );
    1129             :     }
    1130             :     else
    1131             :     {
    1132           0 :         SbiExpression aValue( this );
    1133             :     }
    1134             :     // Don't generate any code - just discard it.
    1135           0 : }
    1136             : 
    1137             : // Call of a SUB or a FUNCTION
    1138             : 
    1139         375 : void SbiParser::Call()
    1140             : {
    1141         375 :     SbiExpression aVar( this, SbSYMBOL );
    1142         375 :     aVar.Gen( FORCE_CALL );
    1143         375 :     aGen.Gen( _GET );
    1144         375 : }
    1145             : 
    1146             : // SUB/FUNCTION
    1147             : 
    1148         358 : void SbiParser::SubFunc()
    1149             : {
    1150         358 :     DefProc( false, false );
    1151         358 : }
    1152             : 
    1153             : // Read in of a procedure
    1154             : 
    1155         386 : void SbiParser::DefProc( bool bStatic, bool bPrivate )
    1156             : {
    1157         386 :     sal_uInt16 l1 = nLine, l2 = nLine;
    1158         386 :     bool bSub = ( eCurTok == SUB );
    1159         386 :     bool bProperty = ( eCurTok == PROPERTY );
    1160         386 :     PropertyMode ePropertyMode = PROPERTY_MODE_NONE;
    1161         386 :     if( bProperty )
    1162             :     {
    1163           0 :         Next();
    1164           0 :         if( eCurTok == GET )
    1165             :         {
    1166           0 :             ePropertyMode = PROPERTY_MODE_GET;
    1167             :         }
    1168           0 :         else if( eCurTok == LET )
    1169             :         {
    1170           0 :             ePropertyMode = PROPERTY_MODE_LET;
    1171             :         }
    1172           0 :         else if( eCurTok == SET )
    1173             :         {
    1174           0 :             ePropertyMode = PROPERTY_MODE_SET;
    1175             :         }
    1176             :         else
    1177             :         {
    1178           0 :             Error( SbERR_EXPECTED, "Get or Let or Set" );
    1179             :         }
    1180             :     }
    1181             : 
    1182         386 :     SbiToken eExit = eCurTok;
    1183         386 :     SbiProcDef* pDef = ProcDecl( false );
    1184         386 :     if( !pDef )
    1185             :     {
    1186           0 :         return;
    1187             :     }
    1188         386 :     pDef->setPropertyMode( ePropertyMode );
    1189             : 
    1190             :     // Is the Proc already declared?
    1191         386 :     SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
    1192         386 :     if( pOld )
    1193             :     {
    1194         208 :         bool bError_ = false;
    1195             : 
    1196         208 :         pProc = pOld->GetProcDef();
    1197         208 :         if( !pProc )
    1198             :         {
    1199             :             // Declared as a variable
    1200           0 :             Error( SbERR_BAD_DECLARATION, pDef->GetName() );
    1201           0 :             delete pDef;
    1202           0 :             pProc = NULL;
    1203           0 :             bError_ = true;
    1204             :         }
    1205             :         // #100027: Multiple declaration -> Error
    1206             :         // #112787: Not for setup, REMOVE for 8
    1207         208 :         else if( pProc->IsUsedForProcDecl() )
    1208             :         {
    1209           0 :             PropertyMode ePropMode = pDef->getPropertyMode();
    1210           0 :             if( ePropMode == PROPERTY_MODE_NONE || ePropMode == pProc->getPropertyMode() )
    1211             :             {
    1212           0 :                 Error( SbERR_PROC_DEFINED, pDef->GetName() );
    1213           0 :                 delete pDef;
    1214           0 :                 pProc = NULL;
    1215           0 :                 bError_ = true;
    1216             :             }
    1217             :         }
    1218             : 
    1219         208 :         if( !bError_ )
    1220             :         {
    1221         208 :             pDef->Match( pProc );
    1222         208 :             pProc = pDef;
    1223             :         }
    1224             :     }
    1225             :     else
    1226             :     {
    1227         178 :         aPublics.Add( pDef ), pProc = pDef;
    1228             :     }
    1229         386 :     if( !pProc )
    1230             :     {
    1231           0 :         return;
    1232             :     }
    1233         386 :     pProc->SetPublic( !bPrivate );
    1234             : 
    1235             :     // Now we set the search hierarchy for symbols as well as the
    1236             :     // current procedure.
    1237         386 :     aPublics.SetProcId( pProc->GetId() );
    1238         386 :     pProc->GetParams().SetParent( &aPublics );
    1239         386 :     if( bStatic )
    1240             :     {
    1241           0 :         if ( bVBASupportOn )
    1242             :         {
    1243           0 :             pProc->SetStatic( sal_True );
    1244             :         }
    1245             :         else
    1246             :         {
    1247           0 :             Error( SbERR_NOT_IMPLEMENTED ); // STATIC SUB ...
    1248             :         }
    1249             :     }
    1250             :     else
    1251             :     {
    1252         386 :         pProc->SetStatic( sal_False );
    1253             :     }
    1254             :     // Normal case: Local variable->parameter->global variable
    1255         386 :     pProc->GetLocals().SetParent( &pProc->GetParams() );
    1256         386 :     pPool = &pProc->GetLocals();
    1257             : 
    1258         386 :     pProc->Define();
    1259         386 :     OpenBlock( eExit );
    1260         386 :     StmntBlock( bSub ? ENDSUB : (bProperty ? ENDPROPERTY : ENDFUNC) );
    1261         386 :     l2 = nLine;
    1262         386 :     pProc->SetLine1( l1 );
    1263         386 :     pProc->SetLine2( l2 );
    1264         386 :     pPool = &aPublics;
    1265         386 :     aPublics.SetProcId( 0 );
    1266             :     // Open labels?
    1267         386 :     pProc->GetLabels().CheckRefs();
    1268         386 :     CloseBlock();
    1269         386 :     aGen.Gen( _LEAVE );
    1270         386 :     pProc = NULL;
    1271             : }
    1272             : 
    1273             : // STATIC variable|procedure
    1274             : 
    1275           0 : void SbiParser::Static()
    1276             : {
    1277           0 :     DefStatic( false );
    1278           0 : }
    1279             : 
    1280           0 : void SbiParser::DefStatic( bool bPrivate )
    1281             : {
    1282             :     SbiSymPool* p;
    1283             : 
    1284           0 :     switch( Peek() )
    1285             :     {
    1286             :     case SUB:
    1287             :     case FUNCTION:
    1288             :     case PROPERTY:
    1289             :         // End global chain if necessary (not done in
    1290             :         // SbiParser::Parse() under these conditions
    1291           0 :         if( bNewGblDefs && nGblChain == 0 )
    1292             :         {
    1293           0 :             nGblChain = aGen.Gen( _JUMP, 0 );
    1294           0 :             bNewGblDefs = false;
    1295             :         }
    1296           0 :         Next();
    1297           0 :         DefProc( true, bPrivate );
    1298           0 :         break;
    1299             :     default:
    1300           0 :         if( !pProc )
    1301             :         {
    1302           0 :             Error( SbERR_NOT_IN_SUBR );
    1303             :         }
    1304             :         // Reset the Pool, so that STATIC-Declarations go into the
    1305             :         // global Pool
    1306           0 :         p = pPool;
    1307           0 :         pPool = &aPublics;
    1308           0 :         DefVar( _STATIC, true );
    1309           0 :         pPool = p;
    1310           0 :         break;
    1311             :     }
    1312           0 : }
    1313             : 
    1314             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10