Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / basic / source / comp / parser.cxx
bloba4a4501077d9992282ec7d133fe7dfe481a2628a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <basic/sbx.hxx>
21 #include "sbcomp.hxx"
22 #include <com/sun/star/script/ModuleType.hpp>
24 struct SbiParseStack { // "Stack" for statement-blocks
25 SbiParseStack* pNext; // Chain
26 SbiExprNode* pWithVar;
27 SbiToken eExitTok;
28 sal_uInt32 nChain; // JUMP-Chain
31 struct SbiStatement {
32 SbiToken eTok;
33 void( SbiParser::*Func )();
34 sal_Bool bMain; // sal_True: OK outside the SUB
35 sal_Bool bSubr; // sal_True: OK inside the SUB
38 #define Y sal_True
39 #define N sal_False
41 static SbiStatement StmntTable [] = {
42 { ATTRIBUTE, &SbiParser::Attribute, Y, Y, }, // ATTRIBUTE
43 { CALL, &SbiParser::Call, N, Y, }, // CALL
44 { CLOSE, &SbiParser::Close, N, Y, }, // CLOSE
45 { _CONST_, &SbiParser::Dim, Y, Y, }, // CONST
46 { DECLARE, &SbiParser::Declare, Y, N, }, // DECLARE
47 { DEFBOOL, &SbiParser::DefXXX, Y, N, }, // DEFBOOL
48 { DEFCUR, &SbiParser::DefXXX, Y, N, }, // DEFCUR
49 { DEFDATE, &SbiParser::DefXXX, Y, N, }, // DEFDATE
50 { DEFDBL, &SbiParser::DefXXX, Y, N, }, // DEFDBL
51 { DEFERR, &SbiParser::DefXXX, Y, N, }, // DEFERR
52 { DEFINT, &SbiParser::DefXXX, Y, N, }, // DEFINT
53 { DEFLNG, &SbiParser::DefXXX, Y, N, }, // DEFLNG
54 { DEFOBJ, &SbiParser::DefXXX, Y, N, }, // DEFOBJ
55 { DEFSNG, &SbiParser::DefXXX, Y, N, }, // DEFSNG
56 { DEFSTR, &SbiParser::DefXXX, Y, N, }, // DEFSTR
57 { DEFVAR, &SbiParser::DefXXX, Y, N, }, // DEFVAR
58 { DIM, &SbiParser::Dim, Y, Y, }, // DIM
59 { DO, &SbiParser::DoLoop, N, Y, }, // DO
60 { ELSE, &SbiParser::NoIf, N, Y, }, // ELSE
61 { ELSEIF, &SbiParser::NoIf, N, Y, }, // ELSEIF
62 { ENDIF, &SbiParser::NoIf, N, Y, }, // ENDIF
63 { END, &SbiParser::Stop, N, Y, }, // END
64 { ENUM, &SbiParser::Enum, Y, N, }, // TYPE
65 { ERASE, &SbiParser::Erase, N, Y, }, // ERASE
66 { _ERROR_, &SbiParser::ErrorStmnt, N, Y, }, // ERROR
67 { EXIT, &SbiParser::Exit, N, Y, }, // EXIT
68 { FOR, &SbiParser::For, N, Y, }, // FOR
69 { FUNCTION, &SbiParser::SubFunc, Y, N, }, // FUNCTION
70 { GOSUB, &SbiParser::Goto, N, Y, }, // GOSUB
71 { GLOBAL, &SbiParser::Dim, Y, N, }, // GLOBAL
72 { GOTO, &SbiParser::Goto, N, Y, }, // GOTO
73 { IF, &SbiParser::If, N, Y, }, // IF
74 { IMPLEMENTS, &SbiParser::Implements, Y, N, }, // IMPLEMENTS
75 { INPUT, &SbiParser::Input, N, Y, }, // INPUT
76 { LET, &SbiParser::Assign, N, Y, }, // LET
77 { LINE, &SbiParser::Line, N, Y, }, // LINE, -> LINE INPUT (#i92642)
78 { LINEINPUT,&SbiParser::LineInput, N, Y, }, // LINE INPUT
79 { LOOP, &SbiParser::BadBlock, N, Y, }, // LOOP
80 { LSET, &SbiParser::LSet, N, Y, }, // LSET
81 { NAME, &SbiParser::Name, N, Y, }, // NAME
82 { NEXT, &SbiParser::BadBlock, N, Y, }, // NEXT
83 { ON, &SbiParser::On, N, Y, }, // ON
84 { OPEN, &SbiParser::Open, N, Y, }, // OPEN
85 { OPTION, &SbiParser::Option, Y, N, }, // OPTION
86 { PRINT, &SbiParser::Print, N, Y, }, // PRINT
87 { PRIVATE, &SbiParser::Dim, Y, N, }, // PRIVATE
88 { PROPERTY, &SbiParser::SubFunc, Y, N, }, // FUNCTION
89 { PUBLIC, &SbiParser::Dim, Y, N, }, // PUBLIC
90 { REDIM, &SbiParser::ReDim, N, Y, }, // DIM
91 { RESUME, &SbiParser::Resume, N, Y, }, // RESUME
92 { RETURN, &SbiParser::Return, N, Y, }, // RETURN
93 { RSET, &SbiParser::RSet, N, Y, }, // RSET
94 { SELECT, &SbiParser::Select, N, Y, }, // SELECT
95 { SET, &SbiParser::Set, N, Y, }, // SET
96 { STATIC, &SbiParser::Static, Y, Y, }, // STATIC
97 { STOP, &SbiParser::Stop, N, Y, }, // STOP
98 { SUB, &SbiParser::SubFunc, Y, N, }, // SUB
99 { TYPE, &SbiParser::Type, Y, N, }, // TYPE
100 { UNTIL, &SbiParser::BadBlock, N, Y, }, // UNTIL
101 { WHILE, &SbiParser::While, N, Y, }, // WHILE
102 { WEND, &SbiParser::BadBlock, N, Y, }, // WEND
103 { WITH, &SbiParser::With, N, Y, }, // WITH
104 { WRITE, &SbiParser::Write, N, Y, }, // WRITE
106 { NIL, NULL, N, N }
110 #ifdef _MSC_VER
111 // 'this' : used in base member initializer list
112 #pragma warning( disable: 4355 )
113 #endif
115 SbiParser::SbiParser( StarBASIC* pb, SbModule* pm )
116 : SbiTokenizer( pm->GetSource32(), pb ),
117 aGblStrings( this ),
118 aLclStrings( this ),
119 aGlobals( aGblStrings, SbGLOBAL ),
120 aPublics( aGblStrings, SbPUBLIC ),
121 aRtlSyms( aGblStrings, SbRTL ),
122 aGen( *pm, this, 1024 )
124 pBasic = pb;
125 eCurExpr = SbSYMBOL;
126 eEndTok = NIL;
127 pProc = NULL;
128 pStack = NULL;
129 pWithVar = NULL;
130 nBase = 0;
131 bText =
132 bGblDefs =
133 bNewGblDefs =
134 bSingleLineIf =
135 bExplicit = false;
136 bClassModule = ( pm->GetModuleType() == com::sun::star::script::ModuleType::CLASS );
137 OSL_TRACE("Parser - %s, bClassModule %d", rtl::OUStringToOString( pm->GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), bClassModule );
138 pPool = &aPublics;
139 for( short i = 0; i < 26; i++ )
140 eDefTypes[ i ] = SbxVARIANT; // no explicit default type
142 aPublics.SetParent( &aGlobals );
143 aGlobals.SetParent( &aRtlSyms );
146 nGblChain = aGen.Gen( _JUMP, 0 );
148 rTypeArray = new SbxArray; // array for user defined types
149 rEnumArray = new SbxArray; // array for Enum types
150 bVBASupportOn = pm->IsVBACompat();
151 if ( bVBASupportOn )
152 EnableCompatibility();
157 // part of the runtime-library?
158 SbiSymDef* SbiParser::CheckRTLForSym( const OUString& rSym, SbxDataType eType )
160 SbxVariable* pVar = GetBasic()->GetRtl()->Find( rSym, SbxCLASS_DONTCARE );
161 SbiSymDef* pDef = NULL;
162 if( pVar )
164 if( pVar->IsA( TYPE(SbxMethod) ) )
166 SbiProcDef* pProc_ = aRtlSyms.AddProc( rSym );
167 pProc_->SetType( pVar->GetType() );
168 pDef = pProc_;
170 else
172 pDef = aRtlSyms.AddSym( rSym );
173 pDef->SetType( eType );
176 return pDef;
179 // close global chain
181 bool SbiParser::HasGlobalCode()
183 if( bGblDefs && nGblChain )
185 aGen.BackChain( nGblChain );
186 aGen.Gen( _LEAVE );
187 nGblChain = 0;
189 return bGblDefs;
192 void SbiParser::OpenBlock( SbiToken eTok, SbiExprNode* pVar )
194 SbiParseStack* p = new SbiParseStack;
195 p->eExitTok = eTok;
196 p->nChain = 0;
197 p->pWithVar = pWithVar;
198 p->pNext = pStack;
199 pStack = p;
200 pWithVar = pVar;
202 // #29955 service the for-loop level
203 if( eTok == FOR )
204 aGen.IncForLevel();
207 void SbiParser::CloseBlock()
209 if( pStack )
211 SbiParseStack* p = pStack;
213 // #29955 service the for-loop level
214 if( p->eExitTok == FOR )
215 aGen.DecForLevel();
217 aGen.BackChain( p->nChain );
218 pStack = p->pNext;
219 pWithVar = p->pWithVar;
220 delete p;
224 // EXIT ...
226 void SbiParser::Exit()
228 SbiToken eTok = Next();
229 for( SbiParseStack* p = pStack; p; p = p->pNext )
231 SbiToken eExitTok = p->eExitTok;
232 if( eTok == eExitTok ||
233 (eTok == PROPERTY && (eExitTok == GET || eExitTok == LET) ) ) // #i109051
235 p->nChain = aGen.Gen( _JUMP, p->nChain );
236 return;
239 if( pStack )
240 Error( SbERR_EXPECTED, pStack->eExitTok );
241 else
242 Error( SbERR_BAD_EXIT );
245 bool SbiParser::TestSymbol( bool bKwdOk )
247 Peek();
248 if( eCurTok == SYMBOL || ( bKwdOk && IsKwd( eCurTok ) ) )
250 Next(); return true;
252 Error( SbERR_SYMBOL_EXPECTED );
253 return false;
258 bool SbiParser::TestToken( SbiToken t )
260 if( Peek() == t )
262 Next(); return true;
264 else
266 Error( SbERR_EXPECTED, t );
267 return false;
273 bool SbiParser::TestComma()
275 SbiToken eTok = Peek();
276 if( IsEoln( eTok ) )
278 Next();
279 return false;
281 else if( eTok != COMMA )
283 Error( SbERR_EXPECTED, COMMA );
284 return false;
286 Next();
287 return true;
292 void SbiParser::TestEoln()
294 if( !IsEoln( Next() ) )
296 Error( SbERR_EXPECTED, EOLN );
297 while( !IsEoln( Next() ) ) {}
303 void SbiParser::StmntBlock( SbiToken eEnd )
305 SbiToken xe = eEndTok;
306 eEndTok = eEnd;
307 while( !bAbort && Parse() ) {}
308 eEndTok = xe;
309 if( IsEof() )
311 Error( SbERR_BAD_BLOCK, eEnd );
312 bAbort = sal_True;
318 bool SbiParser::Parse()
320 if( bAbort ) return false;
322 EnableErrors();
324 bErrorIsSymbol = false;
325 Peek();
326 bErrorIsSymbol = true;
328 if( IsEof() )
330 // AB #33133: If no sub has been created before,
331 // the global chain must be closed here!
332 // AB #40689: Due to the new static-handling there
333 // can be another nGblChain, so ask for it before.
334 if( bNewGblDefs && nGblChain == 0 )
335 nGblChain = aGen.Gen( _JUMP, 0 );
336 return false;
340 if( IsEoln( eCurTok ) )
342 Next(); return true;
345 if( !bSingleLineIf && MayBeLabel( true ) )
347 // is a label
348 if( !pProc )
349 Error( SbERR_NOT_IN_MAIN, aSym );
350 else
351 pProc->GetLabels().Define( aSym );
352 Next(); Peek();
354 if( IsEoln( eCurTok ) )
356 Next(); return true;
360 // end of parsing?
361 if( eCurTok == eEndTok ||
362 ( bVBASupportOn && // #i109075
363 (eCurTok == ENDFUNC || eCurTok == ENDPROPERTY || eCurTok == ENDSUB) &&
364 (eEndTok == ENDFUNC || eEndTok == ENDPROPERTY || eEndTok == ENDSUB) ) )
366 Next();
367 if( eCurTok != NIL )
368 aGen.Statement();
369 return false;
372 // comment?
373 if( eCurTok == REM )
375 Next(); return true;
378 // In vba it's possible to do Error.foobar ( even if it results in
379 // a runtime error
380 if ( eCurTok == _ERROR_ && IsVBASupportOn() ) // we probably need to define a subset of keywords where this madness applies e.g. if ( IsVBASupportOn() && SymbolCanBeRedined( eCurTok ) )
382 SbiTokenizer tokens( *(SbiTokenizer*)this );
383 tokens.Next();
384 if ( tokens.Peek() == DOT )
386 eCurTok = SYMBOL;
387 ePush = eCurTok;
390 // if there's a symbol, it's either a variable (LET)
391 // or a SUB-procedure (CALL without brackets)
392 // DOT for assignments in the WITH-block: .A=5
393 if( eCurTok == SYMBOL || eCurTok == DOT )
395 if( !pProc )
396 Error( SbERR_EXPECTED, SUB );
397 else
399 // for correct line and column...
400 Next();
401 Push( eCurTok );
402 aGen.Statement();
403 Symbol();
406 else
408 Next();
410 // statement parsers
412 SbiStatement* p;
413 for( p = StmntTable; p->eTok != NIL; p++ )
414 if( p->eTok == eCurTok )
415 break;
416 if( p->eTok != NIL )
418 if( !pProc && !p->bMain )
419 Error( SbERR_NOT_IN_MAIN, eCurTok );
420 else if( pProc && !p->bSubr )
421 Error( SbERR_NOT_IN_SUBR, eCurTok );
422 else
424 // AB #41606/#40689: Due to the new static-handling there
425 // can be another nGblChain, so ask for it before.
426 if( bNewGblDefs && nGblChain == 0 &&
427 ( eCurTok == SUB || eCurTok == FUNCTION || eCurTok == PROPERTY ) )
429 nGblChain = aGen.Gen( _JUMP, 0 );
430 bNewGblDefs = false;
432 // statement-opcode at the beginning of a sub, too, please
433 if( ( p->bSubr && (eCurTok != STATIC || Peek() == SUB || Peek() == FUNCTION ) ) ||
434 eCurTok == SUB || eCurTok == FUNCTION )
435 aGen.Statement();
436 (this->*( p->Func ) )();
437 SbxError nSbxErr = SbxBase::GetError();
438 if( nSbxErr )
439 SbxBase::ResetError(), Error( (SbError)nSbxErr );
442 else
443 Error( SbERR_UNEXPECTED, eCurTok );
446 // test for the statement's end -
447 // might also be an ELSE, as there must not neccessary be a : before the ELSE!
449 if( !IsEos() )
451 Peek();
452 if( !IsEos() && eCurTok != ELSE )
454 // if the parsing has been aborted, jump over to the ":"
455 Error( SbERR_UNEXPECTED, eCurTok );
456 while( !IsEos() ) Next();
459 // The parser aborts at the end, the
460 // next token has not been fetched yet!
461 return true;
465 SbiExprNode* SbiParser::GetWithVar()
467 if( pWithVar )
468 return pWithVar;
470 SbiParseStack* p = pStack;
471 while( p )
473 // LoopVar can at the moment only be for with
474 if( p->pWithVar )
475 return p->pWithVar;
476 p = p->pNext;
478 return NULL;
482 // assignment or subroutine call
484 void SbiParser::Symbol( const KeywordSymbolInfo* pKeywordSymbolInfo )
486 SbiExprMode eMode = bVBASupportOn ? EXPRMODE_STANDALONE : EXPRMODE_STANDARD;
487 SbiExpression aVar( this, SbSYMBOL, eMode, pKeywordSymbolInfo );
489 bool bEQ = ( Peek() == EQ );
490 if( !bEQ && bVBASupportOn && aVar.IsBracket() )
491 Error( SbERR_EXPECTED, "=" );
493 RecursiveMode eRecMode = ( bEQ ? PREVENT_CALL : FORCE_CALL );
494 bool bSpecialMidHandling = false;
495 SbiSymDef* pDef = aVar.GetRealVar();
496 if( bEQ && pDef && pDef->GetScope() == SbRTL )
498 OUString aRtlName = pDef->GetName();
499 if( aRtlName.equalsIgnoreAsciiCase("Mid") )
501 SbiExprNode* pExprNode = aVar.GetExprNode();
502 if( pExprNode && pExprNode->GetNodeType() == SbxVARVAL )
504 SbiExprList* pPar = pExprNode->GetParameters();
505 short nParCount = pPar ? pPar->GetSize() : 0;
506 if( nParCount == 2 || nParCount == 3 )
508 if( nParCount == 2 )
509 pPar->addExpression( new SbiExpression( this, -1, SbxLONG ) );
511 TestToken( EQ );
512 pPar->addExpression( new SbiExpression( this ) );
514 bSpecialMidHandling = true;
519 aVar.Gen( eRecMode );
520 if( !bSpecialMidHandling )
522 if( !bEQ )
524 aGen.Gen( _GET );
526 else
528 // so it must be an assignment!
529 if( !aVar.IsLvalue() )
530 Error( SbERR_LVALUE_EXPECTED );
531 TestToken( EQ );
532 SbiExpression aExpr( this );
533 aExpr.Gen();
534 SbiOpcode eOp = _PUT;
535 if( pDef )
537 if( pDef->GetConstDef() )
538 Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
539 if( pDef->GetType() == SbxOBJECT )
541 eOp = _SET;
542 if( pDef->GetTypeId() )
544 aGen.Gen( _SETCLASS, pDef->GetTypeId() );
545 return;
549 aGen.Gen( eOp );
555 void SbiParser::Assign()
557 SbiExpression aLvalue( this, SbLVALUE );
558 TestToken( EQ );
559 SbiExpression aExpr( this );
560 aLvalue.Gen();
561 aExpr.Gen();
562 sal_uInt16 nLen = 0;
563 SbiSymDef* pDef = aLvalue.GetRealVar();
565 if( pDef->GetConstDef() )
566 Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
567 nLen = aLvalue.GetRealVar()->GetLen();
569 if( nLen )
570 aGen.Gen( _PAD, nLen );
571 aGen.Gen( _PUT );
574 // assignments of an object-variable
576 void SbiParser::Set()
578 SbiExpression aLvalue( this, SbLVALUE );
579 SbxDataType eType = aLvalue.GetType();
580 if( eType != SbxOBJECT && eType != SbxEMPTY && eType != SbxVARIANT )
581 Error( SbERR_INVALID_OBJECT );
582 TestToken( EQ );
583 SbiSymDef* pDef = aLvalue.GetRealVar();
584 if( pDef && pDef->GetConstDef() )
585 Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
587 SbiToken eTok = Peek();
588 if( eTok == NEW )
590 Next();
591 OUString aStr;
592 SbiSymDef* pTypeDef = new SbiSymDef( aStr );
593 TypeDecl( *pTypeDef, sal_True );
595 aLvalue.Gen();
596 aGen.Gen( _CREATE, pDef->GetId(), pTypeDef->GetTypeId() );
597 aGen.Gen( _SETCLASS, pDef->GetTypeId() );
599 else
601 SbiExpression aExpr( this );
602 aLvalue.Gen();
603 aExpr.Gen();
604 // Its a good idea to distinguish between
605 // set someting = another &
606 // someting = another
607 // ( its necessary for vba objects where set is object
608 // specific and also doesn't involve processing default params )
609 if( pDef->GetTypeId() )
611 if ( bVBASupportOn )
612 aGen.Gen( _VBASETCLASS, pDef->GetTypeId() );
613 else
614 aGen.Gen( _SETCLASS, pDef->GetTypeId() );
616 else
618 if ( bVBASupportOn )
619 aGen.Gen( _VBASET );
620 else
621 aGen.Gen( _SET );
626 // JSM 07.10.95
627 void SbiParser::LSet()
629 SbiExpression aLvalue( this, SbLVALUE );
630 if( aLvalue.GetType() != SbxSTRING )
632 Error( SbERR_INVALID_OBJECT );
634 TestToken( EQ );
635 SbiSymDef* pDef = aLvalue.GetRealVar();
636 if( pDef && pDef->GetConstDef() )
638 Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
640 SbiExpression aExpr( this );
641 aLvalue.Gen();
642 aExpr.Gen();
643 aGen.Gen( _LSET );
646 // JSM 07.10.95
647 void SbiParser::RSet()
649 SbiExpression aLvalue( this, SbLVALUE );
650 if( aLvalue.GetType() != SbxSTRING )
652 Error( SbERR_INVALID_OBJECT );
654 TestToken( EQ );
655 SbiSymDef* pDef = aLvalue.GetRealVar();
656 if( pDef && pDef->GetConstDef() )
657 Error( SbERR_DUPLICATE_DEF, pDef->GetName() );
658 SbiExpression aExpr( this );
659 aLvalue.Gen();
660 aExpr.Gen();
661 aGen.Gen( _RSET );
664 // DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFSTR and so on
666 void SbiParser::DefXXX()
668 sal_Unicode ch1, ch2;
669 SbxDataType t = SbxDataType( eCurTok - DEFINT + SbxINTEGER );
671 while( !bAbort )
673 if( Next() != SYMBOL ) break;
674 ch1 = aSym.toAsciiUpperCase()[0];
675 ch2 = 0;
676 if( Peek() == MINUS )
678 Next();
679 if( Next() != SYMBOL ) Error( SbERR_SYMBOL_EXPECTED );
680 else
682 ch2 = aSym.toAsciiUpperCase()[0];
683 if( ch2 < ch1 ) Error( SbERR_SYNTAX ), ch2 = 0;
686 if (!ch2) ch2 = ch1;
687 ch1 -= 'A'; ch2 -= 'A';
688 for (; ch1 <= ch2; ch1++) eDefTypes[ ch1 ] = t;
689 if( !TestComma() ) break;
693 // STOP/SYSTEM
695 void SbiParser::Stop()
697 aGen.Gen( _STOP );
698 Peek(); // #35694: only Peek(), so that EOL is recognized in Single-Line-If
701 // IMPLEMENTS
703 void SbiParser::Implements()
705 if( !bClassModule )
707 Error( SbERR_UNEXPECTED, IMPLEMENTS );
708 return;
711 Peek();
712 if( eCurTok != SYMBOL )
714 Error( SbERR_SYMBOL_EXPECTED );
715 return;
718 OUString aImplementedIface = aSym;
719 Next();
720 if( Peek() == DOT )
722 OUString aDotStr( '.' );
723 while( Peek() == DOT )
725 aImplementedIface += aDotStr;
726 Next();
727 SbiToken ePeekTok = Peek();
728 if( ePeekTok == SYMBOL || IsKwd( ePeekTok ) )
730 Next();
731 aImplementedIface += aSym;
733 else
735 Next();
736 Error( SbERR_SYMBOL_EXPECTED );
737 break;
741 aIfaceVector.push_back( aImplementedIface );
744 void SbiParser::EnableCompatibility()
746 if( !bCompatible )
747 AddConstants();
748 bCompatible = sal_True;
751 // OPTION
753 void SbiParser::Option()
755 switch( Next() )
757 case EXPLICIT:
758 bExplicit = true; break;
759 case BASE:
760 if( Next() == NUMBER )
762 if( nVal == 0 || nVal == 1 )
764 nBase = (short) nVal;
765 break;
768 Error( SbERR_EXPECTED, "0/1" );
769 break;
770 case PRIVATE:
772 OUString aString = SbiTokenizer::Symbol(Next());
773 if( !aString.equalsIgnoreAsciiCase("Module") )
775 Error( SbERR_EXPECTED, "Module" );
777 break;
779 case COMPARE:
781 SbiToken eTok = Next();
782 if( eTok == BINARY )
784 bText = false;
786 else if( eTok == SYMBOL && GetSym().equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("text")) )
788 bText = true;
790 else
792 Error( SbERR_EXPECTED, "Text/Binary" );
794 break;
796 case COMPATIBLE:
797 EnableCompatibility();
798 break;
800 case CLASSMODULE:
801 bClassModule = true;
802 aGen.GetModule().SetModuleType( com::sun::star::script::ModuleType::CLASS );
803 break;
804 case VBASUPPORT: // Option VBASupport used to override the module mode ( in fact this must reset the mode
805 if( Next() == NUMBER )
807 if ( nVal == 1 || nVal == 0 )
809 bVBASupportOn = ( nVal == 1 );
810 if ( bVBASupportOn )
812 EnableCompatibility();
814 // if the module setting is different
815 // reset it to what the Option tells us
816 if ( bVBASupportOn != aGen.GetModule().IsVBACompat() )
818 aGen.GetModule().SetVBACompat( bVBASupportOn );
820 break;
823 Error( SbERR_EXPECTED, "0/1" );
824 break;
825 default:
826 Error( SbERR_BAD_OPTION, eCurTok );
830 void addStringConst( SbiSymPool& rPool, const char* pSym, const OUString& rStr )
832 SbiConstDef* pConst = new SbiConstDef( OUString::createFromAscii( pSym ) );
833 pConst->SetType( SbxSTRING );
834 pConst->Set( rStr );
835 rPool.Add( pConst );
838 inline void addStringConst( SbiSymPool& rPool, const char* pSym, const char* pStr )
840 addStringConst( rPool, pSym, rtl::OUString::createFromAscii( pStr ) );
843 void SbiParser::AddConstants( void )
845 // #113063 Create constant RTL symbols
846 addStringConst( aPublics, "vbCr", "\x0D" );
847 addStringConst( aPublics, "vbCrLf", "\x0D\x0A" );
848 addStringConst( aPublics, "vbFormFeed", "\x0C" );
849 addStringConst( aPublics, "vbLf", "\x0A" );
850 #if defined(UNX)
851 addStringConst( aPublics, "vbNewLine", "\x0A" );
852 #else
853 addStringConst( aPublics, "vbNewLine", "\x0D\x0A" );
854 #endif
855 addStringConst( aPublics, "vbNullString", "" );
856 addStringConst( aPublics, "vbTab", "\x09" );
857 addStringConst( aPublics, "vbVerticalTab", "\x0B" );
859 // Force length 1 and make char 0 afterwards
860 OUString aNullCharStr((sal_Unicode)0);
861 addStringConst( aPublics, "vbNullChar", aNullCharStr );
864 // ERROR n
866 void SbiParser::ErrorStmnt()
868 SbiExpression aPar( this );
869 aPar.Gen();
870 aGen.Gen( _ERROR );
873 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */