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