#include "builtins/builtins.h"
#include "codegen/codegen.h"
using namespace empathy;
using namespace empathy::builtins;
using namespace empathy::codegen;
namespace empathy::builtins
{
void SetupRuntimeStructType( Env& e )
{
auto buildStruct = []( const Value& types, uint64_t packed, const optional< Term > identity )
{
if( !IsTuple( types ) )
{
cout << "panic: StructType expects a tuple as first param.\n";
exit( 0 );
}
bool ok = true;
ForEachInTuple( types, [&]( auto&& t )
{
if( !GetLLVMType( t ) )
{
ok = false;
return false;
}
return true;
} );
if( !ok )
{
cout << "panic: StructType expects a tuple of runtime types as first param.\n";
exit( 0 );
}
return ToValue( StructType( identity, get< pvec >( types.val().content() ), !!packed ) );
};
RegisterBuiltinFunc< Eager< Value > ( Value, uint64_t ) >( e, "struct"_sid,
[&]( const Value& types, uint64_t packed )
{
return buildStruct( types, packed, nullopt );
} );
// TODO: make an overload of StructType that can accept a term to use as an identity
// but first I need to implemented the wrapping of terms as values.
}
}
namespace empathy::ir
{
Value Bridge< StructType >::ToValue( const StructType& s )
{
vector< llvm::Type* > elements;
elements.reserve( s.m_memberTypes->terms().size() );
for( auto&& mt : s.m_memberTypes->terms() )
elements.emplace_back( GetLLVMType( *ValueFromIRExpr( mt ) ) );
auto* pllvmType = llvm::StructType::get( GetLLVMContext(), elements, s.m_packed );
if( s.m_identity )
{
return Value( Type(), TVEC( TSID( rt_type ), TERM( pllvmType ),
TSID( struct ), TERM( s.m_packed ? 1ULL : 0ULL ),
Quote( *s.m_identity ), TERM( s.m_memberTypes ) ) );
}
return Value( Type(), TVEC( TSID( rt_type ), TERM( pllvmType ),
TSID( struct ), TERM( s.m_packed ? 1ULL : 0ULL ),
TERM( s.m_memberTypes ) ) );
}
optional< StructType > Bridge< StructType >::FromValue( const Value& v )
{
auto result = Decompose( v.val(),
Vec(
Lit( "rt_type"_sid ),
Val< void* >(),
Lit( "struct"_sid ),
Val< uint64_t >(),
SubTerm(),
Val< pvec >()
)
);
if( !result )
{
auto result = Decompose( v.val(),
Vec(
Lit( "struct"_sid ),
Val< void* >(),
Val< uint64_t >(),
Val< pvec >()
)
);
if( !result )
return nullopt;
auto&& [llvmType, packed, memberTypes] = *result;
return StructType( memberTypes, !!packed );
}
auto&& [llvmType, packed, identity, memberTypes] = *result;
return StructType( *Unquote( identity ), memberTypes, !!packed );
}
}