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"
#include "precedence.h"
#include "helpers.h"
using namespace empathy;
using namespace empathy::ir;
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 Value( GetValueType< bool >(),
make_shared< llr::Instruction >( llr::Xor( operand, ToValue( true ) ) ) );
} )
);
}
}
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
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
|
#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 ) ) );
} )
);
CreateLeftAssInfixOp( e, "|"_sid, "operator_logical_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->createBB();
auto pRhsBB = cfg->createBB();
auto pEndBB = cfg->createBB();
// If the lhs is true, skip to the end directly.
// Otherwise, jump to the BB that computes rhs.
pLhsBB->setTerminator( CondBranch( lhs, pEndBB, pRhsBB ) );
auto rhsIndex = cfg->getNewTemporaryIndex();
pRhsBB->emplace_back( CreateTemporary( rhsIndex, rhs ) );
pRhsBB->setTerminator( Branch( pEndBB ) );
auto resultIndex = cfg->getNewTemporaryIndex();
// Build the Phi instruction that will collect the final result.
auto phi = Phi( *ValueFromIRExpr( GetValueType< bool >() ),
2, resultIndex );
// If coming directly from the lhs BB, we know the result is true.
phi.setIncoming( pLhsBB, ToValue( true ) );
// Otherwise, the result is whatever was computed by the rhs block.
phi.setIncoming( pRhsBB, BuildComputedValue( GetValueType< bool >(),
GetTemporary( rhsIndex ) ) );
pEndBB->emplace_back( move( phi ) );
// Build the result val which pulls the temporary created by the
// cfg above.
auto resultVal = BuildComputedValue( GetValueType< bool >(),
GetTemporary( resultIndex ) );
// Pachage all that in a ComplexValue, the parser will unpack
// it down the line and inline or execute our little cfg.
return ToValue(
ComplexValue( move( resultVal ), move( cfg ) ) );
} )
);
}
}
|