blob: 2ecc0809d3cee30dfbf69dfb48b29d4c55b449bd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Created on: 16 déc. 2011
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "AvmCodeFactory.h"
#include <fml/executable/ExecutableForm.h>
#include <fml/executable/ExecutableLib.h>
#include <fml/operator/OperatorManager.h>
namespace sep
{
/**
* METHODS
* flatten AvmCode
*/
BF AvmCodeFactory::flatten(BF aCode)
{
switch( aCode.classKind() )
{
case FORM_AVMCODE_KIND:
{
return( AvmCodeFactory::flattenCode( aCode.bfCode() ) );
}
default:
{
return( aCode );
}
}
}
BFCode AvmCodeFactory::flattenCode(BFCode anAvmCode)
{
Operator * anOperator = anAvmCode->getOperator();
AvmCode::this_container_type flattenArgs;
BFCode arg;
avm_size_t flatCount = 0;
AvmCode::iterator it = anAvmCode->begin();
AvmCode::iterator itEnd = anAvmCode->end();
for( ; it != itEnd ; ++it )
{
if( (*it).is< AvmCode >() )
{
arg = AvmCodeFactory::flattenCode( (*it).bfCode() );
if( anOperator->isWeakAssociative() &&
arg->isOperator( anOperator ) )
{
flattenArgs.append( arg->getArgs() );
++flatCount;
}
else
{
flattenArgs.append( arg );
if( (*it).raw_pointer() != arg )
{
++flatCount;
}
}
}
else
{
flattenArgs.append( (*it) );
}
}
if( flatCount > 0 )
{
if( anAvmCode->isUnique() )
{
anAvmCode->clear();
anAvmCode->append(flattenArgs);
}
else
{
anAvmCode = AvmCodeFactory::newCode(
anAvmCode->getOperator(), flattenArgs);
}
}
return( anAvmCode );
}
/**
* METHODS
* contains subCode with a specific operator
*/
bool AvmCodeFactory::contains(ExecutableForm * anExecutable,
const BFCode & aCode, AVM_OPCODE anOpcode)
{
if( aCode.invalid() )
{
return( false );
}
else if( aCode->isOpCode(anOpcode) )
{
return true;
}
else if( OperatorManager::isActivity(aCode->getOperator()) &&
(aCode->empty() || (aCode->first() == ExecutableLib::MACHINE_SELF)) )
{
return( contains(anExecutable,
anExecutable->getOnActivity( aCode->getAvmOpCode() ),
anOpcode) );
}
else
{
AvmCode::const_iterator it = aCode->begin();
AvmCode::const_iterator itEnd = aCode->end();
for( ; it != itEnd ; ++it )
{
if( (*it).is< AvmCode >() )
{
if( contains(anExecutable, (*it).bfCode(), anOpcode) )
{
return true;
}
}
}
return( false );
}
}
bool AvmCodeFactory::contains(ExecutableForm * anExecutable,
const BFCode & aCode, AVM_OPCODE anOpcode1, AVM_OPCODE anOpcode2)
{
if( aCode.invalid() )
{
return( false );
}
else if( aCode->isOpCode(anOpcode1) || aCode->isOpCode(anOpcode2) )
{
return true;
}
else if( OperatorManager::isActivity(aCode->getOperator()) &&
(aCode->empty() || (aCode->first() == ExecutableLib::MACHINE_SELF)) )
{
return( contains(anExecutable,
anExecutable->getOnActivity( aCode->getAvmOpCode() ),
anOpcode1, anOpcode2) );
}
else
{
AvmCode::const_iterator it = aCode->begin();
AvmCode::const_iterator itEnd = aCode->end();
for( ; it != itEnd ; ++it )
{
if( (*it).is< AvmCode >() )
{
if( contains(anExecutable, (*it).bfCode(), anOpcode1, anOpcode2) )
{
return true;
}
}
}
return false;
}
}
} /* namespace sep */