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