summaryrefslogtreecommitdiff
path: root/binfilter/bf_basic/source/comp
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_basic/source/comp')
-rw-r--r--binfilter/bf_basic/source/comp/buffer.cxx173
-rw-r--r--binfilter/bf_basic/source/comp/codegen.cxx232
-rw-r--r--binfilter/bf_basic/source/comp/makefile.mk64
-rw-r--r--binfilter/bf_basic/source/comp/parser.cxx872
-rw-r--r--binfilter/bf_basic/source/comp/sbcomp.cxx113
-rw-r--r--binfilter/bf_basic/source/comp/scanner.cxx559
-rw-r--r--binfilter/bf_basic/source/comp/token.cxx575
7 files changed, 2588 insertions, 0 deletions
diff --git a/binfilter/bf_basic/source/comp/buffer.cxx b/binfilter/bf_basic/source/comp/buffer.cxx
new file mode 100644
index 000000000000..7a2a65c845fb
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/buffer.cxx
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * 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.
+ *
+ * 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).
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "buffer.hxx"
+#include <string.h>
+
+namespace binfilter {
+
+const static UINT32 UP_LIMIT=0xFFFFFF00L;
+
+// Der SbiBuffer wird in Inkrements von mindestens 16 Bytes erweitert.
+// Dies ist notwendig, da viele Klassen von einer Pufferlaenge
+// von x*16 Bytes ausgehen.
+
+SbiBuffer::SbiBuffer( SbiParser* p, short n )
+{
+ pParser = p;
+ n = ( (n + 15 ) / 16 ) * 16;
+ if( !n ) n = 16;
+ pBuf = NULL;
+ pCur = NULL;
+ nInc = n;
+ nSize =
+ nOff = 0;
+}
+
+SbiBuffer::~SbiBuffer()
+{
+ delete[] pBuf;
+}
+
+// Rausreichen des Puffers
+// Dies fuehrt zur Loeschung des Puffers!
+
+char* SbiBuffer::GetBuffer()
+{
+ char* p = pBuf;
+ pBuf = NULL;
+ pCur = NULL;
+ return p;
+}
+
+// Test, ob der Puffer n Bytes aufnehmen kann.
+// Im Zweifelsfall wird er vergroessert
+
+BOOL SbiBuffer::Check( USHORT n )
+{
+ if( !n ) return TRUE;
+ if( ( static_cast<UINT32>( nOff )+ n ) > static_cast<UINT32>( nSize ) )
+ {
+ if( nInc == 0 )
+ return FALSE;
+ USHORT nn = 0;
+ while( nn < n ) nn = nn + nInc;
+ char* p;
+ if( ( static_cast<UINT32>( nSize ) + nn ) > UP_LIMIT ) p = NULL;
+ else p = new char [nSize + nn];
+ if( !p )
+ {
+/*?*/ // pParser->Error( SbERR_PROG_TOO_LARGE );
+ nInc = 0;
+ delete[] pBuf; pBuf = NULL;
+ return FALSE;
+ }
+ else
+ {
+ if( nSize ) memcpy( p, pBuf, nSize );
+ delete[] pBuf;
+ pBuf = p;
+ pCur = pBuf + nOff;
+ nSize = nSize + nn;
+ }
+ }
+ return TRUE;
+}
+
+BOOL SbiBuffer::operator +=( INT8 n )
+{
+ if( Check( 1 ) )
+ {
+ *pCur++ = (char) n; nOff++; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT8 n )
+{
+ if( Check( 1 ) )
+ {
+ *pCur++ = (char) n; nOff++; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( INT16 n )
+{
+ if( Check( 2 ) )
+ {
+ *pCur++ = (char) ( n & 0xFF );
+ *pCur++ = (char) ( n >> 8 );
+ nOff += 2; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT16 n )
+{
+ if( Check( 2 ) )
+ {
+ *pCur++ = (char) ( n & 0xFF );
+ *pCur++ = (char) ( n >> 8 );
+ nOff += 2; return TRUE;
+ } else return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( UINT32 n )
+{
+ if( Check( 4 ) )
+ {
+ UINT16 n1 = static_cast<UINT16>( n & 0xFFFF );
+ UINT16 n2 = static_cast<UINT16>( n >> 16 );
+ if ( operator +=( n1 ) && operator +=( n2 ) )
+ return TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL SbiBuffer::operator +=( INT32 n )
+{
+ return operator +=( (UINT32) n );
+}
+
+
+BOOL SbiBuffer::operator +=( const String& n )
+{
+ USHORT l = n.Len() + 1;
+ if( Check( l ) )
+ {
+ ByteString aByteStr( n, gsl_getSystemTextEncoding() );
+ memcpy( pCur, aByteStr.GetBuffer(), l );
+ pCur += l;
+ nOff = nOff + l;
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/codegen.cxx b/binfilter/bf_basic/source/comp/codegen.cxx
new file mode 100644
index 000000000000..7016206b345a
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/codegen.cxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * 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.
+ *
+ * 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).
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "sbx.hxx"
+#include "image.hxx"
+#include "buffer.hxx"
+#include "opcodes.hxx"
+#include "codegen.hxx"
+#include <limits>
+
+namespace binfilter {
+
+template < class T >
+class PCodeVisitor
+{
+public:
+ virtual ~PCodeVisitor();
+
+ virtual void start( BYTE* pStart ) = 0;
+ virtual void processOpCode0( SbiOpcode eOp ) = 0;
+ virtual void processOpCode1( SbiOpcode eOp, T nOp1 ) = 0;
+ virtual void processOpCode2( SbiOpcode eOp, T nOp1, T nOp2 ) = 0;
+ virtual bool processParams() = 0;
+ virtual void end() = 0;
+};
+
+template <class T> PCodeVisitor< T >::~PCodeVisitor()
+{}
+
+template <class T>
+class PCodeBufferWalker
+{
+private:
+ T m_nBytes;
+ BYTE* m_pCode;
+ T readParam( BYTE*& pCode )
+ {
+ short nBytes = sizeof( T );
+ T nOp1=0;
+ for ( int i=0; i<nBytes; ++i )
+ nOp1 |= *pCode++ << ( i * 8);
+ return nOp1;
+ }
+public:
+ PCodeBufferWalker( BYTE* pCode, T nBytes ): m_nBytes( nBytes ), m_pCode( pCode )
+ {
+ }
+ void visitBuffer( PCodeVisitor< T >& visitor )
+ {
+ BYTE* pCode = m_pCode;
+ if ( !pCode )
+ return;
+ BYTE* pEnd = pCode + m_nBytes;
+ visitor.start( m_pCode );
+ T nOp1 = 0, nOp2 = 0;
+ for( ; pCode < pEnd; )
+ {
+ SbiOpcode eOp = (SbiOpcode)(*pCode++);
+
+ if ( eOp <= SbOP0_END )
+ visitor.processOpCode0( eOp );
+ else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
+ {
+ if ( visitor.processParams() )
+ nOp1 = readParam( pCode );
+ else
+ pCode += sizeof( T );
+ visitor.processOpCode1( eOp, nOp1 );
+ }
+ else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
+ {
+ if ( visitor.processParams() )
+ {
+ nOp1 = readParam( pCode );
+ nOp2 = readParam( pCode );
+ }
+ else
+ pCode += ( sizeof( T ) * 2 );
+ visitor.processOpCode2( eOp, nOp1, nOp2 );
+ }
+ }
+ visitor.end();
+ }
+};
+
+template < class T, class S >
+class OffSetAccumulator : public PCodeVisitor< T >
+{
+ T m_nNumOp0;
+ T m_nNumSingleParams;
+ T m_nNumDoubleParams;
+public:
+
+ OffSetAccumulator() : m_nNumOp0(0), m_nNumSingleParams(0), m_nNumDoubleParams(0){}
+ virtual void start( BYTE* /*pStart*/ ){}
+ virtual void processOpCode0( SbiOpcode /*eOp*/ ){ ++m_nNumOp0; }
+ virtual void processOpCode1( SbiOpcode /*eOp*/, T /*nOp1*/ ){ ++m_nNumSingleParams; }
+ virtual void processOpCode2( SbiOpcode /*eOp*/, T /*nOp1*/, T /*nOp2*/ ) { ++m_nNumDoubleParams; }
+ virtual void end(){}
+ S offset()
+ {
+ T result = 0 ;
+ static const S max = std::numeric_limits< S >::max();
+ result = m_nNumOp0 + ( ( sizeof(S) + 1 ) * m_nNumSingleParams ) + ( (( sizeof(S) * 2 )+ 1 ) * m_nNumDoubleParams );
+ if ( result > max )
+ return max;
+
+ return static_cast<S>(result);
+ }
+ virtual bool processParams(){ return false; }
+};
+
+template < class T, class S >
+class BufferTransformer : public PCodeVisitor< T >
+{
+ BYTE* m_pStart;
+ SbiBuffer m_ConvertedBuf;
+public:
+ BufferTransformer():m_pStart(NULL), m_ConvertedBuf( NULL, 1024 ) {}
+ virtual void start( BYTE* pStart ){ m_pStart = pStart; }
+ virtual void processOpCode0( SbiOpcode eOp )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ }
+ virtual void processOpCode1( SbiOpcode eOp, T nOp1 )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ switch( eOp )
+ {
+ case _JUMP:
+ case _JUMPT:
+ case _JUMPF:
+ case _GOSUB:
+ case _CASEIS:
+ case _RETURN:
+ case _ERRHDL:
+ case _TESTFOR:
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ break;
+ case _RESUME:
+ if ( nOp1 > 1 )
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ break;
+ default:
+ break; //
+
+ }
+ m_ConvertedBuf += (S)nOp1;
+ }
+ virtual void processOpCode2( SbiOpcode eOp, T nOp1, T nOp2 )
+ {
+ m_ConvertedBuf += (UINT8)eOp;
+ if ( eOp == _CASEIS )
+ if ( nOp1 )
+ nOp1 = static_cast<T>( convertBufferOffSet(m_pStart, nOp1) );
+ m_ConvertedBuf += (S)nOp1;
+ m_ConvertedBuf += (S)nOp2;
+
+ }
+ virtual bool processParams(){ return true; }
+ virtual void end() {}
+ // yeuch, careful here, you can only call
+ // GetBuffer on the returned SbiBuffer once, also
+ // you (as the caller) get to own the memory
+ SbiBuffer& buffer()
+ {
+ return m_ConvertedBuf;
+ }
+ static S convertBufferOffSet( BYTE* pStart, T nOp1 )
+ {
+ PCodeBufferWalker< T > aBuff( pStart, nOp1);
+ OffSetAccumulator< T, S > aVisitor;
+ aBuff.visitBuffer( aVisitor );
+ return aVisitor.offset();
+ }
+};
+
+UINT32
+SbiCodeGen::calcNewOffSet( BYTE* pCode, UINT16 nOffset )
+{
+ return BufferTransformer< UINT16, UINT32 >::convertBufferOffSet( pCode, nOffset );
+}
+
+UINT16
+SbiCodeGen::calcLegacyOffSet( BYTE* pCode, UINT32 nOffset )
+{
+ return BufferTransformer< UINT32, UINT16 >::convertBufferOffSet( pCode, nOffset );
+}
+
+template <class T, class S>
+void
+PCodeBuffConvertor<T,S>::convert()
+{
+ PCodeBufferWalker< T > aBuf( m_pStart, m_nSize );
+ BufferTransformer< T, S > aTrnsfrmer;
+ aBuf.visitBuffer( aTrnsfrmer );
+ m_pCnvtdBuf = (BYTE*)aTrnsfrmer.buffer().GetBuffer();
+ m_nCnvtdSize = static_cast<S>( aTrnsfrmer.buffer().GetSize() );
+}
+
+// instantiate for types needed in SbiImage::Load and SbiImage::Save
+template class PCodeBuffConvertor<UINT16, UINT32 >;
+template class PCodeBuffConvertor<UINT32, UINT16>;
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/makefile.mk b/binfilter/bf_basic/source/comp/makefile.mk
new file mode 100644
index 000000000000..3e7377cdd8f4
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/makefile.mk
@@ -0,0 +1,64 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# 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.
+#
+# 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).
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=binfilter
+TARGET=basic_comp
+
+NO_HIDS=TRUE
+
+# --- Settings ------------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+INC+= -I$(PRJ)$/inc$/bf_basic
+
+# --- Allgemein -----------------------------------------------------------
+
+EXCEPTIONSFILES=
+#EXCEPTIONSFILES=$(SLO)$/parser.obj
+
+SLOFILES= \
+ $(EXCEPTIONSFILES) \
+ $(SLO)$/codegen.obj \
+ $(SLO)$/token.obj \
+ $(SLO)$/scanner.obj \
+ $(SLO)$/buffer.obj \
+ $(SLO)$/sbcomp.obj \
+
+# $(SLO)$/dim.obj \
+ $(SLO)$/exprtree.obj \
+ $(SLO)$/exprnode.obj \
+ $(SLO)$/exprgen.obj \
+ $(SLO)$/io.obj \
+ $(SLO)$/loops.obj \
+ $(SLO)$/symtbl.obj \
+
+# --- Targets --------------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/binfilter/bf_basic/source/comp/parser.cxx b/binfilter/bf_basic/source/comp/parser.cxx
new file mode 100644
index 000000000000..e68ad6467b3a
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/parser.cxx
@@ -0,0 +1,872 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * 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.
+ *
+ * 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).
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basic.hxx"
+
+#include <sbx.hxx>
+#include "sbcomp.hxx"
+
+struct SbiParseStack { // "Stack" fuer Statement-Blocks
+ SbiParseStack* pNext; // Chain
+ SbiExprNode* pWithVar; // Variable fuer WITH
+ SbiToken eExitTok; // Exit-Token
+ UINT32 nChain; // JUMP-Chain
+};
+
+struct SbiStatement {
+ SbiToken eTok;
+ void( SbiParser::*Func )(); // Verarbeitungsroutine
+ BOOL bMain; // TRUE: ausserhalb SUBs OK
+ BOOL bSubr; // TRUE: in SUBs OK
+};
+
+#define Y TRUE
+#define N FALSE
+
+static SbiStatement StmntTable [] = {
+{ CALL, &SbiParser::Call, N, Y, }, // CALL
+{ CLOSE, &SbiParser::Close, N, Y, }, // CLOSE
+{ _CONST_, &SbiParser::Dim, Y, Y, }, // CONST
+{ DECLARE, &SbiParser::Declare, Y, N, }, // DECLARE
+{ DEFBOOL, &SbiParser::DefXXX, Y, N, }, // DEFBOOL
+{ DEFCUR, &SbiParser::DefXXX, Y, N, }, // DEFCUR
+{ DEFDATE, &SbiParser::DefXXX, Y, N, }, // DEFDATE
+{ DEFDBL, &SbiParser::DefXXX, Y, N, }, // DEFDBL
+{ DEFERR, &SbiParser::DefXXX, Y, N, }, // DEFERR
+{ DEFINT, &SbiParser::DefXXX, Y, N, }, // DEFINT
+{ DEFLNG, &SbiParser::DefXXX, Y, N, }, // DEFLNG
+{ DEFOBJ, &SbiParser::DefXXX, Y, N, }, // DEFOBJ
+{ DEFSNG, &SbiParser::DefXXX, Y, N, }, // DEFSNG
+{ DEFSTR, &SbiParser::DefXXX, Y, N, }, // DEFSTR
+{ DEFVAR, &SbiParser::DefXXX, Y, N, }, // DEFVAR
+{ DIM, &SbiParser::Dim, Y, Y, }, // DIM
+{ DO, &SbiParser::DoLoop, N, Y, }, // DO
+{ ELSE, &SbiParser::NoIf, N, Y, }, // ELSE
+{ ELSEIF, &SbiParser::NoIf, N, Y, }, // ELSEIF
+{ ENDIF, &SbiParser::NoIf, N, Y, }, // ENDIF
+{ END, &SbiParser::Stop, N, Y, }, // END
+{ ENUM, &SbiParser::Enum, Y, N, }, // TYPE
+{ ERASE, &SbiParser::Erase, N, Y, }, // ERASE
+{ _ERROR_, &SbiParser::ErrorStmnt, N, Y, }, // ERROR
+{ EXIT, &SbiParser::Exit, N, Y, }, // EXIT
+{ FOR, &SbiParser::For, N, Y, }, // FOR
+{ FUNCTION, &SbiParser::SubFunc, Y, N, }, // FUNCTION
+{ GOSUB, &SbiParser::Goto, N, Y, }, // GOSUB
+{ GLOBAL, &SbiParser::Dim, Y, N, }, // GLOBAL
+{ GOTO, &SbiParser::Goto, N, Y, }, // GOTO
+{ IF, &SbiParser::If, N, Y, }, // IF
+{ IMPLEMENTS, &SbiParser::Implements, Y, N, }, // IMPLEMENTS
+{ INPUT, &SbiParser::Input, N, Y, }, // INPUT
+{ LET, &SbiParser::Assign, N, Y, }, // LET
+{ LINEINPUT,&SbiParser::LineInput, N, Y, }, // LINE INPUT
+{ LOOP, &SbiParser::BadBlock, N, Y, }, // LOOP
+{ LSET, &SbiParser::LSet, N, Y, }, // LSET
+{ NAME, &SbiParser::Name, N, Y, }, // NAME
+{ NEXT, &SbiParser::BadBlock, N, Y, }, // NEXT
+{ ON, &SbiParser::On, N, Y, }, // ON
+{ OPEN, &SbiParser::Open, N, Y, }, // OPEN
+{ OPTION, &SbiParser::Option, Y, N, }, // OPTION
+{ PRINT, &SbiParser::Print, N, Y, }, // PRINT
+{ PRIVATE, &SbiParser::Dim, Y, N, }, // PRIVATE
+{ PROPERTY, &SbiParser::SubFunc, Y, N, }, // FUNCTION
+{ PUBLIC, &SbiParser::Dim, Y, N, }, // PUBLIC
+{ REDIM, &SbiParser::ReDim, N, Y, }, // DIM
+{ RESUME, &SbiParser::Resume, N, Y, }, // RESUME
+{ RETURN, &SbiParser::Return, N, Y, }, // RETURN
+{ RSET, &SbiParser::RSet, N, Y, }, // RSET
+{ SELECT, &SbiParser::Select, N, Y, }, // SELECT
+{ SET, &SbiParser::Set, N, Y, }, // SET
+{ STATIC, &SbiParser::Static, Y, Y, }, // STATIC
+{ STOP, &SbiParser::Stop, N, Y, }, // STOP
+{ SUB, &SbiParser::SubFunc, Y, N, }, // SUB
+{ TYPE, &SbiParser::Type, Y, N, }, // TYPE
+{ UNTIL, &SbiParser::BadBlock, N, Y, }, // UNTIL
+{ WHILE, &SbiParser::While, N, Y, }, // WHILE
+{ WEND, &SbiParser::BadBlock, N, Y, }, // WEND
+{ WITH, &SbiParser::With, N, Y, }, // WITH
+{ WRITE, &SbiParser::Write, N, Y, }, // WRITE
+
+{ NIL, NULL, N, N }
+};
+
+
+#ifdef MSC
+// 'this' : used in base member initializer list
+#pragma warning( disable: 4355 )
+#endif
+
+SbiParser::SbiParser( StarBASIC* pb, SbModule* pm )
+ : SbiTokenizer( pm->GetSource32(), pb ),
+ aGblStrings( this ),
+ aLclStrings( this ),
+ aGlobals( aGblStrings, SbGLOBAL ),
+ aPublics( aGblStrings, SbPUBLIC ),
+ aRtlSyms( aGblStrings, SbRTL ),
+ aGen( *pm, this, 1024 )
+{
+ pBasic = pb;
+ eCurExpr = SbSYMBOL;
+ eEndTok = NIL;
+ pProc = NULL;
+ pStack = NULL;
+ pWithVar = NULL;
+ nBase = 0;
+ bText =
+ bGblDefs =
+ bNewGblDefs =
+ bSingleLineIf =
+ bExplicit = FALSE;
+ bClassModule = FALSE;
+ bVBASupportOn = FALSE;
+ pPool = &aPublics;
+ for( short i = 0; i < 26; i++ )
+ eDefTypes[ i ] = SbxVARIANT; // Kein expliziter Defaulttyp
+
+ aPublics.SetParent( &aGlobals );
+ aGlobals.SetParent( &aRtlSyms );
+
+ // Die globale Chainkette faengt bei Adresse 0 an:
+ nGblChain = aGen.Gen( _JUMP, 0 );
+
+ rTypeArray = new SbxArray; // Array fuer Benutzerdefinierte Typen
+ rEnumArray = new SbxArray; // Array for Enum types
+}
+
+
+// Ist Teil der Runtime-Library?
+SbiSymDef* SbiParser::CheckRTLForSym( const String& rSym, SbxDataType eType )
+{
+ SbxVariable* pVar = GetBasic()->GetRtl()->Find( rSym, SbxCLASS_DONTCARE );
+ SbiSymDef* pDef = NULL;
+ if( pVar )
+ {
+ if( pVar->IsA( TYPE(SbxMethod) ) )
+ {
+ SbiProcDef* pProc_ = aRtlSyms.AddProc( rSym );
+ pProc_->SetType( pVar->GetType() );
+ pDef = pProc_;
+ }
+ else
+ {
+ pDef = aRtlSyms.AddSym( rSym );
+ pDef->SetType( eType );
+ }
+ }
+ return pDef;
+}
+
+// Globale Chainkette schliessen
+
+BOOL SbiParser::HasGlobalCode()
+{
+ if( bGblDefs && nGblChain )
+ {
+ aGen.BackChain( nGblChain );
+ aGen.Gen( _LEAVE );
+ // aGen.Gen( _STOP );
+ nGblChain = 0;
+ }
+ return bGblDefs;
+}
+
+void SbiParser::OpenBlock( SbiToken eTok, SbiExprNode* pVar )
+{
+ SbiParseStack* p = new SbiParseStack;
+ p->eExitTok = eTok;
+ p->nChain = 0;
+ p->pWithVar = pWithVar;
+ p->pNext = pStack;
+ pStack = p;
+ pWithVar = pVar;
+
+ // #29955 for-Schleifen-Ebene pflegen
+ if( eTok == FOR )
+ aGen.IncForLevel();
+}
+
+void SbiParser::CloseBlock()
+{
+ if( pStack )
+ {
+ SbiParseStack* p = pStack;
+
+ // #29955 for-Schleifen-Ebene pflegen
+ if( p->eExitTok == FOR )
+ aGen.DecForLevel();
+
+ aGen.BackChain( p->nChain );
+ pStack = p->pNext;
+ pWithVar = p->pWithVar;
+ delete p;
+ }
+}
+
+// EXIT ...
+
+void SbiParser::Exit()
+{
+ SbiToken eTok = Next();
+ for( SbiParseStack* p = pStack; p; p = p->pNext )
+ {
+ if( eTok == p->eExitTok )
+ {
+ p->nChain = aGen.Gen( _JUMP, p->nChain );
+ return;
+ }
+ }
+ if( pStack )
+ Error( SbERR_EXPECTED, pStack->eExitTok );
+ else
+ Error( SbERR_BAD_EXIT );
+}
+
+BOOL SbiParser::TestSymbol( BOOL bKwdOk )
+{
+ Peek();
+ if( eCurTok == SYMBOL || ( bKwdOk && IsKwd( eCurTok ) ) )
+ {
+ Next(); return TRUE;
+ }
+ Error( SbERR_SYMBOL_EXPECTED );
+ return FALSE;
+}
+
+// Testen auf ein bestimmtes Token
+
+BOOL SbiParser::TestToken( SbiToken t )
+{
+ if( Peek() == t )
+ {
+ Next(); return TRUE;
+ }
+ else
+ {
+ Error( SbERR_EXPECTED, t );
+ return FALSE;
+ }
+}
+
+// Testen auf Komma oder EOLN
+
+BOOL SbiParser::TestComma()
+{
+ SbiToken eTok = Peek();
+ if( IsEoln( eTok ) )
+ {
+ Next();
+ return FALSE;
+ }
+ else if( eTok != COMMA )
+ {
+ Error( SbERR_EXPECTED, COMMA );
+ return FALSE;
+ }
+ Next();
+ return TRUE;
+}
+
+// Testen, ob EOLN vorliegt
+
+void SbiParser::TestEoln()
+{
+ if( !IsEoln( Next() ) )
+ {
+ Error( SbERR_EXPECTED, EOLN );
+ while( !IsEoln( Next() ) ) {}
+ }
+}
+
+// Parsing eines Statement-Blocks
+// Das Parsing laeuft bis zum Ende-Token.
+
+void SbiParser::StmntBlock( SbiToken eEnd )
+{
+ SbiToken xe = eEndTok;
+ eEndTok = eEnd;
+ while( !bAbort && Parse() ) {}
+ eEndTok = xe;
+ if( IsEof() )
+ {
+ Error( SbERR_BAD_BLOCK, eEnd );
+ bAbort = TRUE;
+ }
+}
+
+// Die Hauptroutine. Durch wiederholten Aufrufs dieser Routine wird
+// die Quelle geparst. Returnwert FALSE bei Ende/Fehlern.
+
+BOOL SbiParser::Parse()
+{
+ if( bAbort ) return FALSE;
+
+ EnableErrors();
+
+ bErrorIsSymbol = false;
+ Peek();
+ bErrorIsSymbol = true;
+ // Dateiende?
+ if( IsEof() )
+ {
+ // AB #33133: Falls keine Sub angelegt wurde, muss hier
+ // der globale Chain abgeschlossen werden!
+ // AB #40689: Durch die neue static-Behandlung kann noch
+ // ein nGblChain vorhanden sein, daher vorher abfragen
+ if( bNewGblDefs && nGblChain == 0 )
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ return FALSE;
+ }
+
+ // Leerstatement?
+ if( IsEoln( eCurTok ) )
+ {
+ Next(); return TRUE;
+ }
+
+ if( !bSingleLineIf && MayBeLabel( TRUE ) )
+ {
+ // Ist ein Label
+ if( !pProc )
+ Error( SbERR_NOT_IN_MAIN, aSym );
+ else
+ pProc->GetLabels().Define( aSym );
+ Next(); Peek();
+ // Leerstatement?
+ if( IsEoln( eCurTok ) )
+ {
+ Next(); return TRUE;
+ }
+ }
+
+ // Ende des Parsings?
+ if( eCurTok == eEndTok )
+ {
+ Next();
+ if( eCurTok != NIL )
+ aGen.Statement();
+ return FALSE;
+ }
+
+ // Kommentar?
+ if( eCurTok == REM )
+ {
+ Next(); return TRUE;
+ }
+
+ // Kommt ein Symbol, ist es entweder eine Variable( LET )
+ // oder eine SUB-Prozedur( CALL ohne Klammern )
+ // DOT fuer Zuweisungen im WITH-Block: .A=5
+ if( eCurTok == SYMBOL || eCurTok == DOT )
+ {
+ if( !pProc )
+ Error( SbERR_EXPECTED, SUB );
+ else
+ {
+ // Damit Zeile & Spalte stimmen...
+ Next();
+ Push( eCurTok );
+ aGen.Statement();
+ Symbol();
+ }
+ }
+ else
+ {
+ Next();
+
+ // Hier folgen nun die Statement-Parser.
+
+ SbiStatement* p;
+ for( p = StmntTable; p->eTok != NIL; p++ )
+ if( p->eTok == eCurTok )
+ break;
+ if( p->eTok != NIL )
+ {
+ if( !pProc && !p->bMain )
+ Error( SbERR_NOT_IN_MAIN, eCurTok );
+ else if( pProc && !p->bSubr )
+ Error( SbERR_NOT_IN_SUBR, eCurTok );
+ else
+ {
+ // globalen Chain pflegen
+ // AB #41606/#40689: Durch die neue static-Behandlung kann noch
+ // ein nGblChain vorhanden sein, daher vorher abfragen
+ if( bNewGblDefs && nGblChain == 0 &&
+ ( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ) )
+ {
+ nGblChain = aGen.Gen( _JUMP, 0 );
+ bNewGblDefs = FALSE;
+ }
+ // Statement-Opcode bitte auch am Anfang einer Sub
+ if( ( p->bSubr && (eCurTok != STATIC || Peek() == SUB || Peek() == FUNCTION ) ) ||
+ eCurTok == SUB || eCurTok == FUNCTION )
+ aGen.Statement();
+ (this->*( p->Func ) )();
+ SbxError nSbxErr = SbxBase::GetError();
+ if( nSbxErr )
+ SbxBase::ResetError(), Error( (SbError)nSbxErr );
+ }
+ }
+ else
+ Error( SbERR_UNEXPECTED, eCurTok );
+ }
+
+ // Test auf Ende des Statements:
+ // Kann auch ein ELSE sein, da vor dem ELSE kein : stehen muss!
+
+ if( !IsEos() )
+ {
+ Peek();
+ if( !IsEos() && eCurTok != ELSE )
+ {
+ // falls das Parsing abgebrochen wurde, bis zum ":" vorgehen:
+ Error( SbERR_UNEXPECTED, eCurTok );
+ while( !IsEos() ) Next();
+ }
+ }
+ // Der Parser bricht am Ende ab, das naechste Token ist noch nicht
+ // geholt!
+ return TRUE;
+}
+
+// Innerste With-Variable liefern
+SbiExprNode* SbiParser::GetWithVar()
+{
+ if( pWithVar )
+ return pWithVar;
+
+ // Sonst im Stack suchen
+ SbiParseStack* p = pStack;
+ while( p )
+ {
+ // LoopVar kann zur Zeit nur fuer with sein
+ if( p->pWithVar )
+ return p->pWithVar;
+ p = p->pNext;
+ }
+ return NULL;
+}
+
+
+// Zuweisung oder Subroutine Call
+
+void SbiParser::Symbol()
+{
+ SbiExpression aVar( this, SbSYMBOL );
+
+ bool bEQ = ( Peek() == EQ );
+ RecursiveMode eRecMode = ( bEQ ? PREVENT_CALL : FORCE_CALL );
+ bool bSpecialMidHandling = false;
+ SbiSymDef* pDef = aVar.GetRealVar();
+ if( bEQ && pDef && pDef->GetScope() == SbRTL )
+ {
+ String aRtlName = pDef->GetName();
+ if( aRtlName.EqualsIgnoreCaseAscii("Mid") )
+ {
+ SbiExprNode* pExprNode = aVar.GetExprNode();
+ // SbiNodeType eNodeType;
+ if( pExprNode && pExprNode->GetNodeType() == SbxVARVAL )
+ {
+ SbiExprList* pPar = pExprNode->GetParameters();
+ short nParCount = pPar ? pPar->GetSize() : 0;
+ if( nParCount == 2 || nParCount == 3 )
+ {
+ if( nParCount == 2 )
+ pPar->addExpression( new SbiExpression( this, -1, SbxLONG ) );
+
+ TestToken( EQ );
+ pPar->addExpression( new SbiExpression( this ) );
+
+ bSpecialMidHandling = true;
+ }
+ }
+ }
+ }
+ aVar.Gen( eRecMode );
+ if( !bSpecialMidHandling )
+ {
+ if( !bEQ )
+ {
+ aGen.Gen( _GET );
+ }
+ else
+ {
+ // Dann muss es eine Zuweisung sein. Was anderes gibts nicht!
+ if( !aVar.IsLvalue() )
+ Error( SbERR_LVALUE_EXPECTED );
+ TestToken( EQ );
+ SbiExpression aExpr( this );
+ aExpr.Gen();
+ SbiOpcode eOp = _PUT;
+ // SbiSymDef* pDef = aVar.GetRealVar();
+ if( pDef )
+ {
+ if( pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ if( pDef->GetType() == SbxOBJECT )
+ {
+ eOp = _SET;
+ if( pDef->GetTypeId() )
+ {
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ return;
+ }
+ }
+ }
+ aGen.Gen( eOp );
+ }
+ }
+}
+
+// Zuweisungen
+
+void SbiParser::Assign()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ TestToken( EQ );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ USHORT nLen = 0;
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ {
+ if( pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ nLen = aLvalue.GetRealVar()->GetLen();
+ }
+ if( nLen )
+ aGen.Gen( _PAD, nLen );
+ aGen.Gen( _PUT );
+}
+
+// Zuweisungen einer Objektvariablen
+
+void SbiParser::Set()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ SbxDataType eType = aLvalue.GetType();
+ if( eType != SbxOBJECT && eType != SbxEMPTY && eType != SbxVARIANT )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+
+ SbiToken eTok = Peek();
+ if( eTok == NEW )
+ {
+ Next();
+ String aStr;
+ SbiSymDef* pTypeDef = new SbiSymDef( aStr );
+ TypeDecl( *pTypeDef, TRUE );
+
+ aLvalue.Gen();
+ // aGen.Gen( _CLASS, pDef->GetTypeId() | 0x8000 );
+ aGen.Gen( _CREATE, pDef->GetId(), pTypeDef->GetTypeId() );
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ }
+ else
+ {
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ // Its a good idea to distinguish between
+ // set someting = another &
+ // someting = another
+ // ( its necessary for vba objects where set is object
+ // specific and also doesn't involve processing default params )
+ if( pDef->GetTypeId() )
+ aGen.Gen( _SETCLASS, pDef->GetTypeId() );
+ else
+ {
+ if ( bVBASupportOn )
+ aGen.Gen( _VBASET );
+ else
+ aGen.Gen( _SET );
+ }
+ }
+ // aGen.Gen( _SET );
+}
+
+// JSM 07.10.95
+void SbiParser::LSet()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ if( aLvalue.GetType() != SbxSTRING )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ aGen.Gen( _LSET );
+}
+
+// JSM 07.10.95
+void SbiParser::RSet()
+{
+ SbiExpression aLvalue( this, SbLVALUE );
+ if( aLvalue.GetType() != SbxSTRING )
+ Error( SbERR_INVALID_OBJECT );
+ TestToken( EQ );
+ SbiSymDef* pDef = aLvalue.GetRealVar();
+ if( pDef && pDef->GetConstDef() )
+ Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
+ SbiExpression aExpr( this );
+ aLvalue.Gen();
+ aExpr.Gen();
+ aGen.Gen( _RSET );
+}
+
+// DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFSTR und so weiter
+
+void SbiParser::DefXXX()
+{
+ sal_Unicode ch1, ch2;
+ SbxDataType t = SbxDataType( eCurTok - DEFINT + SbxINTEGER );
+
+ while( !bAbort )
+ {
+ if( Next() != SYMBOL ) break;
+ ch1 = aSym.ToUpperAscii().GetBuffer()[0];
+ ch2 = 0;
+ if( Peek() == MINUS )
+ {
+ Next();
+ if( Next() != SYMBOL ) Error( SbERR_SYMBOL_EXPECTED );
+ else
+ {
+ ch2 = aSym.ToUpperAscii().GetBuffer()[0];
+ //ch2 = aSym.Upper();
+ if( ch2 < ch1 ) Error( SbERR_SYNTAX ), ch2 = 0;
+ }
+ }
+ if (!ch2) ch2 = ch1;
+ ch1 -= 'A'; ch2 -= 'A';
+ for (; ch1 <= ch2; ch1++) eDefTypes[ ch1 ] = t;
+ if( !TestComma() ) break;
+ }
+}
+
+// STOP/SYSTEM
+
+void SbiParser::Stop()
+{
+ aGen.Gen( _STOP );
+ Peek(); // #35694: Nur Peek(), damit EOL in Single-Line-If erkannt wird
+}
+
+// IMPLEMENTS
+
+void SbiParser::Implements()
+{
+ if( !bClassModule )
+ {
+ Error( SbERR_UNEXPECTED, IMPLEMENTS );
+ return;
+ }
+
+ if( TestSymbol() )
+ {
+ String aImplementedIface = GetSym();
+ aIfaceVector.push_back( aImplementedIface );
+ }
+}
+
+void SbiParser::EnableCompatibility()
+{
+ if( !bCompatible )
+ AddConstants();
+ bCompatible = TRUE;
+}
+
+// OPTION
+
+void SbiParser::Option()
+{
+ switch( Next() )
+ {
+ case EXPLICIT:
+ bExplicit = TRUE; break;
+ case BASE:
+ if( Next() == NUMBER )
+ {
+ if( nVal == 0 || nVal == 1 )
+ {
+ nBase = (short) nVal;
+ break;
+ }
+ }
+ Error( SbERR_EXPECTED, "0/1" );
+ break;
+ case PRIVATE:
+ {
+ String aString = SbiTokenizer::Symbol(Next());
+ if( !aString.EqualsIgnoreCaseAscii("Module") )
+ Error( SbERR_EXPECTED, "Module" );
+ break;
+ }
+ case COMPARE:
+ switch( Next() )
+ {
+ case TEXT: bText = TRUE; return;
+ case BINARY: bText = FALSE; return;
+ default:;
+ } // Fall thru!
+ case COMPATIBLE:
+ EnableCompatibility();
+ break;
+
+ case CLASSMODULE:
+ bClassModule = TRUE;
+ break;
+ case VBASUPPORT:
+ if( Next() == NUMBER )
+ {
+ if ( nVal == 1 || nVal == 0 )
+ {
+ bVBASupportOn = ( nVal == 1 );
+ if ( bVBASupportOn )
+ EnableCompatibility();
+ break;
+ }
+ }
+ Error( SbERR_EXPECTED, "0/1" );
+ break;
+ default:
+ Error( SbERR_BAD_OPTION, eCurTok );
+ }
+}
+
+void addStringConst( SbiSymPool& rPool, const char* pSym, const String& rStr )
+{
+ SbiConstDef* pConst = new SbiConstDef( String::CreateFromAscii( pSym ) );
+ pConst->SetType( SbxSTRING );
+ pConst->Set( rStr );
+ rPool.Add( pConst );
+}
+
+inline void addStringConst( SbiSymPool& rPool, const char* pSym, const char* pStr )
+{
+ addStringConst( rPool, pSym, String::CreateFromAscii( pStr ) );
+}
+
+void SbiParser::AddConstants( void )
+{
+ // #113063 Create constant RTL symbols
+ addStringConst( aPublics, "vbCr", "\x0D" );
+ addStringConst( aPublics, "vbCrLf", "\x0D\x0A" );
+ addStringConst( aPublics, "vbFormFeed", "\x0C" );
+ addStringConst( aPublics, "vbLf", "\x0A" );
+#if defined(UNX)
+ addStringConst( aPublics, "vbNewLine", "\x0A" );
+#else
+ addStringConst( aPublics, "vbNewLine", "\x0D\x0A" );
+#endif
+ addStringConst( aPublics, "vbNullString", "" );
+ addStringConst( aPublics, "vbTab", "\x09" );
+ addStringConst( aPublics, "vbVerticalTab", "\x0B" );
+
+ // Force length 1 and make char 0 afterwards
+ String aNullCharStr( String::CreateFromAscii( " " ) );
+ aNullCharStr.SetChar( 0, 0 );
+ addStringConst( aPublics, "vbNullChar", aNullCharStr );
+}
+
+// ERROR n
+
+void SbiParser::ErrorStmnt()
+{
+ SbiExpression aPar( this );
+ aPar.Gen();
+ aGen.Gen( _ERROR );
+}
+
+
+// AB 22.5.1996
+// JavaScript-Parsing zunaechst provisorisch hier implementiert
+void SbiParser::OpenJavaBlock( SbiToken, SbiExprNode* )
+{
+}
+
+void SbiParser::CloseJavaBlock()
+{
+}
+
+void SbiParser::JavaStmntBlock( SbiToken )
+{
+}
+
+void SbiParser::JavaBreak()
+{
+}
+
+void SbiParser::JavaContinue()
+{
+}
+
+void SbiParser::JavaFor()
+{
+}
+
+void SbiParser::JavaFunction()
+{
+}
+
+void SbiParser::JavaIf()
+{
+}
+
+void SbiParser::JavaNew()
+{
+}
+
+void SbiParser::JavaReturn()
+{
+}
+
+void SbiParser::JavaThis()
+{
+}
+
+void SbiParser::JavaVar()
+{
+}
+
+void SbiParser::JavaWhile()
+{
+}
+
+void SbiParser::JavaWith()
+{
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/sbcomp.cxx b/binfilter/bf_basic/source/comp/sbcomp.cxx
new file mode 100644
index 000000000000..1d703baceac7
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/sbcomp.cxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * 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.
+ *
+ * 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).
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "sbx.hxx"
+#include "image.hxx"
+
+
+// For debugging only
+// #define DBG_SAVE_DISASSEMBLY
+
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
+#include <com/sun/star/io/XTextOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+
+namespace binfilter {
+
+/*?*/ // #ifdef DBG_SAVE_DISASSEMBLY
+/*?*/ // static bool dbg_bDisassemble = true;
+/*?*/ //
+/*?*/ // using namespace comphelper;
+/*?*/ // using namespace rtl;
+/*?*/ // using namespace com::sun::star::uno;
+/*?*/ // using namespace com::sun::star::lang;
+/*?*/ // using namespace com::sun::star::ucb;
+/*?*/ // using namespace com::sun::star::io;
+/*?*/ //
+/*?*/ // void dbg_SaveDisassembly( SbModule* pModule )
+/*?*/ // {
+/*?*/ // bool bDisassemble = dbg_bDisassemble;
+/*?*/ // if( bDisassemble )
+/*?*/ // {
+/*?*/ // Reference< XSimpleFileAccess3 > xSFI;
+/*?*/ // Reference< XTextOutputStream > xTextOut;
+/*?*/ // Reference< XOutputStream > xOut;
+/*?*/ // Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+/*?*/ // if( xSMgr.is() )
+/*?*/ // {
+/*?*/ // Reference< XSimpleFileAccess3 > xSFI = Reference< XSimpleFileAccess3 >( xSMgr->createInstance
+/*?*/ // ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+/*?*/ // if( xSFI.is() )
+/*?*/ // {
+/*?*/ // String aFile( RTL_CONSTASCII_USTRINGPARAM("file:///d:/BasicAsm_") );
+/*?*/ // StarBASIC* pBasic = (StarBASIC*)pModule->GetParent();
+/*?*/ // if( pBasic )
+/*?*/ // {
+/*?*/ // aFile += pBasic->GetName();
+/*?*/ // aFile.AppendAscii( "_" );
+/*?*/ // }
+/*?*/ // aFile += pModule->GetName();
+/*?*/ // aFile.AppendAscii( ".txt" );
+/*?*/ //
+/*?*/ // // String aFile( RTL_CONSTASCII_USTRINGPARAM("file:///d:/BasicAsm.txt") );
+/*?*/ // if( xSFI->exists( aFile ) )
+/*?*/ // xSFI->kill( aFile );
+/*?*/ // xOut = xSFI->openFileWrite( aFile );
+/*?*/ // Reference< XInterface > x = xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.io.TextOutputStream" ) );
+/*?*/ // Reference< XActiveDataSource > xADS( x, UNO_QUERY );
+/*?*/ // xADS->setOutputStream( xOut );
+/*?*/ // xTextOut = Reference< XTextOutputStream >( x, UNO_QUERY );
+/*?*/ // }
+/*?*/ // }
+/*?*/ //
+/*?*/ // if( xTextOut.is() )
+/*?*/ // {
+/*?*/ // String aDisassemblyStr;
+/*?*/ // pModule->Disassemble( aDisassemblyStr );
+/*?*/ // xTextOut->writeString( aDisassemblyStr );
+/*?*/ // }
+/*?*/ // xOut->closeOutput();
+/*?*/ // }
+/*?*/ // }
+/*?*/ // #endif
+
+// Diese Routine ist hier definiert, damit der Compiler als eigenes Segment
+// geladen werden kann.
+
+BOOL SbModule::Compile()
+{
+ DBG_ERROR( "SbModule::Compile: dead code!" );
+ return FALSE;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/scanner.cxx b/binfilter/bf_basic/source/comp/scanner.cxx
new file mode 100644
index 000000000000..069c22b703ed
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/scanner.cxx
@@ -0,0 +1,559 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * 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.
+ *
+ * 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).
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "scanner.hxx"
+#include "sbintern.hxx"
+#include "token.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#if defined UNX
+#include <stdlib.h>
+#else
+#include <math.h> // atof()
+#endif
+#include <rtl/math.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/charclass.hxx>
+
+namespace binfilter {
+
+SbiScanner::SbiScanner( const ::rtl::OUString& rBuf, StarBASIC* p ) : aBuf( rBuf )
+{
+ pBasic = p;
+ pLine = NULL;
+ nVal = 0;
+ eScanType = SbxVARIANT;
+ nErrors = 0;
+ nBufPos = 0;
+ nCurCol1 = 0;
+ nSavedCol1 = 0;
+ nColLock = 0;
+ nLine = 0;
+ nCol1 = 0;
+ nCol2 = 0;
+ nCol = 0;
+ bError =
+ bAbort =
+ bSpaces =
+ bNumber =
+ bSymbol =
+ bUsedForHilite =
+ bCompatible =
+ bPrevLineExtentsComment = FALSE;
+ bHash =
+ bErrors = TRUE;
+}
+
+SbiScanner::~SbiScanner()
+{}
+
+/*?*/ // void SbiScanner::LockColumn()
+/*?*/ // {
+/*?*/ // if( !nColLock++ )
+/*?*/ // nSavedCol1 = nCol1;
+/*?*/ // }
+/*?*/ //
+/*?*/ // void SbiScanner::UnlockColumn()
+/*?*/ // {
+/*?*/ // if( nColLock )
+/*?*/ // nColLock--;
+/*?*/ // }
+/*?*/ //
+void SbiScanner::GenError( SbError code )
+{
+ if( GetSbData()->bBlockCompilerError )
+ {
+ bAbort = TRUE;
+ return;
+ }
+ if( !bError && bErrors )
+ {
+ BOOL bRes = TRUE;
+ // Nur einen Fehler pro Statement reporten
+ bError = TRUE;
+ if( pBasic )
+ {
+ // Falls EXPECTED oder UNEXPECTED kommen sollte, bezieht es sich
+ // immer auf das letzte Token, also die Col1 uebernehmen
+ USHORT nc = nColLock ? nSavedCol1 : nCol1;
+ switch( code )
+ {
+ case SbERR_EXPECTED:
+ case SbERR_UNEXPECTED:
+ case SbERR_SYMBOL_EXPECTED:
+ case SbERR_LABEL_EXPECTED:
+ nc = nCol1;
+ if( nc > nCol2 ) nCol2 = nc;
+ break;
+ }
+ bRes = pBasic->CError( code, aError, nLine, nc, nCol2 );
+ }
+ bAbort |= !bRes |
+ ( code == SbERR_NO_MEMORY || code == SbERR_PROG_TOO_LARGE );
+ }
+ if( bErrors )
+ nErrors++;
+}
+
+// Testen auf ein legales Suffix
+
+static SbxDataType GetSuffixType( sal_Unicode c )
+{
+ static String aSuffixesStr = String::CreateFromAscii( "%&!#@ $" );
+ if( c )
+ {
+ sal_uInt32 n = aSuffixesStr.Search( c );
+ if( STRING_NOTFOUND != n && c != ' ' )
+ return SbxDataType( (USHORT) n + SbxINTEGER );
+ }
+ return SbxVARIANT;
+}
+
+// Einlesen des naechsten Symbols in die Variablen aSym, nVal und eType
+// Returnwert ist FALSE bei EOF oder Fehlern
+#define BUF_SIZE 80
+
+BOOL SbiScanner::NextSym()
+{
+ // Fuer den EOLN-Fall merken
+ USHORT nOldLine = nLine;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ sal_Unicode buf[ BUF_SIZE ], *p = buf;
+ bHash = FALSE;
+
+ eScanType = SbxVARIANT;
+ aSym.Erase();
+ bSymbol =
+ bNumber = bSpaces = FALSE;
+
+ // Zeile einlesen?
+ if( !pLine )
+ {
+ INT32 n = nBufPos;
+ INT32 nLen = aBuf.getLength();
+ if( nBufPos >= nLen )
+ return FALSE;
+ const sal_Unicode* p2 = aBuf.getStr();
+ p2 += n;
+ while( ( n < nLen ) && ( *p2 != '\n' ) && ( *p2 != '\r' ) )
+ p2++, n++;
+ aLine = aBuf.copy( nBufPos, n - nBufPos );
+ if( n < nLen )
+ {
+ if( *p2 == '\r' && *( p2+1 ) == '\n' )
+ n += 2;
+ else
+ n++;
+ }
+ nBufPos = n;
+ pLine = aLine.getStr();
+ nOldLine = ++nLine;
+ nCol = nCol1 = nCol2 = nOldCol1 = nOldCol2 = 0;
+ nColLock = 0;
+ }
+
+ // Leerstellen weg:
+ while( *pLine && (( *pLine == ' ' ) || ( *pLine == '\t' ) || ( *pLine == '\f' )) )
+ pLine++, nCol++, bSpaces = TRUE;
+
+ nCol1 = nCol;
+
+ // nur Leerzeile?
+ if( !*pLine )
+ goto eoln;
+
+ if( bPrevLineExtentsComment )
+ goto PrevLineCommentLbl;
+
+ if( *pLine == '#' )
+ {
+ pLine++;
+ nCol++;
+ bHash = TRUE;
+ }
+
+ // Symbol? Dann Zeichen kopieren.
+ if( BasicSimpleCharClass::isAlpha( *pLine, bCompatible ) || *pLine == '_' )
+ {
+ // Wenn nach '_' nichts kommt, ist es ein Zeilenabschluss!
+ if( *pLine == '_' && !*(pLine+1) )
+ { pLine++;
+ goto eoln; }
+ bSymbol = TRUE;
+ short n = nCol;
+ for ( ; (BasicSimpleCharClass::isAlphaNumeric( *pLine, bCompatible ) || ( *pLine == '_' ) ); pLine++ )
+ nCol++;
+ aSym = aLine.copy( n, nCol - n );
+ // Abschliessendes '_' durch Space ersetzen, wenn Zeilenende folgt
+ // (sonst falsche Zeilenfortsetzung)
+ if( !bUsedForHilite && !*pLine && *(pLine-1) == '_' )
+ {
+ aSym.GetBufferAccess(); // #109693 force copy if necessary
+ *((sal_Unicode*)(pLine-1)) = ' '; // cast wegen const
+ }
+ // Typkennung?
+ // Das Ausrufezeichen bitte nicht testen, wenn
+ // danach noch ein Symbol anschliesst
+ else if( *pLine != '!' || !BasicSimpleCharClass::isAlpha( pLine[ 1 ], bCompatible ) )
+ {
+ SbxDataType t = GetSuffixType( *pLine );
+ if( t != SbxVARIANT )
+ {
+ eScanType = t;
+ pLine++;
+ nCol++;
+ }
+ }
+ }
+
+ // Zahl? Dann einlesen und konvertieren.
+ else if( BasicSimpleCharClass::isDigit( *pLine & 0xFF )
+ || ( *pLine == '.' && BasicSimpleCharClass::isDigit( *(pLine+1) & 0xFF ) ) )
+ {
+ short exp = 0;
+ short comma = 0;
+ short ndig = 0;
+ short ncdig = 0;
+ eScanType = SbxDOUBLE;
+ BOOL bBufOverflow = FALSE;
+ while( strchr( "0123456789.DEde", *pLine ) && *pLine )
+ {
+ // AB 4.1.1996: Buffer voll? -> leer weiter scannen
+ if( (p-buf) == (BUF_SIZE-1) )
+ {
+ bBufOverflow = TRUE;
+ pLine++, nCol++;
+ continue;
+ }
+ // Komma oder Exponent?
+ if( *pLine == '.' )
+ {
+ if( ++comma > 1 )
+ {
+ pLine++; nCol++; continue;
+ }
+ else *p++ = *pLine++, nCol++;
+ }
+ else if( strchr( "DdEe", *pLine ) )
+ {
+ if (++exp > 1)
+ {
+ pLine++; nCol++; continue;
+ }
+// if( toupper( *pLine ) == 'D' )
+// eScanType = SbxDOUBLE;
+ *p++ = 'E'; pLine++; nCol++;
+ // Vorzeichen hinter Exponent?
+ if( *pLine == '+' )
+ pLine++, nCol++;
+ else
+ if( *pLine == '-' )
+ *p++ = *pLine++, nCol++;
+ }
+ else
+ {
+ *p++ = *pLine++, nCol++;
+ if( comma && !exp ) ncdig++;
+ }
+ if (!exp) ndig++;
+ }
+ *p = 0;
+ aSym = p; bNumber = TRUE;
+ // Komma, Exponent mehrfach vorhanden?
+ if( comma > 1 || exp > 1 )
+ { aError = '.';
+ GenError( SbERR_BAD_CHAR_IN_NUMBER ); }
+
+ // #57844 Lokalisierte Funktion benutzen
+ nVal = rtl_math_uStringToDouble( buf, buf+(p-buf), '.', ',', NULL, NULL );
+ // ALT: nVal = atof( buf );
+
+ ndig = ndig - comma;
+ if( !comma && !exp )
+ {
+ if( nVal >= SbxMININT && nVal <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+ else
+ if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
+ eScanType = SbxLONG;
+ }
+ if( bBufOverflow )
+ GenError( SbERR_MATH_OVERFLOW );
+ // zu viele Zahlen fuer SINGLE?
+// if (ndig > 15 || ncdig > 6)
+// eScanType = SbxDOUBLE;
+// else
+// if( nVal > SbxMAXSNG || nVal < SbxMINSNG )
+// eScanType = SbxDOUBLE;
+
+ // Typkennung?
+ SbxDataType t = GetSuffixType( *pLine );
+ if( t != SbxVARIANT )
+ {
+ eScanType = t;
+ pLine++;
+ nCol++;
+ }
+ }
+
+ // Hex/Oktalzahl? Einlesen und konvertieren:
+ else if( *pLine == '&' )
+ {
+ pLine++; nCol++;
+ sal_Unicode cmp1[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', 0 };
+ sal_Unicode cmp2[] = { '0', '1', '2', '3', '4', '5', '6', '7', 0 };
+ sal_Unicode *cmp = cmp1;
+ //char *cmp = "0123456789ABCDEF";
+ sal_Unicode base = 16;
+ sal_Unicode ndig = 8;
+ sal_Unicode xch = *pLine++ & 0xFF; nCol++;
+ switch( toupper( xch ) )
+ {
+ case 'O':
+ cmp = cmp2; base = 8; ndig = 11; break;
+ //cmp = "01234567"; base = 8; ndig = 11; break;
+ case 'H':
+ break;
+ default :
+ // Wird als Operator angesehen
+ pLine--; nCol--; nCol1 = nCol-1; aSym = '&'; return SYMBOL;
+ }
+ bNumber = TRUE;
+ long l = 0;
+ int i;
+ BOOL bBufOverflow = FALSE;
+ while( BasicSimpleCharClass::isAlphaNumeric( *pLine & 0xFF, bCompatible ) )
+ {
+ sal_Unicode ch = sal::static_int_cast< sal_Unicode >(
+ toupper( *pLine & 0xFF ) );
+ pLine++; nCol++;
+ // AB 4.1.1996: Buffer voll, leer weiter scannen
+ if( (p-buf) == (BUF_SIZE-1) )
+ bBufOverflow = TRUE;
+ else if( String( cmp ).Search( ch ) != STRING_NOTFOUND )
+ //else if( strchr( cmp, ch ) )
+ *p++ = ch;
+ else
+ {
+ aError = ch;
+ GenError( SbERR_BAD_CHAR_IN_NUMBER );
+ }
+ }
+ *p = 0;
+ for( p = buf; *p; p++ )
+ {
+ i = (*p & 0xFF) - '0';
+ if( i > 9 ) i -= 7;
+ l = ( l * base ) + i;
+ if( !ndig-- )
+ {
+ GenError( SbERR_MATH_OVERFLOW ); break;
+ }
+ }
+ if( *pLine == '&' ) pLine++, nCol++;
+ nVal = (double) l;
+ eScanType = ( l >= SbxMININT && l <= SbxMAXINT ) ? SbxINTEGER : SbxLONG;
+ if( bBufOverflow )
+ GenError( SbERR_MATH_OVERFLOW );
+ }
+
+ // Strings:
+ else if( *pLine == '"' || *pLine == '[' )
+ {
+ sal_Unicode cSep = *pLine;
+ if( cSep == '[' )
+ bSymbol = TRUE, cSep = ']';
+ short n = nCol+1;
+ while( *pLine )
+ {
+ do pLine++, nCol++;
+ while( *pLine && ( *pLine != cSep ) );
+ if( *pLine == cSep )
+ {
+ pLine++; nCol++;
+ if( *pLine != cSep || cSep == ']' ) break;
+ } else aError = cSep, GenError( SbERR_EXPECTED );
+ }
+ aSym = aLine.copy( n, nCol - n - 1 );
+ // Doppelte Stringbegrenzer raus
+ String s( cSep );
+ s += cSep;
+ USHORT nIdx = 0;
+ do
+ {
+ nIdx = aSym.Search( s, nIdx );
+ if( nIdx == STRING_NOTFOUND )
+ break;
+ aSym.Erase( nIdx, 1 );
+ nIdx++;
+ }
+ while( true );
+ if( cSep != ']' )
+ eScanType = ( cSep == '#' ) ? SbxDATE : SbxSTRING;
+ }
+ // ungueltige Zeichen:
+ else if( ( *pLine & 0xFF ) >= 0x7F )
+ {
+ GenError( SbERR_SYNTAX ); pLine++; nCol++;
+ }
+ // andere Gruppen:
+ else
+ {
+ short n = 1;
+ switch( *pLine++ )
+ {
+ case '<': if( *pLine == '>' || *pLine == '=' ) n = 2; break;
+ case '>': if( *pLine == '=' ) n = 2; break;
+ case ':': if( *pLine == '=' ) n = 2; break;
+ }
+ aSym = aLine.copy( nCol, n );
+ pLine += n-1; nCol = nCol + n;
+ }
+
+ nCol2 = nCol-1;
+
+PrevLineCommentLbl:
+ // Kommentar?
+ if( bPrevLineExtentsComment || (eScanType != SbxSTRING &&
+ ( aSym.GetBuffer()[0] == '\'' || aSym.EqualsIgnoreCaseAscii( "REM" ) ) ) )
+ {
+ bPrevLineExtentsComment = FALSE;
+ aSym = String::CreateFromAscii( "REM" );
+ USHORT nLen = String( pLine ).Len();
+ if( bCompatible && pLine[ nLen - 1 ] == '_' && pLine[ nLen - 2 ] == ' ' )
+ bPrevLineExtentsComment = TRUE;
+ nCol2 = nCol2 + nLen;
+ pLine = NULL;
+ }
+ return TRUE;
+
+ // Sonst Zeilen-Ende: aber bitte auf '_' testen, ob die
+ // Zeile nicht weitergeht!
+eoln:
+ if( nCol && *--pLine == '_' )
+ {
+ pLine = NULL; return NextSym();
+ }
+ else
+ {
+ pLine = NULL;
+ nLine = nOldLine;
+ nCol1 = nOldCol1;
+ nCol2 = nOldCol2;
+ aSym = '\n';
+ nColLock = 0;
+ return TRUE;
+ }
+}
+
+LetterTable BasicSimpleCharClass::aLetterTable;
+
+LetterTable::LetterTable( void )
+{
+ for( int i = 0 ; i < 256 ; ++i )
+ IsLetterTab[i] = false;
+
+ IsLetterTab[0xC0] = true; // À , CAPITAL LETTER A WITH GRAVE ACCENT
+ IsLetterTab[0xC1] = true; // Á , CAPITAL LETTER A WITH ACUTE ACCENT
+ IsLetterTab[0xC2] = true; // Â , CAPITAL LETTER A WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xC3] = true; // Ã , CAPITAL LETTER A WITH TILDE
+ IsLetterTab[0xC4] = true; // Ä , CAPITAL LETTER A WITH DIAERESIS
+ IsLetterTab[0xC5] = true; // Å , CAPITAL LETTER A WITH RING ABOVE
+ IsLetterTab[0xC6] = true; // Æ , CAPITAL LIGATURE AE
+ IsLetterTab[0xC7] = true; // Ç , CAPITAL LETTER C WITH CEDILLA
+ IsLetterTab[0xC8] = true; // È , CAPITAL LETTER E WITH GRAVE ACCENT
+ IsLetterTab[0xC9] = true; // É , CAPITAL LETTER E WITH ACUTE ACCENT
+ IsLetterTab[0xCA] = true; // Ê , CAPITAL LETTER E WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xCB] = true; // Ë , CAPITAL LETTER E WITH DIAERESIS
+ IsLetterTab[0xCC] = true; // Ì , CAPITAL LETTER I WITH GRAVE ACCENT
+ IsLetterTab[0xCD] = true; // Í , CAPITAL LETTER I WITH ACUTE ACCENT
+ IsLetterTab[0xCE] = true; // Î , CAPITAL LETTER I WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xCF] = true; // Ï , CAPITAL LETTER I WITH DIAERESIS
+ IsLetterTab[0xD0] = true; // Ð , CAPITAL LETTER ETH
+ IsLetterTab[0xD1] = true; // Ñ , CAPITAL LETTER N WITH TILDE
+ IsLetterTab[0xD2] = true; // Ò , CAPITAL LETTER O WITH GRAVE ACCENT
+ IsLetterTab[0xD3] = true; // Ó , CAPITAL LETTER O WITH ACUTE ACCENT
+ IsLetterTab[0xD4] = true; // Ô , CAPITAL LETTER O WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xD5] = true; // Õ , CAPITAL LETTER O WITH TILDE
+ IsLetterTab[0xD6] = true; // Ö , CAPITAL LETTER O WITH DIAERESIS
+ IsLetterTab[0xD8] = true; // Ø , CAPITAL LETTER O WITH STROKE
+ IsLetterTab[0xD9] = true; // Ù , CAPITAL LETTER U WITH GRAVE ACCENT
+ IsLetterTab[0xDA] = true; // Ú , CAPITAL LETTER U WITH ACUTE ACCENT
+ IsLetterTab[0xDB] = true; // Û , CAPITAL LETTER U WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xDC] = true; // Ü , CAPITAL LETTER U WITH DIAERESIS
+ IsLetterTab[0xDD] = true; // Ý , CAPITAL LETTER Y WITH ACUTE ACCENT
+ IsLetterTab[0xDE] = true; // Þ , CAPITAL LETTER THORN
+ IsLetterTab[0xDF] = true; // ß , SMALL LETTER SHARP S
+ IsLetterTab[0xE0] = true; // à , SMALL LETTER A WITH GRAVE ACCENT
+ IsLetterTab[0xE1] = true; // á , SMALL LETTER A WITH ACUTE ACCENT
+ IsLetterTab[0xE2] = true; // â , SMALL LETTER A WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xE3] = true; // ã , SMALL LETTER A WITH TILDE
+ IsLetterTab[0xE4] = true; // ä , SMALL LETTER A WITH DIAERESIS
+ IsLetterTab[0xE5] = true; // å , SMALL LETTER A WITH RING ABOVE
+ IsLetterTab[0xE6] = true; // æ , SMALL LIGATURE AE
+ IsLetterTab[0xE7] = true; // ç , SMALL LETTER C WITH CEDILLA
+ IsLetterTab[0xE8] = true; // è , SMALL LETTER E WITH GRAVE ACCENT
+ IsLetterTab[0xE9] = true; // é , SMALL LETTER E WITH ACUTE ACCENT
+ IsLetterTab[0xEA] = true; // ê , SMALL LETTER E WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xEB] = true; // ë , SMALL LETTER E WITH DIAERESIS
+ IsLetterTab[0xEC] = true; // ì , SMALL LETTER I WITH GRAVE ACCENT
+ IsLetterTab[0xED] = true; // í , SMALL LETTER I WITH ACUTE ACCENT
+ IsLetterTab[0xEE] = true; // î , SMALL LETTER I WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xEF] = true; // ï , SMALL LETTER I WITH DIAERESIS
+ IsLetterTab[0xF0] = true; // ð , SMALL LETTER ETH
+ IsLetterTab[0xF1] = true; // ñ , SMALL LETTER N WITH TILDE
+ IsLetterTab[0xF2] = true; // ò , SMALL LETTER O WITH GRAVE ACCENT
+ IsLetterTab[0xF3] = true; // ó , SMALL LETTER O WITH ACUTE ACCENT
+ IsLetterTab[0xF4] = true; // ô , SMALL LETTER O WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xF5] = true; // õ , SMALL LETTER O WITH TILDE
+ IsLetterTab[0xF6] = true; // ö , SMALL LETTER O WITH DIAERESIS
+ IsLetterTab[0xF8] = true; // ø , SMALL LETTER O WITH OBLIQUE BAR
+ IsLetterTab[0xF9] = true; // ù , SMALL LETTER U WITH GRAVE ACCENT
+ IsLetterTab[0xFA] = true; // ú , SMALL LETTER U WITH ACUTE ACCENT
+ IsLetterTab[0xFB] = true; // û , SMALL LETTER U WITH CIRCUMFLEX ACCENT
+ IsLetterTab[0xFC] = true; // ü , SMALL LETTER U WITH DIAERESIS
+ IsLetterTab[0xFD] = true; // ý , SMALL LETTER Y WITH ACUTE ACCENT
+ IsLetterTab[0xFE] = true; // þ , SMALL LETTER THORN
+ IsLetterTab[0xFF] = true; // ÿ , SMALL LETTER Y WITH DIAERESIS
+}
+
+bool LetterTable::isLetterUnicode( sal_Unicode c )
+{
+ static CharClass* pCharClass = NULL;
+ if( pCharClass == NULL )
+ pCharClass = new CharClass( Application::GetSettings().GetLocale() );
+ String aStr( c );
+ bool bRet = pCharClass->isLetter( aStr, 0 );
+ return bRet;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/binfilter/bf_basic/source/comp/token.cxx b/binfilter/bf_basic/source/comp/token.cxx
new file mode 100644
index 000000000000..f26f2b750d5c
--- /dev/null
+++ b/binfilter/bf_basic/source/comp/token.cxx
@@ -0,0 +1,575 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * 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.
+ *
+ * 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).
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include <ctype.h>
+#include "token.hxx"
+
+namespace binfilter {
+
+struct TokenTable { SbiToken t; const char *s; };
+
+static short nToken; // Anzahl der Tokens
+
+static TokenTable* pTokTable;
+
+static TokenTable aTokTable_Basic [] = { // Token-Tabelle:
+
+ { CAT, "&" },
+ { MUL, "*" },
+ { PLUS, "+" },
+ { MINUS, "-" },
+ { DIV, "/" },
+ { EOS, ":" },
+ { ASSIGN, ":=" },
+ { LT, "<" },
+ { LE, "<=" },
+ { NE, "<>" },
+ { EQ, "=" },
+ { GT, ">" },
+ { GE, ">=" },
+ { ACCESS, "Access" },
+ { ALIAS, "Alias" },
+ { AND, "And" },
+ { ANY, "Any" },
+ { APPEND, "Append" },
+ { AS, "As" },
+ { BASE, "Base" },
+ { BINARY, "Binary" },
+ { TBOOLEAN, "Boolean" },
+ { BYREF, "ByRef", },
+ { TBYTE, "Byte", },
+ { BYVAL, "ByVal", },
+ { CALL, "Call" },
+ { CASE, "Case" },
+ { _CDECL_, "Cdecl" },
+ { CLASSMODULE, "ClassModule" },
+ { CLOSE, "Close" },
+ { COMPARE, "Compare" },
+ { COMPATIBLE,"Compatible" },
+ { _CONST_, "Const" },
+ { TCURRENCY,"Currency" },
+ { TDATE, "Date" },
+ { DECLARE, "Declare" },
+ { DEFBOOL, "DefBool" },
+ { DEFCUR, "DefCur" },
+ { DEFDATE, "DefDate" },
+ { DEFDBL, "DefDbl" },
+ { DEFERR, "DefErr" },
+ { DEFINT, "DefInt" },
+ { DEFLNG, "DefLng" },
+ { DEFOBJ, "DefObj" },
+ { DEFSNG, "DefSng" },
+ { DEFSTR, "DefStr" },
+ { DEFVAR, "DefVar" },
+ { DIM, "Dim" },
+ { DO, "Do" },
+ { TDOUBLE, "Double" },
+ { EACH, "Each" },
+ { ELSE, "Else" },
+ { ELSEIF, "ElseIf" },
+ { END, "End" },
+ { ENDENUM, "End Enum" },
+ { ENDFUNC, "End Function" },
+ { ENDIF, "End If" },
+ { ENDPROPERTY, "End Property" },
+ { ENDSELECT,"End Select" },
+ { ENDSUB, "End Sub" },
+ { ENDTYPE, "End Type" },
+ { ENDIF, "EndIf" },
+ { ENUM, "Enum" },
+ { EQV, "Eqv" },
+ { ERASE, "Erase" },
+ { _ERROR_, "Error" },
+ { EXIT, "Exit" },
+ { EXPLICIT, "Explicit" },
+ { FOR, "For" },
+ { FUNCTION, "Function" },
+ { GET, "Get" },
+ { GLOBAL, "Global" },
+ { GOSUB, "GoSub" },
+ { GOTO, "GoTo" },
+ { IF, "If" },
+ { IMP, "Imp" },
+ { IMPLEMENTS, "Implements" },
+ { _IN_, "In" },
+ { INPUT, "Input" }, // auch INPUT #
+ { TINTEGER, "Integer" },
+ { IS, "Is" },
+ { LET, "Let" },
+ { LIB, "Lib" },
+ { LINE, "Line" },
+ { LINEINPUT,"Line Input" },
+ { LOCAL, "Local" },
+ { LOCK, "Lock" },
+ { TLONG, "Long" },
+ { LOOP, "Loop" },
+ { LPRINT, "LPrint" },
+ { LSET, "LSet" }, // JSM
+ { MOD, "Mod" },
+ { NAME, "Name" },
+ { NEW, "New" },
+ { NEXT, "Next" },
+ { NOT, "Not" },
+ { TOBJECT, "Object" },
+ { ON, "On" },
+ { OPEN, "Open" },
+ { OPTION, "Option" },
+ { _OPTIONAL_, "Optional" },
+ { OR, "Or" },
+ { OUTPUT, "Output" },
+ { PARAMARRAY, "ParamArray" },
+ { PRESERVE, "Preserve" },
+ { PRINT, "Print" },
+ { PRIVATE, "Private" },
+ { PROPERTY, "Property" },
+ { PUBLIC, "Public" },
+ { RANDOM, "Random" },
+ { READ, "Read" },
+ { REDIM, "ReDim" },
+ { REM, "Rem" },
+ { RESUME, "Resume" },
+ { RETURN, "Return" },
+ { RSET, "RSet" }, // JSM
+ { SELECT, "Select" },
+ { SET, "Set" },
+#ifdef SHARED
+#undef SHARED
+#define tmpSHARED
+#endif
+ { SHARED, "Shared" },
+#ifdef tmpSHARED
+#define SHARED
+#undef tmpSHARED
+#endif
+ { TSINGLE, "Single" },
+ { STATIC, "Static" },
+ { STEP, "Step" },
+ { STOP, "Stop" },
+ { TSTRING, "String" },
+ { SUB, "Sub" },
+ { STOP, "System" },
+ { TEXT, "Text" },
+ { THEN, "Then" },
+ { TO, "To", },
+ { TYPE, "Type" },
+ { TYPEOF, "TypeOf" },
+ { UNTIL, "Until" },
+ { TVARIANT, "Variant" },
+ { VBASUPPORT, "VbaSupport" },
+ { WEND, "Wend" },
+ { WHILE, "While" },
+ { WITH, "With" },
+ { WRITE, "Write" }, // auch WRITE #
+ { XOR, "Xor" },
+ { NIL, "" }
+};
+
+/*
+TokenTable aTokTable_Java [] = { // Token-Tabelle:
+
+ { JS_LOG_NOT, "!" },
+ { JS_NE, "!=" },
+ { JS_MOD, "%" },
+ { JS_ASS_MOD, "%=" },
+ { JS_BIT_AND, "&" },
+ { JS_LOG_AND, "&&" },
+ { JS_ASS_AND, "&=" },
+ { JS_LPAREN, "(" },
+ { JS_RPAREN, ")" },
+ { JS_MUL, "*" },
+ { JS_ASS_MUL, "*=" },
+ { JS_PLUS, "+" },
+ { JS_INC, "++" },
+ { JS_ASS_PLUS, "+=" },
+ { JS_COMMA, "," },
+ { JS_MINUS, "-" },
+ { JS_DEC, "--" },
+ { JS_ASS_MINUS, "-=" },
+ { JS_DIV, "/" },
+ { JS_ASS_DIV, "/=" },
+ { JS_COND_SEL, ":" },
+ { JS_LT, "<" },
+ { JS_LSHIFT, "<<" },
+ { JS_ASS_LSHIFT,"<<=" },
+ { JS_LE, "<=" },
+ { JS_NE, "<>" },
+ { JS_ASSIGNMENT,"=" },
+ { JS_EQ, "==" },
+ { JS_GT, ">" },
+ { JS_RSHIFT, ">>" },
+ { JS_ASS_RSHIFT,">>=" },
+ { JS_RSHIFT_Z, ">>>" },
+ { JS_ASS_RSHIFT_Z,">>>=" },
+ { JS_GE, ">=" },
+ { JS_COND_QUEST,"?" },
+ { ACCESS, "Access" },
+ { ALIAS, "Alias" },
+ { AND, "And" },
+ { ANY, "Any" },
+ { APPEND, "Append" },
+ { AS, "As" },
+ { BASE, "Base" },
+ { BINARY, "Binary" },
+ { TBOOLEAN, "Boolean" },
+ { BYVAL, "ByVal", },
+ { CALL, "Call" },
+ { CASE, "Case" },
+ { _CDECL_, "Cdecl" },
+ { CLOSE, "Close" },
+ { COMPARE, "Compare" },
+ { _CONST_, "Const" },
+ { TCURRENCY,"Currency" },
+ { TDATE, "Date" },
+ { DECLARE, "Declare" },
+ { DEFBOOL, "DefBool" },
+ { DEFCUR, "DefCur" },
+ { DEFDATE, "DefDate" },
+ { DEFDBL, "DefDbl" },
+ { DEFERR, "DefErr" },
+ { DEFINT, "DefInt" },
+ { DEFLNG, "DefLng" },
+ { DEFOBJ, "DefObj" },
+ { DEFSNG, "DefSng" },
+ { DEFSTR, "DefStr" },
+ { DEFVAR, "DefVar" },
+ { DIM, "Dim" },
+ { DO, "Do" },
+ { TDOUBLE, "Double" },
+ { EACH, "Each" },
+ { ELSE, "Else" },
+ { ELSEIF, "ElseIf" },
+ { END, "End" },
+ { ENDFUNC, "End Function" },
+ { ENDIF, "End If" },
+ { ENDSELECT,"End Select" },
+ { ENDSUB, "End Sub" },
+ { ENDTYPE, "End Type" },
+ { ENDIF, "EndIf" },
+ { EQV, "Eqv" },
+ { ERASE, "Erase" },
+ { _ERROR_, "Error" },
+ { EXIT, "Exit" },
+ { EXPLICIT, "Explicit" },
+ { FOR, "For" },
+ { FUNCTION, "Function" },
+ { GLOBAL, "Global" },
+ { GOSUB, "GoSub" },
+ { GOTO, "GoTo" },
+ { IF, "If" },
+ { IMP, "Imp" },
+ { _IN_, "In" },
+ { INPUT, "Input" }, // auch INPUT #
+ { TINTEGER, "Integer" },
+ { IS, "Is" },
+ { LET, "Let" },
+ { LIB, "Lib" },
+ { LINE, "Line" },
+ { LINEINPUT,"Line Input" },
+ { LOCAL, "Local" },
+ { LOCK, "Lock" },
+ { TLONG, "Long" },
+ { LOOP, "Loop" },
+ { LPRINT, "LPrint" },
+ { LSET, "LSet" }, // JSM
+ { MOD, "Mod" },
+ { NAME, "Name" },
+ { NEW, "New" },
+ { NEXT, "Next" },
+ { NOT, "Not" },
+ { TOBJECT, "Object" },
+ { ON, "On" },
+ { OPEN, "Open" },
+ { OPTION, "Option" },
+ { _OPTIONAL_, "Optional" },
+ { OR, "Or" },
+ { OUTPUT, "Output" },
+ { PRESERVE, "Preserve" },
+ { PRINT, "Print" },
+ { PRIVATE, "Private" },
+ { PUBLIC, "Public" },
+ { RANDOM, "Random" },
+ { READ, "Read" },
+ { REDIM, "ReDim" },
+ { REM, "Rem" },
+ { RESUME, "Resume" },
+ { RETURN, "Return" },
+ { RSET, "RSet" }, // JSM
+ { SELECT, "Select" },
+ { SET, "Set" },
+ { SHARED, "Shared" },
+ { TSINGLE, "Single" },
+ { STATIC, "Static" },
+ { STEP, "Step" },
+ { STOP, "Stop" },
+ { TSTRING, "String" },
+ { SUB, "Sub" },
+ { STOP, "System" },
+ { TEXT, "Text" },
+ { THEN, "Then" },
+ { TO, "To", },
+ { TYPE, "Type" },
+ { UNTIL, "Until" },
+ { TVARIANT, "Variant" },
+ { WEND, "Wend" },
+ { WHILE, "While" },
+ { WITH, "With" },
+ { WRITE, "Write" }, // auch WRITE #
+ { XOR, "Xor" },
+ { JS_LINDEX, "[" },
+ { JS_RINDEX, "]" },
+ { JS_BIT_XOR, "^" },
+ { JS_ASS_XOR, "^=" },
+ { JS_BIT_OR, "|" },
+ { JS_ASS_OR, "|=" },
+ { JS_LOG_OR, "||" },
+ { JS_BIT_NOT, "~" },
+ { NIL }
+};
+*/
+
+// Der Konstruktor ermittelt die Laenge der Token-Tabelle.
+
+SbiTokenizer::SbiTokenizer( const ::rtl::OUString& rSrc, StarBASIC* pb )
+ : SbiScanner( rSrc, pb )
+{
+ pTokTable = aTokTable_Basic;
+ //if( StarBASIC::GetGlobalLanguageMode() == SB_LANG_JAVASCRIPT )
+ // pTokTable = aTokTable_Java;
+ TokenTable *tp;
+ bEof = bAs = FALSE;
+ eCurTok = NIL;
+ ePush = NIL;
+ bEos = bKeywords = bErrorIsSymbol = TRUE;
+ if( !nToken )
+ for( nToken = 0, tp = pTokTable; tp->t; nToken++, tp++ ) {}
+}
+
+SbiTokenizer::~SbiTokenizer()
+{}
+
+// Einlesen des naechsten Tokens, ohne dass das Token geschluckt wird
+
+SbiToken SbiTokenizer::Peek()
+{
+ if( ePush == NIL )
+ {
+ USHORT nOldLine = nLine;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ ePush = Next();
+ nPLine = nLine; nLine = nOldLine;
+ nPCol1 = nCol1; nCol1 = nOldCol1;
+ nPCol2 = nCol2; nCol2 = nOldCol2;
+ }
+ return eCurTok = ePush;
+}
+
+// Einlesen des naechsten Tokens und Ablage desselben
+// Tokens, die nicht in der Token-Tabelle vorkommen, werden
+// direkt als Zeichen zurueckgeliefert.
+// Einige Worte werden gesondert behandelt.
+
+SbiToken SbiTokenizer::Next()
+{
+ if (bEof) return EOLN;
+ // Schon eines eingelesen?
+ if( ePush != NIL )
+ {
+ eCurTok = ePush;
+ ePush = NIL;
+ nLine = nPLine;
+ nCol1 = nPCol1;
+ nCol2 = nPCol2;
+ bEos = IsEoln( eCurTok );
+ return eCurTok;
+ }
+ TokenTable *tp;
+
+ // Sonst einlesen:
+ if( !NextSym() )
+ {
+ bEof = bEos = TRUE;
+ return eCurTok = EOLN;
+ }
+ // Zeilenende?
+ if( aSym.GetBuffer()[0] == '\n' )
+ {
+ bEos = TRUE; return eCurTok = EOLN;
+ }
+ bEos = FALSE;
+
+ // Zahl?
+ if( bNumber )
+ return eCurTok = NUMBER;
+
+ // String?
+ else if( ( eScanType == SbxDATE || eScanType == SbxSTRING ) && !bSymbol )
+ return eCurTok = FIXSTRING;
+ // Sonderfaelle von Zeichen, die zwischen "Z" und "a" liegen. ICompare()
+ // wertet die Position dieser Zeichen unterschiedlich aus.
+ else if( aSym.GetBuffer()[0] == '^' )
+ return eCurTok = EXPON;
+ else if( aSym.GetBuffer()[0] == '\\' )
+ return eCurTok = IDIV;
+ else
+ {
+ // Mit Typkennung oder ein Symbol und keine Keyword-Erkennung?
+ // Dann kein Token-Test
+ if( eScanType != SbxVARIANT
+ || ( !bKeywords && bSymbol ) )
+ return eCurTok = SYMBOL;
+ // Gueltiges Token?
+ short lb = 0;
+ short ub = nToken-1;
+ short delta;
+ do
+ {
+ delta = (ub - lb) >> 1;
+ tp = &pTokTable[ lb + delta ];
+ StringCompare res = aSym.CompareIgnoreCaseToAscii( tp->s );
+ // Gefunden?
+ if( res == COMPARE_EQUAL ) goto special;
+ // Groesser? Dann untere Haelfte
+ if( res == COMPARE_LESS )
+ {
+ if ((ub - lb) == 2) ub = lb;
+ else ub = ub - delta;
+ }
+ // Kleiner? Dann obere Haelfte
+ else
+ {
+ if ((ub -lb) == 2) lb = ub;
+ else lb = lb + delta;
+ }
+ } while( delta );
+ // Symbol? Wenn nicht >= Token
+ sal_Unicode ch = aSym.GetBuffer()[0];
+ if( !BasicSimpleCharClass::isAlpha( ch, bCompatible ) && !bSymbol )
+ return eCurTok = (SbiToken) (ch & 0x00FF);
+ return eCurTok = SYMBOL;
+ }
+special:
+ // LINE INPUT
+ if( tp->t == LINE )
+ {
+ short nC1 = nCol1;
+ String aOldSym = aSym;
+ eCurTok = Peek();
+ if( eCurTok == INPUT )
+ {
+ Next();
+ nCol1 = nC1;
+ return eCurTok = LINEINPUT;
+ }
+ else
+ {
+ aSym = aOldSym;
+ return eCurTok = LINE;
+ }
+ }
+ // END IF, CASE, SUB, DEF, FUNCTION, TYPE, CLASS, WITH
+ if( tp->t == END )
+ {
+ // AB, 15.3.96, Spezialbehandlung fuer END, beim Peek() geht die
+ // aktuelle Zeile verloren, daher alles merken und danach restaurieren
+ USHORT nOldLine = nLine;
+ USHORT nOldCol = nCol;
+ USHORT nOldCol1 = nCol1;
+ USHORT nOldCol2 = nCol2;
+ String aOldSym = aSym;
+ SaveLine(); // pLine im Scanner sichern
+
+ eCurTok = Peek();
+ switch( eCurTok )
+ {
+ case IF: Next(); eCurTok = ENDIF; break;
+ case SELECT: Next(); eCurTok = ENDSELECT; break;
+ case SUB: Next(); eCurTok = ENDSUB; break;
+ case FUNCTION: Next(); eCurTok = ENDFUNC; break;
+ case PROPERTY: Next(); eCurTok = ENDPROPERTY; break;
+ case TYPE: Next(); eCurTok = ENDTYPE; break;
+ case ENUM: Next(); eCurTok = ENDENUM; break;
+ case WITH: Next(); eCurTok = ENDWITH; break;
+ default : eCurTok = END;
+ }
+ nCol1 = nOldCol1;
+ if( eCurTok == END )
+ {
+ // Alles zuruecksetzen, damit Token nach END ganz neu gelesen wird
+ ePush = NIL;
+ nLine = nOldLine;
+ nCol = nOldCol;
+ nCol2 = nOldCol2;
+ aSym = aOldSym;
+ RestoreLine(); // pLine im Scanner restaurieren
+ }
+ return eCurTok;
+ }
+ // Sind Datentypen Keywords?
+ // Nur nach AS, sonst sind es Symbole!
+ // Es gibt ja ERROR(), DATA(), STRING() etc.
+ eCurTok = tp->t;
+ // AS: Datentypen sind Keywords
+ if( tp->t == AS )
+ bAs = TRUE;
+ else
+ {
+ if( bAs )
+ bAs = FALSE;
+ else if( eCurTok >= DATATYPE1 && eCurTok <= DATATYPE2 && (bErrorIsSymbol || eCurTok != _ERROR_) )
+ eCurTok = SYMBOL;
+ }
+
+ // CLASSMODULE, PROPERTY, GET, ENUM token only visible in compatible mode
+ SbiToken eTok = tp->t;
+ if( bCompatible )
+ {
+ // #129904 Suppress system
+ if( eTok == STOP && aSym.CompareIgnoreCaseToAscii( "system" ) == COMPARE_EQUAL )
+ eCurTok = SYMBOL;
+ }
+ else
+ {
+ if( eTok == CLASSMODULE ||
+ eTok == IMPLEMENTS ||
+ eTok == PARAMARRAY ||
+ eTok == ENUM ||
+ eTok == PROPERTY ||
+ eTok == GET ||
+ eTok == TYPEOF )
+ {
+ eCurTok = SYMBOL;
+ }
+ }
+
+ bEos = IsEoln( eCurTok );
+ return eCurTok;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */