Goose  Diff

Differences From Artifact [44a9c97834]:

  • File bs/builtins/types/runtime/unify.cpp — part of check-in [9a68159d52] at 2019-08-25 01:54:54 on branch trunk —
    • Got rid of the LoadConstInt instruction and directly handle integer constants in codegen. The old system didn't work for compile-time evaluated runtime integers.
    • Added missing implementations for unsigned comparison, that were somehow forgotten.
    • Implemented the nullptr constant.
    • Made a test version of the mandelbrot sample that gets both compiled and interpreted and whose results are compared with the same reference file, as a sanity test that interpreted and compiled code behave identically.
    (user: achavasse size: 7473)

To Artifact [d9f983102e]:

  • File bs/builtins/types/runtime/unify.cpp — part of check-in [6e598fe891] at 2019-08-29 20:12:40 on branch trunk — Params are now encoded distinctly from normal values, to allow for more generic unification rules for things suchs as BigInt versus Integer. (user: achavasse size: 7137)

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
        {
            co_yield HalfUnify( lhs, c );
        } );

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

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

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

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            co_return;
        } );

        // ct_integer constant unification against a IntegerType:
        // Check if the IntegerType is big enough for the constant,
        // and emit a LoadConstantInt llr instruction if so.
        e.unificationRuleSet()->addAsymRule(

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

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

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            // The rhs might not be constant. It can happen even with ct_int if the rhs is a
            // fake argument pattern generated to unify a higher-order function param.







|

<
<
|
<














|







|







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
        {
            co_yield HalfUnify( lhs, c );
        } );

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



            ParamPat( GetValueType< BigInt >() ),


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

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            co_return;
        } );

        // ct_integer constant unification against a IntegerType:
        // Check if the IntegerType is big enough for the constant,
        // and emit a LoadConstantInt llr instruction if so.
        e.unificationRuleSet()->addSymRule(

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

            ValueToIRExpr( ValuePattern(
                TSID( constant ),
                GetValueType< BigInt >(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            // The rhs might not be constant. It can happen even with ct_int if the rhs is a
            // fake argument pattern generated to unify a higher-order function param.
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
        {
            co_yield HalfUnify( lhs, c );
        } );

        // Reject the ct_string param and char* 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< string >(),
                ANYTERM( _ ) ) ),

            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                ValueToIRExpr( rtInt8PtrTypePattern ),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            co_return;
        } );

        // ct_string constant unification against a pointer to a integer( 8 ):
        // Emit a LoadConstantStr llr instruction.
        e.unificationRuleSet()->addSymRule(

            ValueToIRExpr( Value(
                GetValueType< string >(),
                ANYTERM( _ ) ) ),

            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                ValueToIRExpr( rtInt8PtrTypePattern ),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen







|

<
<
|
<















<
|
<







134
135
136
137
138
139
140
141
142


143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159

160
161
162
163
164
165
166
        {
            co_yield HalfUnify( lhs, c );
        } );

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



            ParamPat( GetValueType< string >() ),


            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                ValueToIRExpr( rtInt8PtrTypePattern ),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            co_return;
        } );

        // ct_string constant unification against a pointer to a integer( 8 ):
        // Emit a LoadConstantStr llr instruction.
        e.unificationRuleSet()->addSymRule(


            ParamPat( GetValueType< string >(), ANYTERM( _ ) ),


            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                ValueToIRExpr( rtInt8PtrTypePattern ),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
            TSID( pointer ), ANYTERM( _ ) ) );

        // nullptr constant unification against a pointer of any type;
        // Yield a value of the given pointer type, with a 0 integer as its content.
        // This'll be recognized by codegen to emit a null pointer value of the right type.
        e.unificationRuleSet()->addSymRule(

            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                ValueToIRExpr( ptrTypePattern ),
                ANYTERM( _ ) ) ),

            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                GetValueType< NullPointer >(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            auto lVal = *ValuePatternFromIRExpr( lhs );
            co_yield { ValueToIRExpr( Value( lVal.type(), 0U ) ), c };
        } );
    }
}







<
<
|
<













184
185
186
187
188
189
190


191

192
193
194
195
196
197
198
199
200
201
202
203
204
            TSID( pointer ), ANYTERM( _ ) ) );

        // nullptr constant unification against a pointer of any type;
        // Yield a value of the given pointer type, with a 0 integer as its content.
        // This'll be recognized by codegen to emit a null pointer value of the right type.
        e.unificationRuleSet()->addSymRule(



            ParamPat( ValueToIRExpr( ptrTypePattern ) ),


            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                GetValueType< NullPointer >(),
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, UnificationContext& c ) -> UniGen
        {
            auto lVal = *ValuePatternFromIRExpr( lhs );
            co_yield { ValueToIRExpr( Value( lVal.type(), 0U ) ), c };
        } );
    }
}