Goose  Artifact [dfac44b727]

Artifact dfac44b72729e89d39181fde055e17c1a14589479e4ddcff8ed01f39c47ff487:

  • File bs/builtins/types/constrainedfunc/unify.cpp — part of check-in [c39a302502] at 2020-05-23 12:58:20 on branch trunk —
    • Fixed the hole matching score which prevented some unification rules to be selected.
    • Implemented LowerTypeForRuntime for tuples.
    • Implemented an unification rule for constant tuples.
    • Added some debugging helpers.
    (user: achavasse size: 3242)

#include "builtins/builtins.h"

using namespace goose;
using namespace goose::ir;

namespace goose::builtins
{
    void SetupConstrainedFuncUnification( Env& e )
    {
        auto funcTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( func ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

        auto tFuncTypePat = ValueToIRExpr( Value( TypeType(), VEC( TSID( texpr ), TSID( tfunc ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

        // func type param / constrainedfunc arg
        e.unificationRuleSet()->addSymRule( URINFOS,

            ParamPat( move( funcTypePat ) ),

            ValueToIRExpr( ValuePattern(
                TSID( constant ),
                GetValueType< builtins::ConstrainedFunc >(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& uc ) -> UniGen
        {
            auto ldecomp = Decompose( lhs,
                Vec(
                    Lit( "value"_sid ),
                    SubTerm(),
                    SubTerm(),
                    SubTerm(),
                    Val< LocationId >()
                )
            );
            assert( ldecomp );

            auto&& [sort, type, val, locId] = *ldecomp;
            auto callPat = BuildCallPatternFromFuncType( *ValueFromIRExpr( type ) );

            auto rhsVal = *ValueFromIRExpr( rhs );
            auto cfunc = FromValue< ConstrainedFunc >( rhsVal );
            assert( cfunc );

            auto localC = uc;
            auto g = Unify( callPat, cfunc->constraintPat(), localC );
            auto it = g.begin();
            if( it != g.end() )
            {
                auto func = ValueToIRExpr( cfunc->func() );
                co_yield Unify( lhs, func, uc );
            }
        } );

        // tfunc type param / constrainedfunc arg
        e.unificationRuleSet()->addAsymRule( URINFOS,

            ValueToIRExpr( ValuePattern( HOLE( "_"_sid ), move( tFuncTypePat ), HOLE( "_"_sid ) ) ),

            ValueToIRExpr( ValuePattern(
                TSID( constant ),
                GetValueType< builtins::ConstrainedFunc >(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& uc ) -> UniGen
        {
            auto ldecomp = Decompose( lhs,
                Vec(
                    Lit( "value"_sid ),
                    SubTerm(),
                    SubTerm(),
                    SubTerm(),
                    Val< LocationId >()
                )
            );
            assert( ldecomp );

            auto&& [sort, type, val, locId] = *ldecomp;
            auto callPat = BuildArgPatternFromTFuncType( uc.context(), *ValueFromIRExpr( type ) );
            assert( callPat );

            auto rhsVal = *ValueFromIRExpr( rhs );
            auto cfunc = FromValue< ConstrainedFunc >( rhsVal );
            assert( cfunc );

            auto localC = uc;
            auto g = Unify( *callPat, cfunc->constraintPat(), localC );
            auto it = g.begin();
            if( it != g.end() )
            {
                auto func = ValueToIRExpr( cfunc->func() );
                co_yield Unify( lhs, func, uc );
            }
        } );
    }
}