blob: 528b2bc9ede855f5002e3a424004b1f7d92c9378 [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: 7 oct. 2008
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "AvmLambda.h"
#include <fml/common/SpecifierElement.h>
#include <fml/executable/AvmProgram.h>
#include <fml/operator/OperatorManager.h>
namespace sep
{
std::string AvmLambda::ANONYM_UFI = "lambda#anonym";
std::string AvmLambda::APP_UFI = "lambda::app";
std::string AvmLambda::FUN_UFI = "lambda::fun";
std::string AvmLambda::LET_UFI = "lambda::let";
/**
* SETTER
* updateFullyQualifiedNameID()
*/
void AvmLambda::updateFullyQualifiedNameID()
{
switch( mLambdaNature )
{
case AVM_LAMBDA_APP_NATURE:
{
setFullyQualifiedNameID( APP_UFI );
break;
}
case AVM_LAMBDA_LET_NATURE:
{
setFullyQualifiedNameID( LET_UFI );
break;
}
case AVM_LAMBDA_FUN_NATURE:
default:
{
if( hasAstElement() )
{
std::string aFullyQualifiedNameID = getAstFullyQualifiedNameID();
setFullyQualifiedNameID( "program" +
aFullyQualifiedNameID.substr(
aFullyQualifiedNameID.find(FQN_ID_ROOT_SEPARATOR)) );
}
else
{
setAllNameID( ANONYM_UFI , "lambda#anonym" );
}
break;
}
}
}
/**
* Serialization
*/
void AvmLambda::toStream(OutStream & os) const
{
switch( mLambdaNature )
{
case AVM_LAMBDA_APP_NATURE:
{
toStreamApp(os);
break;
}
case AVM_LAMBDA_LET_NATURE:
{
toStreamLet(os);
break;
}
case AVM_LAMBDA_FUN_NATURE:
default:
{
toStreamLambda(os);
break;
}
}
}
void AvmLambda::toStreamApp(OutStream & os) const
{
//os << TAB << "apply ( ";
os << TAB << "${ app " << AVM_STR_INDENT;
toStreamLambda(os);
os << END_INDENT;
//os << " )( ";
TableOfInstanceOfData::const_raw_iterator itData = getData().begin();
TableOfInstanceOfData::const_raw_iterator endData = getData().end();
for( ; itData != endData ; ++itData )
{
if( (itData)->hasValue() )
{
os << TAB << " ${ := " << (itData)->str() << " "
<< (itData)->strValue() << " }";
}
}
//os << " )" << EOL;
os << " }" << EOL << std::flush;
}
void AvmLambda::toStreamLambda(OutStream & os) const
{
TableOfInstanceOfData::const_raw_iterator itData = getData().begin();
TableOfInstanceOfData::const_raw_iterator endData = getData().end();
//os << TAB << "lambda ";
os << TAB << "${ lambda ";
for( ; itData != endData ; ++itData )
{
os << (itData)->str() << " ";
}
os << std::flush;
//os << "->";
os << str_indent( getExpression() );
//os << EOL;
os << " }" << EOL_FLUSH;
}
void AvmLambda::toStreamLet(OutStream & os) const
{
TableOfInstanceOfData::const_raw_iterator itData = getData().begin();
TableOfInstanceOfData::const_raw_iterator endData = getData().end();
if( os.INDENT.TABS.empty() )
{
//os << "let ";
os << "${ let ";
for( ; itData != endData ; ++itData )
{
if( (itData)->hasValue() )
{
os << "${ "
<< OperatorManager::OPERATOR_ASSIGN->strOp() << " "
<< (itData)->str() << " " << (itData)->strValue()
<< " } ";
}
else
{
os << (itData)->str() << " ";
}
}
os << std::flush;
//os << "in";
os << str_indent( getExpression() ) << " }";
}
else
{
//os << TAB << "let " << EOL;
os << TAB << "${ let " << EOL;
for( ; itData != endData ; ++itData )
{
if( (itData)->hasValue() )
{
os << TAB2 << "${ "
<< OperatorManager::OPERATOR_ASSIGN->strOp() << " "
<< (itData)->str() << " " << (itData)->strValue()
<< " }";
}
else
{
os << TAB2 << (itData)->str();
}
os << EOL;
}
os << std::flush;
//os << TAB << "in" << EOL;
os << incr_stream( getExpression() ) << TAB << "}" << EOL;
}
os << std::flush;
}
/*
* Convert to AvmProgram
*/
BF AvmLambda::convertToProgram(const std::string & id)
{
AvmProgram * aProgram = new AvmProgram(Specifier::SCOPE_ROUTINE_KIND,
getContainer()->as< AvmProgram >(), getAstElement(), getDataSize());
aProgram->setAllNameID( aProgram->getFullyQualifiedNameID() + "." + id , id );
aProgram->setParamOffsetCount(0, getDataSize());
avm_size_t endOffset = getData().size();
for( avm_size_t offset = 0 ; offset < endOffset ; ++offset )
{
aProgram->setData(offset, getData().get(offset));
}
aProgram->setCode( getExpression().bfCode() );
return( BF(aProgram) );
}
}