#include "builtins/builtins.h"
using namespace goose;
using namespace goose::sema;
bool OverloadSet::add( const Env& e, const Value& callee )
{
auto pInvRule = GetInvocationRule( e, callee );
assert( pInvRule );
return add( e, callee, pInvRule );
}
bool OverloadSet::add( const Env& e, const Value& callee, const ptr< InvocationRule >& pInvRule )
{
auto signature = pInvRule->getSignature( callee );
assert( signature );
auto sigDecomp = Decompose( *signature, Val< pvec >() );
assert( sigDecomp );
bool success = false;
m_trie = m_trie->merge( *sigDecomp->get(),
[&]( auto&& previous ) -> Overload
{
if( previous.callee )
return move( previous );
success = true;
return { pInvRule, callee };
} );
m_resolutionCache.clear();
return success;
}
OverloadSet::TCGen OverloadSet::typeCheck(
const Term& callPat, const TypeCheckingContext& tcc ) const
{
auto callDecomp = Decompose( callPat, Val< pvec >() );
if( !callDecomp )
co_return;
for( auto&& [callVec, uniCallVec, ovl, tcc] : m_trie->typeCheck( *callDecomp->get(), tcc ) )
{
auto uniCall = TERM( make_shared< Vector >( uniCallVec ) );
co_yield { move( uniCall ), ovl, tcc };
}
}
optional< OverloadSet::Overload > OverloadSet::getResolutionFromCache( const Term& args ) const
{
ProfileZoneScoped;
auto it = m_resolutionCache.find( args );
if( it == m_resolutionCache.end() )
return nullopt;
return it->second;
}
void OverloadSet::addResolutionToCache( const Term& args, const Overload& ovl )
{
ProfileZoneScoped;
m_resolutionCache.emplace( args, ovl );
}
Generator< const OverloadSet::Overload* > OverloadSet::enumerate() const
{
return m_trie->enumerate();
}