#include "builtins/builtins.h"
#include "parse/parse.h"
using namespace goose::builtins;
using namespace goose::cir;
using namespace goose::parse;
namespace goose::builtins
{
bool IsReferenceType( const Term& t )
{
auto result = Decompose( EIRToValue( t )->val(),
Vec(
Lit( "reference"_sid ),
SubTerm(),
SubTerm()
)
);
return !!result;
}
const Term& ReferenceType::PatternAny::GetPattern()
{
static auto pattern = ValueToEIR( ToValue( ReferenceType( HOLE( "_"_sid ), HOLE( "_"_sid ) ) ) );
return pattern;
}
const Term& ReferenceType::PatternAnyTRef::GetPattern()
{
static auto pattern = ValueToEIR( Value( GetValueType< ReferenceType >(),
TVecToEIR( Vector::Make( TSID( reference ), HOLE( "_"_sid ), HOLE( "_"_sid ) ) ) ) );
return pattern;
}
const Term& ReferenceType::PatternAnyMutable::GetPattern()
{
static auto pattern = ValueToEIR( ToValue( ReferenceType( HOLE( "_"_sid ), MutAccessSpecifer() ) ) );
return pattern;
}
const Term& ReferenceType::PatternAnyMutableOfTypeT::GetPattern()
{
static auto pattern = ValueToEIR( ToValue( ReferenceType( HOLE( "T"_sid, "tvar"_sid ), MutAccessSpecifer() ) ) );
return pattern;
}
const Term& ReferenceType::PatternXOfTypeT::GetPattern()
{
static auto pattern = ValueToEIR( ToValue( ReferenceType( HOLE( "T"_sid, "ttvar"_sid ), HOLE( "X"_sid ) ) ) );
return pattern;
}
// Returns an instruction that computes the address of whatever's contained in the locvar.
cir::Instruction GetAddrFromLocalVar( const LocalVar& lv )
{
// TODO LOC: may need loc in LocalVar
return cir::VarAddr( lv.index(), lv.type(), {} );
}
Value BuildLocalVarMutRef( const LocalVar& lv )
{
// TODO LOC: may need loc in LocalVar
auto rt = ValueToEIR( ToValue( ReferenceType{ lv.type(), MutAccessSpecifer() } ) );
return BuildComputedValue( move( rt ), cir::VarAddr( lv.index(), lv.type(), {} ) );
}
const Term& MutAccessSpecifer()
{
static auto al = ValueToEIR( ToValue( AccessSpecifier( "mut"_sid ) ) );
return al;
}
const Term& ConstAccessSpecifer()
{
static auto al = ValueToEIR( ToValue( AccessSpecifier( "const"_sid ) ) );
return al;
}
const Term& TempAccessSpecifer()
{
static auto al = ValueToEIR( ToValue( AccessSpecifier( "temp"_sid ) ) );
return al;
}
}
namespace goose::eir
{
const Term& Bridge< ReferenceType >::Type()
{
return TypeType();
}
Value Bridge< ReferenceType >::ToDeclValue( const ReferenceType& t )
{
return Value( Type(), TVEC( TSID( reference ), t.behavior(), t.type() ) );
}
optional< ReferenceType > Bridge< ReferenceType >::FromDeclValue( const Value& v )
{
auto tv = TVecFromEIR( v.val() );
if( !tv )
return FromValue( v );
auto result = Decompose( tv->content(),
Vec(
Lit( "reference"_sid ),
SubTerm(),
SubTerm()
)
);
if( !result )
return nullopt;
auto&& [bhv, type] = *result;
return ReferenceType( move( type ), move( bhv ) );
}
Value Bridge< ReferenceType >::ToValue( const ReferenceType& t )
{
return Value( Type(), VEC( TSID( reference ), t.behavior(), t.type() ) );
}
optional< ReferenceType > Bridge< ReferenceType >::FromValue( const Value& v )
{
auto result = Decompose( v.val(),
Vec(
Lit( "reference"_sid ),
SubTerm(),
SubTerm()
)
);
if( !result )
return nullopt;
auto&& [bhv, type] = *result;
return ReferenceType( move( type ), move( bhv ) );
}
const Term& Bridge< AccessSpecifier >::Type()
{
static auto type = ValueToEIR( Value( TypeType(), TVEC( TSID( ct_type ), TSID( access_level ) ) ) );
return type;
}
Value Bridge< AccessSpecifier >::ToValue( const AccessSpecifier& a )
{
return Value( Type(), a.level() );
}
optional< AccessSpecifier > Bridge< AccessSpecifier >::FromValue( const Value& v )
{
auto result = Decompose( v.val(),
Val< StringId >()
);
if( !result )
return nullopt;
return AccessSpecifier( *result );
}
}