Goose  Artifact [898928837e]

Artifact 898928837e662ae7c4a30aa8cbf71b6e7d030b61c0b995e41f115255d9c8b5c3:

  • File bs/g0api/extensibility/types.cpp — part of check-in [4a571387ed] at 2021-09-17 23:04:29 on branch trunk — g0api, builtins: got rid of TermWrapper and ValueWrapper, use specializations of TypeWrapper instead to allow for more generic code (user: achavasse size: 3422)

#include "g0api/g0api.h"
#include "eir/eir.h"
#include "builtins/helpers.h"

using namespace goose;
using namespace goose::g0api;

namespace
{
    template< typename T >
    void SetupWrapperForType( Env& e, StringId name, const ptr< OverloadSet >& pEquals, const ptr< OverloadSet >& pNotEquals )
    {
        DefineConstant( e, name, GetValueType< TypeWrapper< T > >() );

        using reftype = CustomPattern< Value, ReferenceType::PatternMutableOfType< TypeWrapper< T > > >;
        auto type = ValueToEIR( ToValue( builtins::ReferenceType( GetValueType< TypeWrapper< T > >(), TSID( mut ) ) ) );
        RegisterBuiltinFunc< Intrinsic< Value ( reftype ) > >( e, e.extInitialize(),
            []( auto&& c, const Value& r )
            {
                // Do nothing: the types we're wrapping are default initialized anyway.
                // The only purpose of this Initialize overload is to let goose know that
                // the type has a default initialization.
                return Value( GetValueType< void >(), 0U );
            } );

        using constreftype = CustomPattern<
            TypeWrapper< T >, ReferenceType::PatternConstOfType< TypeWrapper< T > > >;
        RegisterBuiltinFunc< bool ( constreftype, constreftype ) >( e, pEquals,
            []( const TypeWrapper< T >& lhs, const TypeWrapper< T >& rhs )
            {
                return lhs.get() == rhs.get();
            } );

        RegisterBuiltinFunc< bool ( constreftype, constreftype ) >( e, pNotEquals,
            []( const TypeWrapper< T >& lhs, const TypeWrapper< T >& rhs )
            {
                return lhs.get() != rhs.get();
            } );

        RegisterBuiltinFunc< string ( TypeWrapper< T > ) >( e, "ToString"_sid,
            []( const TypeWrapper< T >& t )
            {
                stringstream sstr;
                sstr << t.get();
                return sstr.str();
            } );
    }
}

namespace goose::g0api
{
    void SetupTypeWrappers( Env& e )
    {
        auto pEquals = GetOverloadSet( e, "operator_equals"_sid );
        auto pNotEquals = GetOverloadSet( e, "operator_not_equals"_sid );

        ////////////////////////////
        // EIR types
        ////////////////////////////

        SetupWrapperForType< Term >( e, "Term"_sid, pEquals, pNotEquals );
        SetupWrapperForType< LocationId >( e, "LocationId"_sid, pEquals, pNotEquals );
        SetupWrapperForType< StringId >( e, "StringId"_sid, pEquals, pNotEquals );
        SetupWrapperForType< Hole >( e, "Hole"_sid, pEquals, pNotEquals );
        SetupWrapperForType< AnyTerm >( e, "AnyTerm"_sid, pEquals, pNotEquals );
        SetupWrapperForType< VecOfLength >( e, "VecOfLength"_sid, pEquals, pNotEquals );
        SetupWrapperForType< pvec >( e, "Vec"_sid, pEquals, pNotEquals );
        SetupWrapperForType< APSInt >( e, "FixedInt"_sid, pEquals, pNotEquals );

        SetupWrapperForType< Value >( e, "Value"_sid, pEquals, pNotEquals );

        ////////////////////////////
        // CIR types
        ////////////////////////////
        SetupWrapperForType< ptr< CFG > >( e, "CFG"_sid, pEquals, pNotEquals );
        SetupWrapperForType< ptr< BasicBlock > >( e, "BasicBlock"_sid, pEquals, pNotEquals );
        SetupWrapperForType< ptr< Instruction > >( e, "Instruction"_sid, pEquals, pNotEquals );
        SetupWrapperForType< ptr< Terminator > >( e, "Terminator"_sid, pEquals, pNotEquals );
    }
}