Goose  Artifact [1c5253c649]

Artifact 1c5253c649d5a31889fc542be80cfd295fd17d188901b1a07c57e5be12c96592:

  • File bs/builtins/types/reference/reference.cpp — part of check-in [97ff23912a] at 2022-07-16 14:42:30 on branch trunk — Varargs: added a "nested repetition depth" property to holes (user: zlodo size: 4599)

#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 );
    }
}