Goose  Diff

Differences From Artifact [ce9cd387f8]:

  • File bs/builtins/types/runtime/unify.cpp — part of check-in [43e22af793] at 2019-08-05 02:45:01 on branch trunk —
    • Unification now works in two passes. The second pass gives unification rules a chance to match again after all the holes have been resolved and substituted.
    • Fixed many horrible bugs in various unification rules that managed to go by unnoticed until the above change, after which they made everything catch on fire.
    • Simplified the ct_int and ct_string unification rules to take advantage of the new unification behavior. Everything finally works as intended wrt to ct_int versus RT integers.
    • Removed unification callbacks. It was a system to provide a way to perform unification work post hole substitution, so it is now obsolete.
    (user: achavasse size: 6050)

To Artifact [3702afa4f1]:

  • File bs/builtins/types/runtime/unify.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: 5923)

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







-
+












-
+








        // ct_int type against a RTInteger type:
        // return the RTInteger type. We don't care if the
        // ct_int fits at this point, this will be dealt with by
        // the ct_int value unification rule below.
        e.unificationRuleSet()->addSymRule(
            ValueToIRExpr( rtIntTypePattern ),
            GetValueType< APSInt >(),
            GetValueType< BigInt >(),
        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            co_yield HalfUnify( lhs, c );
        } );

        // Reject the ct_int param and rtinteger arg pattern,
        // so that it doesn't fall into the rule above which wouls be incorrect
        // in that case.
        e.unificationRuleSet()->addAsymRule(

            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                GetValueType< APSInt >(),
                GetValueType< BigInt >(),
                ANYTERM( _ ) ) ),

            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                ValueToIRExpr( rtIntTypePattern ),
                ANYTERM( _ ) ) ),

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







-
+












-
+















-
+






-
-
+
-
-








            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                ValueToIRExpr( rtIntTypePattern ),
                ANYTERM( _ ) ) ),

            ValueToIRExpr( Value(
                GetValueType< APSInt >(),
                GetValueType< BigInt >(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            // Don't bother during the first pass, the rt integer type pattern
            // is likely to contain unresolved holes.
            if( !c.secondPass() )
            {
                co_yield { lhs, c };
                co_return;
            }

            auto ct = FromValue< APSInt >( *ValueFromIRExpr( rhs ) );
            auto ct = FromValue< BigInt >( *ValueFromIRExpr( rhs ) );
            if( !ct )
                co_return;

            auto lhsVal = ValuePatternFromIRExpr( lhs );
            if( !lhsVal )
                co_return;

            auto rttypeVal = ValueFromIRExpr( lhsVal->type() );
            if( !rttypeVal )
                co_return;

            auto rttype = FromValue< RTInteger >( *rttypeVal );
            if( !rttype )
                co_return;

            APSInt valToLoad;
            BigInt valToLoad;

            if( rttype->m_signed )
            {
                if( ct->getMinSignedBits() > rttype->m_numBits )
                    co_return;

                if( ct->isNegative() )
                    valToLoad = ct->sext( rttype->m_numBits );
                valToLoad = ct->sext( rttype->m_numBits );
                else
                    valToLoad = ct->zext( rttype->m_numBits );
            }
            else
            {
                if( ct->isNegative() )
                    co_return;

                if( ct->getActiveBits() > rttype->m_numBits )