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