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