1*e1f63238SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*e1f63238SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*e1f63238SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*e1f63238SAndrew Rist * distributed with this work for additional information 6*e1f63238SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*e1f63238SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*e1f63238SAndrew Rist * "License"); you may not use this file except in compliance 9*e1f63238SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*e1f63238SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*e1f63238SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*e1f63238SAndrew Rist * software distributed under the License is distributed on an 15*e1f63238SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*e1f63238SAndrew Rist * KIND, either express or implied. See the License for the 17*e1f63238SAndrew Rist * specific language governing permissions and limitations 18*e1f63238SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*e1f63238SAndrew Rist *************************************************************/ 21*e1f63238SAndrew Rist 22*e1f63238SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_basic.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "sbcomp.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir // Single-line IF und Multiline IF 30cdf0e10cSrcweir 31cdf0e10cSrcweir void SbiParser::If() 32cdf0e10cSrcweir { 33cdf0e10cSrcweir sal_uInt32 nEndLbl; 34cdf0e10cSrcweir SbiToken eTok = NIL; 35cdf0e10cSrcweir // Ende-Tokens ignorieren: 36cdf0e10cSrcweir SbiExpression aCond( this ); 37cdf0e10cSrcweir aCond.Gen(); 38cdf0e10cSrcweir TestToken( THEN ); 39cdf0e10cSrcweir if( IsEoln( Next() ) ) 40cdf0e10cSrcweir { 41cdf0e10cSrcweir // AB 13.5.1996: #27720# Am Ende jeden Blocks muss ein Jump zu ENDIF 42cdf0e10cSrcweir // eingefuegt werden, damit bei ELSEIF nicht erneut die Bedingung 43cdf0e10cSrcweir // ausgewertet wird. Die Tabelle nimmt alle Absprungstellen auf. 44cdf0e10cSrcweir #define JMP_TABLE_SIZE 100 45cdf0e10cSrcweir sal_uInt32 pnJmpToEndLbl[JMP_TABLE_SIZE]; // 100 ELSEIFs zulaessig 46cdf0e10cSrcweir sal_uInt16 iJmp = 0; // aktueller Tabellen-Index 47cdf0e10cSrcweir 48cdf0e10cSrcweir // multiline IF 49cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMPF, 0 ); 50cdf0e10cSrcweir eTok = Peek(); 51cdf0e10cSrcweir while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) && 52cdf0e10cSrcweir !bAbort && Parse() ) 53cdf0e10cSrcweir { 54cdf0e10cSrcweir eTok = Peek(); 55cdf0e10cSrcweir if( IsEof() ) 56cdf0e10cSrcweir { 57cdf0e10cSrcweir Error( SbERR_BAD_BLOCK, IF ); bAbort = sal_True; return; 58cdf0e10cSrcweir } 59cdf0e10cSrcweir } 60cdf0e10cSrcweir // ELSEIF? 61cdf0e10cSrcweir while( eTok == ELSEIF ) 62cdf0e10cSrcweir { 63cdf0e10cSrcweir // #27720# Bei erfolgreichem IF/ELSEIF auf ENDIF springen 64cdf0e10cSrcweir if( iJmp >= JMP_TABLE_SIZE ) 65cdf0e10cSrcweir { 66cdf0e10cSrcweir Error( SbERR_PROG_TOO_LARGE ); bAbort = sal_True; return; 67cdf0e10cSrcweir } 68cdf0e10cSrcweir pnJmpToEndLbl[iJmp++] = aGen.Gen( _JUMP, 0 ); 69cdf0e10cSrcweir 70cdf0e10cSrcweir Next(); 71cdf0e10cSrcweir aGen.BackChain( nEndLbl ); 72cdf0e10cSrcweir 73cdf0e10cSrcweir aGen.Statement(); 74cdf0e10cSrcweir SbiExpression* pCond = new SbiExpression( this ); 75cdf0e10cSrcweir pCond->Gen(); 76cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMPF, 0 ); 77cdf0e10cSrcweir delete pCond; 78cdf0e10cSrcweir TestToken( THEN ); 79cdf0e10cSrcweir eTok = Peek(); 80cdf0e10cSrcweir while( !( eTok == ELSEIF || eTok == ELSE || eTok == ENDIF ) && 81cdf0e10cSrcweir !bAbort && Parse() ) 82cdf0e10cSrcweir { 83cdf0e10cSrcweir eTok = Peek(); 84cdf0e10cSrcweir if( IsEof() ) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir Error( SbERR_BAD_BLOCK, ELSEIF ); bAbort = sal_True; return; 87cdf0e10cSrcweir } 88cdf0e10cSrcweir } 89cdf0e10cSrcweir } 90cdf0e10cSrcweir if( eTok == ELSE ) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir Next(); 93cdf0e10cSrcweir sal_uInt32 nElseLbl = nEndLbl; 94cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMP, 0 ); 95cdf0e10cSrcweir aGen.BackChain( nElseLbl ); 96cdf0e10cSrcweir 97cdf0e10cSrcweir aGen.Statement(); 98cdf0e10cSrcweir StmntBlock( ENDIF ); 99cdf0e10cSrcweir } 100cdf0e10cSrcweir else if( eTok == ENDIF ) 101cdf0e10cSrcweir Next(); 102cdf0e10cSrcweir 103cdf0e10cSrcweir // #27720# Jmp-Tabelle abarbeiten 104cdf0e10cSrcweir while( iJmp > 0 ) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir iJmp--; 107cdf0e10cSrcweir aGen.BackChain( pnJmpToEndLbl[iJmp] ); 108cdf0e10cSrcweir } 109cdf0e10cSrcweir } 110cdf0e10cSrcweir else 111cdf0e10cSrcweir { 112cdf0e10cSrcweir // single line IF 113cdf0e10cSrcweir bSingleLineIf = sal_True; 114cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMPF, 0 ); 115cdf0e10cSrcweir Push( eCurTok ); 116cdf0e10cSrcweir while( !bAbort ) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir if( !Parse() ) break; 119cdf0e10cSrcweir eTok = Peek(); 120cdf0e10cSrcweir if( eTok == ELSE || eTok == EOLN || eTok == REM ) 121cdf0e10cSrcweir break; 122cdf0e10cSrcweir } 123cdf0e10cSrcweir if( eTok == ELSE ) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir Next(); 126cdf0e10cSrcweir sal_uInt32 nElseLbl = nEndLbl; 127cdf0e10cSrcweir nEndLbl = aGen.Gen( _JUMP, 0 ); 128cdf0e10cSrcweir aGen.BackChain( nElseLbl ); 129cdf0e10cSrcweir while( !bAbort ) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir if( !Parse() ) break; 132cdf0e10cSrcweir eTok = Peek(); 133cdf0e10cSrcweir if( eTok == EOLN ) 134cdf0e10cSrcweir break; 135cdf0e10cSrcweir } 136cdf0e10cSrcweir } 137cdf0e10cSrcweir bSingleLineIf = sal_False; 138cdf0e10cSrcweir } 139cdf0e10cSrcweir aGen.BackChain( nEndLbl ); 140cdf0e10cSrcweir } 141cdf0e10cSrcweir 142cdf0e10cSrcweir // ELSE/ELSEIF/ENDIF ohne IF 143cdf0e10cSrcweir 144cdf0e10cSrcweir void SbiParser::NoIf() 145cdf0e10cSrcweir { 146cdf0e10cSrcweir Error( SbERR_NO_IF ); 147cdf0e10cSrcweir StmntBlock( ENDIF ); 148cdf0e10cSrcweir } 149cdf0e10cSrcweir 150cdf0e10cSrcweir // DO WHILE...LOOP 151cdf0e10cSrcweir // DO ... LOOP WHILE 152cdf0e10cSrcweir 153cdf0e10cSrcweir void SbiParser::DoLoop() 154cdf0e10cSrcweir { 155cdf0e10cSrcweir sal_uInt32 nStartLbl = aGen.GetPC(); 156cdf0e10cSrcweir OpenBlock( DO ); 157cdf0e10cSrcweir SbiToken eTok = Next(); 158cdf0e10cSrcweir if( IsEoln( eTok ) ) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir // DO ... LOOP [WHILE|UNTIL expr] 161cdf0e10cSrcweir StmntBlock( LOOP ); 162cdf0e10cSrcweir eTok = Next(); 163cdf0e10cSrcweir if( eTok == UNTIL || eTok == WHILE ) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir SbiExpression aExpr( this ); 166cdf0e10cSrcweir aExpr.Gen(); 167cdf0e10cSrcweir aGen.Gen( eTok == UNTIL ? _JUMPF : _JUMPT, nStartLbl ); 168cdf0e10cSrcweir } else 169cdf0e10cSrcweir if (eTok == EOLN || eTok == REM) 170cdf0e10cSrcweir aGen.Gen (_JUMP, nStartLbl); 171cdf0e10cSrcweir else 172cdf0e10cSrcweir Error( SbERR_EXPECTED, WHILE ); 173cdf0e10cSrcweir } 174cdf0e10cSrcweir else 175cdf0e10cSrcweir { 176cdf0e10cSrcweir // DO [WHILE|UNTIL expr] ... LOOP 177cdf0e10cSrcweir if( eTok == UNTIL || eTok == WHILE ) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir SbiExpression aCond( this ); 180cdf0e10cSrcweir aCond.Gen(); 181cdf0e10cSrcweir } 182cdf0e10cSrcweir sal_uInt32 nEndLbl = aGen.Gen( eTok == UNTIL ? _JUMPT : _JUMPF, 0 ); 183cdf0e10cSrcweir StmntBlock( LOOP ); 184cdf0e10cSrcweir TestEoln(); 185cdf0e10cSrcweir aGen.Gen( _JUMP, nStartLbl ); 186cdf0e10cSrcweir aGen.BackChain( nEndLbl ); 187cdf0e10cSrcweir } 188cdf0e10cSrcweir CloseBlock(); 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir // WHILE ... WEND 192cdf0e10cSrcweir 193cdf0e10cSrcweir void SbiParser::While() 194cdf0e10cSrcweir { 195cdf0e10cSrcweir SbiExpression aCond( this ); 196cdf0e10cSrcweir sal_uInt32 nStartLbl = aGen.GetPC(); 197cdf0e10cSrcweir aCond.Gen(); 198cdf0e10cSrcweir sal_uInt32 nEndLbl = aGen.Gen( _JUMPF, 0 ); 199cdf0e10cSrcweir StmntBlock( WEND ); 200cdf0e10cSrcweir aGen.Gen( _JUMP, nStartLbl ); 201cdf0e10cSrcweir aGen.BackChain( nEndLbl ); 202cdf0e10cSrcweir } 203cdf0e10cSrcweir 204cdf0e10cSrcweir // FOR var = expr TO expr STEP 205cdf0e10cSrcweir 206cdf0e10cSrcweir void SbiParser::For() 207cdf0e10cSrcweir { 208cdf0e10cSrcweir bool bForEach = ( Peek() == EACH ); 209cdf0e10cSrcweir if( bForEach ) 210cdf0e10cSrcweir Next(); 211cdf0e10cSrcweir SbiExpression aLvalue( this, SbOPERAND ); 212cdf0e10cSrcweir aLvalue.Gen(); // Variable auf dem Stack 213cdf0e10cSrcweir 214cdf0e10cSrcweir if( bForEach ) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir TestToken( _IN_ ); 217cdf0e10cSrcweir SbiExpression aCollExpr( this, SbOPERAND ); 218cdf0e10cSrcweir aCollExpr.Gen(); // Colletion var to for stack 219cdf0e10cSrcweir TestEoln(); 220cdf0e10cSrcweir aGen.Gen( _INITFOREACH ); 221cdf0e10cSrcweir } 222cdf0e10cSrcweir else 223cdf0e10cSrcweir { 224cdf0e10cSrcweir TestToken( EQ ); 225cdf0e10cSrcweir SbiExpression aStartExpr( this ); 226cdf0e10cSrcweir aStartExpr.Gen(); // Startausdruck auf dem Stack 227cdf0e10cSrcweir TestToken( TO ); 228cdf0e10cSrcweir SbiExpression aStopExpr( this ); 229cdf0e10cSrcweir aStopExpr.Gen(); // Endausdruck auf dem Stack 230cdf0e10cSrcweir if( Peek() == STEP ) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir Next(); 233cdf0e10cSrcweir SbiExpression aStepExpr( this ); 234cdf0e10cSrcweir aStepExpr.Gen(); 235cdf0e10cSrcweir } 236cdf0e10cSrcweir else 237cdf0e10cSrcweir { 238cdf0e10cSrcweir SbiExpression aOne( this, 1, SbxINTEGER ); 239cdf0e10cSrcweir aOne.Gen(); 240cdf0e10cSrcweir } 241cdf0e10cSrcweir TestEoln(); 242cdf0e10cSrcweir // Der Stack hat jetzt 4 Elemente: Variable, Start, Ende, Inkrement 243cdf0e10cSrcweir // Startwert binden 244cdf0e10cSrcweir aGen.Gen( _INITFOR ); 245cdf0e10cSrcweir } 246cdf0e10cSrcweir 247cdf0e10cSrcweir sal_uInt32 nLoop = aGen.GetPC(); 248cdf0e10cSrcweir // Test durchfuehren, evtl. Stack freigeben 249cdf0e10cSrcweir sal_uInt32 nEndTarget = aGen.Gen( _TESTFOR, 0 ); 250cdf0e10cSrcweir OpenBlock( FOR ); 251cdf0e10cSrcweir StmntBlock( NEXT ); 252cdf0e10cSrcweir aGen.Gen( _NEXT ); 253cdf0e10cSrcweir aGen.Gen( _JUMP, nLoop ); 254cdf0e10cSrcweir // Kommen Variable nach NEXT? 255cdf0e10cSrcweir if( Peek() == SYMBOL ) 256cdf0e10cSrcweir { 257cdf0e10cSrcweir SbiExpression aVar( this, SbOPERAND ); 258cdf0e10cSrcweir if( aVar.GetRealVar() != aLvalue.GetRealVar() ) 259cdf0e10cSrcweir Error( SbERR_EXPECTED, aLvalue.GetRealVar()->GetName() ); 260cdf0e10cSrcweir } 261cdf0e10cSrcweir aGen.BackChain( nEndTarget ); 262cdf0e10cSrcweir CloseBlock(); 263cdf0e10cSrcweir } 264cdf0e10cSrcweir 265cdf0e10cSrcweir // WITH .. END WITH 266cdf0e10cSrcweir 267cdf0e10cSrcweir void SbiParser::With() 268cdf0e10cSrcweir { 269cdf0e10cSrcweir SbiExpression aVar( this, SbOPERAND ); 270cdf0e10cSrcweir 271cdf0e10cSrcweir // Letzten Knoten in der Objekt-Kette ueberpruefen 272cdf0e10cSrcweir SbiExprNode *pNode = aVar.GetExprNode()->GetRealNode(); 273cdf0e10cSrcweir SbiSymDef* pDef = pNode->GetVar(); 274cdf0e10cSrcweir // Variant, AB 27.6.1997, #41090: bzw. empty -> mu� Object sein 275cdf0e10cSrcweir if( pDef->GetType() == SbxVARIANT || pDef->GetType() == SbxEMPTY ) 276cdf0e10cSrcweir pDef->SetType( SbxOBJECT ); 277cdf0e10cSrcweir else if( pDef->GetType() != SbxOBJECT ) 278cdf0e10cSrcweir Error( SbERR_NEEDS_OBJECT ); 279cdf0e10cSrcweir 280cdf0e10cSrcweir // Knoten auch auf SbxOBJECT setzen, damit spaeter Gen() klappt 281cdf0e10cSrcweir pNode->SetType( SbxOBJECT ); 282cdf0e10cSrcweir 283cdf0e10cSrcweir OpenBlock( NIL, aVar.GetExprNode() ); 284cdf0e10cSrcweir StmntBlock( ENDWITH ); 285cdf0e10cSrcweir CloseBlock(); 286cdf0e10cSrcweir } 287cdf0e10cSrcweir 288cdf0e10cSrcweir // LOOP/NEXT/WEND ohne Konstrukt 289cdf0e10cSrcweir 290cdf0e10cSrcweir void SbiParser::BadBlock() 291cdf0e10cSrcweir { 292cdf0e10cSrcweir if( eEndTok ) 293cdf0e10cSrcweir Error( SbERR_BAD_BLOCK, eEndTok ); 294cdf0e10cSrcweir else 295cdf0e10cSrcweir Error( SbERR_BAD_BLOCK, "Loop/Next/Wend" ); 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 298cdf0e10cSrcweir // On expr Goto/Gosub n,n,n... 299cdf0e10cSrcweir 300cdf0e10cSrcweir void SbiParser::OnGoto() 301cdf0e10cSrcweir { 302cdf0e10cSrcweir SbiExpression aCond( this ); 303cdf0e10cSrcweir aCond.Gen(); 304cdf0e10cSrcweir sal_uInt32 nLabelsTarget = aGen.Gen( _ONJUMP, 0 ); 305cdf0e10cSrcweir SbiToken eTok = Next(); 306cdf0e10cSrcweir if( eTok != GOTO && eTok != GOSUB ) 307cdf0e10cSrcweir { 308cdf0e10cSrcweir Error( SbERR_EXPECTED, "GoTo/GoSub" ); 309cdf0e10cSrcweir eTok = GOTO; 310cdf0e10cSrcweir } 311cdf0e10cSrcweir // Label-Tabelle einlesen: 312cdf0e10cSrcweir sal_uInt32 nLbl = 0; 313cdf0e10cSrcweir do 314cdf0e10cSrcweir { 315cdf0e10cSrcweir SbiToken eTok2 = NIL; 316cdf0e10cSrcweir eTok2 = Next(); // Label holen 317cdf0e10cSrcweir if( MayBeLabel() ) 318cdf0e10cSrcweir { 319cdf0e10cSrcweir sal_uInt32 nOff = pProc->GetLabels().Reference( aSym ); 320cdf0e10cSrcweir aGen.Gen( _JUMP, nOff ); 321cdf0e10cSrcweir nLbl++; 322cdf0e10cSrcweir } 323cdf0e10cSrcweir else Error( SbERR_LABEL_EXPECTED ); 324cdf0e10cSrcweir } 325cdf0e10cSrcweir while( !bAbort && TestComma() ); 326cdf0e10cSrcweir if( eTok == GOSUB ) 327cdf0e10cSrcweir nLbl |= 0x8000; 328cdf0e10cSrcweir aGen.Patch( nLabelsTarget, nLbl ); 329cdf0e10cSrcweir } 330cdf0e10cSrcweir 331cdf0e10cSrcweir // GOTO/GOSUB 332cdf0e10cSrcweir 333cdf0e10cSrcweir void SbiParser::Goto() 334cdf0e10cSrcweir { 335cdf0e10cSrcweir SbiOpcode eOp = eCurTok == GOTO ? _JUMP : _GOSUB; 336cdf0e10cSrcweir Next(); 337cdf0e10cSrcweir if( MayBeLabel() ) 338cdf0e10cSrcweir { 339cdf0e10cSrcweir sal_uInt32 nOff = pProc->GetLabels().Reference( aSym ); 340cdf0e10cSrcweir aGen.Gen( eOp, nOff ); 341cdf0e10cSrcweir } 342cdf0e10cSrcweir else Error( SbERR_LABEL_EXPECTED ); 343cdf0e10cSrcweir } 344cdf0e10cSrcweir 345cdf0e10cSrcweir // RETURN [label] 346cdf0e10cSrcweir 347cdf0e10cSrcweir void SbiParser::Return() 348cdf0e10cSrcweir { 349cdf0e10cSrcweir Next(); 350cdf0e10cSrcweir if( MayBeLabel() ) 351cdf0e10cSrcweir { 352cdf0e10cSrcweir sal_uInt32 nOff = pProc->GetLabels().Reference( aSym ); 353cdf0e10cSrcweir aGen.Gen( _RETURN, nOff ); 354cdf0e10cSrcweir } 355cdf0e10cSrcweir else aGen.Gen( _RETURN, 0 ); 356cdf0e10cSrcweir } 357cdf0e10cSrcweir 358cdf0e10cSrcweir // SELECT CASE 359cdf0e10cSrcweir 360cdf0e10cSrcweir void SbiParser::Select() 361cdf0e10cSrcweir { 362cdf0e10cSrcweir TestToken( CASE ); 363cdf0e10cSrcweir SbiExpression aCase( this ); 364cdf0e10cSrcweir SbiToken eTok = NIL; 365cdf0e10cSrcweir aCase.Gen(); 366cdf0e10cSrcweir aGen.Gen( _CASE ); 367cdf0e10cSrcweir TestEoln(); 368cdf0e10cSrcweir sal_uInt32 nNextTarget = 0; 369cdf0e10cSrcweir sal_uInt32 nDoneTarget = 0; 370cdf0e10cSrcweir sal_Bool bElse = sal_False; 371cdf0e10cSrcweir // Die Cases einlesen: 372cdf0e10cSrcweir while( !bAbort ) 373cdf0e10cSrcweir { 374cdf0e10cSrcweir eTok = Next(); 375cdf0e10cSrcweir if( eTok == CASE ) 376cdf0e10cSrcweir { 377cdf0e10cSrcweir if( nNextTarget ) 378cdf0e10cSrcweir aGen.BackChain( nNextTarget ), nNextTarget = 0; 379cdf0e10cSrcweir aGen.Statement(); 380cdf0e10cSrcweir // Jeden Case einlesen 381cdf0e10cSrcweir sal_Bool bDone = sal_False; 382cdf0e10cSrcweir sal_uInt32 nTrueTarget = 0; 383cdf0e10cSrcweir if( Peek() == ELSE ) 384cdf0e10cSrcweir { 385cdf0e10cSrcweir // CASE ELSE 386cdf0e10cSrcweir Next(); 387cdf0e10cSrcweir bElse = sal_True; 388cdf0e10cSrcweir } 389cdf0e10cSrcweir else while( !bDone ) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir if( bElse ) 392cdf0e10cSrcweir Error( SbERR_SYNTAX ); 393cdf0e10cSrcweir SbiToken eTok2 = Peek(); 394cdf0e10cSrcweir if( eTok2 == IS || ( eTok2 >= EQ && eTok2 <= GE ) ) 395cdf0e10cSrcweir { // CASE [IS] operator expr 396cdf0e10cSrcweir if( eTok2 == IS ) 397cdf0e10cSrcweir Next(); 398cdf0e10cSrcweir eTok2 = Peek(); 399cdf0e10cSrcweir if( eTok2 < EQ || eTok2 > GE ) 400cdf0e10cSrcweir Error( SbERR_SYNTAX ); 401cdf0e10cSrcweir else Next(); 402cdf0e10cSrcweir SbiExpression aCompare( this ); 403cdf0e10cSrcweir aCompare.Gen(); 404cdf0e10cSrcweir nTrueTarget = aGen.Gen( 405cdf0e10cSrcweir _CASEIS, nTrueTarget, 406cdf0e10cSrcweir sal::static_int_cast< sal_uInt16 >( 407cdf0e10cSrcweir SbxEQ + ( eTok2 - EQ ) ) ); 408cdf0e10cSrcweir } 409cdf0e10cSrcweir else 410cdf0e10cSrcweir { // CASE expr | expr TO expr 411cdf0e10cSrcweir SbiExpression aCase1( this ); 412cdf0e10cSrcweir aCase1.Gen(); 413cdf0e10cSrcweir if( Peek() == TO ) 414cdf0e10cSrcweir { 415cdf0e10cSrcweir // CASE a TO b 416cdf0e10cSrcweir Next(); 417cdf0e10cSrcweir SbiExpression aCase2( this ); 418cdf0e10cSrcweir aCase2.Gen(); 419cdf0e10cSrcweir nTrueTarget = aGen.Gen( _CASETO, nTrueTarget ); 420cdf0e10cSrcweir } 421cdf0e10cSrcweir else 422cdf0e10cSrcweir // CASE a 423cdf0e10cSrcweir nTrueTarget = aGen.Gen( _CASEIS, nTrueTarget, SbxEQ ); 424cdf0e10cSrcweir 425cdf0e10cSrcweir } 426cdf0e10cSrcweir if( Peek() == COMMA ) Next(); 427cdf0e10cSrcweir else TestEoln(), bDone = sal_True; 428cdf0e10cSrcweir } 429cdf0e10cSrcweir // Alle Cases abgearbeitet 430cdf0e10cSrcweir if( !bElse ) 431cdf0e10cSrcweir { 432cdf0e10cSrcweir nNextTarget = aGen.Gen( _JUMP, nNextTarget ); 433cdf0e10cSrcweir aGen.BackChain( nTrueTarget ); 434cdf0e10cSrcweir } 435cdf0e10cSrcweir // den Statement-Rumpf bauen 436cdf0e10cSrcweir while( !bAbort ) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir eTok = Peek(); 439cdf0e10cSrcweir if( eTok == CASE || eTok == ENDSELECT ) 440cdf0e10cSrcweir break; 441cdf0e10cSrcweir if( !Parse() ) goto done; 442cdf0e10cSrcweir eTok = Peek(); 443cdf0e10cSrcweir if( eTok == CASE || eTok == ENDSELECT ) 444cdf0e10cSrcweir break; 445cdf0e10cSrcweir } 446cdf0e10cSrcweir if( !bElse ) 447cdf0e10cSrcweir nDoneTarget = aGen.Gen( _JUMP, nDoneTarget ); 448cdf0e10cSrcweir } 449cdf0e10cSrcweir else if( !IsEoln( eTok ) ) 450cdf0e10cSrcweir break; 451cdf0e10cSrcweir } 452cdf0e10cSrcweir done: 453cdf0e10cSrcweir if( eTok != ENDSELECT ) 454cdf0e10cSrcweir Error( SbERR_EXPECTED, ENDSELECT ); 455cdf0e10cSrcweir if( nNextTarget ) 456cdf0e10cSrcweir aGen.BackChain( nNextTarget ); 457cdf0e10cSrcweir aGen.BackChain( nDoneTarget ); 458cdf0e10cSrcweir aGen.Gen( _ENDCASE ); 459cdf0e10cSrcweir } 460cdf0e10cSrcweir 461cdf0e10cSrcweir // ON Error/Variable 462cdf0e10cSrcweir 463cdf0e10cSrcweir #ifdef _MSC_VER 464cdf0e10cSrcweir #pragma optimize("",off) 465cdf0e10cSrcweir #endif 466cdf0e10cSrcweir 467cdf0e10cSrcweir void SbiParser::On() 468cdf0e10cSrcweir { 469cdf0e10cSrcweir SbiToken eTok = Peek(); 470cdf0e10cSrcweir String aString = SbiTokenizer::Symbol(eTok); 471cdf0e10cSrcweir if (aString.EqualsIgnoreCaseAscii("ERROR")) 472cdf0e10cSrcweir //if (!aString.ICompare("ERROR")) 473cdf0e10cSrcweir eTok = _ERROR_; // Error kommt als SYMBOL 474cdf0e10cSrcweir if( eTok != _ERROR_ && eTok != LOCAL ) OnGoto(); 475cdf0e10cSrcweir else 476cdf0e10cSrcweir { 477cdf0e10cSrcweir if( eTok == LOCAL ) Next(); 478cdf0e10cSrcweir Next (); // Kein TestToken mehr, da es sonst einen Fehler gibt 479cdf0e10cSrcweir 480cdf0e10cSrcweir Next(); // Token nach Error holen 481cdf0e10cSrcweir if( eCurTok == GOTO ) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir // ON ERROR GOTO label|0 484cdf0e10cSrcweir Next(); 485cdf0e10cSrcweir bool bError_ = false; 486cdf0e10cSrcweir if( MayBeLabel() ) 487cdf0e10cSrcweir { 488cdf0e10cSrcweir if( eCurTok == NUMBER && !nVal ) 489cdf0e10cSrcweir aGen.Gen( _STDERROR ); 490cdf0e10cSrcweir else 491cdf0e10cSrcweir { 492cdf0e10cSrcweir sal_uInt32 nOff = pProc->GetLabels().Reference( aSym ); 493cdf0e10cSrcweir aGen.Gen( _ERRHDL, nOff ); 494cdf0e10cSrcweir } 495cdf0e10cSrcweir } 496cdf0e10cSrcweir else if( eCurTok == MINUS ) 497cdf0e10cSrcweir { 498cdf0e10cSrcweir Next(); 499cdf0e10cSrcweir if( eCurTok == NUMBER && nVal == 1 ) 500cdf0e10cSrcweir aGen.Gen( _STDERROR ); 501cdf0e10cSrcweir else 502cdf0e10cSrcweir bError_ = true; 503cdf0e10cSrcweir } 504cdf0e10cSrcweir if( bError_ ) 505cdf0e10cSrcweir Error( SbERR_LABEL_EXPECTED ); 506cdf0e10cSrcweir } 507cdf0e10cSrcweir else if( eCurTok == RESUME ) 508cdf0e10cSrcweir { 509cdf0e10cSrcweir TestToken( NEXT ); 510cdf0e10cSrcweir aGen.Gen( _NOERROR ); 511cdf0e10cSrcweir } 512cdf0e10cSrcweir else Error( SbERR_EXPECTED, "GoTo/Resume" ); 513cdf0e10cSrcweir } 514cdf0e10cSrcweir } 515cdf0e10cSrcweir 516cdf0e10cSrcweir #ifdef _MSC_VER 517cdf0e10cSrcweir #pragma optimize("",off) 518cdf0e10cSrcweir #endif 519cdf0e10cSrcweir 520cdf0e10cSrcweir // RESUME [0]|NEXT|label 521cdf0e10cSrcweir 522cdf0e10cSrcweir void SbiParser::Resume() 523cdf0e10cSrcweir { 524cdf0e10cSrcweir sal_uInt32 nLbl; 525cdf0e10cSrcweir 526cdf0e10cSrcweir switch( Next() ) 527cdf0e10cSrcweir { 528cdf0e10cSrcweir case EOS: 529cdf0e10cSrcweir case EOLN: 530cdf0e10cSrcweir aGen.Gen( _RESUME, 0 ); 531cdf0e10cSrcweir break; 532cdf0e10cSrcweir case NEXT: 533cdf0e10cSrcweir aGen.Gen( _RESUME, 1 ); 534cdf0e10cSrcweir Next(); 535cdf0e10cSrcweir break; 536cdf0e10cSrcweir case NUMBER: 537cdf0e10cSrcweir if( !nVal ) 538cdf0e10cSrcweir { 539cdf0e10cSrcweir aGen.Gen( _RESUME, 0 ); 540cdf0e10cSrcweir break; 541cdf0e10cSrcweir } // fall thru 542cdf0e10cSrcweir case SYMBOL: 543cdf0e10cSrcweir if( MayBeLabel() ) 544cdf0e10cSrcweir { 545cdf0e10cSrcweir nLbl = pProc->GetLabels().Reference( aSym ); 546cdf0e10cSrcweir aGen.Gen( _RESUME, nLbl ); 547cdf0e10cSrcweir Next(); 548cdf0e10cSrcweir break; 549cdf0e10cSrcweir } // fall thru 550cdf0e10cSrcweir default: 551cdf0e10cSrcweir Error( SbERR_LABEL_EXPECTED ); 552cdf0e10cSrcweir } 553cdf0e10cSrcweir } 554cdf0e10cSrcweir 555