Goose  Diff

Differences From Artifact [65254ece1e]:

  • File bs/builtins/types/runtime/typecheck.cpp — part of check-in [b64ea47f6b] at 2020-06-27 22:05:05 on branch trunk — Clearly separate the type checking rules and the unification rules, instead of lumping them all together in a single set of patterns which is increasingly confusing. (user: achavasse size: 7507)

To Artifact [7415008b26]:

  • File bs/builtins/types/runtime/typecheck.cpp — part of check-in [04aea08600] at 2020-07-02 00:47:34 on branch trunk —
    • Added overloads to the comma operator to be able to construct tuples of references.
    • Fixed reference typechecking rules so that overloads taking values directly have priority over overloads taking references.
    • Fixed a template function expression parsing bug.
    (user: achavasse size: 7518)

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    {
        auto rtIntTypePattern = Value( TypeType(), MkStdType( TSID( integer ),
            VEC( ANYTERM( _ ), ANYTERM( _ ) ) ) );

        // ct_int type against a IntegerType type:
        // return the IntegerType 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.typeCheckingRuleSet()->addUnificationRule( TCRINFOS,
            ValueToIRExpr( rtIntTypePattern ),
            GetValueType< BigInt >(),
        []( const Term& lhs, const Term& rhs, const TypeCheckingContext& c ) -> TCGen
        {
            return HalfUnify( lhs, c );
        } );







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    {
        auto rtIntTypePattern = Value( TypeType(), MkStdType( TSID( integer ),
            VEC( ANYTERM( _ ), ANYTERM( _ ) ) ) );

        // ct_int type against a IntegerType type:
        // return the IntegerType type. We don't care if the
        // ct_int fits at this point, this will be dealt with by
        // the ct_int value type checking rule below.
        e.typeCheckingRuleSet()->addUnificationRule( TCRINFOS,
            ValueToIRExpr( rtIntTypePattern ),
            GetValueType< BigInt >(),
        []( const Term& lhs, const Term& rhs, const TypeCheckingContext& c ) -> TCGen
        {
            return HalfUnify( lhs, c );
        } );
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
                ANYTERM( _ ) ) ),

        []( const Term& lhs, const Term& rhs, const TypeCheckingContext& c ) -> TCGen
        {
            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.typeCheckingRuleSet()->addUnificationRule( TCRINFOS,

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

            ValueToIRExpr( ValuePattern(







|


|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
                ANYTERM( _ ) ) ),

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

        // ct_integer constant type checking against a IntegerType:
        // Check if the IntegerType is big enough for the constant,
        // and emit a LoadConstantInt llr instruction if so.
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

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

            ValueToIRExpr( ValuePattern(
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

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

            for( auto&& [s,tcc] : HalfUnify( lhsVal->type(), tcc ) )
            {
                // We need to defer the calculation of the init value until after the rest of the unification is complete,
                // because we need to make sure that any hole present in the integer type is resolved before we can do
                // the sign/bitsize check. However, since we still need to be able to manipulate the result as a value in
                // the mean time, we construct a value with the correct (but possibly not complete yet type), and a payload
                // that contains the type + the ct_int value wrapped with a post process callback that finalizes the job.
                auto wrapped = WrapWithPostprocFunc( VEC( lhsVal->type(), rhs ),
                []( const Term& t, TypeCheckingContext tcc ) -> optional< Term >
                {







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

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

            for( auto&& [s,tcc] : HalfUnify( lhsVal->type(), tcc ) )
            {
                // We need to defer the calculation of the init value until after the rest of the type checking is complete,
                // because we need to make sure that any hole present in the integer type is resolved before we can do
                // the sign/bitsize check. However, since we still need to be able to manipulate the result as a value in
                // the mean time, we construct a value with the correct (but possibly not complete yet type), and a payload
                // that contains the type + the ct_int value wrapped with a post process callback that finalizes the job.
                auto wrapped = WrapWithPostprocFunc( VEC( lhsVal->type(), rhs ),
                []( const Term& t, TypeCheckingContext tcc ) -> optional< Term >
                {
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
            ValueToIRExpr( rtInt8PtrTypePattern ),
            GetValueType< string >(),
        []( const Term& lhs, const Term& rhs, const TypeCheckingContext& c ) -> TCGen
        {
            co_yield HalfUnify( lhs, c );
        } );

        // ct_string constant unification against a pointer to a integer( 8 ):
        // Emit a LoadConstantStr llr instruction.
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

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







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
            ValueToIRExpr( rtInt8PtrTypePattern ),
            GetValueType< string >(),
        []( const Term& lhs, const Term& rhs, const TypeCheckingContext& c ) -> TCGen
        {
            co_yield HalfUnify( lhs, c );
        } );

        // ct_string constant type checking against a pointer to a integer( 8 ):
        // Emit a LoadConstantStr llr instruction.
        e.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ValueToIRExpr( ValuePattern(
                ANYTERM( _ ),
                ValueToIRExpr( rtInt8PtrTypePattern ),
                ANYTERM( _ ) ) ),
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
            co_yield { ValueToIRExpr(
                BuildComputedValue( lhsVal.type(), llr::LoadConstStr( str ) ) ), c };
        } );

        auto ptrTypePattern = Value( TypeType(), MkStdType( 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.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ParamPat( ValueToIRExpr( ptrTypePattern ) ),

            ValueToIRExpr( ValuePattern(







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
            co_yield { ValueToIRExpr(
                BuildComputedValue( lhsVal.type(), llr::LoadConstStr( str ) ) ), c };
        } );

        auto ptrTypePattern = Value( TypeType(), MkStdType( TSID( pointer ),
            ANYTERM( _ ) ) );

        // nullptr constant type checking 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.typeCheckingRuleSet()->addTypeCheckingRule( TCRINFOS,

            ParamPat( ValueToIRExpr( ptrTypePattern ) ),

            ValueToIRExpr( ValuePattern(