Goose  overloadset.cpp at [44403d3ab8]

File bs/builtins/types/overloadset/overloadset.cpp artifact e42099b0bb part of check-in 44403d3ab8


#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() );
    }
}