Goose  Diff

Differences From Artifact [7f3d6955a7]:

  • File bs/builtins/operators/logic.cpp — part of check-in [2bee844d3c] at 2019-08-05 17:46:41 on branch trunk — Implemented a wrapper around llvm::APSInt for compile time integers to manage mixing operations on integers of different bitsizes, and to automatically extend them as needed. (user: achavasse size: 5763)

To Artifact [dbe43380ce]:

  • File bs/builtins/operators/logic.cpp — part of check-in [c7acd1eba0] at 2019-08-05 20:07:39 on branch trunk — Implemented the bitwise not, bitwise and and bitwise or operators. (user: achavasse size: 7769)

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();