xref: /AOO41X/main/basic/source/comp/exprgen.cxx (revision e1f63238eb022c8a12b30d46a012444ff20e0951)
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
Gen(RecursiveMode eRecMode)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 
GenElement(SbiOpcode eOp)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 
Gen()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 
Gen(RecursiveMode eRecMode)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