#include "sema.h"
namespace empathy::sema
{
Term Substitute( const Term& src, const UnificationContext& context )
{
if( !holds_alternative< pvec >( src ) )
return src;
if( auto optHole = HoleFromIRExpr( src ) )
{
const auto& hole = *optHole;
// We only substitute indexed holes. If we encounter a named hole,
// output it as is.
if( !holds_alternative< uint32_t >( hole ) )
return src;
const auto& optVal = context.getValue( get< uint32_t >( hole ) );
if( !optVal )
return MkHole( "_"_sid );
return Substitute( *optVal, context );
}
const auto& vec = *get< pvec >( src );
auto outputTerms = make_shared< Vector >();
outputTerms->reserve( vec.terms().size() );
for( auto&& t : vec.terms() )
outputTerms->append( Substitute( t, context ) );
return outputTerms;
}
Term SubstituteNamed( const Term& src, const UnificationContext& context )
{
if( !holds_alternative< pvec >( src ) )
return src;
if( auto optHole = HoleFromIRExpr( src ) )
{
const auto& hole = *optHole;
if( holds_alternative< StringId >( hole ) )
{
// If the name is not found, output it as is.
auto index = context.getLHSHoleIndex( get< StringId >( hole ) );
if( index == UnificationContext::InvalidIndex )
return src;
const auto& val = context.getValue( index );
if( !val )
return src;
return SubstituteNamed( *val, context );
}
else
{
const auto& optVal = context.getValue( get< uint32_t >( hole ) );
if( !optVal )
return MkHole( "_"_sid );
return SubstituteNamed( *optVal, context );
}
}
const auto& vec = *get< pvec >( src );
auto outputTerms = make_shared< Vector >();
outputTerms->reserve( vec.terms().size() );
for( auto&& t : vec.terms() )
outputTerms->append( SubstituteNamed( t, context ) );
return outputTerms;
}
}