Goose  Check-in [ef1e94f44d]

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

Overview
Comment:Added a domain specifier in function and template function types.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ef1e94f44d82adabdea89ba1ac2d126e8cbd4a87c2d2dcb0a58c35b82bb673b9
User & Date: achavasse 2019-06-29 11:40:08.954
Context
2019-06-29
13:43
Build fixes to work with the latest git version of libc++. check-in: 326d403e6c user: achavasse tags: trunk
11:40
Added a domain specifier in function and template function types. check-in: ef1e94f44d user: achavasse tags: trunk
2019-06-27
19:37
sema: fixed a context creation mistake when resolving an invocation. check-in: 48ee263157 user: achavasse tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to bs/builtins/types/constrainedfunc/unify.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "builtins/builtins.h"

using namespace empathy;
using namespace empathy::ir;

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

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

        // func type param / constrainedfunc arg
        e.unificationRuleSet()->addAsymRule(

            ValueToIRExpr( ValuePattern( MkHole( "_"_sid ), move( funcTypePat ), MkHole( "_"_sid ) ) ),

            ValueToIRExpr( ValuePattern(










|


|







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

using namespace empathy;
using namespace empathy::ir;

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

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

        // func type param / constrainedfunc arg
        e.unificationRuleSet()->addAsymRule(

            ValueToIRExpr( ValuePattern( MkHole( "_"_sid ), move( funcTypePat ), MkHole( "_"_sid ) ) ),

            ValueToIRExpr( ValuePattern(
Changes to bs/builtins/types/func/bfunc.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
#include "builtins/builtins.h"

namespace empathy::builtins
{
    bool IsBuiltinFunc( const Value& func )
    {
        auto funcType = ValueFromIRExpr( func.type() );
        assert( funcType );

        auto decomp = Decompose( funcType->val(),
            Vec(
                Lit( "func"_sid ),
                Lit( "builtin"_sid ),

                SubTerm(),  // return type
                SubTerm()   // param types
            )
        );

        return !!decomp;
    }













>







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

namespace empathy::builtins
{
    bool IsBuiltinFunc( const Value& func )
    {
        auto funcType = ValueFromIRExpr( func.type() );
        assert( funcType );

        auto decomp = Decompose( funcType->val(),
            Vec(
                Lit( "func"_sid ),
                Lit( "builtin"_sid ),
                SubTerm(),  // domain
                SubTerm(),  // return type
                SubTerm()   // param types
            )
        );

        return !!decomp;
    }
Changes to bs/builtins/types/func/bfunc.inl.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
        return TVEC( ValueToIRExpr( ValuePattern( sema::MkHole( "_"_sid ), GetValueType< T >(), sema::MkHole( "_"_sid ) ) )... );
    }

    template< typename R, typename... T >
    const Term& Bridge< R ( T... ) >::Type()
    {
        static auto type = ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ), TSID( builtin ),
            GetValueType< R >(),
            sema::Quote( BuildBuiltinFuncParamTypeList< T... >() )
        ) ) );
        return type;
    }

    template< typename R, typename... T >
    template< typename F >







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
        return TVEC( ValueToIRExpr( ValuePattern( sema::MkHole( "_"_sid ), GetValueType< T >(), sema::MkHole( "_"_sid ) ) )... );
    }

    template< typename R, typename... T >
    const Term& Bridge< R ( T... ) >::Type()
    {
        static auto type = ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ), TSID( builtin ),
            sema::DomainCompileTime(), GetValueType< R >(),
            sema::Quote( BuildBuiltinFuncParamTypeList< T... >() )
        ) ) );
        return type;
    }

    template< typename R, typename... T >
    template< typename F >
Changes to bs/builtins/types/func/build.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
#include "builtins/builtins.h"

namespace empathy::builtins
{
    FuncType BuildFuncType( const Value& returnType, const Value& params )
    {
        immer::vector< Term > tv;
        auto tvt = tv.transient();

        ForEachInTuple( params, [&]( auto&& param )
        {
            if( IsDecl( param ) )
            {
                auto decl = *FromValue< Decl >( param );
                tvt.push_back( ValueToIRExpr( ValuePattern( MkHole( "_"_sid ), move( decl.type() ), MkHole( "_"_sid ) ) ) );
            }
            else if( param.isConstant() )
                tvt.push_back( ValueToIRExpr( param ) );

            return true;
        } );

        return FuncType( ValueToIRExpr( returnType ),
            TERM( make_shared< Vector >( tvt.persistent(), false ) ) );
    }

    Value BuildFunc( const Context& c, const Term& funcIdentity, const Value& returnType, const Value& params, const pvec& unparsedBody, Context& out_bodyContext )
    {
        auto funcType = BuildFuncType( returnType, params );
        return BuildFunc( c, funcType, funcIdentity, returnType, params, unparsedBody, out_bodyContext );
    }

    Value BuildFunc( const Context& c, const FuncType& funcType, const Term& funcIdentity, const Value& returnType, const Value& params, const pvec& unparsedBody, Context& out_bodyContext )
    {
        // TODO: instead of a normal import rule, we should use a custom visibility
        // rule that deals with variables from the parent context in a special way:




|

















|



|

|







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
#include "builtins/builtins.h"

namespace empathy::builtins
{
    FuncType BuildFuncType( const Term& domain, const Value& returnType, const Value& params )
    {
        immer::vector< Term > tv;
        auto tvt = tv.transient();

        ForEachInTuple( params, [&]( auto&& param )
        {
            if( IsDecl( param ) )
            {
                auto decl = *FromValue< Decl >( param );
                tvt.push_back( ValueToIRExpr( ValuePattern( MkHole( "_"_sid ), move( decl.type() ), MkHole( "_"_sid ) ) ) );
            }
            else if( param.isConstant() )
                tvt.push_back( ValueToIRExpr( param ) );

            return true;
        } );

        return FuncType( domain, ValueToIRExpr( returnType ),
            TERM( make_shared< Vector >( tvt.persistent(), false ) ) );
    }

    Value BuildFunc( const Context& c, const Term& funcIdentity, const Term& domain, const Value& returnType, const Value& params, const pvec& unparsedBody, Context& out_bodyContext )
    {
        auto funcType = BuildFuncType( domain, returnType, params );
        return BuildFunc( c, funcType, funcIdentity, returnType, params, unparsedBody, out_bodyContext );
    }

    Value BuildFunc( const Context& c, const FuncType& funcType, const Term& funcIdentity, const Value& returnType, const Value& params, const pvec& unparsedBody, Context& out_bodyContext )
    {
        // TODO: instead of a normal import rule, we should use a custom visibility
        // rule that deals with variables from the parent context in a special way:
Changes to bs/builtins/types/func/build.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef EMPATHY_BUILTINS_FUNC_BUILD_H
#define EMPATHY_BUILTINS_FUNC_BUILD_H

namespace empathy::builtins
{
    extern FuncType BuildFuncType( const Value& returnType, const Value& params );

    extern Value BuildFunc( const Context& c, const Term& funcIdentity, const Value& returnType, const Value& params, const pvec& unparsedBody, Context& out_bodyContext );
    extern Value BuildFunc( const Context& c, const FuncType& funcType, const Term& funcIdentity, const Value& returnType, const Value& params, const pvec& unparsedBody,
        Context& out_bodyContext );

    extern Term BuildCallPatternFromFuncType( const Value& funcType );
}

#endif





|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef EMPATHY_BUILTINS_FUNC_BUILD_H
#define EMPATHY_BUILTINS_FUNC_BUILD_H

namespace empathy::builtins
{
    extern FuncType BuildFuncType( const Term& domain, const Value& returnType, const Value& params );

    extern Value BuildFunc( const Context& c, const Term& funcIdentity, const Term& domain, const Value& returnType, const Value& params, const pvec& unparsedBody, Context& out_bodyContext );
    extern Value BuildFunc( const Context& c, const FuncType& funcType, const Term& funcIdentity, const Value& returnType, const Value& params, const pvec& unparsedBody,
        Context& out_bodyContext );

    extern Term BuildCallPatternFromFuncType( const Value& funcType );
}

#endif
Changes to bs/builtins/types/func/func.cpp.
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
        auto funcType = ValueFromIRExpr( func.type() );
        assert( funcType );

        auto typeDecomp = Decompose( funcType->val(),
            Vec(
                Lit( "func"_sid ),
                SubTerm(),  // kind

                SubTerm(),  // return type
                SubTerm()   // param types
            )
        );
        assert( typeDecomp );
        auto&& [kind, rtype, ptypes] = *typeDecomp;

        return TVEC( *Unquote( ptypes ), rtype );
    }

    Term GetFuncRType( const Value& func )
    {
        auto funcType = ValueFromIRExpr( func.type() );
        assert( funcType );

        auto typeDecomp = Decompose( funcType->val(),
            Vec(
                Lit( "func"_sid ),
                SubTerm(),  // kind

                SubTerm(),  // return type
                SubTerm()   // param types
            )
        );
        assert( typeDecomp );
        auto&& [kind, rtype, ptypes] = *typeDecomp;

        return rtype;
    }

    ptr< llr::Func > GetFuncLLR( const Value& f )
    {
        if( !f.isConstant() )







>





|













>





|







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
        auto funcType = ValueFromIRExpr( func.type() );
        assert( funcType );

        auto typeDecomp = Decompose( funcType->val(),
            Vec(
                Lit( "func"_sid ),
                SubTerm(),  // kind
                SubTerm(),  // domain
                SubTerm(),  // return type
                SubTerm()   // param types
            )
        );
        assert( typeDecomp );
        auto&& [kind, domain, rtype, ptypes] = *typeDecomp;

        return TVEC( *Unquote( ptypes ), rtype );
    }

    Term GetFuncRType( const Value& func )
    {
        auto funcType = ValueFromIRExpr( func.type() );
        assert( funcType );

        auto typeDecomp = Decompose( funcType->val(),
            Vec(
                Lit( "func"_sid ),
                SubTerm(),  // kind
                SubTerm(),  // domain
                SubTerm(),  // return type
                SubTerm()   // param types
            )
        );
        assert( typeDecomp );
        auto&& [kind, domain, rtype, ptypes] = *typeDecomp;

        return rtype;
    }

    ptr< llr::Func > GetFuncLLR( const Value& f )
    {
        if( !f.isConstant() )
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
    {
        return TypeType();
    }

    Value Bridge< FuncType >::ToValue( const FuncType& ft )
    {
        return Value( Type(), TVEC( TSID( func ), TSID( regular ),
            ft.returnType(), Quote( ft.params() ) ) );
    }

    optional< FuncType > Bridge< FuncType >::FromValue( const Value& v )
    {
        auto result = Decompose( v.val(),
            Vec(
                Lit( "func"_sid ),
                Lit( "regular"_sid ),

                SubTerm(),  // return type
                SubTerm()  // param types
            )
        );

        if( !result )
            return nullopt;

        auto&& [rtype, params] = *result;
        return FuncType( rtype, *Unquote( params ) );
    }

    Term Bridge< Func >::Type( const builtins::Func& func )
    {
        return ValueToIRExpr( ::ToValue( func.type() ) );
    }








|








>








|
|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    {
        return TypeType();
    }

    Value Bridge< FuncType >::ToValue( const FuncType& ft )
    {
        return Value( Type(), TVEC( TSID( func ), TSID( regular ),
            ft.domain(), ft.returnType(), Quote( ft.params() ) ) );
    }

    optional< FuncType > Bridge< FuncType >::FromValue( const Value& v )
    {
        auto result = Decompose( v.val(),
            Vec(
                Lit( "func"_sid ),
                Lit( "regular"_sid ),
                SubTerm(),  // domain
                SubTerm(),  // return type
                SubTerm()  // param types
            )
        );

        if( !result )
            return nullopt;

        auto&& [domain, rtype, params] = *result;
        return FuncType( domain, rtype, *Unquote( params ) );
    }

    Term Bridge< Func >::Type( const builtins::Func& func )
    {
        return ValueToIRExpr( ::ToValue( func.type() ) );
    }

Changes to bs/builtins/types/func/func.h.
22
23
24
25
26
27
28
29
30

31
32
33
34

35
36
37
38

39
40
41
42
43
44
45

    template< typename F >
    void ForEachDeclInTuple( const Value& tup, F&& func );

    class FuncType
    {
        public:
            template< typename R, typename P >
            FuncType( R&& returnType, P&& params ) :

                m_returnType( forward< R >( returnType ) ),
                m_params( forward< P >( params ) )
            {}


            const auto& returnType() const { return m_returnType; }
            const auto& params() const { return m_params; }

        private:

            Term m_returnType;
            Term m_params;
    };

    class Func
    {
        public:







|
|
>




>




>







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

    template< typename F >
    void ForEachDeclInTuple( const Value& tup, F&& func );

    class FuncType
    {
        public:
            template< typename D, typename R, typename P >
            FuncType( D&& domain, R&& returnType, P&& params ) :
                m_domain( forward< D >( domain ) ),
                m_returnType( forward< R >( returnType ) ),
                m_params( forward< P >( params ) )
            {}

            const auto& domain() const { return m_domain; }
            const auto& returnType() const { return m_returnType; }
            const auto& params() const { return m_params; }

        private:
            Term m_domain;
            Term m_returnType;
            Term m_params;
    };

    class Func
    {
        public:
Changes to bs/builtins/types/func/invoke.cpp.
93
94
95
96
97
98
99
100
101
102
103
104
    };

    void SetupFunctionInvocationRule( Env& e )
    {
        e.invocationRuleSet()->addRule(
            ValueToIRExpr( ValuePattern( ANYTERM( _ ),
                ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ),
                ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) ),
                ANYTERM( _ ) ) ),
            make_shared< FunctionInvocationRule >() );
    }
}







|




93
94
95
96
97
98
99
100
101
102
103
104
    };

    void SetupFunctionInvocationRule( Env& e )
    {
        e.invocationRuleSet()->addRule(
            ValueToIRExpr( ValuePattern( ANYTERM( _ ),
                ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ),
                ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) ),
                ANYTERM( _ ) ) ),
            make_shared< FunctionInvocationRule >() );
    }
}
Changes to bs/builtins/types/func/unify.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "builtins/builtins.h"

using namespace empathy;
using namespace empathy::ir;

namespace empathy::builtins
{
    void SetupFunctionUnification( Env& e )
    {
        auto funcTypePat = ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

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

        e.unificationRuleSet()->addAsymRule(

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

            ValueToIRExpr( ValuePattern(
                TSID( constant ),










|


|







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

using namespace empathy;
using namespace empathy::ir;

namespace empathy::builtins
{
    void SetupFunctionUnification( Env& e )
    {
        auto funcTypePat = ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

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

        e.unificationRuleSet()->addAsymRule(

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

            ValueToIRExpr( ValuePattern(
                TSID( constant ),
Changes to bs/builtins/types/overloadset/unify.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "builtins/builtins.h"

using namespace empathy;
using namespace empathy::ir;

namespace empathy::builtins
{
    void SetupOverloadSetUnification( Env& e )
    {
        auto funcTypePat = ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

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

        // func type param / overloadset arg
        e.unificationRuleSet()->addAsymRule(

            ValueToIRExpr( ValuePattern( MkHole( "_"_sid ), move( funcTypePat ), MkHole( "_"_sid ) ) ),

            ValueToIRExpr( ValuePattern(










|


|







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

using namespace empathy;
using namespace empathy::ir;

namespace empathy::builtins
{
    void SetupOverloadSetUnification( Env& e )
    {
        auto funcTypePat = ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

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

        // func type param / overloadset arg
        e.unificationRuleSet()->addAsymRule(

            ValueToIRExpr( ValuePattern( MkHole( "_"_sid ), move( funcTypePat ), MkHole( "_"_sid ) ) ),

            ValueToIRExpr( ValuePattern(
Changes to bs/builtins/types/template/build.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
#include "builtins/builtins.h"

namespace empathy::builtins
{
    optional< TDecl > BuildTDecl( const Context& c, const Term& typeTExpr, const StringId& name )
    {
        auto typeSig = BuildTemplateSignature( c, typeTExpr );
        if( !typeSig )
            return nullopt;

        return TDecl( *typeSig, name );
    }

    TFuncType BuildTFuncType( const Value& returnType, const Value& params )
    {
        immer::vector< Term > v;
        auto vt = v.transient();

        ForEachInTuple( params, [&]( auto&& param )
        {
            vt.push_back( ValueToIRExpr( param ) );
            return true;
        } );

        return TFuncType( ValueToIRExpr( returnType ), TERM( make_shared< Vector >( vt.persistent(), false ) ) );
    }

    optional< Term > BuildTFuncSignature( const Context& c, const TFuncType& tft )
    {
        immer::vector< Term > v;
        auto vt = v.transient();














|










|







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
#include "builtins/builtins.h"

namespace empathy::builtins
{
    optional< TDecl > BuildTDecl( const Context& c, const Term& typeTExpr, const StringId& name )
    {
        auto typeSig = BuildTemplateSignature( c, typeTExpr );
        if( !typeSig )
            return nullopt;

        return TDecl( *typeSig, name );
    }

    TFuncType BuildTFuncType( const Term& domain, const Value& returnType, const Value& params )
    {
        immer::vector< Term > v;
        auto vt = v.transient();

        ForEachInTuple( params, [&]( auto&& param )
        {
            vt.push_back( ValueToIRExpr( param ) );
            return true;
        } );

        return TFuncType( domain, ValueToIRExpr( returnType ), TERM( make_shared< Vector >( vt.persistent(), false ) ) );
    }

    optional< Term > BuildTFuncSignature( const Context& c, const TFuncType& tft )
    {
        immer::vector< Term > v;
        auto vt = v.transient();

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
            return nullopt;
        }

        return TVEC( TERM( make_shared< Vector >( vt.persistent(), false ) ),
            *rtSig );
    }

    optional< Value > BuildTFunc( const Context& c, const Term& identity, const Value& returnType, const Value& params, pvec&& body )
    {
        auto funcType = BuildTFuncType( returnType, params );

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

        return ToValue( TFunc( move( funcType ), *sig, identity, move( body ) ) );
    }







|

|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
            return nullopt;
        }

        return TVEC( TERM( make_shared< Vector >( vt.persistent(), false ) ),
            *rtSig );
    }

    optional< Value > BuildTFunc( const Context& c, const Term& identity, const Term& domain, const Value& returnType, const Value& params, pvec&& body )
    {
        auto funcType = BuildTFuncType( domain, returnType, params );

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

        return ToValue( TFunc( move( funcType ), *sig, identity, move( body ) ) );
    }
Changes to bs/builtins/types/template/build.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef EMPATHY_BUILTINS_TEMPLATE_BUILD_H
#define EMPATHY_BUILTINS_TEMPLATE_BUILD_H

namespace empathy::builtins
{
    extern optional< TDecl > BuildTDecl( const Context& c, const Term& typeTExpr, const StringId& name );
    extern TFuncType BuildTFuncType( const Value& returnType, const Value& params );
    extern optional< Term > BuildTFuncSignature( const Context& c, const TFuncType& tft );
    extern optional< Value > BuildTFunc( const Context& c, const Term& identity, const Value& returnType, const Value& params, pvec&& body );

    extern optional< Term > BuildArgPatternFromTFuncType( const Context& c, const Value& tfuncType );
}

#endif






|

|





1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef EMPATHY_BUILTINS_TEMPLATE_BUILD_H
#define EMPATHY_BUILTINS_TEMPLATE_BUILD_H

namespace empathy::builtins
{
    extern optional< TDecl > BuildTDecl( const Context& c, const Term& typeTExpr, const StringId& name );
    extern TFuncType BuildTFuncType( const Term& domain, const Value& returnType, const Value& params );
    extern optional< Term > BuildTFuncSignature( const Context& c, const TFuncType& tft );
    extern optional< Value > BuildTFunc( const Context& c, const Term& identity, const Term& domain, const Value& returnType, const Value& params, pvec&& body );

    extern optional< Term > BuildArgPatternFromTFuncType( const Context& c, const Value& tfuncType );
}

#endif
Changes to bs/builtins/types/template/instantiate.cpp.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

                return true;
            } );
        assert( argsOk );

        // Build the instance function type and identity
        auto returnType = *ValueFromIRExpr( unifiedRType );
        auto instanceType = BuildFuncType( returnType, instanceParams );
        auto instanceTypeTerm = ValueToIRExpr( ToValue( instanceType ) );

        auto instanceIdentity = AppendToVectorTerm(
            InjectDomainIntoIdentity( tf->identity(), c.domain() ), instanceTypeTerm );

        // Look for an already existing instanced function
        optional< Value > instanceFunc;







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

                return true;
            } );
        assert( argsOk );

        // Build the instance function type and identity
        auto returnType = *ValueFromIRExpr( unifiedRType );
        auto instanceType = BuildFuncType( c.domain(), returnType, instanceParams );
        auto instanceTypeTerm = ValueToIRExpr( ToValue( instanceType ) );

        auto instanceIdentity = AppendToVectorTerm(
            InjectDomainIntoIdentity( tf->identity(), c.domain() ), instanceTypeTerm );

        // Look for an already existing instanced function
        optional< Value > instanceFunc;
Changes to bs/builtins/types/template/invoke.cpp.
107
108
109
110
111
112
113
114
115
116
117
118
    }

    void SetupTemplateFunctionInvocationRule( Env& e )
    {
        e.invocationRuleSet()->addRule(
            ValueToIRExpr( ValuePattern( TSID( constant ),
                ValueToIRExpr( Value( TypeType(), TVEC( TSID( texpr ), TSID( tfunc ),
                    ANYTERM( _ ), ANYTERM( _ ) ) ) ),
                ANYTERM( _ ) ) ),
            GetTFuncInvocationRule() );
    }
}







|




107
108
109
110
111
112
113
114
115
116
117
118
    }

    void SetupTemplateFunctionInvocationRule( Env& e )
    {
        e.invocationRuleSet()->addRule(
            ValueToIRExpr( ValuePattern( TSID( constant ),
                ValueToIRExpr( Value( TypeType(), TVEC( TSID( texpr ), TSID( tfunc ),
                    ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) ),
                ANYTERM( _ ) ) ),
            GetTFuncInvocationRule() );
    }
}
Changes to bs/builtins/types/template/tfunctype.cpp.
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
    {
        return TypeType();
    }

    Value Bridge< TFuncType >::ToValue( const TFuncType& tft )
    {
        return Value( Type(), TVEC( TSID( texpr ), TSID( tfunc ),
            tft.returnType(), tft.params() ) );
    }

    optional< TFuncType > Bridge< TFuncType >::FromValue( const Value& v )
    {
        auto result = Decompose( v.val(),
            Vec(
                Lit( "texpr"_sid ),
                Lit( "tfunc"_sid ),

                SubTerm(),  // return type
                SubTerm()  // param types
            )
        );

        if( !result )
            return nullopt;

        auto&& [rtype, params] = *result;
        return TFuncType( rtype, params );
    }
}







|








>








|
|


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
    {
        return TypeType();
    }

    Value Bridge< TFuncType >::ToValue( const TFuncType& tft )
    {
        return Value( Type(), TVEC( TSID( texpr ), TSID( tfunc ),
            tft.domain(), tft.returnType(), tft.params() ) );
    }

    optional< TFuncType > Bridge< TFuncType >::FromValue( const Value& v )
    {
        auto result = Decompose( v.val(),
            Vec(
                Lit( "texpr"_sid ),
                Lit( "tfunc"_sid ),
                SubTerm(),  // domain
                SubTerm(),  // return type
                SubTerm()  // param types
            )
        );

        if( !result )
            return nullopt;

        auto&& [domain, rtype, params] = *result;
        return TFuncType( domain, rtype, params );
    }
}
Changes to bs/builtins/types/template/tfunctype.h.
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
#ifndef EMPATHY_BUILTINS_TYPES_TEMPLATE_TFUNCTYPE_H
#define EMPATHY_BUILTINS_TYPES_TEMPLATE_TFUNCTYPE_H

namespace empathy::builtins
{
    class TFuncType
    {
        public:
            template< typename R, typename P >
            TFuncType( R&& returnType, P&& params ) :

                m_returnType( forward< R >( returnType ) ),
                m_params( forward< P >( params ) )
            {}


            const auto& returnType() const { return m_returnType; }
            const auto& params() const { return m_params; }

        private:

            Term m_returnType;
            Term m_params;
    };
}

namespace empathy::ir
{








|
|
>




>




>







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
#ifndef EMPATHY_BUILTINS_TYPES_TEMPLATE_TFUNCTYPE_H
#define EMPATHY_BUILTINS_TYPES_TEMPLATE_TFUNCTYPE_H

namespace empathy::builtins
{
    class TFuncType
    {
        public:
            template< typename D, typename R, typename P >
            TFuncType( D&& domain, R&& returnType, P&& params ) :
                m_domain( forward< D >( domain ) ),
                m_returnType( forward< R >( returnType ) ),
                m_params( forward< P >( params ) )
            {}

            const auto& domain() const { return m_domain; }
            const auto& returnType() const { return m_returnType; }
            const auto& params() const { return m_params; }

        private:
            Term m_domain;
            Term m_returnType;
            Term m_params;
    };
}

namespace empathy::ir
{
Changes to bs/builtins/types/template/uni-tdecl.cpp.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
            } );

        e.unificationRuleSet()->addSymRule( tDeclPat, ANYTERM( _ ), UnifyTDecl );
        e.unificationRuleSet()->addSymRule( tDeclPat, UnifyTDecl );

        // tfunc tdecl param / tfunc arg
        auto tFuncTypePat = ValueToIRExpr( Value( TypeType(), TVEC( TSID( texpr ), TSID( tfunc ),
            ANYTERM( _ ), ANYTERM( _ ) ) ) );

        auto tDeclTFuncPat = ValueToIRExpr( Value( GetValueType< TDecl >(), TVEC( tFuncTypePat, ANYTERM( _ ) ) ) );

        e.unificationRuleSet()->addAsymRule(

            tDeclTFuncPat,








|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
            } );

        e.unificationRuleSet()->addSymRule( tDeclPat, ANYTERM( _ ), UnifyTDecl );
        e.unificationRuleSet()->addSymRule( tDeclPat, UnifyTDecl );

        // tfunc tdecl param / tfunc arg
        auto tFuncTypePat = ValueToIRExpr( Value( TypeType(), TVEC( TSID( texpr ), TSID( tfunc ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

        auto tDeclTFuncPat = ValueToIRExpr( Value( GetValueType< TDecl >(), TVEC( tFuncTypePat, ANYTERM( _ ) ) ) );

        e.unificationRuleSet()->addAsymRule(

            tDeclTFuncPat,

Changes to bs/builtins/types/template/unify.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "builtins/builtins.h"

using namespace empathy;
using namespace empathy::ir;

namespace empathy::builtins
{
    void SetupTemplateFunctionUnification( Env& e )
    {
        auto funcTypePat = ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

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

        // func type param / tfunc arg
        e.unificationRuleSet()->addAsymRule(

            ValueToIRExpr( ValuePattern( MkHole( "_"_sid ), move( funcTypePat ), MkHole( "_"_sid ) ) ),

            ValueToIRExpr( ValuePattern(










|


|







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

using namespace empathy;
using namespace empathy::ir;

namespace empathy::builtins
{
    void SetupTemplateFunctionUnification( Env& e )
    {
        auto funcTypePat = ValueToIRExpr( Value( TypeType(), TVEC( TSID( func ),
            ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ), ANYTERM( _ ) ) ) );

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

        // func type param / tfunc arg
        e.unificationRuleSet()->addAsymRule(

            ValueToIRExpr( ValuePattern( MkHole( "_"_sid ), move( funcTypePat ), MkHole( "_"_sid ) ) ),

            ValueToIRExpr( ValuePattern(
Changes to bs/parse/func.cpp.
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
            break;
    }

    // Check if a brace block follows, in which case this is a function declaration. Otherwise, it's just a function type.
    auto next = m_resolver->lookAheadUnresolved();
    if( !next )
    {

        pushValue( ToValue( BuildFuncType( returnType, params ) ) );
        return true;
    }

    auto decomp = Decompose( *next, Val< Delimiter >() );
    if( !decomp || *decomp != Delimiter::OpenBrace )
    {

        pushValue( ToValue( BuildFuncType( returnType, params ) ) );
        return true;
    }

    return parseFunctionDeclExpr( returnType, params );
}

bool Parser::parseFunctionDeclExpr( const Value& returnType, const Value& params )
{
    auto pBody = getFuncBody();
    if( !pBody )
        return false;

    const auto& c = m_resolver->context();
    auto identity = AppendToVectorTerm( c.identity(), TERM( StringId( m_resolver->context().env()->GetUniqueId() ) ) );

    auto bodyContext = m_resolver->context();

    auto func = BuildFunc( m_resolver->context(),
        identity, returnType, params, move( pBody ), bodyContext );

    if( !CompileFunc( c, func ) )
        return false;

    pushValue( move( func ) );
    return true;
}







>
|






>
|
















>

|







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
            break;
    }

    // Check if a brace block follows, in which case this is a function declaration. Otherwise, it's just a function type.
    auto next = m_resolver->lookAheadUnresolved();
    if( !next )
    {
        // TODO syntax for domain specifier
        pushValue( ToValue( BuildFuncType( DomainCompileTime(), returnType, params ) ) );
        return true;
    }

    auto decomp = Decompose( *next, Val< Delimiter >() );
    if( !decomp || *decomp != Delimiter::OpenBrace )
    {
        // TODO syntax for domain specifier
        pushValue( ToValue( BuildFuncType( DomainCompileTime(), returnType, params ) ) );
        return true;
    }

    return parseFunctionDeclExpr( returnType, params );
}

bool Parser::parseFunctionDeclExpr( const Value& returnType, const Value& params )
{
    auto pBody = getFuncBody();
    if( !pBody )
        return false;

    const auto& c = m_resolver->context();
    auto identity = AppendToVectorTerm( c.identity(), TERM( StringId( m_resolver->context().env()->GetUniqueId() ) ) );

    auto bodyContext = m_resolver->context();
    // TODO syntax for domain specifier
    auto func = BuildFunc( m_resolver->context(),
        identity, DomainCompileTime(), returnType, params, move( pBody ), bodyContext );

    if( !CompileFunc( c, func ) )
        return false;

    pushValue( move( func ) );
    return true;
}
107
108
109
110
111
112
113


114
115
116
117
118
119
120
121
    auto pBody = getFuncBody();
    if( !pBody )
        return nullopt;

    auto& c = m_resolver->context();

    auto bodyContext = c;


    return BuildFunc( c, identity, returnType, params, move( pBody ), bodyContext );
}

pvec Parser::getFuncBody()
{
    auto next = m_resolver->lookAheadUnresolved();
    if( !next )
    {







>
>
|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    auto pBody = getFuncBody();
    if( !pBody )
        return nullopt;

    auto& c = m_resolver->context();

    auto bodyContext = c;

    // TODO syntax for domain specifier
    return BuildFunc( c, identity, DomainCompileTime(), returnType, params, move( pBody ), bodyContext );
}

pvec Parser::getFuncBody()
{
    auto next = m_resolver->lookAheadUnresolved();
    if( !next )
    {
Changes to bs/parse/tfunc.cpp.
15
16
17
18
19
20
21

22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
        return false;
    }

    // Check if a brace block follows, in which case this is a function declaration. Otherwise, it's just a function type.
    auto next = m_resolver->lookAheadUnresolved();
    if( !next )
    {

        pushValue( ToValue( BuildTFuncType( returnType, params ) ) );
        return true;
    }

    auto decomp = Decompose( *next, Val< Delimiter >() );
    if( !decomp || *decomp != Delimiter::OpenBrace )
    {

        pushValue( ToValue( BuildTFuncType( returnType, params ) ) );
        return true;
    }

    const auto& c = m_resolver->context();
    auto tfuncIdentity = AppendToVectorTerm( c.identity(),
        TERM( StringId( m_resolver->context().env()->GetUniqueId() ) ) );








>
|






>
|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
        return false;
    }

    // Check if a brace block follows, in which case this is a function declaration. Otherwise, it's just a function type.
    auto next = m_resolver->lookAheadUnresolved();
    if( !next )
    {
        // TODO syntax for domain specifier
        pushValue( ToValue( BuildTFuncType( DomainCompileTime(), returnType, params ) ) );
        return true;
    }

    auto decomp = Decompose( *next, Val< Delimiter >() );
    if( !decomp || *decomp != Delimiter::OpenBrace )
    {
        // TODO syntax for domain specifier
        pushValue( ToValue( BuildTFuncType( DomainCompileTime(), returnType, params ) ) );
        return true;
    }

    const auto& c = m_resolver->context();
    auto tfuncIdentity = AppendToVectorTerm( c.identity(),
        TERM( StringId( m_resolver->context().env()->GetUniqueId() ) ) );

75
76
77
78
79
80
81


82
83
optional< Value > Parser::parseTemplateFunction( const Term& identity, const Value& returnType, const Value& params )
{
    auto pBody = getFuncBody();
    if( !pBody )
        return nullopt;

    auto& c = m_resolver->context();


    return BuildTFunc( c, identity, returnType, params, move( pBody ) );
}







>
>
|

77
78
79
80
81
82
83
84
85
86
87
optional< Value > Parser::parseTemplateFunction( const Term& identity, const Value& returnType, const Value& params )
{
    auto pBody = getFuncBody();
    if( !pBody )
        return nullopt;

    auto& c = m_resolver->context();

    // TODO syntax for domain specifier
    return BuildTFunc( c, identity, DomainCompileTime(), returnType, params, move( pBody ) );
}