bump product version to 5.0.4.1
[LibreOffice.git] / basic / source / comp / exprgen.cxx
blob22e59bb2424f2d3aa72999799b5eced0851705b6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "codegen.hxx"
22 #include "expr.hxx"
23 #include "parser.hxx"
25 // Transform table for token operators and opcodes
27 typedef struct {
28 SbiToken eTok; // Token
29 SbiOpcode eOp; // Opcode
30 } OpTable;
32 static const OpTable aOpTable [] = {
33 { EXPON,_EXP },
34 { MUL, _MUL },
35 { DIV, _DIV },
36 { IDIV, _IDIV },
37 { MOD, _MOD },
38 { PLUS, _PLUS },
39 { MINUS,_MINUS },
40 { EQ, _EQ },
41 { NE, _NE },
42 { LE, _LE },
43 { GE, _GE },
44 { LT, _LT },
45 { GT, _GT },
46 { AND, _AND },
47 { OR, _OR },
48 { XOR, _XOR },
49 { EQV, _EQV },
50 { IMP, _IMP },
51 { NOT, _NOT },
52 { NEG, _NEG },
53 { CAT, _CAT },
54 { LIKE, _LIKE },
55 { IS, _IS },
56 { NIL, _NOP }};
58 // Output of an element
59 void SbiExprNode::Gen( RecursiveMode eRecMode )
61 sal_uInt16 nStringId;
63 if( IsConstant() )
65 switch( GetType() )
67 case SbxEMPTY:
68 pGen->Gen( _EMPTY );
69 break;
70 case SbxINTEGER:
71 pGen->Gen( _CONST, (short) nVal );
72 break;
73 case SbxSTRING:
74 nStringId = pGen->GetParser()->aGblStrings.Add( aStrVal, true );
75 pGen->Gen( _SCONST, nStringId );
76 break;
77 default:
78 nStringId = pGen->GetParser()->aGblStrings.Add( nVal, eType );
79 pGen->Gen( _NUMBER, nStringId );
80 break;
83 else if( IsOperand() )
85 SbiExprNode* pWithParent_ = NULL;
86 SbiOpcode eOp;
87 if( aVar.pDef->GetScope() == SbPARAM )
89 eOp = _PARAM;
90 if( 0 == aVar.pDef->GetPos() )
92 bool bTreatFunctionAsParam = true;
93 if( eRecMode == FORCE_CALL )
95 bTreatFunctionAsParam = false;
97 else if( eRecMode == UNDEFINED )
99 if( aVar.pPar && aVar.pPar->IsBracket() )
101 bTreatFunctionAsParam = false;
104 if( !bTreatFunctionAsParam )
106 eOp = aVar.pDef->IsGlobal() ? _FIND_G : _FIND;
110 // special treatment for WITH
111 else if( (pWithParent_ = GetWithParent()) != NULL )
113 eOp = _ELEM; // .-Term in WITH
115 else
117 eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL :
118 (aVar.pDef->IsGlobal() ? _FIND_G : _FIND);
121 if( eOp == _FIND )
124 SbiProcDef* pProc = aVar.pDef->GetProcDef();
125 if ( pGen->GetParser()->bClassModule )
127 eOp = _FIND_CM;
129 else if ( aVar.pDef->IsStatic() || (pProc && pProc->IsStatic()) )
131 eOp = _FIND_STATIC;
134 for( SbiExprNode* p = this; p; p = p->aVar.pNext )
136 if( p == this && pWithParent_ != NULL )
138 pWithParent_->Gen();
140 p->GenElement( eOp );
141 eOp = _ELEM;
144 else if( IsTypeOf() )
146 pLeft->Gen();
147 pGen->Gen( _TESTCLASS, nTypeStrId );
149 else if( IsNew() )
151 pGen->Gen( _CREATE, 0, nTypeStrId );
153 else
155 pLeft->Gen();
156 if( pRight )
158 pRight->Gen();
160 for( const OpTable* p = aOpTable; p->eTok != NIL; p++ )
162 if( p->eTok == eTok )
164 pGen->Gen( p->eOp ); break;
170 // Output of an operand element
172 void SbiExprNode::GenElement( SbiOpcode eOp )
174 #ifdef DBG_UTIL
175 if ((eOp < _RTL || eOp > _CALLC) && eOp != _FIND_G && eOp != _FIND_CM && eOp != _FIND_STATIC)
176 pGen->GetParser()->Error( SbERR_INTERNAL_ERROR, "Opcode" );
177 #endif
178 SbiSymDef* pDef = aVar.pDef;
179 // The ID is either the position or the String-ID
180 // If the bit Bit 0x8000 is set, the variable have
181 // a parameter list.
182 sal_uInt16 nId = ( eOp == _PARAM ) ? pDef->GetPos() : pDef->GetId();
183 // Build a parameter list
184 if( aVar.pPar && aVar.pPar->GetSize() )
186 nId |= 0x8000;
187 aVar.pPar->Gen();
190 pGen->Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( GetType() ) );
192 if( aVar.pvMorePar )
194 SbiExprListVector* pvMorePar = aVar.pvMorePar;
195 SbiExprListVector::iterator it;
196 for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
198 SbiExprList* pExprList = *it;
199 pExprList->Gen();
200 pGen->Gen( _ARRAYACCESS );
205 // Create an Argv-Table
206 // The first element remain available for return value etc.
207 // See as well SbiProcDef::SbiProcDef() in symtbl.cxx
209 void SbiExprList::Gen()
211 if( pFirst )
213 pParser->aGen.Gen( _ARGC );
214 // Type adjustment at DECLARE
215 sal_uInt16 nCount = 1;
217 for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ )
219 pExpr->Gen();
220 if( !pExpr->GetName().isEmpty() )
222 // named arg
223 sal_uInt16 nSid = pParser->aGblStrings.Add( pExpr->GetName() );
224 pParser->aGen.Gen( _ARGN, nSid );
226 /* TODO: Check after Declare concept change
227 // From 1996-01-10: Type adjustment at named -> search suitable parameter
228 if( pProc )
230 // For the present: trigger an error
231 pParser->Error( SbERR_NO_NAMED_ARGS );
233 // Later, if Named Args at DECLARE is possible
234 //for( sal_uInt16 i = 1 ; i < nParAnz ; i++ )
236 // SbiSymDef* pDef = pPool->Get( i );
237 // const String& rName = pDef->GetName();
238 // if( rName.Len() )
239 // {
240 // if( pExpr->GetName().ICompare( rName )
241 // == COMPARE_EQUAL )
242 // {
243 // pParser->aGen.Gen( _ARGTYP, pDef->GetType() );
244 // break;
245 // }
246 // }
251 else
253 pParser->aGen.Gen( _ARGV );
259 void SbiExpression::Gen( RecursiveMode eRecMode )
261 // special treatment for WITH
262 // If pExpr == .-term in With, approximately Gen for Basis-Object
263 pExpr->Gen( eRecMode );
264 if( bByVal )
266 pParser->aGen.Gen( _BYVAL );
268 if( bBased )
270 sal_uInt16 uBase = pParser->nBase;
271 if( pParser->IsCompatible() )
273 uBase |= 0x8000; // #109275 Flag compatibility
275 pParser->aGen.Gen( _BASED, uBase );
276 pParser->aGen.Gen( _ARGV );
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */