| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_basic.hxx" |
| |
| #include "sbcomp.hxx" |
| #include "expr.hxx" |
| |
| // Umsetztabelle fuer Token-Operatoren und Opcodes |
| |
| typedef struct { |
| SbiToken eTok; // Token |
| SbiOpcode eOp; // Opcode |
| } OpTable; |
| |
| static OpTable aOpTable [] = { |
| { EXPON,_EXP }, |
| { MUL, _MUL }, |
| { DIV, _DIV }, |
| { IDIV, _IDIV }, |
| { MOD, _MOD }, |
| { PLUS, _PLUS }, |
| { MINUS,_MINUS }, |
| { EQ, _EQ }, |
| { NE, _NE }, |
| { LE, _LE }, |
| { GE, _GE }, |
| { LT, _LT }, |
| { GT, _GT }, |
| { AND, _AND }, |
| { OR, _OR }, |
| { XOR, _XOR }, |
| { EQV, _EQV }, |
| { IMP, _IMP }, |
| { NOT, _NOT }, |
| { NEG, _NEG }, |
| { CAT, _CAT }, |
| { LIKE, _LIKE }, |
| { IS, _IS }, |
| { NIL, _NOP }}; |
| |
| // Ausgabe eines Elements |
| void SbiExprNode::Gen( RecursiveMode eRecMode ) |
| { |
| if( IsConstant() ) |
| { |
| switch( GetType() ) |
| { |
| case SbxEMPTY: pGen->Gen( _EMPTY ); break; |
| case SbxINTEGER: pGen->Gen( _CONST, (short) nVal ); break; |
| case SbxSTRING: |
| { |
| sal_uInt16 nStringId = pGen->GetParser()->aGblStrings.Add( aStrVal, sal_True ); |
| pGen->Gen( _SCONST, nStringId ); break; |
| } |
| default: |
| { |
| sal_uInt16 nStringId = pGen->GetParser()->aGblStrings.Add( nVal, eType ); |
| pGen->Gen( _NUMBER, nStringId ); |
| } |
| } |
| } |
| else if( IsOperand() ) |
| { |
| SbiExprNode* pWithParent_ = NULL; |
| SbiOpcode eOp; |
| if( aVar.pDef->GetScope() == SbPARAM ) |
| { |
| eOp = _PARAM; |
| if( 0 == aVar.pDef->GetPos() ) |
| { |
| bool bTreatFunctionAsParam = true; |
| if( eRecMode == FORCE_CALL ) |
| { |
| bTreatFunctionAsParam = false; |
| } |
| else if( eRecMode == UNDEFINED ) |
| { |
| if( aVar.pPar && aVar.pPar->IsBracket() ) |
| bTreatFunctionAsParam = false; |
| } |
| if( !bTreatFunctionAsParam ) |
| eOp = aVar.pDef->IsGlobal() ? _FIND_G : _FIND; |
| } |
| } |
| // AB: 17.12.1995, Spezialbehandlung fuer WITH |
| else if( (pWithParent_ = GetWithParent()) != NULL ) |
| { |
| eOp = _ELEM; // .-Ausdruck in WITH |
| } |
| else |
| { |
| eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL : |
| (aVar.pDef->IsGlobal() ? _FIND_G : _FIND); |
| } |
| |
| if( eOp == _FIND ) |
| { |
| |
| SbiProcDef* pProc = aVar.pDef->GetProcDef(); |
| if ( pGen->GetParser()->bClassModule ) |
| eOp = _FIND_CM; |
| else if ( aVar.pDef->IsStatic() || (pProc && pProc->IsStatic()) ) |
| { |
| eOp = _FIND_STATIC; |
| } |
| } |
| for( SbiExprNode* p = this; p; p = p->aVar.pNext ) |
| { |
| if( p == this && pWithParent_ != NULL ) |
| pWithParent_->Gen(); |
| p->GenElement( eOp ); |
| eOp = _ELEM; |
| } |
| } |
| else if( IsTypeOf() ) |
| { |
| pLeft->Gen(); |
| pGen->Gen( _TESTCLASS, nTypeStrId ); |
| } |
| else if( IsNew() ) |
| { |
| pGen->Gen( _CREATE, 0, nTypeStrId ); |
| } |
| else |
| { |
| pLeft->Gen(); |
| if( pRight ) |
| pRight->Gen(); |
| for( OpTable* p = aOpTable; p->eTok != NIL; p++ ) |
| { |
| if( p->eTok == eTok ) |
| { |
| pGen->Gen( p->eOp ); break; |
| } |
| } |
| } |
| } |
| |
| // Ausgabe eines Operanden-Elements |
| |
| void SbiExprNode::GenElement( SbiOpcode eOp ) |
| { |
| #ifdef DBG_UTIL |
| if( (eOp < _RTL || eOp > _CALLC) && eOp != _FIND_G && eOp != _FIND_CM ) |
| pGen->GetParser()->Error( SbERR_INTERNAL_ERROR, "Opcode" ); |
| #endif |
| SbiSymDef* pDef = aVar.pDef; |
| // Das ID ist entweder die Position oder das String-ID |
| // Falls das Bit 0x8000 gesetzt ist, hat die Variable |
| // eine Parameterliste. |
| sal_uInt16 nId = ( eOp == _PARAM ) ? pDef->GetPos() : pDef->GetId(); |
| // Parameterliste aufbauen |
| if( aVar.pPar && aVar.pPar->GetSize() ) |
| { |
| nId |= 0x8000; |
| aVar.pPar->Gen(); |
| } |
| |
| pGen->Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( GetType() ) ); |
| |
| if( aVar.pvMorePar ) |
| { |
| SbiExprListVector* pvMorePar = aVar.pvMorePar; |
| SbiExprListVector::iterator it; |
| for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it ) |
| { |
| SbiExprList* pExprList = *it; |
| pExprList->Gen(); |
| pGen->Gen( _ARRAYACCESS ); |
| } |
| } |
| } |
| |
| // Erzeugen einer Argv-Tabelle |
| // Das erste Element bleibt immer frei fuer Returnwerte etc. |
| // Siehe auch SbiProcDef::SbiProcDef() in symtbl.cxx |
| |
| void SbiExprList::Gen() |
| { |
| if( pFirst ) |
| { |
| pParser->aGen.Gen( _ARGC ); |
| // AB 10.1.96: Typ-Anpassung bei DECLARE |
| sal_uInt16 nCount = 1 /*, nParAnz = 0*/; |
| // SbiSymPool* pPool = NULL; |
| for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ ) |
| { |
| pExpr->Gen(); |
| if( pExpr->GetName().Len() ) |
| { |
| // named arg |
| sal_uInt16 nSid = pParser->aGblStrings.Add( pExpr->GetName() ); |
| pParser->aGen.Gen( _ARGN, nSid ); |
| |
| /* TODO: Check after Declare concept change |
| // AB 10.1.96: Typanpassung bei named -> passenden Parameter suchen |
| if( pProc ) |
| { |
| // Vorerst: Error ausloesen |
| pParser->Error( SbERR_NO_NAMED_ARGS ); |
| |
| // Spaeter, wenn Named Args bei DECLARE moeglich |
| //for( sal_uInt16 i = 1 ; i < nParAnz ; i++ ) |
| //{ |
| // SbiSymDef* pDef = pPool->Get( i ); |
| // const String& rName = pDef->GetName(); |
| // if( rName.Len() ) |
| // { |
| // if( pExpr->GetName().ICompare( rName ) |
| // == COMPARE_EQUAL ) |
| // { |
| // pParser->aGen.Gen( _ARGTYP, pDef->GetType() ); |
| // break; |
| // } |
| // } |
| //} |
| } |
| */ |
| } |
| else |
| { |
| pParser->aGen.Gen( _ARGV ); |
| } |
| } |
| } |
| } |
| |
| void SbiExpression::Gen( RecursiveMode eRecMode ) |
| { |
| // AB: 17.12.1995, Spezialbehandlung fuer WITH |
| // Wenn pExpr == .-Ausdruck in With, zunaechst Gen fuer Basis-Objekt |
| pExpr->Gen( eRecMode ); |
| if( bByVal ) |
| pParser->aGen.Gen( _BYVAL ); |
| if( bBased ) |
| { |
| sal_uInt16 uBase = pParser->nBase; |
| if( pParser->IsCompatible() ) |
| uBase |= 0x8000; // #109275 Flag compatiblity |
| pParser->aGen.Gen( _BASED, uBase ); |
| pParser->aGen.Gen( _ARGV ); |
| } |
| } |
| |