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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
+
+
-
-
+
+
+
-
+
-
-
+
-
+
|
template< typename... R >
void BuildParseRule( sema::Env& env, StringId name, R&&... ruleBuilders )
{
parse::BuildParseRule( env, name, AppendToVectorTerm( RootG0Identity(), TERM( name ) ),
forward< R >( ruleBuilders )... );
}
struct UnaryOpTag {};
struct BinaryOpTag {};
template< typename... R >
auto PrefixOp( StringId funcName, uint32_t precedence, R&&... rules )
struct UnaryOpTag
{
};
struct BinaryOpTag
{
};
template< typename... R > auto PrefixOp( StringId funcName, uint32_t precedence, R&&... rules )
{
return [&,precedence,funcName]( auto&& e, auto&& r, auto&& name )
return [&, precedence, funcName]( auto&& e, auto&& r, auto&& name )
{
MakePrefixOp( e, r, name, precedence,
BuildOpFunc< UnaryOpTag >( e, funcName, forward< R >( rules )... ) );
};
}
template< typename... R >
auto PostfixOp( StringId funcName, uint32_t precedence, R&&... rules )
template< typename... R > auto PostfixOp( StringId funcName, uint32_t precedence, R&&... rules )
{
return [&,precedence,funcName]( auto&& e, auto&& r, auto&& name )
return [&, precedence, funcName]( auto&& e, auto&& r, auto&& name )
{
MakePostfixOp( e, r, name, precedence,
BuildOpFunc< UnaryOpTag >( e, funcName, forward< R >( rules )... ) );
};
}
template< typename... R >
auto LeftAssInfixOp( StringId funcName, uint32_t precedence, R&&... rules )
{
return [&,precedence,funcName]( auto&& e, auto&& r, auto&& name )
return [&, precedence, funcName]( auto&& e, auto&& r, auto&& name )
{
MakeLeftAssInfixOp( e, r, name, precedence,
BuildOpFunc< BinaryOpTag >( e, funcName, forward< R >( rules )... ) );
};
}
template< typename... R >
auto RightAssInfixOp( StringId funcName, uint32_t precedence, R&&... rules )
{
return [&,precedence,funcName]( auto&& e, auto&& r, auto&& name )
return [&, precedence, funcName]( auto&& e, auto&& r, auto&& name )
{
MakeRightAssInfixOp( e, r, name, precedence,
BuildOpFunc< BinaryOpTag >( e, funcName, forward< R >( rules )... ) );
};
}
template< typename tag, typename... R >
auto BuildOpFunc( Env& e, StringId funcName, R&&... ruleBuilders )
{
auto pOvlSet = GetOrCreateOverloadSet( e, funcName );
( ( ruleBuilders( e, pOvlSet, tag() ) ), ... );
return [pOvlSet, funcName]< typename... O >( Parser& p, O&&... operands )
{
DiagnosticsContext dc( 0, format( "When invoking {}.", funcName.str() ) );
return InvokeOverloadSet( p.context(), pOvlSet, MakeClosedTuple( forward< O >( operands )... ),
p.context().locationId() );
return InvokeOverloadSet( p.context(), pOvlSet,
MakeClosedTuple( forward< O >( operands )... ), p.context().locationId() );
};
}
template< typename T, typename I, typename RT = T >
template< typename T, typename I, typename RT = T > auto ForType( CURRENT_LOC )
auto ForType( CURRENT_LOC )
{
return [sloc]< typename tag >( auto&& e, auto&& pOvlSet, tag t )
{
using intrinsicType = Intrinsic< Value ( T, T ) >;
using intrinsicType = Intrinsic< Value( T, T ) >;
auto intrinsicFunc = []( const Context& c, const Value& lhs, const Value& rhs )
{
return BuildComputedValue( GetValueType< RT >(), lhs, rhs, I( ( c.locationId() ) ) );
{ return BuildComputedValue( GetValueType< RT >(), lhs, rhs, I( c.locationId() ) ); };
};
auto loc = Location::Create( sloc );
pOvlSet->add( e, ToValue< intrinsicType >( move( intrinsicFunc ) ).setLocationId( loc ),
GetBuiltinIntrinsicFuncInvocationRule() );
};
}
template< typename T, typename F >
template< typename T, typename F > auto ForType( F&& func, CURRENT_LOC )
auto ForType( F&& func, CURRENT_LOC )
{
return [&,sloc]< typename tag >( auto&& e, auto&& pOvlSet, tag t )
return [&, sloc]< typename tag >( auto&& e, auto&& pOvlSet, tag t )
{
auto loc = Location::Create( sloc );
if constexpr( is_same_v< tag, UnaryOpTag > )
{
using intrinsicType = Intrinsic< Value ( T ) >;
pOvlSet->add( e, ToValue< intrinsicType >( forward< F >( func ) ).setLocationId( loc ),
using intrinsicType = Intrinsic< Value( T ) >;
pOvlSet->add( e,
ToValue< intrinsicType >( forward< F >( func ) ).setLocationId( loc ),
GetBuiltinIntrinsicFuncInvocationRule() );
}
else
{
using intrinsicType = Intrinsic< Value ( T, T ) >;
pOvlSet->add( e, ToValue< intrinsicType >( forward< F >( func ) ).setLocationId( loc ),
using intrinsicType = Intrinsic< Value( T, T ) >;
pOvlSet->add( e,
ToValue< intrinsicType >( forward< F >( func ) ).setLocationId( loc ),
GetBuiltinIntrinsicFuncInvocationRule() );
}
};
}
template< typename T1, typename T2, typename F >
template< typename T1, typename T2, typename F > auto ForTypes( F&& func, CURRENT_LOC )
auto ForTypes( F&& func, CURRENT_LOC )
{
return [=]< typename tag >( auto&& e, auto&& pOvlSet, tag t )
{
using intrinsicType = Intrinsic< Value ( T1, T2 ) >;
using intrinsicType = Intrinsic< Value( T1, T2 ) >;
auto loc = Location::Create( sloc );
pOvlSet->add( e, ToValue< intrinsicType >( func ).setLocationId( loc ),
GetBuiltinIntrinsicFuncInvocationRule() );
};
}
}
} // namespace goose::builtins
#endif
|