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
|
#include "builtins/builtins.h"
#include "precedence.h"
#include "helpers.h"
using namespace empathy;
using namespace empathy::ir;
using namespace empathy::llr;
using namespace empathy::parse;
namespace empathy::builtins
{
void SetupLogicOps( Env& e )
{
CreatePrefixOp( e, "!"_sid, "operator_not"_sid, precedence::UnaryOps,
ForType< bool >( []( auto&& operand ) -> Value
{
return BuildComputedValue( GetValueType< bool >(),
Xor( operand, ToValue( true ) ) );
} )
);
CreateLeftAssInfixOp( e, "^"_sid, "operator_xor"_sid, precedence::OrOp,
// Logical xor
ForType< bool >( []( auto&& lhs, auto&& rhs ) -> Value
{
return BuildComputedValue( GetValueType< bool >(),
Xor( lhs, rhs ) );
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
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 "builtins/builtins.h"
#include "precedence.h"
#include "helpers.h"
using namespace empathy;
using namespace empathy::ir;
using namespace empathy::llr;
using namespace empathy::parse;
namespace empathy::builtins
{
void SetupLogicOps( Env& e )
{
CreatePrefixOp( e, "!"_sid, "operator_logical_not"_sid, precedence::UnaryOps,
ForType< bool >( []( auto&& operand ) -> Value
{
return BuildComputedValue( GetValueType< bool >(),
Xor( operand, ToValue( true ) ) );
} )
);
CreatePrefixOp( e, "~"_sid, "operator_bitwise_not"_sid, precedence::UnaryOps,
ForType< CustomPattern< RTInteger, RTInteger::Pattern > >( []( auto&& operand ) -> Value
{
auto opTypeVal = *ValueFromIRExpr( operand.type() );
auto opType = *FromValue< RTInteger >( opTypeVal );
return BuildComputedValue( operand.type(),
Xor( operand,
BuildComputedValue( operand.type(),
LoadConstInt( static_cast< llvm::IntegerType* >( GetLLVMType( opTypeVal ) ),
APSInt::getMaxValue( opType.m_numBits, true) )
)
) );
} )
);
CreateLeftAssInfixOp( e, "^"_sid, "operator_xor"_sid, precedence::OrOp,
// Logical xor
ForType< bool >( []( auto&& lhs, auto&& rhs ) -> Value
{
return BuildComputedValue( GetValueType< bool >(),
Xor( lhs, rhs ) );
|
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
{
return BuildComputedValue( lhs.type(),
Xor( lhs, rhs ) );
} )
);
CreateLeftAssInfixOp( e, "|"_sid, "operator_or"_sid, precedence::OrOp,
ForType< bool >( []( auto&& lhs, auto&& rhs ) -> Value
{
// Build a CFG that implements the control flow for
// shortcut evaluation.
auto cfg = make_shared< CFG >();
auto pLhsBB = cfg->entryBB();
auto pRhsBB = cfg->createBB();
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
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
|
{
return BuildComputedValue( lhs.type(),
Xor( lhs, rhs ) );
} )
);
CreateLeftAssInfixOp( e, "|"_sid, "operator_or"_sid, precedence::OrOp,
// ct_int or
ForType< BigInt >( []( auto&& lhs, auto&& rhs ) -> Value
{
return BuildComputedValue( GetValueType< BigInt >(),
Or( lhs, rhs ) );
} ),
// runtime integer or, defined to work for any two integers of same
// bit size and signedness.
ForType< CustomPattern< RTInteger, RTInteger::Pattern > >(
[]( auto&& lhs, auto&& rhs ) -> Value
{
return BuildComputedValue( lhs.type(),
Or( lhs, rhs ) );
} ),
// bool or
ForType< bool >( []( auto&& lhs, auto&& rhs ) -> Value
{
// Build a CFG that implements the control flow for
// shortcut evaluation.
auto cfg = make_shared< CFG >();
auto pLhsBB = cfg->entryBB();
auto pRhsBB = cfg->createBB();
|
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
// Pachage our cfg in a value with an inline CFG instruction.
return BuildComputedValue( GetValueType< bool >(), move( cfg ) );
} )
);
CreateLeftAssInfixOp( e, "&"_sid, "operator_and"_sid, precedence::AndOp,
ForType< bool >( []( auto&& lhs, auto&& rhs ) -> Value
{
// Build a CFG that implements the control flow for
// shortcut evaluation.
auto cfg = make_shared< CFG >();
auto pLhsBB = cfg->entryBB();
auto pRhsBB = cfg->createBB();
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
// Pachage our cfg in a value with an inline CFG instruction.
return BuildComputedValue( GetValueType< bool >(), move( cfg ) );
} )
);
CreateLeftAssInfixOp( e, "&"_sid, "operator_and"_sid, precedence::AndOp,
// ct_int and
ForType< BigInt >( []( auto&& lhs, auto&& rhs ) -> Value
{
return BuildComputedValue( GetValueType< BigInt >(),
And( lhs, rhs ) );
} ),
// runtime integer and, defined to work for any two integers of same
// bit size and signedness.
ForType< CustomPattern< RTInteger, RTInteger::Pattern > >(
[]( auto&& lhs, auto&& rhs ) -> Value
{
return BuildComputedValue( lhs.type(),
And( lhs, rhs ) );
} ),
// bool or
ForType< bool >( []( auto&& lhs, auto&& rhs ) -> Value
{
// Build a CFG that implements the control flow for
// shortcut evaluation.
auto cfg = make_shared< CFG >();
auto pLhsBB = cfg->entryBB();
auto pRhsBB = cfg->createBB();
|