Goose  helpers.cpp at [b3aeaae2df]

File bs/builtins/types/overloadset/helpers.cpp artifact 2b1699bd1b part of check-in b3aeaae2df


#include "builtins/builtins.h"
#include "execute/execute.h"

namespace goose::builtins
{
    ptr< OverloadSet > CreateOverloadSet( Env& env, const StringId& name )
    {
        auto identity = AppendToVectorTerm( RootIdentity(), TERM( name ) );
        auto pOvlSet = make_shared< OverloadSet >( identity );
        env.storeValue( identity, ANYTERM( _ ), ValueToIRExpr( ToValue( pOvlSet ) ) );
        return pOvlSet;
    }

    ptr< OverloadSet > GetOverloadSet( Env& env, const StringId& name )
    {
        auto identity = AppendToVectorTerm( RootIdentity(), TERM( name ) );

        Term result;

        switch( env.retrieveValue( identity, RootIdentity(), result ) )
        {
            case sema::Env::Status::Success:
                return *FromValue< ptr< OverloadSet > >( *ValueFromIRExpr( result ) );

            case sema::Env::Status::NoMatch:
                throw logic_error( format( "fatal: overload set {} not found", name ) );

            case sema::Env::Status::AmbiguousMatch:
                throw logic_error( format( "fatal: ambiguous match for overload set {}", name ) );
        }

        return nullptr;
    }

    ptr< OverloadSet > GetOrCreateOverloadSet( Env& env, const StringId& name )
    {
        auto identity = AppendToVectorTerm( RootIdentity(), TERM( name ) );

        Term result;

        switch( env.retrieveValue( identity, RootIdentity(), result ) )
        {
            case sema::Env::Status::Success:
                return *FromValue< ptr< OverloadSet > >( *ValueFromIRExpr( result ) );

            case sema::Env::Status::NoMatch:
            {
                auto pOvlSet = make_shared< OverloadSet >( identity );
                env.storeValue( identity, ANYTERM( _ ), ValueToIRExpr( ToValue( pOvlSet ) ) );
                return pOvlSet;
            }

            case sema::Env::Status::AmbiguousMatch:
                throw logic_error( format( "fatal: ambiguous match for overload set {}", name ) );
        }

        return nullptr;
    }

    Value InvokeOverloadSet( const Context& c, const ptr< OverloadSet >& pOvlSet, const Value& args )
    {
        assert( pOvlSet );

        Context localC( c.env(), c.identity(), GetValueType< uint32_t >() );
        localC.setBuilder( c.codeBuilder() );
        auto val = ResolveInvocation( localC, GetOverloadSetInvocationRule(), ToValue( pOvlSet ), args );

        if( val.isConstant() || !llr::CanValueBeEagerlyEvaluated( val ) )
            return val;

        execute::VM vm;
        return execute::Evaluate( val, vm );
    }
}