#include "builtins/builtins.h"
using namespace empathy::builtins;
namespace empathy::builtins
{
void OverloadSet::add( const sema::Context& context, const Value& callee )
{
auto pInvRule = GetInvocationRule( context, callee );
assert( pInvRule );
auto signature = pInvRule->getSignature( callee );
assert( signature );
auto result = Decompose( *signature,
Vec(
Val< pvec >(),
SubTerm()
)
);
assert( result );
auto&& [params,rt] = *result;
const auto& rtype = rt;
m_trie = m_trie->merge( *params, [&]( auto&& rtTrie )
{
return Merge( rtTrie, rtype, [&]( auto&& ) -> Overload
{
return { pInvRule, callee };
} );
} );
}
OverloadSet::UniGen OverloadSet::unify( const Term& argsPat, const Term& rtPat, UnificationContext& uc ) const
{
auto argDecomp = Decompose( argsPat,
Val< pvec >()
);
if( !argDecomp )
co_return;
for( auto&& [uniParamsVec,rtTrie,c] : m_trie->unify( *argDecomp->get(), uc ) )
{
auto uniParams = TERM( make_shared< Vector >( uniParamsVec ) );
for( auto&& [rt,ovl] : Enumerate( rtTrie ) )
{
for( auto&& [uniRt,uc] : Unify( rt, rtPat, uc ) )
{
auto uniCall = TERM( Vector::Make( uniParams, uniRt ) );
co_yield { move( uniCall ), ovl, uc };
}
}
}
}
bool IsOverloadSet( const Value& os )
{
return os.type() == GetValueType< ptr< OverloadSet > >();
}
}
namespace empathy::ir
{
const Term& Bridge< ptr< builtins::OverloadSet > >::Type()
{
static auto type = ValueToIRExpr( Value( TSID( type ), TSID( overloadset ) ) );
return type;
}
Value Bridge< ptr< builtins::OverloadSet > >::ToValue( const ptr< builtins::OverloadSet >& os )
{
return Value( Type(), TERM( static_pointer_cast< void >( os ) ) );
}
ptr< builtins::OverloadSet > Bridge< ptr< builtins::OverloadSet > >::FromValue( const Value& v )
{
if( !IsOverloadSet( v ) )
return nullptr;
auto result = Decompose( v.val(),
Val< ptr< void > >()
);
if( !result )
return nullptr;
return static_pointer_cast< builtins::OverloadSet >( result->get() );
}
}