update dev300-m58
[ooovba.git] / basic / source / comp / exprgen.cxx
blob9afcf5262f8c6dda548c1eecb679014f36f6dd87
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: exprgen.cxx,v $
10 * $Revision: 1.19 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basic.hxx"
34 #include "sbcomp.hxx"
35 #include "expr.hxx"
37 // Umsetztabelle fuer Token-Operatoren und Opcodes
39 typedef struct {
40 SbiToken eTok; // Token
41 SbiOpcode eOp; // Opcode
42 } OpTable;
44 static OpTable aOpTable [] = {
45 { EXPON,_EXP },
46 { MUL, _MUL },
47 { DIV, _DIV },
48 { IDIV, _IDIV },
49 { MOD, _MOD },
50 { PLUS, _PLUS },
51 { MINUS,_MINUS },
52 { EQ, _EQ },
53 { NE, _NE },
54 { LE, _LE },
55 { GE, _GE },
56 { LT, _LT },
57 { GT, _GT },
58 { AND, _AND },
59 { OR, _OR },
60 { XOR, _XOR },
61 { EQV, _EQV },
62 { IMP, _IMP },
63 { NOT, _NOT },
64 { NEG, _NEG },
65 { CAT, _CAT },
66 { LIKE, _LIKE },
67 { IS, _IS },
68 { NIL, _NOP }};
70 // Ausgabe eines Elements
71 void SbiExprNode::Gen( RecursiveMode eRecMode )
73 if( IsConstant() )
75 switch( GetType() )
77 case SbxEMPTY: pGen->Gen( _EMPTY ); break;
78 case SbxINTEGER: pGen->Gen( _CONST, (short) nVal ); break;
79 case SbxSTRING:
81 USHORT nStringId = pGen->GetParser()->aGblStrings.Add( aStrVal, TRUE );
82 pGen->Gen( _SCONST, nStringId ); break;
84 default:
86 USHORT nStringId = pGen->GetParser()->aGblStrings.Add( nVal, eType );
87 pGen->Gen( _NUMBER, nStringId );
91 else if( IsOperand() )
93 SbiExprNode* pWithParent_ = NULL;
94 SbiOpcode eOp;
95 if( aVar.pDef->GetScope() == SbPARAM )
97 eOp = _PARAM;
98 if( 0 == aVar.pDef->GetPos() )
100 bool bTreatFunctionAsParam = true;
101 if( eRecMode == FORCE_CALL )
103 bTreatFunctionAsParam = false;
105 else if( eRecMode == UNDEFINED )
107 if( aVar.pPar && aVar.pPar->IsBracket() )
108 bTreatFunctionAsParam = false;
110 if( !bTreatFunctionAsParam )
111 eOp = aVar.pDef->IsGlobal() ? _FIND_G : _FIND;
114 // AB: 17.12.1995, Spezialbehandlung fuer WITH
115 else if( (pWithParent_ = GetWithParent()) != NULL )
117 eOp = _ELEM; // .-Ausdruck in WITH
119 else
121 SbiProcDef* pProc = aVar.pDef->GetProcDef();
122 // per DECLARE definiert?
123 if( pProc && pProc->GetLib().Len() )
124 eOp = pProc->IsCdecl() ? _CALLC : _CALL;
125 else
126 eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL :
127 (aVar.pDef->IsGlobal() ? _FIND_G : _FIND);
130 if( eOp == _FIND )
133 SbiProcDef* pProc = aVar.pDef->GetProcDef();
134 if ( pGen->GetParser()->bClassModule )
135 eOp = _FIND_CM;
136 else if ( aVar.pDef->IsStatic() || (pProc && pProc->IsStatic()) )
138 eOp = _FIND_STATIC;
141 for( SbiExprNode* p = this; p; p = p->aVar.pNext )
143 if( p == this && pWithParent_ != NULL )
144 pWithParent_->Gen();
145 p->GenElement( eOp );
146 eOp = _ELEM;
149 else if( IsTypeOf() )
151 pLeft->Gen();
152 pGen->Gen( _TESTCLASS, nTypeStrId );
154 else
156 pLeft->Gen();
157 if( pRight )
158 pRight->Gen();
159 for( OpTable* p = aOpTable; p->eTok != NIL; p++ )
161 if( p->eTok == eTok )
163 pGen->Gen( p->eOp ); break;
169 // Ausgabe eines Operanden-Elements
171 void SbiExprNode::GenElement( SbiOpcode eOp )
173 #ifndef PRODUCT
174 if( (eOp < _RTL || eOp > _CALLC) && eOp != _FIND_G && eOp != _FIND_CM )
175 pGen->GetParser()->Error( SbERR_INTERNAL_ERROR, "Opcode" );
176 #endif
177 SbiSymDef* pDef = aVar.pDef;
178 // Das ID ist entweder die Position oder das String-ID
179 // Falls das Bit 0x8000 gesetzt ist, hat die Variable
180 // eine Parameterliste.
181 USHORT nId = ( eOp == _PARAM ) ? pDef->GetPos() : pDef->GetId();
182 // Parameterliste aufbauen
183 if( aVar.pPar && aVar.pPar->GetSize() )
185 nId |= 0x8000;
186 aVar.pPar->Gen();
189 SbiProcDef* pProc = aVar.pDef->GetProcDef();
190 // per DECLARE definiert?
191 if( pProc )
193 // Dann evtl. einen LIB-Befehl erzeugen
194 if( pProc->GetLib().Len() )
195 pGen->Gen( _LIB, pGen->GetParser()->aGblStrings.Add( pProc->GetLib() ) );
196 // und den Aliasnamen nehmen
197 if( pProc->GetAlias().Len() )
198 nId = ( nId & 0x8000 ) | pGen->GetParser()->aGblStrings.Add( pProc->GetAlias() );
200 pGen->Gen( eOp, nId, sal::static_int_cast< UINT16 >( GetType() ) );
202 if( aVar.pvMorePar )
204 SbiExprListVector* pvMorePar = aVar.pvMorePar;
205 SbiExprListVector::iterator it;
206 for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
208 SbiExprList* pExprList = *it;
209 pExprList->Gen();
210 pGen->Gen( _ARRAYACCESS );
215 // Erzeugen einer Argv-Tabelle
216 // Das erste Element bleibt immer frei fuer Returnwerte etc.
217 // Siehe auch SbiProcDef::SbiProcDef() in symtbl.cxx
219 void SbiExprList::Gen()
221 if( pFirst )
223 pParser->aGen.Gen( _ARGC );
224 // AB 10.1.96: Typ-Anpassung bei DECLARE
225 USHORT nCount = 1, nParAnz = 0;
226 SbiSymPool* pPool = NULL;
227 if( pProc )
229 pPool = &pProc->GetParams();
230 nParAnz = pPool->GetSize();
232 for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ )
234 pExpr->Gen();
235 if( pExpr->GetName().Len() )
237 // named arg
238 USHORT nSid = pParser->aGblStrings.Add( pExpr->GetName() );
239 pParser->aGen.Gen( _ARGN, nSid );
241 // AB 10.1.96: Typanpassung bei named -> passenden Parameter suchen
242 if( pProc )
244 // Vorerst: Error ausloesen
245 pParser->Error( SbERR_NO_NAMED_ARGS );
247 // Spaeter, wenn Named Args bei DECLARE moeglich
249 for( USHORT i = 1 ; i < nParAnz ; i++ )
251 SbiSymDef* pDef = pPool->Get( i );
252 const String& rName = pDef->GetName();
253 if( rName.Len() )
255 if( pExpr->GetName().ICompare( rName )
256 == COMPARE_EQUAL )
258 pParser->aGen.Gen( _ARGTYP, pDef->GetType() );
259 break;
266 else
268 pParser->aGen.Gen( _ARGV );
270 // Funktion mit DECLARE -> Typ-Anpassung
271 if( pProc && nCount < nParAnz )
273 SbiSymDef* pDef = pPool->Get( nCount );
274 USHORT nTyp = sal::static_int_cast< USHORT >(
275 pDef->GetType() );
276 // Zusätzliches Flag für BYVAL einbauen
277 if( pDef->IsByVal() )
278 nTyp |= 0x8000;
279 pParser->aGen.Gen( _ARGTYP, nTyp );
286 void SbiExpression::Gen( RecursiveMode eRecMode )
288 // AB: 17.12.1995, Spezialbehandlung fuer WITH
289 // Wenn pExpr == .-Ausdruck in With, zunaechst Gen fuer Basis-Objekt
290 pExpr->Gen( eRecMode );
291 if( bBased )
293 USHORT uBase = pParser->nBase;
294 if( pParser->IsCompatible() )
295 uBase |= 0x8000; // #109275 Flag compatiblity
296 pParser->aGen.Gen( _BASED, uBase );
297 pParser->aGen.Gen( _ARGV );