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
Gen(RecursiveMode eRecMode)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
GenElement(SbiOpcode eOp)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
Gen()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
Gen(RecursiveMode eRecMode)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