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 ),
|