1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: exprgen.cxx,v $
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"
37 // Umsetztabelle fuer Token-Operatoren und Opcodes
40 SbiToken eTok
; // Token
41 SbiOpcode eOp
; // Opcode
44 static OpTable aOpTable
[] = {
70 // Ausgabe eines Elements
71 void SbiExprNode::Gen( RecursiveMode eRecMode
)
77 case SbxEMPTY
: pGen
->Gen( _EMPTY
); break;
78 case SbxINTEGER
: pGen
->Gen( _CONST
, (short) nVal
); break;
81 USHORT nStringId
= pGen
->GetParser()->aGblStrings
.Add( aStrVal
, TRUE
);
82 pGen
->Gen( _SCONST
, nStringId
); break;
86 USHORT nStringId
= pGen
->GetParser()->aGblStrings
.Add( nVal
, eType
);
87 pGen
->Gen( _NUMBER
, nStringId
);
91 else if( IsOperand() )
93 SbiExprNode
* pWithParent_
= NULL
;
95 if( aVar
.pDef
->GetScope() == SbPARAM
)
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
121 SbiProcDef
* pProc
= aVar
.pDef
->GetProcDef();
122 // per DECLARE definiert?
123 if( pProc
&& pProc
->GetLib().Len() )
124 eOp
= pProc
->IsCdecl() ? _CALLC
: _CALL
;
126 eOp
= ( aVar
.pDef
->GetScope() == SbRTL
) ? _RTL
:
127 (aVar
.pDef
->IsGlobal() ? _FIND_G
: _FIND
);
133 SbiProcDef
* pProc
= aVar
.pDef
->GetProcDef();
134 if ( pGen
->GetParser()->bClassModule
)
136 else if ( aVar
.pDef
->IsStatic() || (pProc
&& pProc
->IsStatic()) )
141 for( SbiExprNode
* p
= this; p
; p
= p
->aVar
.pNext
)
143 if( p
== this && pWithParent_
!= NULL
)
145 p
->GenElement( eOp
);
149 else if( IsTypeOf() )
152 pGen
->Gen( _TESTCLASS
, nTypeStrId
);
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
)
174 if( (eOp
< _RTL
|| eOp
> _CALLC
) && eOp
!= _FIND_G
&& eOp
!= _FIND_CM
)
175 pGen
->GetParser()->Error( SbERR_INTERNAL_ERROR
, "Opcode" );
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() )
189 SbiProcDef
* pProc
= aVar
.pDef
->GetProcDef();
190 // per DECLARE definiert?
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() ) );
204 SbiExprListVector
* pvMorePar
= aVar
.pvMorePar
;
205 SbiExprListVector::iterator it
;
206 for( it
= pvMorePar
->begin() ; it
!= pvMorePar
->end() ; ++it
)
208 SbiExprList
* pExprList
= *it
;
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()
223 pParser
->aGen
.Gen( _ARGC
);
224 // AB 10.1.96: Typ-Anpassung bei DECLARE
225 USHORT nCount
= 1, nParAnz
= 0;
226 SbiSymPool
* pPool
= NULL
;
229 pPool
= &pProc
->GetParams();
230 nParAnz
= pPool
->GetSize();
232 for( SbiExpression
* pExpr
= pFirst
; pExpr
; pExpr
= pExpr
->pNext
,nCount
++ )
235 if( pExpr
->GetName().Len() )
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
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();
255 if( pExpr->GetName().ICompare( rName )
258 pParser->aGen.Gen( _ARGTYP, pDef->GetType() );
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
>(
276 // Zusätzliches Flag für BYVAL einbauen
277 if( pDef
->IsByVal() )
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
);
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
);