Goose  Diff

Differences From Artifact [8a5e0f6050]:

  • File bs/sema/inv-func.cpp — part of check-in [8c0bcfa896] at 2019-01-28 23:31:50 on branch trunk — Sema: implement getsignature for function types. (user: achavasse size: 1563)

To Artifact [0967180c36]:

  • File bs/sema/inv-func.cpp — part of check-in [0be0ac2e29] at 2019-01-29 20:16:02 on branch trunk — Function invocation: unify the arguments and create the llr call. (user: achavasse size: 3069)

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

namespace empathy::sema
{
    class FunctionInvocationRule : public InvocationRule
    {
        public:
            virtual optional< Value > resolveInvocation( const ptr< Env >& env, const Value& callee, const Value& args ) const override
            {

                // Just a placeholder for now





                cout << "func invocation\n";









                cout << getSignature( env, callee ) << endl;










                return nullopt;
            }














            virtual Term getSignature( const ptr< Env >& env, const Value& callee ) const override
            {






                // Extract the signature from the type
                auto valType = ValueFromIRExpr( callee.type() );
                assert( valType );

               auto decomp = Decompose( valType->val(),
                    Vec(
                        Lit( "func"_sid ),
                        SubTerm(),  // kind
                        SubTerm(),  // return type
                        SubTerm(),  // param types
                        SubTerm()   // signature
                    )
                );

                assert( decomp );
                auto&& [kind, rtype, ptypes, sig] = *decomp;

                return sig;
            }
    };

    void SetupFunctionInvocationRule( InvocationRuleSet& ruleSet )
    {
        ruleSet.addRule(
            ValueToIRExpr( Value( TSID( type ), TVEC( TSID( func ),









>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
|

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


>
>
>
>
>
>




|











<
|







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

namespace empathy::sema
{
    class FunctionInvocationRule : public InvocationRule
    {
        public:
            virtual optional< Value > resolveInvocation( const ptr< Env >& env, const Value& callee, const Value& args ) const override
            {
                UnificationContext uc( env );

                optional< UnificationContext > bestUC;
                optional< Term > bestSol;
                bool ambiguous = false;
                auto&& [sig, rtype] = getSignatureAndRType( env, callee );
                auto argsIr = ValueToIRExpr( args );

                for( auto&& [s, uc] : Unify( sig, argsIr, uc ) )
                {
                    if( !bestSol || uc.score() > bestUC->score() )
                    {
                        bestUC = uc;
                        bestSol = s;
                        ambiguous = false;
                        continue;
                    }

                    if( uc.score() < bestUC->score() )
                        continue;

                    ambiguous = true;
                }

                if( ambiguous )
                {
                    // TODO error mgmt
                    cout << "ambiguous function call.\n";
                    return nullopt;
                }

                if( !bestSol )
                {
                    // TODO error mgmt
                    cout << "function arguments mismatch.\n";
                    return nullopt;
                }

                auto unifiedArgs = ValueFromIRExpr( Substitute( *bestSol, *bestUC ) );

                // TODO: reduce the value
                return Value( rtype, static_pointer_cast< void >( make_shared< llr::Call >( callee, *unifiedArgs ) ) );
            }

            virtual Term getSignature( const ptr< Env >& env, const Value& callee ) const override
            {
                return getSignatureAndRType( env, callee ).first;
            }

        private:
            pair< Term, Term > getSignatureAndRType( const ptr< Env >& env, const Value& callee ) const
            {
                // Extract the signature from the type
                auto valType = ValueFromIRExpr( callee.type() );
                assert( valType );

                auto decomp = Decompose( valType->val(),
                    Vec(
                        Lit( "func"_sid ),
                        SubTerm(),  // kind
                        SubTerm(),  // return type
                        SubTerm(),  // param types
                        SubTerm()   // signature
                    )
                );

                assert( decomp );
                auto&& [kind, rtype, ptypes, sig] = *decomp;

                return { sig, rtype };
            }
    };

    void SetupFunctionInvocationRule( InvocationRuleSet& ruleSet )
    {
        ruleSet.addRule(
            ValueToIRExpr( Value( TSID( type ), TVEC( TSID( func ),