1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_basic.hxx" 26 27 #include "sbcomp.hxx" 28 #include "expr.hxx" 29 30 // Umsetztabelle fuer Token-Operatoren und Opcodes 31 32 typedef struct { 33 SbiToken eTok; // Token 34 SbiOpcode eOp; // Opcode 35 } OpTable; 36 37 static OpTable aOpTable [] = { 38 { EXPON,_EXP }, 39 { MUL, _MUL }, 40 { DIV, _DIV }, 41 { IDIV, _IDIV }, 42 { MOD, _MOD }, 43 { PLUS, _PLUS }, 44 { MINUS,_MINUS }, 45 { EQ, _EQ }, 46 { NE, _NE }, 47 { LE, _LE }, 48 { GE, _GE }, 49 { LT, _LT }, 50 { GT, _GT }, 51 { AND, _AND }, 52 { OR, _OR }, 53 { XOR, _XOR }, 54 { EQV, _EQV }, 55 { IMP, _IMP }, 56 { NOT, _NOT }, 57 { NEG, _NEG }, 58 { CAT, _CAT }, 59 { LIKE, _LIKE }, 60 { IS, _IS }, 61 { NIL, _NOP }}; 62 63 // Ausgabe eines Elements 64 void SbiExprNode::Gen( RecursiveMode eRecMode ) 65 { 66 if( IsConstant() ) 67 { 68 switch( GetType() ) 69 { 70 case SbxEMPTY: pGen->Gen( _EMPTY ); break; 71 case SbxINTEGER: pGen->Gen( _CONST, (short) nVal ); break; 72 case SbxSTRING: 73 { 74 sal_uInt16 nStringId = pGen->GetParser()->aGblStrings.Add( aStrVal, sal_True ); 75 pGen->Gen( _SCONST, nStringId ); break; 76 } 77 default: 78 { 79 sal_uInt16 nStringId = pGen->GetParser()->aGblStrings.Add( nVal, eType ); 80 pGen->Gen( _NUMBER, nStringId ); 81 } 82 } 83 } 84 else if( IsOperand() ) 85 { 86 SbiExprNode* pWithParent_ = NULL; 87 SbiOpcode eOp; 88 if( aVar.pDef->GetScope() == SbPARAM ) 89 { 90 eOp = _PARAM; 91 if( 0 == aVar.pDef->GetPos() ) 92 { 93 bool bTreatFunctionAsParam = true; 94 if( eRecMode == FORCE_CALL ) 95 { 96 bTreatFunctionAsParam = false; 97 } 98 else if( eRecMode == UNDEFINED ) 99 { 100 if( aVar.pPar && aVar.pPar->IsBracket() ) 101 bTreatFunctionAsParam = false; 102 } 103 if( !bTreatFunctionAsParam ) 104 eOp = aVar.pDef->IsGlobal() ? _FIND_G : _FIND; 105 } 106 } 107 // AB: 17.12.1995, Spezialbehandlung fuer WITH 108 else if( (pWithParent_ = GetWithParent()) != NULL ) 109 { 110 eOp = _ELEM; // .-Ausdruck in WITH 111 } 112 else 113 { 114 eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL : 115 (aVar.pDef->IsGlobal() ? _FIND_G : _FIND); 116 } 117 118 if( eOp == _FIND ) 119 { 120 121 SbiProcDef* pProc = aVar.pDef->GetProcDef(); 122 if ( pGen->GetParser()->bClassModule ) 123 eOp = _FIND_CM; 124 else if ( aVar.pDef->IsStatic() || (pProc && pProc->IsStatic()) ) 125 { 126 eOp = _FIND_STATIC; 127 } 128 } 129 for( SbiExprNode* p = this; p; p = p->aVar.pNext ) 130 { 131 if( p == this && pWithParent_ != NULL ) 132 pWithParent_->Gen(); 133 p->GenElement( eOp ); 134 eOp = _ELEM; 135 } 136 } 137 else if( IsTypeOf() ) 138 { 139 pLeft->Gen(); 140 pGen->Gen( _TESTCLASS, nTypeStrId ); 141 } 142 else if( IsNew() ) 143 { 144 pGen->Gen( _CREATE, 0, nTypeStrId ); 145 } 146 else 147 { 148 pLeft->Gen(); 149 if( pRight ) 150 pRight->Gen(); 151 for( OpTable* p = aOpTable; p->eTok != NIL; p++ ) 152 { 153 if( p->eTok == eTok ) 154 { 155 pGen->Gen( p->eOp ); break; 156 } 157 } 158 } 159 } 160 161 // Ausgabe eines Operanden-Elements 162 163 void SbiExprNode::GenElement( SbiOpcode eOp ) 164 { 165 #ifdef DBG_UTIL 166 if( (eOp < _RTL || eOp > _CALLC) && eOp != _FIND_G && eOp != _FIND_CM ) 167 pGen->GetParser()->Error( SbERR_INTERNAL_ERROR, "Opcode" ); 168 #endif 169 SbiSymDef* pDef = aVar.pDef; 170 // Das ID ist entweder die Position oder das String-ID 171 // Falls das Bit 0x8000 gesetzt ist, hat die Variable 172 // eine Parameterliste. 173 sal_uInt16 nId = ( eOp == _PARAM ) ? pDef->GetPos() : pDef->GetId(); 174 // Parameterliste aufbauen 175 if( aVar.pPar && aVar.pPar->GetSize() ) 176 { 177 nId |= 0x8000; 178 aVar.pPar->Gen(); 179 } 180 181 pGen->Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( GetType() ) ); 182 183 if( aVar.pvMorePar ) 184 { 185 SbiExprListVector* pvMorePar = aVar.pvMorePar; 186 SbiExprListVector::iterator it; 187 for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it ) 188 { 189 SbiExprList* pExprList = *it; 190 pExprList->Gen(); 191 pGen->Gen( _ARRAYACCESS ); 192 } 193 } 194 } 195 196 // Erzeugen einer Argv-Tabelle 197 // Das erste Element bleibt immer frei fuer Returnwerte etc. 198 // Siehe auch SbiProcDef::SbiProcDef() in symtbl.cxx 199 200 void SbiExprList::Gen() 201 { 202 if( pFirst ) 203 { 204 pParser->aGen.Gen( _ARGC ); 205 // AB 10.1.96: Typ-Anpassung bei DECLARE 206 sal_uInt16 nCount = 1 /*, nParAnz = 0*/; 207 // SbiSymPool* pPool = NULL; 208 for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ ) 209 { 210 pExpr->Gen(); 211 if( pExpr->GetName().Len() ) 212 { 213 // named arg 214 sal_uInt16 nSid = pParser->aGblStrings.Add( pExpr->GetName() ); 215 pParser->aGen.Gen( _ARGN, nSid ); 216 217 /* TODO: Check after Declare concept change 218 // AB 10.1.96: Typanpassung bei named -> passenden Parameter suchen 219 if( pProc ) 220 { 221 // Vorerst: Error ausloesen 222 pParser->Error( SbERR_NO_NAMED_ARGS ); 223 224 // Spaeter, wenn Named Args bei DECLARE moeglich 225 //for( sal_uInt16 i = 1 ; i < nParAnz ; i++ ) 226 //{ 227 // SbiSymDef* pDef = pPool->Get( i ); 228 // const String& rName = pDef->GetName(); 229 // if( rName.Len() ) 230 // { 231 // if( pExpr->GetName().ICompare( rName ) 232 // == COMPARE_EQUAL ) 233 // { 234 // pParser->aGen.Gen( _ARGTYP, pDef->GetType() ); 235 // break; 236 // } 237 // } 238 //} 239 } 240 */ 241 } 242 else 243 { 244 pParser->aGen.Gen( _ARGV ); 245 } 246 } 247 } 248 } 249 250 void SbiExpression::Gen( RecursiveMode eRecMode ) 251 { 252 // AB: 17.12.1995, Spezialbehandlung fuer WITH 253 // Wenn pExpr == .-Ausdruck in With, zunaechst Gen fuer Basis-Objekt 254 pExpr->Gen( eRecMode ); 255 if( bByVal ) 256 pParser->aGen.Gen( _BYVAL ); 257 if( bBased ) 258 { 259 sal_uInt16 uBase = pParser->nBase; 260 if( pParser->IsCompatible() ) 261 uBase |= 0x8000; // #109275 Flag compatiblity 262 pParser->aGen.Gen( _BASED, uBase ); 263 pParser->aGen.Gen( _ARGV ); 264 } 265 } 266 267