Files
libreoffice/basic/source/comp/exprgen.cxx

280 lines
7.8 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
2000-09-18 15:18:56 +00:00
2000-09-18 15:18:56 +00:00
#include "sbcomp.hxx"
#include "expr.hxx"
2010-11-20 22:47:15 +01:00
// Transform table for token operators and opcodes
2000-09-18 15:18:56 +00:00
typedef struct {
SbiToken eTok; // Token
SbiOpcode eOp; // Opcode
} OpTable;
static OpTable aOpTable [] = {
{ EXPON,_EXP },
{ MUL, _MUL },
{ DIV, _DIV },
{ IDIV, _IDIV },
{ MOD, _MOD },
{ PLUS, _PLUS },
{ MINUS,_MINUS },
{ EQ, _EQ },
{ NE, _NE },
{ LE, _LE },
{ GE, _GE },
{ LT, _LT },
{ GT, _GT },
{ AND, _AND },
{ OR, _OR },
{ XOR, _XOR },
{ EQV, _EQV },
{ IMP, _IMP },
{ NOT, _NOT },
{ NEG, _NEG },
{ CAT, _CAT },
{ LIKE, _LIKE },
{ IS, _IS },
{ NIL, _NOP }};
2010-11-20 22:47:15 +01:00
// Output of an element
void SbiExprNode::Gen( RecursiveMode eRecMode )
2000-09-18 15:18:56 +00:00
{
sal_uInt16 nStringId;
2000-09-18 15:18:56 +00:00
if( IsConstant() )
{
switch( GetType() )
{
case SbxEMPTY:
pGen->Gen( _EMPTY );
break;
case SbxINTEGER:
pGen->Gen( _CONST, (short) nVal );
break;
case SbxSTRING:
nStringId = pGen->GetParser()->aGblStrings.Add( aStrVal, sal_True );
pGen->Gen( _SCONST, nStringId );
break;
default:
nStringId = pGen->GetParser()->aGblStrings.Add( nVal, eType );
pGen->Gen( _NUMBER, nStringId );
break;
2000-09-18 15:18:56 +00:00
}
}
else if( IsOperand() )
{
SbiExprNode* pWithParent_ = NULL;
2000-09-18 15:18:56 +00:00
SbiOpcode eOp;
if( aVar.pDef->GetScope() == SbPARAM )
{
2000-09-18 15:18:56 +00:00
eOp = _PARAM;
if( 0 == aVar.pDef->GetPos() )
{
bool bTreatFunctionAsParam = true;
if( eRecMode == FORCE_CALL )
{
bTreatFunctionAsParam = false;
}
else if( eRecMode == UNDEFINED )
{
if( aVar.pPar && aVar.pPar->IsBracket() )
{
bTreatFunctionAsParam = false;
}
}
if( !bTreatFunctionAsParam )
{
eOp = aVar.pDef->IsGlobal() ? _FIND_G : _FIND;
}
}
}
// special treatment for WITH
else if( (pWithParent_ = GetWithParent()) != NULL )
2000-09-18 15:18:56 +00:00
{
2010-11-20 22:47:15 +01:00
eOp = _ELEM; // .-Term in in WITH
2000-09-18 15:18:56 +00:00
}
else
{
2010-08-06 09:35:51 +02:00
eOp = ( aVar.pDef->GetScope() == SbRTL ) ? _RTL :
(aVar.pDef->IsGlobal() ? _FIND_G : _FIND);
2000-09-18 15:18:56 +00:00
}
if( eOp == _FIND )
{
SbiProcDef* pProc = aVar.pDef->GetProcDef();
if ( pGen->GetParser()->bClassModule )
{
eOp = _FIND_CM;
}
CWS-TOOLING: integrate CWS cmcfixes51 2008-12-08 10:12:55 +0100 cmc r264975 : #i96203# protect with ifdefs to avoid unused symbol on mac 2008-12-05 12:23:47 +0100 cmc r264898 : CWS-TOOLING: rebase CWS cmcfixes51 to trunk@264807 (milestone: DEV300:m37) 2008-12-01 14:45:17 +0100 cmc r264606 : #i76655# ehlos apparently required 2008-11-28 17:49:30 +0100 cmc r264567 : #i96655# remove newly unused method 2008-11-28 10:41:28 +0100 cmc r264531 : #i96647# better ppc-bridges flushCode impl 2008-11-27 12:58:40 +0100 cmc r264478 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 12:32:49 +0100 cmc r264476 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 12:26:02 +0100 cmc r264475 : #i96655# redundant old table export helpers 2008-11-27 11:49:06 +0100 cmc r264473 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 11:38:35 +0100 cmc r264471 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 11:14:21 +0100 cmc r264467 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 11:06:22 +0100 cmc r264464 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 10:58:18 +0100 cmc r264462 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 10:41:44 +0100 cmc r264461 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 10:19:24 +0100 cmc r264460 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 10:13:39 +0100 cmc r264459 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 10:06:14 +0100 cmc r264458 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 09:59:54 +0100 cmc r264457 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 09:52:51 +0100 cmc r264456 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 09:48:26 +0100 cmc r264454 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 09:40:20 +0100 cmc r264452 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 09:35:26 +0100 cmc r264451 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 09:31:00 +0100 cmc r264450 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 09:24:08 +0100 cmc r264449 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 00:26:15 +0100 cmc r264443 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 00:21:01 +0100 cmc r264442 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-27 00:09:40 +0100 cmc r264441 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 23:51:56 +0100 cmc r264440 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 23:49:09 +0100 cmc r264439 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 18:09:54 +0100 cmc r264432 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 18:07:40 +0100 cmc r264431 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 17:28:02 +0100 cmc r264429 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 17:27:39 +0100 cmc r264428 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 17:18:36 +0100 cmc r264426 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 16:22:16 +0100 cmc r264415 : #i96624# make implicit braces and brackets explicit to avoid warnings 2008-11-26 16:00:23 +0100 cmc r264409 : #i90426# remove warnings from svtools 2008-11-26 15:59:17 +0100 cmc r264408 : #i90426# remove warnings 2008-11-26 15:47:32 +0100 cmc r264404 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 14:46:57 +0100 cmc r264394 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 14:19:50 +0100 cmc r264387 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 14:15:26 +0100 cmc r264386 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 14:11:26 +0100 cmc r264384 : #i96084# confirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 13:44:23 +0100 cmc r264380 : #i96084# comfirm existing logic with explicit brackets to remove new gcc warnings 2008-11-26 13:12:24 +0100 cmc r264372 : #i96604# silence new warnings 2008-11-26 12:35:02 +0100 cmc r264369 : #i96203# make qstarter work in 3-layer land 2008-11-26 12:33:04 +0100 cmc r264368 : #i96170# ensure gtypes are up and running
2008-12-11 07:05:03 +00:00
else if ( aVar.pDef->IsStatic() || (pProc && pProc->IsStatic()) )
{
eOp = _FIND_STATIC;
}
}
2000-09-18 15:18:56 +00:00
for( SbiExprNode* p = this; p; p = p->aVar.pNext )
{
if( p == this && pWithParent_ != NULL )
{
pWithParent_->Gen();
}
2000-09-18 15:18:56 +00:00
p->GenElement( eOp );
eOp = _ELEM;
}
}
else if( IsTypeOf() )
{
pLeft->Gen();
pGen->Gen( _TESTCLASS, nTypeStrId );
}
else if( IsNew() )
{
pGen->Gen( _CREATE, 0, nTypeStrId );
}
2000-09-18 15:18:56 +00:00
else
{
pLeft->Gen();
if( pRight )
{
2000-09-18 15:18:56 +00:00
pRight->Gen();
}
2000-09-18 15:18:56 +00:00
for( OpTable* p = aOpTable; p->eTok != NIL; p++ )
{
if( p->eTok == eTok )
{
pGen->Gen( p->eOp ); break;
}
}
}
}
2010-11-20 22:47:15 +01:00
// Output of an operand element
2000-09-18 15:18:56 +00:00
void SbiExprNode::GenElement( SbiOpcode eOp )
{
#ifdef DBG_UTIL
if( (eOp < _RTL || eOp > _CALLC) && eOp != _FIND_G && eOp != _FIND_CM )
2000-09-18 15:18:56 +00:00
pGen->GetParser()->Error( SbERR_INTERNAL_ERROR, "Opcode" );
#endif
SbiSymDef* pDef = aVar.pDef;
2010-11-20 22:47:15 +01:00
// The ID is either the position or the String-ID
// If the bit Bit 0x8000 is set, the variable have
// a parameter list.
sal_uInt16 nId = ( eOp == _PARAM ) ? pDef->GetPos() : pDef->GetId();
2010-11-20 22:47:15 +01:00
// Build a parameter list
2000-09-18 15:18:56 +00:00
if( aVar.pPar && aVar.pPar->GetSize() )
{
nId |= 0x8000;
aVar.pPar->Gen();
}
pGen->Gen( eOp, nId, sal::static_int_cast< sal_uInt16 >( GetType() ) );
if( aVar.pvMorePar )
{
SbiExprListVector* pvMorePar = aVar.pvMorePar;
SbiExprListVector::iterator it;
for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
{
SbiExprList* pExprList = *it;
pExprList->Gen();
pGen->Gen( _ARRAYACCESS );
}
}
2000-09-18 15:18:56 +00:00
}
2010-11-20 22:47:15 +01:00
// Create an Argv-Table
// The first element remain available for return value etc.
// See as well SbiProcDef::SbiProcDef() in symtbl.cxx
2000-09-18 15:18:56 +00:00
void SbiExprList::Gen()
{
if( pFirst )
{
pParser->aGen.Gen( _ARGC );
// Type adjustment at DECLARE
sal_uInt16 nCount = 1;
2000-09-18 15:18:56 +00:00
for( SbiExpression* pExpr = pFirst; pExpr; pExpr = pExpr->pNext,nCount++ )
{
pExpr->Gen();
if( !pExpr->GetName().isEmpty() )
2000-09-18 15:18:56 +00:00
{
// named arg
sal_uInt16 nSid = pParser->aGblStrings.Add( pExpr->GetName() );
2000-09-18 15:18:56 +00:00
pParser->aGen.Gen( _ARGN, nSid );
2010-08-06 09:35:51 +02:00
/* TODO: Check after Declare concept change
2010-11-20 22:47:15 +01:00
// From 1996-01-10: Type adjustment at named -> search suitable parameter
2000-09-18 15:18:56 +00:00
if( pProc )
{
2010-11-20 22:47:15 +01:00
// For the present: trigger an error
2000-09-18 15:18:56 +00:00
pParser->Error( SbERR_NO_NAMED_ARGS );
2010-11-20 22:47:15 +01:00
// Later, if Named Args at DECLARE is posible
//for( sal_uInt16 i = 1 ; i < nParAnz ; i++ )
2010-08-06 09:35:51 +02:00
//{
// SbiSymDef* pDef = pPool->Get( i );
// const String& rName = pDef->GetName();
// if( rName.Len() )
// {
// if( pExpr->GetName().ICompare( rName )
// == COMPARE_EQUAL )
// {
// pParser->aGen.Gen( _ARGTYP, pDef->GetType() );
// break;
// }
// }
//}
2000-09-18 15:18:56 +00:00
}
2010-08-06 09:35:51 +02:00
*/
2000-09-18 15:18:56 +00:00
}
else
{
pParser->aGen.Gen( _ARGV );
}
}
}
}
void SbiExpression::Gen( RecursiveMode eRecMode )
2000-09-18 15:18:56 +00:00
{
// special treatment for WITH
2010-11-20 22:47:15 +01:00
// If pExpr == .-term in With, approximately Gen for Basis-Object
pExpr->Gen( eRecMode );
if( bByVal )
{
pParser->aGen.Gen( _BYVAL );
}
2000-09-18 15:18:56 +00:00
if( bBased )
{
sal_uInt16 uBase = pParser->nBase;
if( pParser->IsCompatible() )
{
uBase |= 0x8000; // #109275 Flag compatiblity
}
pParser->aGen.Gen( _BASED, uBase );
2000-09-18 15:18:56 +00:00
pParser->aGen.Gen( _ARGV );
}
2000-09-18 15:18:56 +00:00
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */