Goose  Artifact [556c44fc05]

Artifact 556c44fc058a3b180af4ceb020742bf595726d775d636a576e68bc9ba36e57f9:

  • File bs/builtins/types/reference/reference.cpp — part of check-in [e1ede8dafa] at 2021-11-25 20:30:26 on branch trunk —
    • simplified ref parsing implementation by using the parser's infix parsing rule helper
    • refactored "requires" and "ensures": they are now simply infix operators that take a function type on the lhs and a proposition list on the rhs
    (user: zlodo size: 4526)

#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 ), MutAccessLevel() ) ) );
        return pattern;
    }

    const Term& ReferenceType::PatternAnyMutableOfTypeT::GetPattern()
    {
        static auto pattern = ValueToEIR( ToValue( ReferenceType( HOLE( "T"_sid, TSID( tvar ) ), MutAccessLevel() ) ) );
        return pattern;
    }

    const Term& ReferenceType::PatternXOfTypeT::GetPattern()
    {
        static auto pattern = ValueToEIR( ToValue( ReferenceType( HOLE( "T"_sid, TSID( tvar ) ), HOLE( "X"_sid ) ) ) );
        return pattern;
    }

    // Returns an instruction that computes the address of whatever's contained in the locvar.
    ptr< cir::Instruction > GetAddrFromLocalVar( const LocalVar& lv )
    {
        return make_shared< cir::Instruction >( cir::VarAddr( lv.index(), lv.type() ) );
    }

    Value BuildLocalVarMutRef( const LocalVar& lv )
    {
        auto rt = ValueToEIR( ToValue( ReferenceType{ lv.type(), MutAccessLevel() } ) );
        return BuildComputedValue( move( rt ), cir::VarAddr( lv.index(), lv.type() ) );
    }

    const Term& MutAccessLevel()
    {
        static auto al = ValueToEIR( ToValue( AccessSpecifier( "mut"_sid ) ) );
        return al;
    }

    const Term& ConstAccessLevel()
    {
        static auto al = ValueToEIR( ToValue( AccessSpecifier( "const"_sid ) ) );
        return al;
    }

    const Term& TempAccessLevel()
    {
        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 );
    }
}