#include "builtins/builtins.h"
using namespace empathy;
using namespace empathy::ir;
namespace empathy::builtins
{
void SetupRuntimeTypesUnification( Env& e )
{
auto rtTypePattern = Value( TypeType(), TVEC( TSID( rt_type ),
ANYTERM( _ ),
TSID( rt_integer ), ANYTERM( _ ) ) );
// ct_integer constant unification against a RTInteger:
// Check if the RTInteger is big enough for the constant,
// and emit a LoadConstantInt llr instruction if so.
e.unificationRuleSet()->addSymRule(
ValueToIRExpr( Value(
GetValueType< uint64_t >(),
ANYTERM( _ ) ) ),
ValueToIRExpr( ValuePattern(
ANYTERM( _ ),
ValueToIRExpr( rtTypePattern ),
ANYTERM( _ ) ) ),
[]( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
{
auto ct = *FromValue< uint64_t >( *ValueFromIRExpr( lhs ) );
auto rhsVal = *ValuePatternFromIRExpr( rhs );
auto rttypeVal = *ValueFromIRExpr( rhsVal.type() );
auto rttype = *FromValue< RTInteger >( rttypeVal );
if( ( 1 << rttype.m_numBits ) > ct )
{
auto* llvmType = static_cast< llvm::IntegerType* >( GetLLVMType( rttypeVal ) );
co_yield { ValueToIRExpr( Value( rhsVal.type(),
make_shared< llr::Instruction >( llr::LoadConstInt( llvmType, ct ) ) ) ), c };
}
} );
}
}