2010-06-15 20:02:53 +02:00
|
|
|
|
/*************************************************************************
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 10:49:15 +00:00
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
2005-09-29 11:45:01 +00:00
|
|
|
|
*
|
2010-02-12 15:01:35 +01:00
|
|
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
2005-09-29 11:45:01 +00:00
|
|
|
|
*
|
2008-04-11 10:49:15 +00:00
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 10:49:15 +00:00
|
|
|
|
* This file is part of OpenOffice.org.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 10:49:15 +00:00
|
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
|
* only, as published by the Free Software Foundation.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 10:49:15 +00:00
|
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
2008-04-11 10:49:15 +00:00
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
|
* for a copy of the LGPLv3 License.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
*
|
|
|
|
|
************************************************************************/
|
2006-09-17 09:01:33 +00:00
|
|
|
|
|
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
|
#include "precompiled_basic.hxx"
|
2007-06-27 13:20:05 +00:00
|
|
|
|
#include <basic/sbx.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#include "sbcomp.hxx"
|
|
|
|
|
|
2010-06-15 20:02:53 +02:00
|
|
|
|
SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Deklaration einer Variablen
|
|
|
|
|
// Bei Fehlern wird bis zum Komma oder Newline geparst.
|
|
|
|
|
// Returnwert: eine neue Instanz, die eingefuegt und dann geloescht wird.
|
|
|
|
|
// Array-Indexe werden als SbiDimList zurueckgegeben
|
|
|
|
|
|
|
|
|
|
SbiSymDef* SbiParser::VarDecl( SbiDimList** ppDim, BOOL bStatic, BOOL bConst )
|
|
|
|
|
{
|
2010-06-15 20:02:53 +02:00
|
|
|
|
bool bWithEvents = false;
|
|
|
|
|
if( Peek() == WITHEVENTS )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
bWithEvents = true;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( !TestSymbol() ) return NULL;
|
|
|
|
|
SbxDataType t = eScanType;
|
|
|
|
|
SbiSymDef* pDef = bConst ? new SbiConstDef( aSym ) : new SbiSymDef( aSym );
|
|
|
|
|
SbiDimList* pDim = NULL;
|
|
|
|
|
// Klammern?
|
|
|
|
|
if( Peek() == LPAREN )
|
|
|
|
|
pDim = new SbiDimList( this );
|
|
|
|
|
pDef->SetType( t );
|
|
|
|
|
if( bStatic )
|
|
|
|
|
pDef->SetStatic();
|
2010-06-15 20:02:53 +02:00
|
|
|
|
if( bWithEvents )
|
|
|
|
|
pDef->SetWithEvents();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
TypeDecl( *pDef );
|
|
|
|
|
if( !ppDim && pDim )
|
|
|
|
|
{
|
|
|
|
|
if(pDim->GetDims() )
|
|
|
|
|
Error( SbERR_EXPECTED, "()" );
|
|
|
|
|
delete pDim;
|
|
|
|
|
}
|
|
|
|
|
else if( ppDim )
|
|
|
|
|
*ppDim = pDim;
|
|
|
|
|
return pDef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Aufloesen einer AS-Typdeklaration
|
|
|
|
|
// Der Datentyp wird in die uebergebene Variable eingetragen
|
|
|
|
|
|
2004-03-17 12:32:57 +00:00
|
|
|
|
void SbiParser::TypeDecl( SbiSymDef& rDef, BOOL bAsNewAlreadyParsed )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
SbxDataType eType = rDef.GetType();
|
|
|
|
|
short nSize = 0;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
if( bAsNewAlreadyParsed || Peek() == AS )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-03-17 12:32:57 +00:00
|
|
|
|
if( !bAsNewAlreadyParsed )
|
|
|
|
|
Next();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
rDef.SetDefinedAs();
|
|
|
|
|
String aType;
|
|
|
|
|
SbiToken eTok = Next();
|
2004-03-17 12:32:57 +00:00
|
|
|
|
if( !bAsNewAlreadyParsed && eTok == NEW )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
rDef.SetNew();
|
|
|
|
|
eTok = Next();
|
|
|
|
|
}
|
|
|
|
|
switch( eTok )
|
|
|
|
|
{
|
|
|
|
|
case ANY:
|
|
|
|
|
if( rDef.IsNew() )
|
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
|
eType = SbxVARIANT; break;
|
|
|
|
|
case TINTEGER:
|
|
|
|
|
case TLONG:
|
|
|
|
|
case TSINGLE:
|
|
|
|
|
case TDOUBLE:
|
|
|
|
|
case TCURRENCY:
|
|
|
|
|
case TDATE:
|
|
|
|
|
case TSTRING:
|
|
|
|
|
case TOBJECT:
|
|
|
|
|
case _ERROR_:
|
|
|
|
|
case TBOOLEAN:
|
|
|
|
|
case TVARIANT:
|
2006-05-05 07:37:43 +00:00
|
|
|
|
case TBYTE:
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( rDef.IsNew() )
|
|
|
|
|
Error( SbERR_SYNTAX );
|
2006-05-05 07:37:43 +00:00
|
|
|
|
eType = (eTok==TBYTE) ? SbxBYTE : SbxDataType( eTok - TINTEGER + SbxINTEGER );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( eType == SbxSTRING )
|
|
|
|
|
{
|
|
|
|
|
// STRING*n ?
|
|
|
|
|
if( Peek() == MUL )
|
|
|
|
|
{ // fixed size!
|
|
|
|
|
Next();
|
|
|
|
|
SbiConstExpression aSize( this );
|
|
|
|
|
nSize = aSize.GetShortValue();
|
2010-06-15 20:02:53 +02:00
|
|
|
|
if( nSize < 0 || (bVBASupportOn && nSize <= 0) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Error( SbERR_OUT_OF_RANGE );
|
2010-06-15 20:02:53 +02:00
|
|
|
|
else
|
|
|
|
|
rDef.SetFixedStringLength( nSize );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SYMBOL: // kann nur ein TYPE oder eine Objektklasse sein!
|
|
|
|
|
if( eScanType != SbxVARIANT )
|
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
String aCompleteName = aSym;
|
|
|
|
|
|
|
|
|
|
// #52709 DIM AS NEW fuer Uno mit voll-qualifizierten Namen
|
|
|
|
|
if( Peek() == DOT )
|
|
|
|
|
{
|
|
|
|
|
String aDotStr( '.' );
|
|
|
|
|
while( Peek() == DOT )
|
|
|
|
|
{
|
|
|
|
|
aCompleteName += aDotStr;
|
|
|
|
|
Next();
|
2006-06-19 16:41:17 +00:00
|
|
|
|
SbiToken ePeekTok = Peek();
|
|
|
|
|
if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
aCompleteName += aSym;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
Error( SbERR_UNEXPECTED, SYMBOL );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-11-15 15:41:23 +00:00
|
|
|
|
else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) )
|
|
|
|
|
{
|
|
|
|
|
eType = SbxLONG;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// In den String-Pool uebernehmen
|
|
|
|
|
rDef.SetTypeId( aGblStrings.Add( aCompleteName ) );
|
2010-08-05 11:52:07 +02:00
|
|
|
|
|
|
|
|
|
if( rDef.IsNew() && pProc == NULL )
|
|
|
|
|
aRequiredTypes.push_back( aCompleteName );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
eType = SbxOBJECT;
|
|
|
|
|
break;
|
2004-06-03 13:33:07 +00:00
|
|
|
|
case FIXSTRING: // new syntax for complex UNO types
|
|
|
|
|
rDef.SetTypeId( aGblStrings.Add( aSym ) );
|
|
|
|
|
eType = SbxOBJECT;
|
|
|
|
|
break;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
default:
|
|
|
|
|
Error( SbERR_UNEXPECTED, eTok );
|
|
|
|
|
Next();
|
|
|
|
|
}
|
|
|
|
|
// Die Variable koennte mit Suffix deklariert sein
|
|
|
|
|
if( rDef.GetType() != SbxVARIANT )
|
|
|
|
|
{
|
|
|
|
|
if( rDef.GetType() != eType )
|
|
|
|
|
Error( SbERR_VAR_DEFINED, rDef.GetName() );
|
|
|
|
|
else if( eType == SbxSTRING && rDef.GetLen() != nSize )
|
|
|
|
|
Error( SbERR_VAR_DEFINED, rDef.GetName() );
|
|
|
|
|
}
|
|
|
|
|
rDef.SetType( eType );
|
|
|
|
|
rDef.SetLen( nSize );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Hier werden Variable, Arrays und Strukturen definiert.
|
|
|
|
|
// DIM/PRIVATE/PUBLIC/GLOBAL
|
|
|
|
|
|
|
|
|
|
void SbiParser::Dim()
|
|
|
|
|
{
|
2008-07-02 08:57:46 +00:00
|
|
|
|
DefVar( _DIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : FALSE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbiParser::DefVar( SbiOpcode eOp, BOOL bStatic )
|
|
|
|
|
{
|
|
|
|
|
SbiSymPool* pOldPool = pPool;
|
|
|
|
|
BOOL bSwitchPool = FALSE;
|
2001-09-04 09:04:24 +00:00
|
|
|
|
BOOL bPersistantGlobal = FALSE;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
SbiToken eFirstTok = eCurTok;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( pProc && ( eCurTok == GLOBAL || eCurTok == PUBLIC || eCurTok == PRIVATE ) )
|
|
|
|
|
Error( SbERR_NOT_IN_SUBR, eCurTok );
|
|
|
|
|
if( eCurTok == PUBLIC || eCurTok == GLOBAL )
|
2001-09-04 09:04:24 +00:00
|
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
|
bSwitchPool = TRUE; // im richtigen Moment auf globalen Pool schalten
|
2001-09-04 09:04:24 +00:00
|
|
|
|
if( eCurTok == GLOBAL )
|
|
|
|
|
bPersistantGlobal = TRUE;
|
|
|
|
|
}
|
2007-08-30 08:59:44 +00:00
|
|
|
|
// behavior in VBA is that a module scope variable's lifetime is
|
|
|
|
|
// tied to the document. e.g. a module scope variable is global
|
|
|
|
|
if( GetBasic()->IsDocBasic() && bVBASupportOn && !pProc )
|
|
|
|
|
bPersistantGlobal = TRUE;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// PRIVATE ist Synonym fuer DIM
|
|
|
|
|
// _CONST_?
|
|
|
|
|
BOOL bConst = FALSE;
|
|
|
|
|
if( eCurTok == _CONST_ )
|
|
|
|
|
bConst = TRUE;
|
|
|
|
|
else if( Peek() == _CONST_ )
|
|
|
|
|
Next(), bConst = TRUE;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
|
|
|
|
|
// #110004 It can also be a sub/function
|
2004-11-15 15:41:23 +00:00
|
|
|
|
if( !bConst && (eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ||
|
2010-06-15 20:02:53 +02:00
|
|
|
|
eCurTok == STATIC || eCurTok == ENUM || eCurTok == DECLARE || eCurTok == TYPE) )
|
2004-03-17 12:32:57 +00:00
|
|
|
|
{
|
|
|
|
|
// Next token is read here, because !bConst
|
|
|
|
|
bool bPrivate = ( eFirstTok == PRIVATE );
|
|
|
|
|
|
|
|
|
|
if( eCurTok == STATIC )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
DefStatic( bPrivate );
|
|
|
|
|
}
|
2004-11-02 10:53:35 +00:00
|
|
|
|
else if( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY )
|
2004-03-17 12:32:57 +00:00
|
|
|
|
{
|
2004-11-02 10:53:35 +00:00
|
|
|
|
// End global chain if necessary (not done in
|
|
|
|
|
// SbiParser::Parse() under these conditions
|
|
|
|
|
if( bNewGblDefs && nGblChain == 0 )
|
|
|
|
|
{
|
|
|
|
|
nGblChain = aGen.Gen( _JUMP, 0 );
|
|
|
|
|
bNewGblDefs = FALSE;
|
|
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
|
Next();
|
|
|
|
|
DefProc( FALSE, bPrivate );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2004-11-15 15:41:23 +00:00
|
|
|
|
else if( eCurTok == ENUM )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
DefEnum( bPrivate );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-02-12 16:56:44 +01:00
|
|
|
|
else if( eCurTok == DECLARE )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
DefDeclare( bPrivate );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-06-15 20:02:53 +02:00
|
|
|
|
// #i109049
|
|
|
|
|
else if( eCurTok == TYPE )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
DefType( bPrivate );
|
|
|
|
|
return;
|
|
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
#ifdef SHARED
|
|
|
|
|
#define tmpSHARED
|
|
|
|
|
#undef SHARED
|
|
|
|
|
#endif
|
|
|
|
|
// SHARED wird ignoriert
|
|
|
|
|
if( Peek() == SHARED ) Next();
|
|
|
|
|
#ifdef tmpSHARED
|
|
|
|
|
#define SHARED
|
|
|
|
|
#undef tmpSHARED
|
|
|
|
|
#endif
|
|
|
|
|
// PRESERVE nur bei REDIM
|
|
|
|
|
if( Peek() == PRESERVE )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
if( eOp == _REDIM )
|
|
|
|
|
eOp = _REDIMP;
|
|
|
|
|
else
|
|
|
|
|
Error( SbERR_UNEXPECTED, eCurTok );
|
|
|
|
|
}
|
|
|
|
|
SbiSymDef* pDef;
|
|
|
|
|
SbiDimList* pDim;
|
|
|
|
|
|
|
|
|
|
// AB 9.7.97, #40689, Statics -> Modul-Initialisierung, in Sub ueberspringen
|
2006-11-01 15:13:55 +00:00
|
|
|
|
UINT32 nEndOfStaticLbl = 0;
|
2008-07-02 08:57:46 +00:00
|
|
|
|
if( !bVBASupportOn && bStatic )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
nEndOfStaticLbl = aGen.Gen( _JUMP, 0 );
|
|
|
|
|
aGen.Statement(); // bei static hier nachholen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL bDefined = FALSE;
|
|
|
|
|
while( ( pDef = VarDecl( &pDim, bStatic, bConst ) ) != NULL )
|
|
|
|
|
{
|
|
|
|
|
EnableErrors();
|
|
|
|
|
// Variable suchen:
|
|
|
|
|
if( bSwitchPool )
|
|
|
|
|
pPool = &aGlobals;
|
|
|
|
|
SbiSymDef* pOld = pPool->Find( pDef->GetName() );
|
|
|
|
|
// AB 31.3.1996, #25651#, auch in Runtime-Library suchen
|
|
|
|
|
BOOL bRtlSym = FALSE;
|
|
|
|
|
if( !pOld )
|
|
|
|
|
{
|
|
|
|
|
pOld = CheckRTLForSym( pDef->GetName(), SbxVARIANT );
|
|
|
|
|
if( pOld )
|
|
|
|
|
bRtlSym = TRUE;
|
|
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
|
if( pOld && !(eOp == _REDIM || eOp == _REDIMP) )
|
|
|
|
|
{
|
|
|
|
|
if( pDef->GetScope() == SbLOCAL && pOld->GetScope() != SbLOCAL )
|
|
|
|
|
pOld = NULL;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( pOld )
|
|
|
|
|
{
|
|
|
|
|
bDefined = TRUE;
|
|
|
|
|
// Bei RTL-Symbol immer Fehler
|
|
|
|
|
if( !bRtlSym && (eOp == _REDIM || eOp == _REDIMP) )
|
|
|
|
|
{
|
|
|
|
|
// Bei REDIM die Attribute vergleichen
|
2004-03-17 12:32:57 +00:00
|
|
|
|
SbxDataType eDefType;
|
2006-06-19 16:41:17 +00:00
|
|
|
|
bool bError_ = false;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
if( pOld->IsStatic() )
|
|
|
|
|
{
|
2006-06-19 16:41:17 +00:00
|
|
|
|
bError_ = true;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
}
|
|
|
|
|
else if( pOld->GetType() != ( eDefType = pDef->GetType() ) )
|
|
|
|
|
{
|
|
|
|
|
if( !( eDefType == SbxVARIANT && !pDef->IsDefinedAs() ) )
|
2006-06-19 16:41:17 +00:00
|
|
|
|
bError_ = true;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
}
|
2006-06-19 16:41:17 +00:00
|
|
|
|
if( bError_ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Error( SbERR_VAR_DEFINED, pDef->GetName() );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
Error( SbERR_VAR_DEFINED, pDef->GetName() );
|
|
|
|
|
delete pDef; pDef = pOld;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pPool->Add( pDef );
|
|
|
|
|
|
|
|
|
|
// #36374: Variable vor Unterscheidung IsNew() anlegen
|
|
|
|
|
// Sonst Error bei Dim Identifier As New Type und option explicit
|
2001-06-05 08:47:16 +00:00
|
|
|
|
if( !bDefined && !(eOp == _REDIM || eOp == _REDIMP)
|
|
|
|
|
&& ( !bConst || pDef->GetScope() == SbGLOBAL ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Variable oder globale Konstante deklarieren
|
2006-06-19 16:41:17 +00:00
|
|
|
|
SbiOpcode eOp2;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
switch ( pDef->GetScope() )
|
|
|
|
|
{
|
2006-06-19 16:41:17 +00:00
|
|
|
|
case SbGLOBAL: eOp2 = bPersistantGlobal ? _GLOBAL_P : _GLOBAL;
|
2001-09-04 09:04:24 +00:00
|
|
|
|
goto global;
|
2007-08-30 08:59:44 +00:00
|
|
|
|
case SbPUBLIC: eOp2 = bPersistantGlobal ? _PUBLIC_P : _PUBLIC;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// AB 9.7.97, #40689, kein eigener Opcode mehr
|
2008-07-02 08:57:46 +00:00
|
|
|
|
if( bVBASupportOn && bStatic )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2006-06-19 16:41:17 +00:00
|
|
|
|
eOp2 = _STATIC;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
global: aGen.BackChain( nGblChain );
|
|
|
|
|
nGblChain = 0;
|
|
|
|
|
bGblDefs = bNewGblDefs = TRUE;
|
|
|
|
|
break;
|
2006-06-19 16:41:17 +00:00
|
|
|
|
default: eOp2 = _LOCAL;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2010-06-15 20:02:53 +02:00
|
|
|
|
UINT32 nOpnd2 = sal::static_int_cast< UINT16 >( pDef->GetType() );
|
|
|
|
|
if( pDef->IsWithEvents() )
|
|
|
|
|
nOpnd2 |= SBX_TYPE_WITH_EVENTS_FLAG;
|
|
|
|
|
|
|
|
|
|
short nFixedStringLength = pDef->GetFixedStringLength();
|
|
|
|
|
if( nFixedStringLength >= 0 )
|
|
|
|
|
nOpnd2 |= (SBX_FIXED_LEN_STRING_FLAG + (UINT32(nFixedStringLength) << 17)); // len = all bits above 0x10000
|
|
|
|
|
|
|
|
|
|
aGen.Gen( eOp2, pDef->GetId(), nOpnd2 );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialisierung fuer selbstdefinierte Datentypen
|
|
|
|
|
// und per NEW angelegte Variable
|
|
|
|
|
if( pDef->GetType() == SbxOBJECT
|
2004-03-17 12:32:57 +00:00
|
|
|
|
&& pDef->GetTypeId() )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-03-17 12:32:57 +00:00
|
|
|
|
if( !bCompatible && !pDef->IsNew() )
|
|
|
|
|
{
|
|
|
|
|
String aTypeName( aGblStrings.Find( pDef->GetTypeId() ) );
|
|
|
|
|
if( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) == NULL )
|
|
|
|
|
Error( SbERR_UNDEF_TYPE, aTypeName );
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( bConst )
|
|
|
|
|
{
|
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( pDim )
|
|
|
|
|
{
|
2003-03-18 15:28:40 +00:00
|
|
|
|
if( eOp == _REDIMP )
|
|
|
|
|
{
|
|
|
|
|
SbiExpression aExpr( this, *pDef, NULL );
|
|
|
|
|
aExpr.Gen();
|
|
|
|
|
aGen.Gen( _REDIMP_ERASE );
|
|
|
|
|
|
|
|
|
|
pDef->SetDims( pDim->GetDims() );
|
|
|
|
|
SbiExpression aExpr2( this, *pDef, pDim );
|
|
|
|
|
aExpr2.Gen();
|
|
|
|
|
aGen.Gen( _DCREATE_REDIMP, pDef->GetId(), pDef->GetTypeId() );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pDef->SetDims( pDim->GetDims() );
|
|
|
|
|
SbiExpression aExpr( this, *pDef, pDim );
|
|
|
|
|
aExpr.Gen();
|
|
|
|
|
aGen.Gen( _DCREATE, pDef->GetId(), pDef->GetTypeId() );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SbiExpression aExpr( this, *pDef );
|
|
|
|
|
aExpr.Gen();
|
2006-06-19 16:41:17 +00:00
|
|
|
|
SbiOpcode eOp_ = pDef->IsNew() ? _CREATE : _TCREATE;
|
|
|
|
|
aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aGen.Gen( _SET );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( bConst )
|
|
|
|
|
{
|
|
|
|
|
// Konstanten-Definition
|
|
|
|
|
if( pDim )
|
|
|
|
|
{
|
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
|
delete pDim;
|
|
|
|
|
}
|
|
|
|
|
SbiExpression aVar( this, *pDef );
|
|
|
|
|
if( !TestToken( EQ ) )
|
|
|
|
|
goto MyBreak; // AB 24.6.1996 (s.u.)
|
|
|
|
|
SbiConstExpression aExpr( this );
|
|
|
|
|
if( !bDefined && aExpr.IsValid() )
|
|
|
|
|
{
|
|
|
|
|
if( pDef->GetScope() == SbGLOBAL )
|
|
|
|
|
{
|
|
|
|
|
// Nur Code fuer globale Konstante erzeugen!
|
|
|
|
|
aVar.Gen();
|
|
|
|
|
aExpr.Gen();
|
|
|
|
|
aGen.Gen( _PUTC );
|
|
|
|
|
}
|
|
|
|
|
SbiConstDef* pConst = pDef->GetConstDef();
|
|
|
|
|
if( aExpr.GetType() == SbxSTRING )
|
|
|
|
|
pConst->Set( aExpr.GetString() );
|
|
|
|
|
else
|
|
|
|
|
pConst->Set( aExpr.GetValue(), aExpr.GetType() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( pDim )
|
|
|
|
|
{
|
|
|
|
|
// Die Variable dimensionieren
|
|
|
|
|
// Bei REDIM die Var vorher loeschen
|
|
|
|
|
if( eOp == _REDIM )
|
|
|
|
|
{
|
|
|
|
|
SbiExpression aExpr( this, *pDef, NULL );
|
|
|
|
|
aExpr.Gen();
|
2007-08-30 08:59:44 +00:00
|
|
|
|
if ( bVBASupportOn )
|
|
|
|
|
// delete the array but
|
|
|
|
|
// clear the variable ( this
|
|
|
|
|
// allows the processing of
|
|
|
|
|
// the param to happen as normal without errors ( ordinary ERASE just clears the array )
|
|
|
|
|
aGen.Gen( _ERASE_CLEAR );
|
|
|
|
|
else
|
|
|
|
|
aGen.Gen( _ERASE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2001-05-07 15:29:55 +00:00
|
|
|
|
else if( eOp == _REDIMP )
|
|
|
|
|
{
|
|
|
|
|
SbiExpression aExpr( this, *pDef, NULL );
|
|
|
|
|
aExpr.Gen();
|
|
|
|
|
aGen.Gen( _REDIMP_ERASE );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pDef->SetDims( pDim->GetDims() );
|
2001-09-04 09:04:24 +00:00
|
|
|
|
if( bPersistantGlobal )
|
|
|
|
|
pDef->SetGlobal( TRUE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbiExpression aExpr( this, *pDef, pDim );
|
|
|
|
|
aExpr.Gen();
|
2001-09-04 09:04:24 +00:00
|
|
|
|
pDef->SetGlobal( FALSE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aGen.Gen( (eOp == _STATIC) ? _DIM : eOp );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( !TestComma() )
|
|
|
|
|
goto MyBreak; // AB 24.6.1996 (s.u.)
|
|
|
|
|
|
|
|
|
|
// #27963# AB, 24.6.1996
|
|
|
|
|
// Einfuehrung bSwitchPool (s.o.): pPool darf beim VarDecl-Aufruf
|
|
|
|
|
// noch nicht auf &aGlobals gesetzt sein.
|
|
|
|
|
// Ansonsten soll das Verhalten aber absolut identisch bleiben,
|
|
|
|
|
// d.h. pPool muss immer am Schleifen-Ende zurueckgesetzt werden.
|
|
|
|
|
// auch bei break
|
|
|
|
|
pPool = pOldPool;
|
2010-06-15 20:02:53 +02:00
|
|
|
|
continue; // MyBreak <20>berspingen
|
2000-09-18 15:18:56 +00:00
|
|
|
|
MyBreak:
|
|
|
|
|
pPool = pOldPool;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AB 9.7.97, #40689, Sprung ueber Statics-Deklaration abschliessen
|
2008-07-02 08:57:46 +00:00
|
|
|
|
if( !bVBASupportOn && bStatic )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
// globalen Chain pflegen
|
|
|
|
|
nGblChain = aGen.Gen( _JUMP, 0 );
|
|
|
|
|
bGblDefs = bNewGblDefs = TRUE;
|
|
|
|
|
|
|
|
|
|
// fuer Sub Sprung auf Ende der statics eintragen
|
|
|
|
|
aGen.BackChain( nEndOfStaticLbl );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//pPool = pOldPool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Hier werden Arrays redimensioniert.
|
|
|
|
|
|
|
|
|
|
void SbiParser::ReDim()
|
|
|
|
|
{
|
2008-07-02 08:57:46 +00:00
|
|
|
|
DefVar( _REDIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : FALSE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ERASE array, ...
|
|
|
|
|
|
|
|
|
|
void SbiParser::Erase()
|
|
|
|
|
{
|
|
|
|
|
while( !bAbort )
|
|
|
|
|
{
|
2010-06-15 20:02:53 +02:00
|
|
|
|
SbiExpression aExpr( this, SbLVALUE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aExpr.Gen();
|
|
|
|
|
aGen.Gen( _ERASE );
|
|
|
|
|
if( !TestComma() ) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Deklaration eines Datentyps
|
|
|
|
|
|
|
|
|
|
void SbiParser::Type()
|
|
|
|
|
{
|
2004-11-15 15:41:23 +00:00
|
|
|
|
DefType( FALSE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbiParser::DefType( BOOL bPrivate )
|
|
|
|
|
{
|
|
|
|
|
// TODO: Use bPrivate
|
2006-06-19 16:41:17 +00:00
|
|
|
|
(void)bPrivate;
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
// Neues Token lesen, es muss ein Symbol sein
|
|
|
|
|
if (!TestSymbol())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (rTypeArray->Find(aSym,SbxCLASS_OBJECT))
|
|
|
|
|
{
|
|
|
|
|
Error( SbERR_VAR_DEFINED, aSym );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbxObject *pType = new SbxObject(aSym);
|
|
|
|
|
|
|
|
|
|
SbiSymDef* pElem;
|
2009-09-17 14:29:05 +00:00
|
|
|
|
SbiDimList* pDim = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
BOOL bDone = FALSE;
|
|
|
|
|
|
|
|
|
|
while( !bDone && !IsEof() )
|
|
|
|
|
{
|
2004-03-17 12:32:57 +00:00
|
|
|
|
switch( Peek() )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
case ENDTYPE :
|
|
|
|
|
pElem = NULL;
|
|
|
|
|
bDone = TRUE;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
Next();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case EOLN :
|
2004-09-09 06:43:08 +00:00
|
|
|
|
case REM :
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pElem = NULL;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
Next();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
pDim = NULL;
|
|
|
|
|
pElem = VarDecl(&pDim,FALSE,FALSE);
|
2004-09-09 06:43:08 +00:00
|
|
|
|
if( !pElem )
|
|
|
|
|
bDone = TRUE; // Error occured
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
if( pElem )
|
|
|
|
|
{
|
2010-06-15 20:02:53 +02:00
|
|
|
|
SbxArray *pTypeMembers = pType->GetProperties();
|
|
|
|
|
String aElemName = pElem->GetName();
|
|
|
|
|
if( pTypeMembers->Find( aElemName, SbxCLASS_DONTCARE) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Error (SbERR_VAR_DEFINED);
|
|
|
|
|
else
|
|
|
|
|
{
|
2010-06-15 20:02:53 +02:00
|
|
|
|
SbxDataType eElemType = pElem->GetType();
|
|
|
|
|
SbxProperty *pTypeElem = new SbxProperty( aElemName, eElemType );
|
2010-02-12 16:56:44 +01:00
|
|
|
|
if( pDim )
|
|
|
|
|
{
|
|
|
|
|
SbxDimArray* pArray = new SbxDimArray( pElem->GetType() );
|
|
|
|
|
if ( pDim->GetSize() )
|
|
|
|
|
{
|
|
|
|
|
// Dimension the target array
|
|
|
|
|
|
|
|
|
|
for ( short i=0; i<pDim->GetSize();++i )
|
|
|
|
|
{
|
|
|
|
|
INT32 ub = -1;
|
|
|
|
|
INT32 lb = nBase;
|
|
|
|
|
SbiExprNode* pNode = pDim->Get(i)->GetExprNode();
|
|
|
|
|
ub = pNode->GetNumber();
|
|
|
|
|
if ( !pDim->Get( i )->IsBased() ) // each dim is low/up
|
|
|
|
|
{
|
|
|
|
|
if ( ++i >= pDim->GetSize() ) // trouble
|
|
|
|
|
StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
|
|
|
|
|
pNode = pDim->Get(i)->GetExprNode();
|
|
|
|
|
lb = ub;
|
|
|
|
|
ub = pNode->GetNumber();
|
|
|
|
|
}
|
|
|
|
|
else if ( !bCompatible )
|
|
|
|
|
ub += nBase;
|
|
|
|
|
pArray->AddDim32( lb, ub );
|
|
|
|
|
}
|
|
|
|
|
pArray->setHasFixedSize( true );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pArray->unoAddDim( 0, -1 ); // variant array
|
|
|
|
|
USHORT nSavFlags = pTypeElem->GetFlags();
|
|
|
|
|
// need to reset the FIXED flag
|
|
|
|
|
// when calling PutObject ( because the type will not match Object )
|
|
|
|
|
pTypeElem->ResetFlag( SBX_FIXED );
|
|
|
|
|
pTypeElem->PutObject( pArray );
|
|
|
|
|
pTypeElem->SetFlags( nSavFlags );
|
|
|
|
|
}
|
2010-06-15 20:02:53 +02:00
|
|
|
|
// Nested user type?
|
|
|
|
|
if( eElemType == SbxOBJECT )
|
|
|
|
|
{
|
|
|
|
|
USHORT nElemTypeId = pElem->GetTypeId();
|
|
|
|
|
if( nElemTypeId != 0 )
|
|
|
|
|
{
|
|
|
|
|
String aTypeName( aGblStrings.Find( nElemTypeId ) );
|
|
|
|
|
SbxObject* pTypeObj = static_cast< SbxObject* >( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) );
|
|
|
|
|
if( pTypeObj != NULL )
|
|
|
|
|
{
|
|
|
|
|
SbxObject* pCloneObj = cloneTypeObjectImpl( *pTypeObj );
|
|
|
|
|
pTypeElem->PutObject( pCloneObj );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-09-17 14:29:05 +00:00
|
|
|
|
delete pDim;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
pTypeMembers->Insert( pTypeElem, pTypeMembers->Count() );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
delete pElem;
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
|
|
|
|
|
|
pType->Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
|
|
|
|
|
pType->Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
rTypeArray->Insert (pType,rTypeArray->Count());
|
|
|
|
|
}
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Declaration of Enum type
|
|
|
|
|
|
|
|
|
|
void SbiParser::Enum()
|
|
|
|
|
{
|
|
|
|
|
DefEnum( FALSE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbiParser::DefEnum( BOOL bPrivate )
|
|
|
|
|
{
|
|
|
|
|
// Neues Token lesen, es muss ein Symbol sein
|
|
|
|
|
if (!TestSymbol())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
String aEnumName = aSym;
|
|
|
|
|
if( rEnumArray->Find(aEnumName,SbxCLASS_OBJECT) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-15 15:41:23 +00:00
|
|
|
|
Error( SbERR_VAR_DEFINED, aSym );
|
|
|
|
|
return;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-11-15 15:41:23 +00:00
|
|
|
|
SbxObject *pEnum = new SbxObject( aEnumName );
|
|
|
|
|
if( bPrivate )
|
|
|
|
|
pEnum->SetFlag( SBX_PRIVATE );
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbiSymDef* pElem;
|
|
|
|
|
SbiDimList* pDim;
|
|
|
|
|
BOOL bDone = FALSE;
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
|
|
|
|
// Starting with -1 to make first default value 0 after ++
|
|
|
|
|
sal_Int32 nCurrentEnumValue = -1;
|
|
|
|
|
while( !bDone && !IsEof() )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-15 15:41:23 +00:00
|
|
|
|
switch( Peek() )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2004-11-15 15:41:23 +00:00
|
|
|
|
case ENDENUM :
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pElem = NULL;
|
|
|
|
|
bDone = TRUE;
|
2004-11-15 15:41:23 +00:00
|
|
|
|
Next();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case EOLN :
|
|
|
|
|
case REM :
|
|
|
|
|
pElem = NULL;
|
|
|
|
|
Next();
|
|
|
|
|
break;
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
default:
|
2004-11-15 15:41:23 +00:00
|
|
|
|
{
|
|
|
|
|
// TODO: Check existing!
|
|
|
|
|
BOOL bDefined = FALSE;
|
|
|
|
|
|
|
|
|
|
pDim = NULL;
|
|
|
|
|
pElem = VarDecl( &pDim, FALSE, TRUE );
|
|
|
|
|
if( !pElem )
|
|
|
|
|
{
|
|
|
|
|
bDone = TRUE; // Error occured
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if( pDim )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
delete pDim;
|
2004-11-15 15:41:23 +00:00
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
|
bDone = TRUE; // Error occured
|
|
|
|
|
break;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
|
|
|
|
SbiExpression aVar( this, *pElem );
|
|
|
|
|
if( Peek() == EQ )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
|
|
|
|
|
SbiConstExpression aExpr( this );
|
|
|
|
|
if( !bDefined && aExpr.IsValid() )
|
|
|
|
|
{
|
|
|
|
|
SbxVariableRef xConvertVar = new SbxVariable();
|
|
|
|
|
if( aExpr.GetType() == SbxSTRING )
|
|
|
|
|
xConvertVar->PutString( aExpr.GetString() );
|
|
|
|
|
else
|
|
|
|
|
xConvertVar->PutDouble( aExpr.GetValue() );
|
|
|
|
|
|
|
|
|
|
nCurrentEnumValue = xConvertVar->GetLong();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
nCurrentEnumValue++;
|
|
|
|
|
|
|
|
|
|
SbiSymPool* pPoolToUse = bPrivate ? pPool : &aGlobals;
|
|
|
|
|
|
|
|
|
|
SbiSymDef* pOld = pPoolToUse->Find( pElem->GetName() );
|
|
|
|
|
if( pOld )
|
|
|
|
|
{
|
|
|
|
|
Error( SbERR_VAR_DEFINED, pElem->GetName() );
|
|
|
|
|
bDone = TRUE; // Error occured
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pPool->Add( pElem );
|
|
|
|
|
|
|
|
|
|
if( !bPrivate )
|
|
|
|
|
{
|
|
|
|
|
SbiOpcode eOp = _GLOBAL;
|
|
|
|
|
aGen.BackChain( nGblChain );
|
|
|
|
|
nGblChain = 0;
|
|
|
|
|
bGblDefs = bNewGblDefs = TRUE;
|
2006-10-12 13:26:32 +00:00
|
|
|
|
aGen.Gen(
|
|
|
|
|
eOp, pElem->GetId(),
|
|
|
|
|
sal::static_int_cast< UINT16 >( pElem->GetType() ) );
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
|
|
|
|
aVar.Gen();
|
|
|
|
|
USHORT nStringId = aGen.GetParser()->aGblStrings.Add( nCurrentEnumValue, SbxLONG );
|
|
|
|
|
aGen.Gen( _NUMBER, nStringId );
|
|
|
|
|
aGen.Gen( _PUTC );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SbiConstDef* pConst = pElem->GetConstDef();
|
|
|
|
|
pConst->Set( nCurrentEnumValue, SbxLONG );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
if( pElem )
|
2004-11-15 15:41:23 +00:00
|
|
|
|
{
|
|
|
|
|
SbxArray *pEnumMembers = pEnum->GetProperties();
|
|
|
|
|
SbxProperty *pEnumElem = new SbxProperty( pElem->GetName(), SbxLONG );
|
|
|
|
|
pEnumElem->PutLong( nCurrentEnumValue );
|
|
|
|
|
pEnumElem->ResetFlag( SBX_WRITE );
|
|
|
|
|
pEnumElem->SetFlag( SBX_CONST );
|
|
|
|
|
pEnumMembers->Insert( pEnumElem, pEnumMembers->Count() );
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
|
|
|
|
pEnum->Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
|
|
|
|
|
pEnum->Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );
|
|
|
|
|
|
|
|
|
|
rEnumArray->Insert( pEnum, rEnumArray->Count() );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Prozedur-Deklaration
|
|
|
|
|
// das erste Token ist bereits eingelesen (SUB/FUNCTION)
|
|
|
|
|
// xxx Name [LIB "name"[ALIAS "name"]][(Parameter)][AS TYPE]
|
|
|
|
|
|
|
|
|
|
SbiProcDef* SbiParser::ProcDecl( BOOL bDecl )
|
|
|
|
|
{
|
|
|
|
|
BOOL bFunc = BOOL( eCurTok == FUNCTION );
|
2010-02-12 16:56:44 +01:00
|
|
|
|
BOOL bProp = BOOL( eCurTok == GET || eCurTok == SET || eCurTok == LET );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
if( !TestSymbol() ) return NULL;
|
|
|
|
|
String aName( aSym );
|
|
|
|
|
SbxDataType eType = eScanType;
|
2002-08-12 11:04:52 +00:00
|
|
|
|
SbiProcDef* pDef = new SbiProcDef( this, aName, true );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pDef->SetType( eType );
|
|
|
|
|
if( Peek() == _CDECL_ )
|
|
|
|
|
{
|
|
|
|
|
Next(); pDef->SetCdecl();
|
|
|
|
|
}
|
|
|
|
|
if( Peek() == LIB )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
if( Next() == FIXSTRING )
|
|
|
|
|
pDef->GetLib() = aSym;
|
|
|
|
|
else
|
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
|
}
|
|
|
|
|
if( Peek() == ALIAS )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
if( Next() == FIXSTRING )
|
|
|
|
|
pDef->GetAlias() = aSym;
|
|
|
|
|
else
|
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
|
}
|
|
|
|
|
if( !bDecl )
|
|
|
|
|
{
|
|
|
|
|
// CDECL, LIB und ALIAS sind unzulaessig
|
|
|
|
|
if( pDef->GetLib().Len() )
|
|
|
|
|
Error( SbERR_UNEXPECTED, LIB );
|
|
|
|
|
if( pDef->GetAlias().Len() )
|
|
|
|
|
Error( SbERR_UNEXPECTED, ALIAS );
|
|
|
|
|
if( pDef->IsCdecl() )
|
|
|
|
|
Error( SbERR_UNEXPECTED, _CDECL_ );
|
|
|
|
|
pDef->SetCdecl( FALSE );
|
|
|
|
|
pDef->GetLib().Erase();
|
|
|
|
|
pDef->GetAlias().Erase();
|
|
|
|
|
}
|
|
|
|
|
else if( !pDef->GetLib().Len() )
|
|
|
|
|
{
|
|
|
|
|
// ALIAS und CDECL nur zusammen mit LIB
|
|
|
|
|
if( pDef->GetAlias().Len() )
|
|
|
|
|
Error( SbERR_UNEXPECTED, ALIAS );
|
|
|
|
|
if( pDef->IsCdecl() )
|
|
|
|
|
Error( SbERR_UNEXPECTED, _CDECL_ );
|
|
|
|
|
pDef->SetCdecl( FALSE );
|
|
|
|
|
pDef->GetAlias().Erase();
|
|
|
|
|
}
|
|
|
|
|
// Klammern?
|
|
|
|
|
if( Peek() == LPAREN )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
if( Peek() == RPAREN )
|
|
|
|
|
Next();
|
|
|
|
|
else
|
|
|
|
|
for(;;) {
|
|
|
|
|
BOOL bByVal = FALSE;
|
|
|
|
|
BOOL bOptional = FALSE;
|
2005-01-28 15:05:59 +00:00
|
|
|
|
BOOL bParamArray = FALSE;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
while( Peek() == BYVAL || Peek() == BYREF || Peek() == _OPTIONAL_ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
if ( Peek() == BYVAL ) Next(), bByVal = TRUE;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
else if ( Peek() == BYREF ) Next(), bByVal = FALSE;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
else if ( Peek() == _OPTIONAL_ ) Next(), bOptional = TRUE;
|
|
|
|
|
}
|
2005-01-28 15:05:59 +00:00
|
|
|
|
if( bCompatible && Peek() == PARAMARRAY )
|
|
|
|
|
{
|
2010-08-06 09:35:51 +02:00
|
|
|
|
if( bByVal || bOptional )
|
2005-01-28 15:05:59 +00:00
|
|
|
|
Error( SbERR_UNEXPECTED, PARAMARRAY );
|
|
|
|
|
Next();
|
|
|
|
|
bParamArray = TRUE;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbiSymDef* pPar = VarDecl( NULL, FALSE, FALSE );
|
|
|
|
|
if( !pPar )
|
|
|
|
|
break;
|
|
|
|
|
if( bByVal )
|
|
|
|
|
pPar->SetByVal();
|
|
|
|
|
if( bOptional )
|
|
|
|
|
pPar->SetOptional();
|
2005-01-28 15:05:59 +00:00
|
|
|
|
if( bParamArray )
|
|
|
|
|
pPar->SetParamArray();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pDef->GetParams().Add( pPar );
|
|
|
|
|
SbiToken eTok = Next();
|
|
|
|
|
if( eTok != COMMA && eTok != RPAREN )
|
|
|
|
|
{
|
2006-06-19 16:41:17 +00:00
|
|
|
|
BOOL bError2 = TRUE;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
if( bOptional && bCompatible && eTok == EQ )
|
|
|
|
|
{
|
|
|
|
|
SbiConstExpression* pDefaultExpr = new SbiConstExpression( this );
|
2006-06-19 16:41:17 +00:00
|
|
|
|
SbxDataType eType2 = pDefaultExpr->GetType();
|
2004-03-17 12:32:57 +00:00
|
|
|
|
|
|
|
|
|
USHORT nStringId;
|
2006-06-19 16:41:17 +00:00
|
|
|
|
if( eType2 == SbxSTRING )
|
2006-10-12 13:26:32 +00:00
|
|
|
|
nStringId = aGblStrings.Add( pDefaultExpr->GetString() );
|
2004-03-17 12:32:57 +00:00
|
|
|
|
else
|
2006-06-19 16:41:17 +00:00
|
|
|
|
nStringId = aGblStrings.Add( pDefaultExpr->GetValue(), eType2 );
|
2004-03-17 12:32:57 +00:00
|
|
|
|
|
|
|
|
|
pPar->SetDefaultId( nStringId );
|
|
|
|
|
delete pDefaultExpr;
|
|
|
|
|
|
|
|
|
|
eTok = Next();
|
|
|
|
|
if( eTok == COMMA || eTok == RPAREN )
|
2006-06-19 16:41:17 +00:00
|
|
|
|
bError2 = FALSE;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
}
|
2006-06-19 16:41:17 +00:00
|
|
|
|
if( bError2 )
|
2004-03-17 12:32:57 +00:00
|
|
|
|
{
|
|
|
|
|
Error( SbERR_EXPECTED, RPAREN );
|
|
|
|
|
break;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
if( eTok == RPAREN )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
TypeDecl( *pDef );
|
|
|
|
|
if( eType != SbxVARIANT && pDef->GetType() != eType )
|
|
|
|
|
Error( SbERR_BAD_DECLARATION, aName );
|
|
|
|
|
// if( pDef->GetType() == SbxOBJECT )
|
|
|
|
|
// pDef->SetType( SbxVARIANT ),
|
|
|
|
|
// Error( SbERR_SYNTAX );
|
2010-02-12 16:56:44 +01:00
|
|
|
|
if( pDef->GetType() == SbxVARIANT && !( bFunc || bProp ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pDef->SetType( SbxEMPTY );
|
|
|
|
|
return pDef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DECLARE
|
|
|
|
|
|
|
|
|
|
void SbiParser::Declare()
|
|
|
|
|
{
|
2010-02-12 16:56:44 +01:00
|
|
|
|
DefDeclare( FALSE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbiParser::DefDeclare( BOOL bPrivate )
|
|
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Next();
|
|
|
|
|
if( eCurTok != SUB && eCurTok != FUNCTION )
|
|
|
|
|
Error( SbERR_UNEXPECTED, eCurTok );
|
|
|
|
|
else
|
|
|
|
|
{
|
2010-08-06 09:35:51 +02:00
|
|
|
|
bool bFunction = (eCurTok == FUNCTION);
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbiProcDef* pDef = ProcDecl( TRUE );
|
|
|
|
|
if( pDef )
|
|
|
|
|
{
|
|
|
|
|
if( !pDef->GetLib().Len() )
|
|
|
|
|
Error( SbERR_EXPECTED, LIB );
|
|
|
|
|
// gibts den schon?
|
|
|
|
|
SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
|
|
|
|
|
if( pOld )
|
|
|
|
|
{
|
|
|
|
|
SbiProcDef* p = pOld->GetProcDef();
|
|
|
|
|
if( !p )
|
|
|
|
|
{
|
|
|
|
|
// Als Variable deklariert
|
|
|
|
|
Error( SbERR_BAD_DECLARATION, pDef->GetName() );
|
|
|
|
|
delete pDef;
|
2009-09-17 14:29:05 +00:00
|
|
|
|
pDef = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pDef->Match( p );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
aPublics.Add( pDef );
|
2009-09-17 14:29:05 +00:00
|
|
|
|
|
2010-02-12 16:56:44 +01:00
|
|
|
|
if ( pDef )
|
2010-08-06 09:35:51 +02:00
|
|
|
|
{
|
2010-02-12 16:56:44 +01:00
|
|
|
|
pDef->SetPublic( !bPrivate );
|
2010-08-06 09:35:51 +02:00
|
|
|
|
|
|
|
|
|
// New declare handling
|
|
|
|
|
if( pDef->GetLib().Len() > 0 )
|
|
|
|
|
{
|
2010-08-11 08:24:45 +02:00
|
|
|
|
if( bNewGblDefs && nGblChain == 0 )
|
|
|
|
|
{
|
|
|
|
|
nGblChain = aGen.Gen( _JUMP, 0 );
|
|
|
|
|
bNewGblDefs = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-06 09:35:51 +02:00
|
|
|
|
USHORT nSavLine = nLine;
|
|
|
|
|
aGen.Statement();
|
|
|
|
|
pDef->Define();
|
|
|
|
|
pDef->SetLine1( nSavLine );
|
|
|
|
|
pDef->SetLine2( nSavLine );
|
|
|
|
|
|
|
|
|
|
SbiSymPool& rPool = pDef->GetParams();
|
|
|
|
|
USHORT nParCount = rPool.GetSize();
|
|
|
|
|
|
|
|
|
|
SbxDataType eType = pDef->GetType();
|
|
|
|
|
if( bFunction )
|
|
|
|
|
aGen.Gen( _PARAM, 0, sal::static_int_cast< UINT16 >( eType ) );
|
|
|
|
|
|
|
|
|
|
if( nParCount > 1 )
|
|
|
|
|
{
|
|
|
|
|
aGen.Gen( _ARGC );
|
|
|
|
|
|
|
|
|
|
for( USHORT i = 1 ; i < nParCount ; ++i )
|
|
|
|
|
{
|
|
|
|
|
SbiSymDef* pParDef = rPool.Get( i );
|
|
|
|
|
SbxDataType eParType = pParDef->GetType();
|
|
|
|
|
|
|
|
|
|
aGen.Gen( _PARAM, i, sal::static_int_cast< UINT16 >( eParType ) );
|
|
|
|
|
aGen.Gen( _ARGV );
|
|
|
|
|
|
|
|
|
|
USHORT nTyp = sal::static_int_cast< USHORT >( pParDef->GetType() );
|
|
|
|
|
if( pParDef->IsByVal() )
|
|
|
|
|
{
|
|
|
|
|
// Reset to avoid additional byval in call to wrapper function
|
|
|
|
|
pParDef->SetByVal( FALSE );
|
|
|
|
|
nTyp |= 0x8000;
|
|
|
|
|
}
|
|
|
|
|
aGen.Gen( _ARGTYP, nTyp );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
aGen.Gen( _LIB, aGblStrings.Add( pDef->GetLib() ) );
|
|
|
|
|
|
|
|
|
|
SbiOpcode eOp = pDef->IsCdecl() ? _CALLC : _CALL;
|
|
|
|
|
USHORT nId = pDef->GetId();
|
|
|
|
|
if( pDef->GetAlias().Len() )
|
|
|
|
|
nId = ( nId & 0x8000 ) | aGblStrings.Add( pDef->GetAlias() );
|
|
|
|
|
if( nParCount > 1 )
|
|
|
|
|
nId |= 0x8000;
|
|
|
|
|
aGen.Gen( eOp, nId, sal::static_int_cast< UINT16 >( eType ) );
|
|
|
|
|
|
|
|
|
|
if( bFunction )
|
|
|
|
|
aGen.Gen( _PUT );
|
|
|
|
|
|
|
|
|
|
aGen.Gen( _LEAVE );
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Aufruf einer SUB oder FUNCTION
|
|
|
|
|
|
|
|
|
|
void SbiParser::Call()
|
|
|
|
|
{
|
|
|
|
|
String aName( aSym );
|
|
|
|
|
SbiExpression aVar( this, SbSYMBOL );
|
2003-05-22 07:53:04 +00:00
|
|
|
|
aVar.Gen( FORCE_CALL );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
aGen.Gen( _GET );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SUB/FUNCTION
|
|
|
|
|
|
|
|
|
|
void SbiParser::SubFunc()
|
|
|
|
|
{
|
2004-03-17 12:32:57 +00:00
|
|
|
|
DefProc( FALSE, FALSE );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Einlesen einer Prozedur
|
|
|
|
|
|
2003-12-01 10:35:22 +00:00
|
|
|
|
BOOL runsInSetup( void );
|
|
|
|
|
|
2004-03-17 12:32:57 +00:00
|
|
|
|
void SbiParser::DefProc( BOOL bStatic, BOOL bPrivate )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
USHORT l1 = nLine, l2 = nLine;
|
|
|
|
|
BOOL bSub = BOOL( eCurTok == SUB );
|
2004-11-02 10:53:35 +00:00
|
|
|
|
BOOL bProperty = BOOL( eCurTok == PROPERTY );
|
|
|
|
|
PropertyMode ePropertyMode = PROPERTY_MODE_NONE;
|
|
|
|
|
if( bProperty )
|
|
|
|
|
{
|
|
|
|
|
Next();
|
|
|
|
|
if( eCurTok == GET )
|
|
|
|
|
ePropertyMode = PROPERTY_MODE_GET;
|
|
|
|
|
else if( eCurTok == LET )
|
|
|
|
|
ePropertyMode = PROPERTY_MODE_LET;
|
|
|
|
|
else if( eCurTok == SET )
|
|
|
|
|
ePropertyMode = PROPERTY_MODE_SET;
|
|
|
|
|
else
|
|
|
|
|
Error( SbERR_EXPECTED, "Get or Let or Set" );
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
SbiToken eExit = eCurTok;
|
|
|
|
|
SbiProcDef* pDef = ProcDecl( FALSE );
|
|
|
|
|
if( !pDef )
|
|
|
|
|
return;
|
2004-11-02 10:53:35 +00:00
|
|
|
|
pDef->setPropertyMode( ePropertyMode );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Ist die Proc bereits deklariert?
|
|
|
|
|
SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
|
|
|
|
|
if( pOld )
|
|
|
|
|
{
|
2006-06-19 16:41:17 +00:00
|
|
|
|
bool bError_ = false;
|
2004-11-02 10:53:35 +00:00
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
|
pProc = pOld->GetProcDef();
|
|
|
|
|
if( !pProc )
|
|
|
|
|
{
|
|
|
|
|
// Als Variable deklariert
|
|
|
|
|
Error( SbERR_BAD_DECLARATION, pDef->GetName() );
|
|
|
|
|
delete pDef;
|
|
|
|
|
pProc = NULL;
|
2006-06-19 16:41:17 +00:00
|
|
|
|
bError_ = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
}
|
2002-08-12 11:04:52 +00:00
|
|
|
|
// #100027: Multiple declaration -> Error
|
2003-12-01 10:35:22 +00:00
|
|
|
|
// #112787: Not for setup, REMOVE for 8
|
|
|
|
|
else if( !runsInSetup() && pProc->IsUsedForProcDecl() )
|
2002-08-12 11:04:52 +00:00
|
|
|
|
{
|
2004-11-02 10:53:35 +00:00
|
|
|
|
PropertyMode ePropMode = pDef->getPropertyMode();
|
|
|
|
|
if( ePropMode == PROPERTY_MODE_NONE || ePropMode == pProc->getPropertyMode() )
|
|
|
|
|
{
|
|
|
|
|
Error( SbERR_PROC_DEFINED, pDef->GetName() );
|
|
|
|
|
delete pDef;
|
|
|
|
|
pProc = NULL;
|
2006-06-19 16:41:17 +00:00
|
|
|
|
bError_ = true;
|
2004-11-02 10:53:35 +00:00
|
|
|
|
}
|
2002-08-12 11:04:52 +00:00
|
|
|
|
}
|
2004-11-02 10:53:35 +00:00
|
|
|
|
|
2006-06-19 16:41:17 +00:00
|
|
|
|
if( !bError_ )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
pDef->Match( pProc );
|
|
|
|
|
pProc = pDef;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
aPublics.Add( pDef ), pProc = pDef;
|
|
|
|
|
|
|
|
|
|
if( !pProc )
|
|
|
|
|
return;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
pProc->SetPublic( !bPrivate );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
// Nun setzen wir die Suchhierarchie fuer Symbole sowie die aktuelle
|
|
|
|
|
// Prozedur.
|
|
|
|
|
aPublics.SetProcId( pProc->GetId() );
|
|
|
|
|
pProc->GetParams().SetParent( &aPublics );
|
2008-07-02 08:57:46 +00:00
|
|
|
|
if( bStatic )
|
|
|
|
|
{
|
|
|
|
|
if ( bVBASupportOn )
|
|
|
|
|
pProc->SetStatic( TRUE );
|
|
|
|
|
else
|
|
|
|
|
Error( SbERR_NOT_IMPLEMENTED ); // STATIC SUB ...
|
|
|
|
|
}
|
|
|
|
|
else
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
2008-07-02 08:57:46 +00:00
|
|
|
|
pProc->SetStatic( FALSE );
|
|
|
|
|
}
|
|
|
|
|
// Normalfall: Lokale Variable->Parameter->Globale Variable
|
|
|
|
|
pProc->GetLocals().SetParent( &pProc->GetParams() );
|
|
|
|
|
pPool = &pProc->GetLocals();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
|
|
pProc->Define();
|
|
|
|
|
OpenBlock( eExit );
|
2004-11-02 10:53:35 +00:00
|
|
|
|
StmntBlock( bSub ? ENDSUB : (bProperty ? ENDPROPERTY : ENDFUNC) );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
l2 = nLine;
|
|
|
|
|
pProc->SetLine1( l1 );
|
|
|
|
|
pProc->SetLine2( l2 );
|
|
|
|
|
pPool = &aPublics;
|
|
|
|
|
aPublics.SetProcId( 0 );
|
|
|
|
|
// Offene Labels?
|
|
|
|
|
pProc->GetLabels().CheckRefs();
|
|
|
|
|
CloseBlock();
|
|
|
|
|
aGen.Gen( _LEAVE );
|
|
|
|
|
pProc = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// STATIC variable|procedure
|
|
|
|
|
|
|
|
|
|
void SbiParser::Static()
|
2004-03-17 12:32:57 +00:00
|
|
|
|
{
|
|
|
|
|
DefStatic( FALSE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SbiParser::DefStatic( BOOL bPrivate )
|
2000-09-18 15:18:56 +00:00
|
|
|
|
{
|
|
|
|
|
switch( Peek() )
|
|
|
|
|
{
|
|
|
|
|
case SUB:
|
|
|
|
|
case FUNCTION:
|
2004-11-02 10:53:35 +00:00
|
|
|
|
case PROPERTY:
|
|
|
|
|
// End global chain if necessary (not done in
|
|
|
|
|
// SbiParser::Parse() under these conditions
|
|
|
|
|
if( bNewGblDefs && nGblChain == 0 )
|
|
|
|
|
{
|
|
|
|
|
nGblChain = aGen.Gen( _JUMP, 0 );
|
|
|
|
|
bNewGblDefs = FALSE;
|
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
Next();
|
2004-03-17 12:32:57 +00:00
|
|
|
|
DefProc( TRUE, bPrivate );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
break;
|
|
|
|
|
default: {
|
|
|
|
|
if( !pProc )
|
|
|
|
|
Error( SbERR_NOT_IN_SUBR );
|
|
|
|
|
// Pool umsetzen, damit STATIC-Deklarationen im globalen
|
|
|
|
|
// Pool landen
|
|
|
|
|
SbiSymPool* p = pPool; pPool = &aPublics;
|
|
|
|
|
DefVar( _STATIC, TRUE );
|
|
|
|
|
pPool = p;
|
|
|
|
|
} break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|