Goose  Check-in [64224a915f]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Refactored some template rules and type checking rules to avoid calling BuildTemplateSignature from inside type checking rules
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 64224a915fbf330ec7d4fa6901c36852182c7485abfb485c1b899d5ade036e6f
User & Date: zlodo 2022-07-04 17:45:47.410
Context
2022-07-04
21:20
typechecking: refactor type checking context to be able to hold more sub-context information than hole namespace indices check-in: 9fd8a2a87e user: zlodo tags: trunk
17:45
Refactored some template rules and type checking rules to avoid calling BuildTemplateSignature from inside type checking rules check-in: 64224a915f user: zlodo tags: trunk
2022-07-02
14:22
Vararg templates: function param decls with open tuple types are expanded into multiple params check-in: ecd5b0e89a user: zlodo tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to bs/builtins/types/constrainedfunc/typecheck.cpp.
48
49
50
51
52
53
54
55



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
                }
            }
        } );

        // tfunc type param / constrainedfunc arg
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ValueToEIR( ValuePattern( ANYTERM( _ ), TFuncTypePattern(), ANYTERM( _ ) ) ),




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

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

            auto&& [sort, type, val, locId] = *ldecomp;

            auto callPat = BuildArgPatternFromTFuncType( tcc.context(), *EIRToValue( type ) );
            assert( callPat );

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

            auto localC = tcc;







|
>
>
>




















>
|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
                }
            }
        } );

        // tfunc type param / constrainedfunc arg
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ValueToEIR( ValuePattern(
                ANYTERM( _ ),
                TFuncTypeSigPattern( ANYTERM( _ ), ANYTERM( _ ) ),
                ANYTERM( _ ) ) ),

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

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

            auto&& [sort, type, val, locId] = *ldecomp;
            auto [tfType,_] = DecomposeTFTSig( type );
            auto callPat = BuildArgPatternFromTFuncType( tcc.context(), *EIRToValue( tfType ) );
            assert( callPat );

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

            auto localC = tcc;
Changes to bs/builtins/types/func/build.cpp.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
        uint32_t varId = 0;
        ForEachInTuple( params, [&]( auto&& param )
        {
            if( IsDecl( param ) )
            {
                auto decl = *FromValue< Decl >( param );

                // TODO extract that stuff below that one param decl into separate funcs
                // coz its starting to get ugly

                // TODO: convertFuncParam is incorrectly implemented, because when compiling the function
                // we still work from the unconverted param decls.
                // We should probably first convert all the param decls (including param packs)

                // Handle parameter packs (open tuples)
                auto declType = *EIRToValue( decl.type() );
                if( IsOpenTuple( declType ) )
                {
                    ForEachInTuple( declType, [&]( auto&& type )
                    {
                        tv->append( BuildParamPat( c, type, param.locationId() ) );







<
<
<
<
<
<
<







23
24
25
26
27
28
29







30
31
32
33
34
35
36
        uint32_t varId = 0;
        ForEachInTuple( params, [&]( auto&& param )
        {
            if( IsDecl( param ) )
            {
                auto decl = *FromValue< Decl >( param );








                // Handle parameter packs (open tuples)
                auto declType = *EIRToValue( decl.type() );
                if( IsOpenTuple( declType ) )
                {
                    ForEachInTuple( declType, [&]( auto&& type )
                    {
                        tv->append( BuildParamPat( c, type, param.locationId() ) );
Changes to bs/builtins/types/func/typecheck.cpp.
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

            co_yield { move( wrapped ), tcc };
        } );

        // tfunc type param / func arg
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ParamPat( TFuncTypePattern() ),

            ValueToEIR( ValuePattern(
                TSID( constant ),
                FuncTypePattern(),
                ANYTERM( _ ) ) ),

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

            auto&& [sort, type, val, locId] = *ldecomp;

            auto callPat = BuildArgPatternFromTFuncType( tcc.context(), *EIRToValue( type ) );
            assert( callPat );

            auto rhsVal = *EIRToValue( rhs );
            auto sig = GetFuncSig( rhsVal );

            for( auto&& [s, tcc] : TypeCheck( sig, *callPat, tcc ) )
            {







|




















|
|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

            co_yield { move( wrapped ), tcc };
        } );

        // tfunc type param / func arg
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ParamPat( TFuncTypeSigPattern( ANYTERM( _ ), ANYTERM( _ ) ) ),

            ValueToEIR( ValuePattern(
                TSID( constant ),
                FuncTypePattern(),
                ANYTERM( _ ) ) ),

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

            auto&& [sort, type, val, locId] = *ldecomp;
            auto [tfType,_] = DecomposeTFTSig( type );
            auto callPat = BuildArgPatternFromTFuncType( tcc.context(), *EIRToValue( tfType ) );
            assert( callPat );

            auto rhsVal = *EIRToValue( rhs );
            auto sig = GetFuncSig( rhsVal );

            for( auto&& [s, tcc] : TypeCheck( sig, *callPat, tcc ) )
            {
Changes to bs/builtins/types/overloadset/typecheck.cpp.
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
        } );

        // tfunc type param / overloadset arg
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ValueToEIR( ValuePattern(
                ANYTERM( _ ),
                TFuncTypePattern(),
                ANYTERM( _ ) ) ),

            ValueToEIR( ValuePattern(
                TSID( constant ),
                GetValueType< ptr< sema::OverloadSet > >(),
                ANYTERM( _ ) ) ),








|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
        } );

        // tfunc type param / overloadset arg
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ValueToEIR( ValuePattern(
                ANYTERM( _ ),
                TFuncTypeSigPattern( ANYTERM( _ ), ANYTERM( _ ) ),
                ANYTERM( _ ) ) ),

            ValueToEIR( ValuePattern(
                TSID( constant ),
                GetValueType< ptr< sema::OverloadSet > >(),
                ANYTERM( _ ) ) ),

93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
                    SubTerm(),
                    Val< LocationId >()
                )
            );
            assert( ldecomp );

            auto&& [sort, type, val, locId] = *ldecomp;

            auto callPat = BuildArgPatternFromTFuncType( tcc.context(), *EIRToValue( type ) );
            assert( callPat );

            auto rhsVal = *EIRToValue( rhs );
            auto os = *FromValue< ptr< OverloadSet > >( rhsVal );

            auto rhsLocId = rhsVal.locationId();








>
|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
                    SubTerm(),
                    Val< LocationId >()
                )
            );
            assert( ldecomp );

            auto&& [sort, type, val, locId] = *ldecomp;
            auto [tfType,_] = DecomposeTFTSig( type );
            auto callPat = BuildArgPatternFromTFuncType( tcc.context(), *EIRToValue( tfType ) );
            assert( callPat );

            auto rhsVal = *EIRToValue( rhs );
            auto os = *FromValue< ptr< OverloadSet > >( rhsVal );

            auto rhsLocId = rhsVal.locationId();

Changes to bs/builtins/types/template/rules/tdecl.cpp.
1
2
3
4
5
6
7
8
9



10


11
12
13
14
15
16
17
#include "builtins/builtins.h"

namespace goose::builtins
{
    class TDeclTemplateRule : public TemplateRule
    {
        optional< Term > buildSignature( const Context& c, const Term& val ) const final
        {
            auto td = *FromValue< TDecl >( *EIRToValue( val ) );



            return TDeclToTDSig( td );


        }

        Value buildParamDecl( const Context& c, const Term& param, const Term& arg ) const final
        {
            return *EIRToValue( arg );
        }










>
>
>
|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "builtins/builtins.h"

namespace goose::builtins
{
    class TDeclTemplateRule : public TemplateRule
    {
        optional< Term > buildSignature( const Context& c, const Term& val ) const final
        {
            auto td = *FromValue< TDecl >( *EIRToValue( val ) );

            auto sig = BuildTemplateSignature( c, td.type() );
            if( !sig )
                return nullopt;

            return TDeclSigPattern( TERM( td.name() ), move( *sig ) );
        }

        Value buildParamDecl( const Context& c, const Term& param, const Term& arg ) const final
        {
            return *EIRToValue( arg );
        }

Changes to bs/builtins/types/template/rules/tfunctype.cpp.
1
2
3
4
5
6
7
8




9


10
11
12
13
14
15
16
#include "builtins/builtins.h"

namespace goose::builtins
{
    class TFuncTypeTemplateRule : public TemplateRule
    {
        optional< Term > buildSignature( const Context& c, const Term& val ) const final
        {




            return val;


        }

        Value buildParamDecl( const Context& c, const Term& param, const Term& arg ) const final
        {
            return *EIRToValue( arg );
        }









>
>
>
>
|
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "builtins/builtins.h"

namespace goose::builtins
{
    class TFuncTypeTemplateRule : public TemplateRule
    {
        optional< Term > buildSignature( const Context& c, const Term& val ) const final
        {
            auto tfuncType = FromValue< TFuncType >( *EIRToValue( val ) );

            auto sig = BuildTFuncSignature( c, *tfuncType );
            if( !sig )
                return nullopt;

            return TFuncTypeSigPattern( val, move( *sig ) );
        }

        Value buildParamDecl( const Context& c, const Term& param, const Term& arg ) const final
        {
            return *EIRToValue( arg );
        }

Changes to bs/builtins/types/template/tc-tdecl.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "builtins/builtins.h"

namespace goose::builtins
{
    Term BuildArgPatternFromTDecl( const Context& c, const TDecl& td )
    {
        auto typeSig = BuildTemplateSignature( c, td.type() );
        assert( typeSig );
        return ValueToEIR( ValuePattern( HOLE( "_"_sid ), move( *typeSig ), HOLE( "_"_sid ) ) );
    }

    void SetupTDeclTypeChecking( Env& e )
    {
        auto tDeclPat = TDeclSigPattern( ANYTERM( _ ), ANYTERM( _ ) ); //    ValueToEIR( Value( GetValueType< TDecl >(), VEC( ANYTERM( _ ), ANYTERM( _ ) ) ) );

        e.typeCheckingRuleSet()->addHalfUnificationRule( TCRINFOS, tDeclPat,
            []( const Term& lhs, TypeCheckingContext& c )
            {
                auto tdecl = TDSigToTDecl( lhs );
                return HalfUnify( tdecl.type(), c );
            } );

        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS, tDeclPat, ANYTERM( _ ),
            []( const Term& lhs, const Term& rhs, TypeCheckingContext tcc ) -> TCGen
            {
                auto tdecl = TDSigToTDecl( lhs );
                auto typeSig = BuildTemplateSignature( tcc.context(), tdecl.type() );
                assert( typeSig );

                auto tdeclHole = HOLE( tdecl.name() );

                auto pat = ValueToEIR( Value( move( *typeSig ), HOLE( "_"_sid ) ) );
                for( auto&& [s,tcc] : TypeCheck( pat, rhs, tcc ) )
                {
                    // We need to typecheck the result with a hole named after the decl. However, since both sides of
                    // this unification orignally appeared on the LHS, we need to setup RHS to alias the LHS namespace for this.
                    auto savedRHSNamespaceIndex = tcc.RHSNamespaceIndex();
                    tcc.setRHSNamespaceIndex( tcc.LHSNamespaceIndex() );

                    for( auto&& [s,tcc] : TypeCheck( s, tdeclHole, tcc ) )
                    {
                        tcc.setRHSNamespaceIndex( savedRHSNamespaceIndex );
                        co_yield { s, tcc };
                    }
                }
            } );

        e.typeCheckingRuleSet()->addUnificationRule( TCRINFOS, tDeclPat, ANYTERM( _ ),
            []( const Term& lhs, const Term& rhs, TypeCheckingContext tcc ) -> TCGen
            {
                auto tdecl = TDSigToTDecl( lhs );

                auto typeSig = BuildTemplateSignature( tcc.context(), tdecl.type() );
                assert( typeSig );

                auto tdeclHole = HOLE( tdecl.name() );

                auto pat = ValueToEIR( Value( move( *typeSig ), HOLE( "_"_sid ) ) );
                for( auto&& [s,tcc] : Unify( pat, rhs, tcc ) )
                {
                    // We need to unify the result with a hole named after the decl. However, since both sides of
                    // this unification orignally appeared on the LHS, we need to setup RHS to alias the LHS namespace for this.
                    auto savedRHSNamespaceIndex = tcc.RHSNamespaceIndex();
                    tcc.setRHSNamespaceIndex( tcc.LHSNamespaceIndex() );

                    for( auto&& [s,tcc] : Unify( s, tdeclHole, tcc ) )
                    {
                        tcc.setRHSNamespaceIndex( savedRHSNamespaceIndex );
                        co_yield { s, tcc };
                    }
                }
            } );

        // tfunc tdecl param / tfunc arg
        auto tDeclTFuncPat = TDeclSigPattern( TFuncTypePattern(), ANYTERM( _ ) );

        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            tDeclTFuncPat,

            ValueToEIR( ValuePattern(
                TSID( constant ),
                TFuncTypePattern(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, TypeCheckingContext tcc ) -> TCGen
        {
            auto tdecl = TDSigToTDecl( lhs );

            auto tfuncType = FromValue< TFuncType >( *EIRToValue( tdecl.type() ) );
            assert( tfuncType );

            auto callPat = BuildArgPatternFromTDecl( tcc.context(), tdecl );
            auto tdeclHole = HOLE( tdecl.name() );

            auto rhsVal = *EIRToValue( rhs );

            auto constraintPat = BuildTFuncSignature( tcc.context(), *tfuncType );
            assert( constraintPat );

            ConstrainedFunc cfunc( *constraintPat, GetTFuncInvocationRule(), rhsVal );
            auto cFuncTerm = ValueToEIR( ToValue( move( cfunc ) ) );

            // Create a new named hole namespace to isolate holes from the passed function from those in
            // the called function.
            auto savedRHSNamespaceIndex = tcc.RHSNamespaceIndex();
            tcc.setRHSNamespaceIndex( tcc.newNamespaceIndex() );





|

<
<
|




|




|
|





<
<
<
|
|

|


















<
|
<
<
<
|

|
















|












|
|
<
<

|
|



<
<
<
|







1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80


81
82
83
84
85
86



87
88
89
90
91
92
93
94
#include "builtins/builtins.h"

namespace goose::builtins
{
    Term BuildArgPatternFromTDecl( const Context& c, Term&& sig )
    {


        return ValueToEIR( ValuePattern( HOLE( "_"_sid ), move( sig ), HOLE( "_"_sid ) ) );
    }

    void SetupTDeclTypeChecking( Env& e )
    {
        auto tDeclPat = TDeclSigPattern( ANYTERM( _ ), ANYTERM( _ ) );

        e.typeCheckingRuleSet()->addHalfUnificationRule( TCRINFOS, tDeclPat,
            []( const Term& lhs, TypeCheckingContext& c )
            {
                auto [name,sig] = DecomposeTDSig( lhs );
                return HalfUnify( sig, c );
            } );

        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS, tDeclPat, ANYTERM( _ ),
            []( const Term& lhs, const Term& rhs, TypeCheckingContext tcc ) -> TCGen
            {



                auto [name,typeSig] = DecomposeTDSig( lhs );
                auto tdeclHole = HOLE( name );

                auto pat = ValueToEIR( Value( move( typeSig ), HOLE( "_"_sid ) ) );
                for( auto&& [s,tcc] : TypeCheck( pat, rhs, tcc ) )
                {
                    // We need to typecheck the result with a hole named after the decl. However, since both sides of
                    // this unification orignally appeared on the LHS, we need to setup RHS to alias the LHS namespace for this.
                    auto savedRHSNamespaceIndex = tcc.RHSNamespaceIndex();
                    tcc.setRHSNamespaceIndex( tcc.LHSNamespaceIndex() );

                    for( auto&& [s,tcc] : TypeCheck( s, tdeclHole, tcc ) )
                    {
                        tcc.setRHSNamespaceIndex( savedRHSNamespaceIndex );
                        co_yield { s, tcc };
                    }
                }
            } );

        e.typeCheckingRuleSet()->addUnificationRule( TCRINFOS, tDeclPat, ANYTERM( _ ),
            []( const Term& lhs, const Term& rhs, TypeCheckingContext tcc ) -> TCGen
            {

                auto [name,typeSig] = DecomposeTDSig( lhs );



                auto tdeclHole = HOLE( name );

                auto pat = ValueToEIR( Value( move( typeSig ), HOLE( "_"_sid ) ) );
                for( auto&& [s,tcc] : Unify( pat, rhs, tcc ) )
                {
                    // We need to unify the result with a hole named after the decl. However, since both sides of
                    // this unification orignally appeared on the LHS, we need to setup RHS to alias the LHS namespace for this.
                    auto savedRHSNamespaceIndex = tcc.RHSNamespaceIndex();
                    tcc.setRHSNamespaceIndex( tcc.LHSNamespaceIndex() );

                    for( auto&& [s,tcc] : Unify( s, tdeclHole, tcc ) )
                    {
                        tcc.setRHSNamespaceIndex( savedRHSNamespaceIndex );
                        co_yield { s, tcc };
                    }
                }
            } );

        // tfunc tdecl param / tfunc arg
        auto tDeclTFuncPat = TDeclSigPattern( ANYTERM( _ ), TFuncTypeSigPattern( ANYTERM( _ ), ANYTERM( _ ) ) );

        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            tDeclTFuncPat,

            ValueToEIR( ValuePattern(
                TSID( constant ),
                TFuncTypePattern(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, TypeCheckingContext tcc ) -> TCGen
        {
            auto [name,typeSig] = DecomposeTDSig( lhs );
            auto [_,tfSig] = DecomposeTFTSig( typeSig );



            auto callPat = BuildArgPatternFromTDecl( tcc.context(), move( typeSig ) );
            auto tdeclHole = HOLE( name );

            auto rhsVal = *EIRToValue( rhs );




            ConstrainedFunc cfunc( tfSig, GetTFuncInvocationRule(), rhsVal );
            auto cFuncTerm = ValueToEIR( ToValue( move( cfunc ) ) );

            // Create a new named hole namespace to isolate holes from the passed function from those in
            // the called function.
            auto savedRHSNamespaceIndex = tcc.RHSNamespaceIndex();
            tcc.setRHSNamespaceIndex( tcc.newNamespaceIndex() );

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
            ValueToEIR( ValuePattern(
                TSID( constant ),
                GetValueType< ptr< sema::OverloadSet > >(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, TypeCheckingContext tcc ) -> TCGen
        {
            auto tdecl = TDSigToTDecl( lhs );

            auto tfuncType = FromValue< TFuncType >( *EIRToValue( tdecl.type() ) );
            assert( tfuncType );

            auto callPat = BuildArgPatternFromTDecl( tcc.context(), tdecl );
            auto tdeclHole = HOLE( tdecl.name() );

            auto rhsVal = *EIRToValue( rhs );

            auto constraintPat = BuildTFuncSignature( tcc.context(), *tfuncType );
            assert( constraintPat );

            ConstrainedFunc cfunc( *constraintPat, GetOverloadSetInvocationRule(), rhsVal );
            auto cFuncTerm = ValueToEIR( ToValue( move( cfunc ) ) );

            // Create a new named hole namespace to isolate holes from the passed function from those in
            // the called function.
            auto savedRHSNamespaceIndex = tcc.RHSNamespaceIndex();
            tcc.setRHSNamespaceIndex( tcc.newNamespaceIndex() );








|
|
<
<

|
|



<
<
<
|







121
122
123
124
125
126
127
128
129


130
131
132
133
134
135



136
137
138
139
140
141
142
143
            ValueToEIR( ValuePattern(
                TSID( constant ),
                GetValueType< ptr< sema::OverloadSet > >(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, TypeCheckingContext tcc ) -> TCGen
        {
            auto [name,typeSig] = DecomposeTDSig( lhs );
            auto [_,tfSig] = DecomposeTFTSig( typeSig );



            auto callPat = BuildArgPatternFromTDecl( tcc.context(), move( typeSig ) );
            auto tdeclHole = HOLE( name );

            auto rhsVal = *EIRToValue( rhs );




            ConstrainedFunc cfunc( tfSig, GetOverloadSetInvocationRule(), rhsVal );
            auto cFuncTerm = ValueToEIR( ToValue( move( cfunc ) ) );

            // Create a new named hole namespace to isolate holes from the passed function from those in
            // the called function.
            auto savedRHSNamespaceIndex = tcc.RHSNamespaceIndex();
            tcc.setRHSNamespaceIndex( tcc.newNamespaceIndex() );

Changes to bs/builtins/types/template/tdecl.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
#include "builtins/builtins.h"

using namespace goose::builtins;

namespace goose::builtins
{
    bool IsTDecl( const Value& td )
    {
        return td.type() == GetValueType< TDecl >();
    }

    Term TDeclSigPattern( const Term& type, const Term& name )
    {
        return VEC( TSID( tdecl ), type, name );
    }

    Term TDeclToTDSig( const TDecl& td )
    {
        return VEC( TSID( tdecl ), td.type(), td.name() );
    }

    TDecl TDSigToTDecl( const Term& tdsig )
    {
        auto result = Decompose( tdsig,
            Vec(
                Lit( "tdecl"_sid ),
                SubTerm(),
                Val< StringId >()

            )
        );

        auto&& [type,name] = *result;
        return TDecl( type, name );
    }
}

namespace goose::eir
{
    const Term& Bridge< TDecl >::Type()
    {











|

|


<
<
<
<
<
|



|
<
|
>



|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16





17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "builtins/builtins.h"

using namespace goose::builtins;

namespace goose::builtins
{
    bool IsTDecl( const Value& td )
    {
        return td.type() == GetValueType< TDecl >();
    }

    Term TDeclSigPattern( const Term& name, Term&& sig )
    {
        return VEC( TSID( tdecl_sig ), name, move( sig ) );
    }






    tuple< StringId, Term > DecomposeTDSig( const Term& tdsig )
    {
        auto result = Decompose( tdsig,
            Vec(
                Lit( "tdecl_sig"_sid ),

                Val< StringId >(),
                SubTerm()
            )
        );

        auto&& [name,sig] = *result;
        return { name, sig };
    }
}

namespace goose::eir
{
    const Term& Bridge< TDecl >::Type()
    {
Changes to bs/builtins/types/template/tdecl.h.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
        private:
            Term m_type;
            StringId m_name;
    };

    extern bool IsTDecl( const Value& td );

    extern Term TDeclSigPattern( const Term& type, const Term& name );
    extern Term TDeclToTDSig( const TDecl& td );
    extern TDecl TDSigToTDecl( const Term& tdsig );
}

namespace goose::eir
{
    template<>
    struct Bridge< builtins::TDecl >
    {







|
<
|







22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
        private:
            Term m_type;
            StringId m_name;
    };

    extern bool IsTDecl( const Value& td );

    extern Term TDeclSigPattern( const Term& name, Term&& sig );

    extern tuple< StringId, Term > DecomposeTDSig( const Term& tdsig );
}

namespace goose::eir
{
    template<>
    struct Bridge< builtins::TDecl >
    {
Changes to bs/builtins/types/template/tfunctype.cpp.
41
42
43
44
45
46
47














48
49
50
51
52
53
54

    const Term& TFuncTypePattern()
    {
        static auto tFuncTypePat = ValueToEIR( Value( TypeType(), VEC( TSID( texpr ), TSID( tfunc ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );
        return tFuncTypePat;
    }














}

namespace goose::eir
{
    const Term& Bridge< TFuncType >::Type()
    {
        return TypeType();







>
>
>
>
>
>
>
>
>
>
>
>
>
>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

    const Term& TFuncTypePattern()
    {
        static auto tFuncTypePat = ValueToEIR( Value( TypeType(), VEC( TSID( texpr ), TSID( tfunc ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );
        return tFuncTypePat;
    }

    tuple< Term, Term > DecomposeTFTSig( const Term& tdsig )
    {
        auto result = Decompose( tdsig,
            Vec(
                Lit( "tfunctype_sig"_sid ),
                SubTerm(),
                SubTerm()
            )
        );

        auto&& [type,sig] = *result;
        return { type, sig };
    }
}

namespace goose::eir
{
    const Term& Bridge< TFuncType >::Type()
    {
        return TypeType();
Changes to bs/builtins/types/template/tfunctype.h.
50
51
52
53
54
55
56







57
58
59
60
61
62
63
    // Helper to provide generic param patterns for template functions.
    struct TFuncPattern
    {
        static const Term& GetPattern();
    };

    extern const Term& TFuncTypePattern();







}

namespace goose::eir
{
    template<>
    struct Bridge< builtins::TFuncType >
    {







>
>
>
>
>
>
>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    // Helper to provide generic param patterns for template functions.
    struct TFuncPattern
    {
        static const Term& GetPattern();
    };

    extern const Term& TFuncTypePattern();

    static inline Term TFuncTypeSigPattern( const Term& type, Term&& sig )
    {
        return VEC( TSID( tfunctype_sig ), type, move( sig ) );
    }

    extern tuple< Term, Term > DecomposeTFTSig( const Term& tdsig );
}

namespace goose::eir
{
    template<>
    struct Bridge< builtins::TFuncType >
    {
Changes to bs/builtins/types/template/typecheck.cpp.
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
99
                co_yield { move( wrapped ), tcc };
            }
        } );

        // tfunc type param / tfunc arg
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ParamPat( TFuncTypePattern() ),

            ValueToEIR( ValuePattern(
                TSID( constant ),
                TFuncTypePattern(),
                ANYTERM( _ ) ) ),

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

            auto&& [sort, type, val, locId] = *ldecomp;

            auto callPat = BuildArgPatternFromTFuncType( tcc.context(), *EIRToValue( type ) );
            assert( callPat );

            auto rhsVal = *EIRToValue( rhs );
            auto tf = *FromValue< TFunc >( rhsVal );

            // Create a new named hole namespace to isolate holes from the passed function from those in
            // the called function.







|




















>
|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
                co_yield { move( wrapped ), tcc };
            }
        } );

        // tfunc type param / tfunc arg
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ParamPat( TFuncTypeSigPattern( ANYTERM( _ ), ANYTERM( _ ) ) ),

            ValueToEIR( ValuePattern(
                TSID( constant ),
                TFuncTypePattern(),
                ANYTERM( _ ) ) ),

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

            auto&& [sort, type, val, locId] = *ldecomp;
            auto [tfType,_] = DecomposeTFTSig( type );
            auto callPat = BuildArgPatternFromTFuncType( tcc.context(), *EIRToValue( tfType ) );
            assert( callPat );

            auto rhsVal = *EIRToValue( rhs );
            auto tf = *FromValue< TFunc >( rhsVal );

            // Create a new named hole namespace to isolate holes from the passed function from those in
            // the called function.