#include "builtins/builtins.h"
using namespace empathy;
using namespace empathy::ir;
using namespace empathy::llr;
namespace empathy::builtins
{
void SetupLocalVarUnification( Env& e )
{
auto localVarPattern = GetValueType< LocalVar >( ANYTERM( _ ) );
// LocalVar unification against a param:
// Unify the contained value with the param.
e.unificationRuleSet()->addAsymRule(
ValueToIRExpr( ValuePattern(
ANYTERM( _ ),
ANYTERM( _ ),
ANYTERM( _ ) ) ),
ValueToIRExpr( ValuePattern(
ANYTERM( _ ),
localVarPattern,
ANYTERM( _ ) ) ),
[]( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
{
auto locvar = FromValue< LocalVar >( *ValueFromIRExpr( rhs ) );
if( !locvar )
co_return;
auto varcontent = ValueToIRExpr( BuildComputedValue( locvar->type(),
GetVar( locvar->cfgId(), locvar->index() ) ) );
// Unify the param with the var's content
co_yield Unify( lhs, varcontent, c );
} );
// LocalVar unification against another LocalVar: unify their types.
e.unificationRuleSet()->addAsymRule(
ValueToIRExpr( ValuePattern(
ANYTERM( _ ),
localVarPattern,
ANYTERM( _ ) ) ),
ValueToIRExpr( ValuePattern(
ANYTERM( _ ),
localVarPattern,
ANYTERM( _ ) ) ),
[]( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
{
auto lvarType = *FromValue< LocalVarType >( *ValueFromIRExpr( ValuePatternFromIRExpr( lhs )->type() ) );
auto rvar = *FromValue< LocalVar >( *ValueFromIRExpr( rhs ) );
for( auto&& [s, uc] : Unify( lvarType.type(), rvar.type(), c ) )
co_yield { ValueToIRExpr( ToValue( LocalVar( s, rvar.cfgId(), rvar.index() ) ) ), uc };
} );
}
}