2010-10-12 15:53:47 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-07-17 12:30:48 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2006-09-17 09:01:33 +00:00
|
|
|
|
2007-06-27 13:20:05 +00:00
|
|
|
#include <basic/sbx.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
#include "sbcomp.hxx"
|
2010-10-06 10:16:27 +01:00
|
|
|
#include "sbunoobj.hxx"
|
2013-06-17 13:07:05 +02:00
|
|
|
#include <svtools/miscopt.hxx>
|
|
|
|
#include "com/sun/star/reflection/XIdlReflection.hpp"
|
|
|
|
#include <comphelper/namedvaluecollection.hxx>
|
|
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
#include <comphelper/configurationhelper.hxx>
|
|
|
|
#include "com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp"
|
|
|
|
#include "com/sun/star/reflection/XIdlMethod.hpp"
|
|
|
|
#include "com/sun/star/uno/Exception.hpp"
|
2013-07-23 12:42:37 +02:00
|
|
|
#include <basic/codecompletecache.hxx>
|
2013-06-17 13:07:05 +02:00
|
|
|
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
using namespace ::com::sun::star::uno;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2010-06-15 20:02:53 +02:00
|
|
|
SbxObject* cloneTypeObjectImpl( const SbxObject& rTypeObj );
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Declaration of a variable
|
|
|
|
// If there are errors it will be parsed up to the comma or the newline.
|
|
|
|
// Return-value: a new instance, which were inserted and then deleted.
|
|
|
|
// Array-Indexex were returned as SbiDimList
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2012-08-19 17:49:02 +09:00
|
|
|
SbiSymDef* SbiParser::VarDecl( SbiDimList** ppDim, bool bStatic, bool bConst )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
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;
|
2010-11-21 19:56:23 +01:00
|
|
|
// Brackets?
|
2000-09-18 15:18:56 +00:00
|
|
|
if( Peek() == LPAREN )
|
2011-03-25 10:40:25 +01:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
pDim = new SbiDimList( this );
|
2011-03-25 10:40:25 +01:00
|
|
|
if( !pDim->GetDims() )
|
|
|
|
pDef->SetWithBrackets();
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Resolving of a AS-Type-Declaration
|
|
|
|
// The data type were inserted into the handed over variable
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2012-08-20 09:44:32 +09:00
|
|
|
void SbiParser::TypeDecl( SbiSymDef& rDef, bool bAsNewAlreadyParsed )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
SbxDataType eType = rDef.GetType();
|
2004-03-17 12:32:57 +00:00
|
|
|
if( bAsNewAlreadyParsed || Peek() == AS )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-12-23 15:02:10 +00:00
|
|
|
short nSize = 0;
|
2004-03-17 12:32:57 +00:00
|
|
|
if( !bAsNewAlreadyParsed )
|
|
|
|
Next();
|
2000-09-18 15:18:56 +00:00
|
|
|
rDef.SetDefinedAs();
|
|
|
|
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;
|
2010-11-21 19:56:23 +01:00
|
|
|
case SYMBOL: // can only be a TYPE or a object class!
|
2000-09-18 15:18:56 +00:00
|
|
|
if( eScanType != SbxVARIANT )
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
else
|
|
|
|
{
|
2012-11-06 23:34:23 -06:00
|
|
|
OUString aCompleteName = aSym;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// #52709 DIM AS NEW for Uno with full-qualified name
|
2000-09-18 15:18:56 +00:00
|
|
|
if( Peek() == DOT )
|
|
|
|
{
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aDotStr( '.' );
|
2000-09-18 15:18:56 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-10-06 10:16:27 +01:00
|
|
|
else if( rEnumArray->Find( aCompleteName, SbxCLASS_OBJECT ) || ( IsVBASupportOn() && VBAConstantHelper::instance().isVBAConstantType( aCompleteName ) ) )
|
2004-11-15 15:41:23 +00:00
|
|
|
{
|
|
|
|
eType = SbxLONG;
|
|
|
|
break;
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2012-11-06 23:34:23 -06:00
|
|
|
// Take over in the string pool
|
2000-09-18 15:18:56 +00:00
|
|
|
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();
|
|
|
|
}
|
2010-11-21 19:56:23 +01:00
|
|
|
// The variable could have been declared with a suffix
|
2000-09-18 15:18:56 +00:00
|
|
|
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 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Here variables, arrays and structures were definied.
|
2000-09-18 15:18:56 +00:00
|
|
|
// DIM/PRIVATE/PUBLIC/GLOBAL
|
|
|
|
|
|
|
|
void SbiParser::Dim()
|
|
|
|
{
|
2012-08-19 17:49:02 +09:00
|
|
|
DefVar( _DIM, ( pProc && bVBASupportOn ) ? pProc->IsStatic() : false );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2012-08-19 17:49:02 +09:00
|
|
|
void SbiParser::DefVar( SbiOpcode eOp, bool bStatic )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
SbiSymPool* pOldPool = pPool;
|
2012-08-19 17:49:02 +09:00
|
|
|
bool bSwitchPool = false;
|
|
|
|
bool bPersistantGlobal = false;
|
2004-03-17 12:32:57 +00:00
|
|
|
SbiToken eFirstTok = eCurTok;
|
2013-07-23 12:42:37 +02:00
|
|
|
|
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
|
|
|
{
|
2012-08-19 17:49:02 +09:00
|
|
|
bSwitchPool = true; // at the right moment switch to the global pool
|
2001-09-04 09:04:24 +00:00
|
|
|
if( eCurTok == GLOBAL )
|
2012-08-19 17:49:02 +09:00
|
|
|
bPersistantGlobal = true;
|
2001-09-04 09:04:24 +00:00
|
|
|
}
|
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 )
|
2012-08-19 17:49:02 +09:00
|
|
|
bPersistantGlobal = true;
|
2010-11-21 19:56:23 +01:00
|
|
|
// PRIVATE is a synonymous for DIM
|
2000-09-18 15:18:56 +00:00
|
|
|
// _CONST_?
|
2012-08-19 17:49:02 +09:00
|
|
|
bool bConst = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
if( eCurTok == _CONST_ )
|
2012-08-19 17:49:02 +09:00
|
|
|
bConst = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
else if( Peek() == _CONST_ )
|
2012-08-19 17:49:02 +09:00
|
|
|
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 );
|
2012-08-19 17:49:02 +09:00
|
|
|
bNewGblDefs = false;
|
2004-11-02 10:53:35 +00:00
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
Next();
|
2012-08-20 09:44:32 +09:00
|
|
|
DefProc( false, bPrivate );
|
2004-03-17 12:32:57 +00:00
|
|
|
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
|
2010-11-21 19:56:23 +01:00
|
|
|
// SHARED were ignored
|
2000-09-18 15:18:56 +00:00
|
|
|
if( Peek() == SHARED ) Next();
|
|
|
|
#ifdef tmpSHARED
|
|
|
|
#define SHARED
|
|
|
|
#undef tmpSHARED
|
|
|
|
#endif
|
2010-11-21 19:56:23 +01:00
|
|
|
// PRESERVE only at REDIM
|
2000-09-18 15:18:56 +00:00
|
|
|
if( Peek() == PRESERVE )
|
|
|
|
{
|
|
|
|
Next();
|
|
|
|
if( eOp == _REDIM )
|
|
|
|
eOp = _REDIMP;
|
|
|
|
else
|
|
|
|
Error( SbERR_UNEXPECTED, eCurTok );
|
|
|
|
}
|
|
|
|
SbiSymDef* pDef;
|
|
|
|
SbiDimList* pDim;
|
|
|
|
|
2011-03-21 12:55:40 +01:00
|
|
|
// #40689, Statics -> Modul-Initialising, skip in Sub
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_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 );
|
2010-11-21 19:56:23 +01:00
|
|
|
aGen.Statement(); // catch up on static here
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2012-08-19 17:49:02 +09:00
|
|
|
bool bDefined = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
while( ( pDef = VarDecl( &pDim, bStatic, bConst ) ) != NULL )
|
|
|
|
{
|
GSOC work week 2, getting infromation from variables and print on terminal
This is an early version. I use the BASIC parser to parse the source,
then the infromation is extracted from the symbol table built by parser.
Error reporting is suppressed, beacuse it is not needed fro code completition.
I placed my function inside SbModule, and created a struct called CodeCompletitionData, which holds the object's name, it's parent, and it's type name.
This function, SbMethod::GetCodeCompleteDataFromParse() is called from Basic IDE's Notify function, which updates a cache(actually, reassigns a viariable :) ).
Later, in the EditorWindow::KeyInput function there is a check wheteher dot key is pressed. After that, the actual variable (or word) is being looked up in the vector that holds code completition data. And finally, if it is found, it's methods are printed on the terminal.
Change-Id: Idaf19baa8f720b8b117a76dc3cc2f90dd04fd155
2013-06-21 14:10:31 +02:00
|
|
|
/*fprintf(stderr, "Actual sub: \n");
|
|
|
|
fprintf(stderr, "Symbol name: %s\n",OUStringToOString(pDef->GetName(),RTL_TEXTENCODING_UTF8).getStr());*/
|
2000-09-18 15:18:56 +00:00
|
|
|
EnableErrors();
|
2010-11-21 19:56:23 +01:00
|
|
|
// search variable:
|
2000-09-18 15:18:56 +00:00
|
|
|
if( bSwitchPool )
|
|
|
|
pPool = &aGlobals;
|
|
|
|
SbiSymDef* pOld = pPool->Find( pDef->GetName() );
|
2011-03-21 12:55:40 +01:00
|
|
|
// search also in the Runtime-Library
|
2012-08-19 17:49:02 +09:00
|
|
|
bool bRtlSym = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
if( !pOld )
|
|
|
|
{
|
|
|
|
pOld = CheckRTLForSym( pDef->GetName(), SbxVARIANT );
|
|
|
|
if( pOld )
|
2012-08-19 17:49:02 +09:00
|
|
|
bRtlSym = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
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 )
|
|
|
|
{
|
2012-08-19 17:49:02 +09:00
|
|
|
bDefined = true;
|
2010-11-21 19:56:23 +01:00
|
|
|
// always an error at a RTL-S
|
2000-09-18 15:18:56 +00:00
|
|
|
if( !bRtlSym && (eOp == _REDIM || eOp == _REDIMP) )
|
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// compare the attributes at a REDIM
|
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 );
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// #36374: Create the variable in front of the distinction IsNew()
|
|
|
|
// Otherwise error at Dim Identifier As New Type and 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
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// Declare variable or global constant
|
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;
|
2011-03-21 12:55:40 +01:00
|
|
|
// #40689, no own Opcode anymore
|
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;
|
2012-08-19 17:49:02 +09:00
|
|
|
bGblDefs = bNewGblDefs = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
break;
|
2006-06-19 16:41:17 +00:00
|
|
|
default: eOp2 = _LOCAL;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt32 nOpnd2 = sal::static_int_cast< sal_uInt16 >( pDef->GetType() );
|
2010-06-15 20:02:53 +02:00
|
|
|
if( pDef->IsWithEvents() )
|
|
|
|
nOpnd2 |= SBX_TYPE_WITH_EVENTS_FLAG;
|
|
|
|
|
2010-09-09 12:45:01 +02:00
|
|
|
if( bCompatible && pDef->IsNew() )
|
|
|
|
nOpnd2 |= SBX_TYPE_DIM_AS_NEW_FLAG;
|
|
|
|
|
2010-06-15 20:02:53 +02:00
|
|
|
short nFixedStringLength = pDef->GetFixedStringLength();
|
|
|
|
if( nFixedStringLength >= 0 )
|
2011-01-10 14:40:57 +01:00
|
|
|
nOpnd2 |= (SBX_FIXED_LEN_STRING_FLAG + (sal_uInt32(nFixedStringLength) << 17)); // len = all bits above 0x10000
|
2010-06-15 20:02:53 +02:00
|
|
|
|
2011-03-25 10:40:25 +01:00
|
|
|
if( pDim != NULL && pDim->GetDims() > 0 )
|
|
|
|
nOpnd2 |= SBX_TYPE_VAR_TO_DIM_FLAG;
|
|
|
|
|
2010-06-15 20:02:53 +02:00
|
|
|
aGen.Gen( eOp2, pDef->GetId(), nOpnd2 );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Initialising for self-defined daty types
|
|
|
|
// and per NEW created variable
|
2000-09-18 15:18:56 +00:00
|
|
|
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() )
|
|
|
|
{
|
2012-11-06 23:34:23 -06:00
|
|
|
OUString aTypeName( aGblStrings.Find( pDef->GetTypeId() ) );
|
2013-07-23 12:42:37 +02:00
|
|
|
if( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) == NULL )
|
2012-11-06 23:34:23 -06:00
|
|
|
{
|
2013-08-20 13:29:18 +02:00
|
|
|
if( CodeCompleteOptions::IsExtendedTypeDeclaration() )
|
2013-07-23 12:42:37 +02:00
|
|
|
{
|
|
|
|
if(!IsUnoInterface(aTypeName))
|
|
|
|
Error( SbERR_UNDEF_TYPE, aTypeName );
|
|
|
|
}
|
2013-08-20 13:29:18 +02:00
|
|
|
else
|
|
|
|
Error( SbERR_UNDEF_TYPE, aTypeName );
|
2012-11-06 23:34:23 -06:00
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
}
|
|
|
|
|
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() );
|
2010-10-06 10:16:27 +01:00
|
|
|
if ( bVBASupportOn )
|
|
|
|
aGen.Gen( _VBASET );
|
|
|
|
else
|
|
|
|
aGen.Gen( _SET );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( bConst )
|
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// Definition of the constants
|
2000-09-18 15:18:56 +00:00
|
|
|
if( pDim )
|
|
|
|
{
|
|
|
|
Error( SbERR_SYNTAX );
|
|
|
|
delete pDim;
|
|
|
|
}
|
|
|
|
SbiExpression aVar( this, *pDef );
|
|
|
|
if( !TestToken( EQ ) )
|
2011-03-21 12:55:40 +01:00
|
|
|
goto MyBreak; // (see below)
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiConstExpression aExpr( this );
|
|
|
|
if( !bDefined && aExpr.IsValid() )
|
|
|
|
{
|
|
|
|
if( pDef->GetScope() == SbGLOBAL )
|
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// Create code only for the global constant!
|
2000-09-18 15:18:56 +00:00
|
|
|
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 )
|
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// Dimension the variable
|
|
|
|
// Delete the var at REDIM beforehand
|
2000-09-18 15:18:56 +00:00
|
|
|
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 )
|
2011-01-10 14:40:57 +01:00
|
|
|
pDef->SetGlobal( sal_True );
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiExpression aExpr( this, *pDef, pDim );
|
|
|
|
aExpr.Gen();
|
2011-01-10 14:40:57 +01:00
|
|
|
pDef->SetGlobal( sal_False );
|
2000-09-18 15:18:56 +00:00
|
|
|
aGen.Gen( (eOp == _STATIC) ? _DIM : eOp );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( !TestComma() )
|
2011-03-21 12:55:40 +01:00
|
|
|
goto MyBreak;
|
2010-11-21 19:56:23 +01:00
|
|
|
|
|
|
|
// Implementation of bSwitchPool (see above): pPool must not be set to &aGlobals
|
|
|
|
// at the VarDecl-Call.
|
|
|
|
// Apart from that the behavior should be absolutely identical,
|
|
|
|
// i.e., pPool had to be reset always at the end of the loop.
|
|
|
|
// also at a break
|
2000-09-18 15:18:56 +00:00
|
|
|
pPool = pOldPool;
|
2010-11-21 19:56:23 +01:00
|
|
|
continue; // Skip MyBreak
|
2000-09-18 15:18:56 +00:00
|
|
|
MyBreak:
|
|
|
|
pPool = pOldPool;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-03-21 12:55:40 +01:00
|
|
|
// #40689, finalize the jump over statics declarations
|
2008-07-02 08:57:46 +00:00
|
|
|
if( !bVBASupportOn && bStatic )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// maintain the global chain
|
2000-09-18 15:18:56 +00:00
|
|
|
nGblChain = aGen.Gen( _JUMP, 0 );
|
2012-08-19 17:49:02 +09:00
|
|
|
bGblDefs = bNewGblDefs = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Register for Sub a jump to the end of statics
|
2000-09-18 15:18:56 +00:00
|
|
|
aGen.BackChain( nEndOfStaticLbl );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Here were Arrays redimensioned.
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
void SbiParser::ReDim()
|
|
|
|
{
|
2012-08-19 17:49:02 +09: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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Declaration of a data type
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
void SbiParser::Type()
|
|
|
|
{
|
2012-08-20 09:44:32 +09:00
|
|
|
DefType( false );
|
2004-11-15 15:41:23 +00:00
|
|
|
}
|
|
|
|
|
2012-08-20 09:44:32 +09:00
|
|
|
void SbiParser::DefType( bool bPrivate )
|
2004-11-15 15:41:23 +00:00
|
|
|
{
|
|
|
|
// TODO: Use bPrivate
|
2006-06-19 16:41:17 +00:00
|
|
|
(void)bPrivate;
|
2004-11-15 15:41:23 +00:00
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Read the new Token lesen. It had to be a symbol
|
2000-09-18 15:18:56 +00:00
|
|
|
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;
|
2012-08-19 17:49:02 +09:00
|
|
|
bool bDone = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
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;
|
2012-08-19 17:49:02 +09:00
|
|
|
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:
|
2012-08-19 17:49:02 +09:00
|
|
|
pElem = VarDecl(&pDim, false, false);
|
2004-09-09 06:43:08 +00:00
|
|
|
if( !pElem )
|
2012-08-19 17:49:02 +09:00
|
|
|
bDone = true; // Error occurred
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
if( pElem )
|
|
|
|
{
|
2010-06-15 20:02:53 +02:00
|
|
|
SbxArray *pTypeMembers = pType->GetProperties();
|
2012-11-06 23:34:23 -06:00
|
|
|
OUString aElemName = pElem->GetName();
|
2010-06-15 20:02:53 +02:00
|
|
|
if( pTypeMembers->Find( aElemName, SbxCLASS_DONTCARE) )
|
2012-11-06 23:34:23 -06:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error (SbERR_VAR_DEFINED);
|
2012-11-06 23:34:23 -06:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
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 )
|
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_Int32 lb = nBase;
|
2010-02-12 16:56:44 +01:00
|
|
|
SbiExprNode* pNode = pDim->Get(i)->GetExprNode();
|
2013-02-12 14:47:52 +01:00
|
|
|
sal_Int32 ub = pNode->GetNumber();
|
2010-02-12 16:56:44 +01:00
|
|
|
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
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nSavFlags = pTypeElem->GetFlags();
|
2010-02-12 16:56:44 +01:00
|
|
|
// 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 )
|
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nElemTypeId = pElem->GetTypeId();
|
2010-06-15 20:02:53 +02:00
|
|
|
if( nElemTypeId != 0 )
|
|
|
|
{
|
2012-11-06 23:34:23 -06:00
|
|
|
OUString aTypeName( aGblStrings.Find( nElemTypeId ) );
|
2010-06-15 20:02:53 +02:00
|
|
|
SbxObject* pTypeObj = static_cast< SbxObject* >( rTypeArray->Find( aTypeName, SbxCLASS_OBJECT ) );
|
|
|
|
if( pTypeObj != NULL )
|
|
|
|
{
|
|
|
|
SbxObject* pCloneObj = cloneTypeObjectImpl( *pTypeObj );
|
|
|
|
pTypeElem->PutObject( pCloneObj );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
pTypeMembers->Insert( pTypeElem, pTypeMembers->Count() );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2011-05-16 12:31:19 +02:00
|
|
|
delete pDim, pDim = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
delete pElem;
|
|
|
|
}
|
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
pType->Remove( OUString("Name"), SbxCLASS_DONTCARE );
|
|
|
|
pType->Remove( OUString("Parent"), SbxCLASS_DONTCARE );
|
2004-03-17 12:32:57 +00:00
|
|
|
|
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()
|
|
|
|
{
|
2012-08-20 09:44:32 +09:00
|
|
|
DefEnum( false );
|
2004-11-15 15:41:23 +00:00
|
|
|
}
|
|
|
|
|
2012-08-20 09:44:32 +09:00
|
|
|
void SbiParser::DefEnum( bool bPrivate )
|
2004-11-15 15:41:23 +00:00
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// Read a the new Token. It had to be a symbol
|
2004-11-15 15:41:23 +00:00
|
|
|
if (!TestSymbol())
|
|
|
|
return;
|
|
|
|
|
2012-11-06 23:34:23 -06:00
|
|
|
OUString aEnumName = aSym;
|
2004-11-15 15:41:23 +00:00
|
|
|
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 )
|
2012-11-06 23:34:23 -06:00
|
|
|
{
|
2004-11-15 15:41:23 +00:00
|
|
|
pEnum->SetFlag( SBX_PRIVATE );
|
2012-11-06 23:34:23 -06:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiSymDef* pElem;
|
|
|
|
SbiDimList* pDim;
|
2012-08-19 17:49:02 +09:00
|
|
|
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;
|
2012-08-19 17:49:02 +09:00
|
|
|
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!
|
2012-08-19 17:49:02 +09:00
|
|
|
bool bDefined = false;
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
|
|
pDim = NULL;
|
2012-08-19 17:49:02 +09:00
|
|
|
pElem = VarDecl( &pDim, false, true );
|
2004-11-15 15:41:23 +00:00
|
|
|
if( !pElem )
|
|
|
|
{
|
2012-08-19 17:49:02 +09:00
|
|
|
bDone = true; // Error occurred
|
2004-11-15 15:41:23 +00:00
|
|
|
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 );
|
2012-08-19 17:49:02 +09:00
|
|
|
bDone = true; // Error occurred
|
2004-11-15 15:41:23 +00:00
|
|
|
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() );
|
2012-08-19 17:49:02 +09:00
|
|
|
bDone = true; // Error occurred
|
2004-11-15 15:41:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
pPool->Add( pElem );
|
|
|
|
|
|
|
|
if( !bPrivate )
|
|
|
|
{
|
|
|
|
SbiOpcode eOp = _GLOBAL;
|
|
|
|
aGen.BackChain( nGblChain );
|
|
|
|
nGblChain = 0;
|
2012-08-19 17:49:02 +09:00
|
|
|
bGblDefs = bNewGblDefs = true;
|
2006-10-12 13:26:32 +00:00
|
|
|
aGen.Gen(
|
|
|
|
eOp, pElem->GetId(),
|
2011-01-10 14:40:57 +01:00
|
|
|
sal::static_int_cast< sal_uInt16 >( pElem->GetType() ) );
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
|
|
aVar.Gen();
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nStringId = aGen.GetParser()->aGblStrings.Add( nCurrentEnumValue, SbxLONG );
|
2004-11-15 15:41:23 +00:00
|
|
|
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
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
pEnum->Remove( OUString("Name"), SbxCLASS_DONTCARE );
|
|
|
|
pEnum->Remove( OUString("Parent"), SbxCLASS_DONTCARE );
|
2004-11-15 15:41:23 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Procedure-Declaration
|
|
|
|
// the first Token is already read in (SUB/FUNCTION)
|
2000-09-18 15:18:56 +00:00
|
|
|
// xxx Name [LIB "name"[ALIAS "name"]][(Parameter)][AS TYPE]
|
|
|
|
|
2012-08-19 17:49:02 +09:00
|
|
|
SbiProcDef* SbiParser::ProcDecl( bool bDecl )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2012-08-19 17:49:02 +09:00
|
|
|
bool bFunc = ( eCurTok == FUNCTION );
|
|
|
|
bool bProp = ( eCurTok == GET || eCurTok == SET || eCurTok == LET );
|
2000-09-18 15:18:56 +00:00
|
|
|
if( !TestSymbol() ) return NULL;
|
2012-11-06 23:34:23 -06:00
|
|
|
OUString aName( aSym );
|
2000-09-18 15:18:56 +00:00
|
|
|
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 )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
pDef->GetLib() = aSym;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
else
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_SYNTAX );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
if( Peek() == ALIAS )
|
|
|
|
{
|
|
|
|
Next();
|
|
|
|
if( Next() == FIXSTRING )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
pDef->GetAlias() = aSym;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
else
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_SYNTAX );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
if( !bDecl )
|
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// CDECL, LIB and ALIAS are invalid
|
2012-11-06 23:34:23 -06:00
|
|
|
if( !pDef->GetLib().isEmpty() )
|
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_UNEXPECTED, LIB );
|
2012-11-06 23:34:23 -06:00
|
|
|
}
|
|
|
|
if( !pDef->GetAlias().isEmpty() )
|
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_UNEXPECTED, ALIAS );
|
2012-11-06 23:34:23 -06:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
if( pDef->IsCdecl() )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_UNEXPECTED, _CDECL_ );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2012-08-22 19:20:19 +09:00
|
|
|
pDef->SetCdecl( false );
|
2012-11-06 23:34:23 -06:00
|
|
|
pDef->GetLib() = "";
|
|
|
|
pDef->GetAlias() = "";
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2012-11-06 23:34:23 -06:00
|
|
|
else if( pDef->GetLib().isEmpty() )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// ALIAS and CDECL only together with LIB
|
2012-11-06 23:34:23 -06:00
|
|
|
if( !pDef->GetAlias().isEmpty() )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_UNEXPECTED, ALIAS );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
if( pDef->IsCdecl() )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_UNEXPECTED, _CDECL_ );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2012-08-22 19:20:19 +09:00
|
|
|
pDef->SetCdecl( false );
|
2012-11-06 23:34:23 -06:00
|
|
|
pDef->GetAlias() = "";
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2010-11-21 19:56:23 +01:00
|
|
|
// Brackets?
|
2000-09-18 15:18:56 +00:00
|
|
|
if( Peek() == LPAREN )
|
|
|
|
{
|
|
|
|
Next();
|
|
|
|
if( Peek() == RPAREN )
|
2012-11-06 23:34:23 -06:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Next();
|
2012-11-06 23:34:23 -06:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
else
|
2012-11-06 23:34:23 -06:00
|
|
|
{
|
|
|
|
for(;;)
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2012-11-06 23:34:23 -06:00
|
|
|
bool bByVal = false;
|
|
|
|
bool bOptional = false;
|
|
|
|
bool bParamArray = false;
|
|
|
|
while( Peek() == BYVAL || Peek() == BYREF || Peek() == _OPTIONAL_ )
|
2004-03-17 12:32:57 +00:00
|
|
|
{
|
2012-11-06 23:34:23 -06:00
|
|
|
if( Peek() == BYVAL )
|
|
|
|
{
|
|
|
|
bByVal = true;
|
|
|
|
}
|
|
|
|
else if ( Peek() == BYREF )
|
|
|
|
{
|
|
|
|
bByVal = false;
|
|
|
|
}
|
|
|
|
else if ( Peek() == _OPTIONAL_ )
|
|
|
|
{
|
|
|
|
bOptional = true;
|
|
|
|
}
|
|
|
|
Next();
|
|
|
|
}
|
|
|
|
if( bCompatible && Peek() == PARAMARRAY )
|
|
|
|
{
|
|
|
|
if( bByVal || bOptional )
|
|
|
|
{
|
|
|
|
Error( SbERR_UNEXPECTED, PARAMARRAY );
|
|
|
|
}
|
|
|
|
Next();
|
|
|
|
bParamArray = true;
|
|
|
|
}
|
|
|
|
SbiSymDef* pPar = VarDecl( NULL, false, false );
|
|
|
|
if( !pPar )
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if( bByVal )
|
|
|
|
{
|
|
|
|
pPar->SetByVal();
|
|
|
|
}
|
|
|
|
if( bOptional )
|
|
|
|
{
|
|
|
|
pPar->SetOptional();
|
|
|
|
}
|
|
|
|
if( bParamArray )
|
|
|
|
{
|
|
|
|
pPar->SetParamArray();
|
|
|
|
}
|
|
|
|
pDef->GetParams().Add( pPar );
|
|
|
|
SbiToken eTok = Next();
|
|
|
|
if( eTok != COMMA && eTok != RPAREN )
|
|
|
|
{
|
|
|
|
bool bError2 = true;
|
|
|
|
if( bOptional && bCompatible && eTok == EQ )
|
|
|
|
{
|
|
|
|
SbiConstExpression* pDefaultExpr = new SbiConstExpression( this );
|
|
|
|
SbxDataType eType2 = pDefaultExpr->GetType();
|
2004-03-17 12:32:57 +00:00
|
|
|
|
2012-11-06 23:34:23 -06:00
|
|
|
sal_uInt16 nStringId;
|
|
|
|
if( eType2 == SbxSTRING )
|
|
|
|
{
|
|
|
|
nStringId = aGblStrings.Add( pDefaultExpr->GetString() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nStringId = aGblStrings.Add( pDefaultExpr->GetValue(), eType2 );
|
|
|
|
}
|
|
|
|
pPar->SetDefaultId( nStringId );
|
|
|
|
delete pDefaultExpr;
|
2004-03-17 12:32:57 +00:00
|
|
|
|
2012-11-06 23:34:23 -06:00
|
|
|
eTok = Next();
|
|
|
|
if( eTok == COMMA || eTok == RPAREN )
|
|
|
|
{
|
|
|
|
bError2 = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( bError2 )
|
|
|
|
{
|
|
|
|
Error( SbERR_EXPECTED, RPAREN );
|
|
|
|
break;
|
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
}
|
2012-11-06 23:34:23 -06:00
|
|
|
if( eTok == RPAREN )
|
2004-03-17 12:32:57 +00:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TypeDecl( *pDef );
|
|
|
|
if( eType != SbxVARIANT && pDef->GetType() != eType )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_BAD_DECLARATION, aName );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-02-12 16:56:44 +01:00
|
|
|
if( pDef->GetType() == SbxVARIANT && !( bFunc || bProp ) )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
pDef->SetType( SbxEMPTY );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
return pDef;
|
|
|
|
}
|
|
|
|
|
|
|
|
// DECLARE
|
|
|
|
|
|
|
|
void SbiParser::Declare()
|
|
|
|
{
|
2012-08-20 09:44:32 +09:00
|
|
|
DefDeclare( false );
|
2010-02-12 16:56:44 +01:00
|
|
|
}
|
|
|
|
|
2012-08-20 09:44:32 +09:00
|
|
|
void SbiParser::DefDeclare( bool bPrivate )
|
2010-02-12 16:56:44 +01:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Next();
|
|
|
|
if( eCurTok != SUB && eCurTok != FUNCTION )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_UNEXPECTED, eCurTok );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
else
|
|
|
|
{
|
2010-08-06 09:35:51 +02:00
|
|
|
bool bFunction = (eCurTok == FUNCTION);
|
|
|
|
|
2012-08-19 17:49:02 +09:00
|
|
|
SbiProcDef* pDef = ProcDecl( true );
|
2000-09-18 15:18:56 +00:00
|
|
|
if( pDef )
|
|
|
|
{
|
2012-11-06 23:34:23 -06:00
|
|
|
if( pDef->GetLib().isEmpty() )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
Error( SbERR_EXPECTED, LIB );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-11-21 19:56:23 +01:00
|
|
|
// Is it already there?
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiSymDef* pOld = aPublics.Find( pDef->GetName() );
|
|
|
|
if( pOld )
|
|
|
|
{
|
|
|
|
SbiProcDef* p = pOld->GetProcDef();
|
|
|
|
if( !p )
|
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// Declared as a variable
|
2000-09-18 15:18:56 +00:00
|
|
|
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
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
pDef->Match( p );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
else
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
aPublics.Add( pDef );
|
2012-11-03 09:07:25 -05: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
|
2012-11-06 23:34:23 -06:00
|
|
|
if( !pDef->GetLib().isEmpty())
|
2010-08-06 09:35:51 +02:00
|
|
|
{
|
2010-08-11 08:24:45 +02:00
|
|
|
if( bNewGblDefs && nGblChain == 0 )
|
|
|
|
{
|
|
|
|
nGblChain = aGen.Gen( _JUMP, 0 );
|
2012-08-19 17:49:02 +09:00
|
|
|
bNewGblDefs = false;
|
2010-08-11 08:24:45 +02:00
|
|
|
}
|
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nSavLine = nLine;
|
2010-08-06 09:35:51 +02:00
|
|
|
aGen.Statement();
|
|
|
|
pDef->Define();
|
|
|
|
pDef->SetLine1( nSavLine );
|
|
|
|
pDef->SetLine2( nSavLine );
|
|
|
|
|
|
|
|
SbiSymPool& rPool = pDef->GetParams();
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nParCount = rPool.GetSize();
|
2010-08-06 09:35:51 +02:00
|
|
|
|
|
|
|
SbxDataType eType = pDef->GetType();
|
|
|
|
if( bFunction )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
aGen.Gen( _PARAM, 0, sal::static_int_cast< sal_uInt16 >( eType ) );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-08-06 09:35:51 +02:00
|
|
|
if( nParCount > 1 )
|
|
|
|
{
|
|
|
|
aGen.Gen( _ARGC );
|
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
for( sal_uInt16 i = 1 ; i < nParCount ; ++i )
|
2010-08-06 09:35:51 +02:00
|
|
|
{
|
|
|
|
SbiSymDef* pParDef = rPool.Get( i );
|
|
|
|
SbxDataType eParType = pParDef->GetType();
|
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
aGen.Gen( _PARAM, i, sal::static_int_cast< sal_uInt16 >( eParType ) );
|
2010-08-06 09:35:51 +02:00
|
|
|
aGen.Gen( _ARGV );
|
|
|
|
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nTyp = sal::static_int_cast< sal_uInt16 >( pParDef->GetType() );
|
2010-08-06 09:35:51 +02:00
|
|
|
if( pParDef->IsByVal() )
|
|
|
|
{
|
|
|
|
// Reset to avoid additional byval in call to wrapper function
|
2011-01-10 14:40:57 +01:00
|
|
|
pParDef->SetByVal( sal_False );
|
2010-08-06 09:35:51 +02:00
|
|
|
nTyp |= 0x8000;
|
|
|
|
}
|
|
|
|
aGen.Gen( _ARGTYP, nTyp );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
aGen.Gen( _LIB, aGblStrings.Add( pDef->GetLib() ) );
|
|
|
|
|
|
|
|
SbiOpcode eOp = pDef->IsCdecl() ? _CALLC : _CALL;
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 nId = pDef->GetId();
|
2012-11-06 23:34:23 -06:00
|
|
|
if( !pDef->GetAlias().isEmpty() )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2010-08-06 09:35:51 +02:00
|
|
|
nId = ( nId & 0x8000 ) | aGblStrings.Add( pDef->GetAlias() );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-08-06 09:35:51 +02:00
|
|
|
if( nParCount > 1 )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2010-08-06 09:35:51 +02:00
|
|
|
nId |= 0x8000;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2011-01-10 14:40:57 +01:00
|
|
|
aGen.Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( eType ) );
|
2010-08-06 09:35:51 +02:00
|
|
|
|
|
|
|
if( bFunction )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2010-08-06 09:35:51 +02:00
|
|
|
aGen.Gen( _PUT );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-08-06 09:35:51 +02:00
|
|
|
aGen.Gen( _LEAVE );
|
|
|
|
}
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-06 10:16:27 +01:00
|
|
|
void SbiParser::Attribute()
|
|
|
|
{
|
|
|
|
// TODO: Need to implement the method as an attributed object.
|
|
|
|
while( Next() != EQ )
|
|
|
|
{
|
|
|
|
if( Next() != DOT)
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2010-10-06 10:16:27 +01:00
|
|
|
break;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-10-06 10:16:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if( eCurTok != EQ )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2010-10-06 10:16:27 +01:00
|
|
|
Error( SbERR_SYNTAX );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-10-06 10:16:27 +01:00
|
|
|
else
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2010-10-06 10:16:27 +01:00
|
|
|
SbiExpression aValue( this );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-10-06 10:16:27 +01:00
|
|
|
// Don't generate any code - just discard it.
|
|
|
|
}
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Call of a SUB or a FUNCTION
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
void SbiParser::Call()
|
|
|
|
{
|
|
|
|
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()
|
|
|
|
{
|
2012-08-20 09:44:32 +09:00
|
|
|
DefProc( false, false );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Read in of a procedure
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2012-08-20 09:44:32 +09:00
|
|
|
void SbiParser::DefProc( bool bStatic, bool bPrivate )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
sal_uInt16 l1 = nLine, l2 = nLine;
|
2012-08-19 17:49:02 +09:00
|
|
|
bool bSub = ( eCurTok == SUB );
|
|
|
|
bool bProperty = ( eCurTok == PROPERTY );
|
2004-11-02 10:53:35 +00:00
|
|
|
PropertyMode ePropertyMode = PROPERTY_MODE_NONE;
|
|
|
|
if( bProperty )
|
|
|
|
{
|
|
|
|
Next();
|
|
|
|
if( eCurTok == GET )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2004-11-02 10:53:35 +00:00
|
|
|
ePropertyMode = PROPERTY_MODE_GET;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2004-11-02 10:53:35 +00:00
|
|
|
else if( eCurTok == LET )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2004-11-02 10:53:35 +00:00
|
|
|
ePropertyMode = PROPERTY_MODE_LET;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2004-11-02 10:53:35 +00:00
|
|
|
else if( eCurTok == SET )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2004-11-02 10:53:35 +00:00
|
|
|
ePropertyMode = PROPERTY_MODE_SET;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2004-11-02 10:53:35 +00:00
|
|
|
else
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2004-11-02 10:53:35 +00:00
|
|
|
Error( SbERR_EXPECTED, "Get or Let or Set" );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2004-11-02 10:53:35 +00:00
|
|
|
}
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
SbiToken eExit = eCurTok;
|
2012-08-19 17:49:02 +09:00
|
|
|
SbiProcDef* pDef = ProcDecl( false );
|
2000-09-18 15:18:56 +00:00
|
|
|
if( !pDef )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
return;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2004-11-02 10:53:35 +00:00
|
|
|
pDef->setPropertyMode( ePropertyMode );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Is the Proc already declared?
|
2000-09-18 15:18:56 +00:00
|
|
|
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 )
|
|
|
|
{
|
2010-11-21 19:56:23 +01:00
|
|
|
// Declared as a variable
|
2000-09-18 15:18:56 +00:00
|
|
|
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
|
2011-07-12 11:31:47 +02:00
|
|
|
else if( 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
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
aPublics.Add( pDef ), pProc = pDef;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
if( !pProc )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
return;
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2004-03-17 12:32:57 +00:00
|
|
|
pProc->SetPublic( !bPrivate );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2010-11-21 19:56:23 +01:00
|
|
|
// Now we set the search hierarchy for symbols as well as the
|
|
|
|
// current procedure.
|
2000-09-18 15:18:56 +00:00
|
|
|
aPublics.SetProcId( pProc->GetId() );
|
|
|
|
pProc->GetParams().SetParent( &aPublics );
|
2008-07-02 08:57:46 +00:00
|
|
|
if( bStatic )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2008-07-02 08:57:46 +00:00
|
|
|
if ( bVBASupportOn )
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
pProc->SetStatic( sal_True );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2008-07-02 08:57:46 +00:00
|
|
|
else
|
2012-11-03 09:07:25 -05:00
|
|
|
{
|
2008-07-02 08:57:46 +00:00
|
|
|
Error( SbERR_NOT_IMPLEMENTED ); // STATIC SUB ...
|
|
|
|
}
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
|
|
|
else
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2011-01-10 14:40:57 +01:00
|
|
|
pProc->SetStatic( sal_False );
|
2012-11-03 09:07:25 -05:00
|
|
|
}
|
2010-11-21 19:56:23 +01:00
|
|
|
// Normal case: Local variable->parameter->global variable
|
2008-07-02 08:57:46 +00:00
|
|
|
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 );
|
2010-11-21 19:56:23 +01:00
|
|
|
// Open labels?
|
2000-09-18 15:18:56 +00:00
|
|
|
pProc->GetLabels().CheckRefs();
|
|
|
|
CloseBlock();
|
|
|
|
aGen.Gen( _LEAVE );
|
|
|
|
pProc = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// STATIC variable|procedure
|
|
|
|
|
|
|
|
void SbiParser::Static()
|
2004-03-17 12:32:57 +00:00
|
|
|
{
|
2012-08-20 09:44:32 +09:00
|
|
|
DefStatic( false );
|
2004-03-17 12:32:57 +00:00
|
|
|
}
|
|
|
|
|
2012-08-20 09:44:32 +09:00
|
|
|
void SbiParser::DefStatic( bool bPrivate )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2012-11-03 09:07:25 -05:00
|
|
|
SbiSymPool* p;
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
switch( Peek() )
|
|
|
|
{
|
2012-11-03 09:07:25 -05:00
|
|
|
case SUB:
|
|
|
|
case FUNCTION:
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
Next();
|
|
|
|
DefProc( true, bPrivate );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if( !pProc )
|
|
|
|
{
|
|
|
|
Error( SbERR_NOT_IN_SUBR );
|
|
|
|
}
|
|
|
|
// Reset the Pool, so that STATIC-Declarations go into the
|
|
|
|
// global Pool
|
|
|
|
p = pPool;
|
|
|
|
pPool = &aPublics;
|
|
|
|
DefVar( _STATIC, true );
|
|
|
|
pPool = p;
|
|
|
|
break;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-17 13:07:05 +02:00
|
|
|
bool SbiParser::IsUnoInterface(const OUString& sTypeName)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Reference< lang::XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory(), UNO_SET_THROW );
|
|
|
|
Reference< reflection::XIdlReflection > xRefl( xFactory->createInstance("com.sun.star.reflection.CoreReflection"), UNO_QUERY_THROW );
|
|
|
|
//DBG_ASSERT(xRefl.Is(), "No reflection class!"); ???
|
|
|
|
if( !xRefl.is() )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Reference< reflection::XIdlClass > xClass = xRefl->forName(sTypeName);
|
|
|
|
if( xClass != NULL )
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
catch(const Exception& ex)
|
|
|
|
{
|
|
|
|
OSL_FAIL("Could not create reflection.CoreReflection.");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-10-12 15:53:47 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|