#include "builtins/builtins.h"
#include "execute/execute.h"
namespace goose::builtins
{
ptr< OverloadSet > CreateOverloadSet( Env& env, const StringId& name )
{
auto identity = AppendToVectorTerm( RootG0Identity(), TERM( name ) );
auto pOvlSet = make_shared< OverloadSet >( identity );
env.storeValue( identity, ANYTERM( _ ), ValueToEIR( ToValue( pOvlSet ) ) );
return pOvlSet;
}
ptr< OverloadSet > GetOverloadSet( Env& env, const StringId& name )
{
auto identity = AppendToVectorTerm( RootG0Identity(), TERM( name ) );
Term result;
switch( env.retrieveValue( identity, RootG0Identity(), result ) )
{
case sema::Env::Status::Success:
return *FromValue< ptr< OverloadSet > >( *EIRToValue( result ) );
case sema::Env::Status::NoMatch:
G_ERROR( format( "fatal: overload set {} not found", name ) );
case sema::Env::Status::AmbiguousMatch:
G_ERROR( format( "fatal: ambiguous match for overload set {}", name ) );
}
return nullptr;
}
ptr< OverloadSet > GetOrCreateOverloadSet( Env& env, const StringId& name )
{
auto identity = AppendToVectorTerm( RootG0Identity(), TERM( name ) );
Term result;
switch( env.retrieveValue( identity, RootG0Identity(), result ) )
{
case sema::Env::Status::Success:
return *FromValue< ptr< OverloadSet > >( *EIRToValue( result ) );
case sema::Env::Status::NoMatch:
{
auto pOvlSet = make_shared< OverloadSet >( identity );
env.storeValue( identity, ANYTERM( _ ), ValueToEIR( ToValue( pOvlSet ) ) );
return pOvlSet;
}
case sema::Env::Status::AmbiguousMatch:
G_ERROR( format( "fatal: ambiguous match for overload set {}", name ) );
}
return nullptr;
}
Value InvokeOverloadSet( const Context& c, const ptr< OverloadSet >& pOvlSet, Value args )
{
assert( pOvlSet );
Context localC( c.env(), c.identity(), GetValueType< uint32_t >() );
localC.setBuilder( c.codeBuilder() );
execute::VM vm;
if( !args.isConstant() && cir::CanValueBeEagerlyEvaluated( args ) )
args = execute::Evaluate( args, vm );
if( args.isPoison() )
return PoisonValue();
auto val = ResolveInvocation( localC, GetOverloadSetInvocationRule(), ToValue( pOvlSet ), args );
if( val.isConstant() || !cir::CanValueBeEagerlyEvaluated( val ) )
return val;
return execute::Evaluate( val, vm );
}
}