#include "sema.h"
namespace empathy::sema
{
Term WrapWithPostprocFunc( const Term& t, const ptr< PostProcFunc >& pp )
{
return TVEC( TSID( postproc ),
TERM( static_pointer_cast< void >( pp ) ),
t );
}
Term WrapWithPostprocFunc( const Term& t, PostProcFunc&& pp )
{
return TVEC( TSID( postproc ),
TERM( static_pointer_cast< void >( make_shared< PostProcFunc >( move( pp ) ) ) ),
t );
}
optional< pair< Term, ptr< PostProcFunc > > > UnwrapPostprocFunc( const Term& ppt )
{
auto result = Decompose( ppt,
Vec(
Lit( "postproc"_sid ),
Val< ptr< void > >(),
SubTerm()
)
);
if( !result )
return nullopt;
auto&& [pPP, t] = *result;
return make_pair( t, static_pointer_cast< PostProcFunc >( pPP ) );
}
optional< Term > Postprocess( const Term& src, UnificationContext& uc )
{
if( !holds_alternative< pvec >( src.content() ) )
return src;
if( auto optPP = UnwrapPostprocFunc( src ) )
{
auto val = Postprocess( optPP->first, uc );
if( !val )
return nullopt;
return ( *optPP->second )( *val, uc );
}
const auto& vec = *get< pvec >( src.content() );
immer::vector< Term > outputTerms;
auto vt = outputTerms.transient();
bool faulty = false;
for( auto&& t : vec.terms() )
{
auto newT = Postprocess( t, uc );
if( !newT )
return nullopt;
faulty = faulty || newT->isFaulty();
vt.push_back( move( *newT ) );
}
return Term( src.location(), make_shared< Vector >( vt.persistent(), faulty ) );
}
}