Stabel

Check-in [9b06579c64]
Login
Overview
Comment:It's now possible to reference arrays in the type system.
Timelines: family | ancestors | descendants | both | arrays
Files: files | file ages | folders
SHA3-256: 9b06579c64a17b6b5f8d4e29cdce34ad437ba033b854700d129826b67c73ee3f
User & Date: robin.hansen on 2021-08-30 17:02:25
Other Links: branch diff | manifest | tags
Context
2021-08-30
20:06
Discovered, and fixed, several issues related to arrays used in multi functions. What remains is to ... check-in: c5016144d8 user: robin.hansen tags: arrays
17:02
It's now possible to reference arrays in the type system. check-in: 9b06579c64 user: robin.hansen tags: arrays
2021-08-29
17:50
Added tests to verify correct array implementation. check-in: f3dcfa50ab user: robin.hansen tags: arrays
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Stabel/Data/Type.elm from [ad62e63d60] to [789a945a65].

310
311
312
313
314
315
316











317
318
319
320
321
322
323
            let
                ( _, compatibleMembers ) =
                    compatibleTypeLists lMembers rMembers Dict.empty
            in
            if lName == rName && compatibleMembers then
                compatibleTypeLists annotatedRest inferredRest rangeDict












            else
                ( rangeDict, False )

        ( (Union _ lMembers) :: annotatedRest, (Union _ rMembers) :: inferredRest ) ->
            let
                lSet =
                    Set.fromList (List.map toString lMembers)







>
>
>
>
>
>
>
>
>
>
>







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
            let
                ( _, compatibleMembers ) =
                    compatibleTypeLists lMembers rMembers Dict.empty
            in
            if lName == rName && compatibleMembers then
                compatibleTypeLists annotatedRest inferredRest rangeDict

            else
                ( rangeDict, False )

        ( (Array lMember) :: annotatedRest, (Array rMember) :: inferredRest ) ->
            let
                ( _, compatibleMembers ) =
                    compatibleTypeLists [ lMember ] [ rMember ] Dict.empty
            in
            if compatibleMembers then
                ( rangeDict, True )

            else
                ( rangeDict, False )

        ( (Union _ lMembers) :: annotatedRest, (Union _ rMembers) :: inferredRest ) ->
            let
                lSet =
                    Set.fromList (List.map toString lMembers)

Modified src/Stabel/Qualifier.elm from [e859a8f4e9] to [854b5fd650].

457
458
459
460
461
462
463














464
465
466
467
468
469
470
                Nothing ->
                    Err <| UnknownTypeRef range name
    in
    case type_ of
        Parser.LocalRef "Int" [] ->
            Ok <| Type.Int















        Parser.LocalRef name [] ->
            case Dict.get name config.ast.types of
                Just _ ->
                    Ok <| Type.Custom (qualifyName config name)

                Nothing ->
                    importsLookup name []







>
>
>
>
>
>
>
>
>
>
>
>
>
>







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
                Nothing ->
                    Err <| UnknownTypeRef range name
    in
    case type_ of
        Parser.LocalRef "Int" [] ->
            Ok <| Type.Int

        Parser.LocalRef "Int" other ->
            Err <| BadIntType range (List.length other)

        Parser.LocalRef "Array" [ t ] ->
            case qualifyMemberType config modRefs range t of
                Err err ->
                    Err err

                Ok t_ ->
                    Ok <| Type.Array t_

        Parser.LocalRef "Array" other ->
            Err <| BadArrayType range (List.length other)

        Parser.LocalRef name [] ->
            case Dict.get name config.ast.types of
                Just _ ->
                    Ok <| Type.Custom (qualifyName config name)

                Nothing ->
                    importsLookup name []

Modified src/Stabel/Qualifier/Problem.elm from [616702f68f] to [2744deccb7].

11
12
13
14
15
16
17


18
19
20
21
22
23
24
..
83
84
85
86
87
88
89




















90
91
92
93
94
95
96
...
107
108
109
110
111
112
113






    = UnknownFunctionRef SourceLocationRange String
    | UnknownTypeRef SourceLocationRange String
    | UnionTypeMatchWithPatterns SourceLocationRange
    | InvalidTypeMatch SourceLocationRange
    | NoSuchMemberOnType SourceLocationRange String String
    | FunctionNotExposed SourceLocationRange String
    | TypeNotExposed SourceLocationRange String




toString : String -> Problem -> String
toString source problem =
    case problem of
        UnknownFunctionRef range functionRef ->
            ">> "
................................................................................
                ++ "\n\n"
                ++ SourceLocation.extractFromString source range.start range.end
                ++ "\n\n"
                ++ "Referencing '"
                ++ typeRef
                ++ "' but this type is not exposed."






















sourceLocationRef : Problem -> String
sourceLocationRef problem =
    case problem of
        UnknownFunctionRef range _ ->
            range.source

................................................................................
            range.source

        FunctionNotExposed range _ ->
            range.source

        TypeNotExposed range _ ->
            range.source













>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
129
130
131
132
133
134
135
136
137
138
139
140
141
    = UnknownFunctionRef SourceLocationRange String
    | UnknownTypeRef SourceLocationRange String
    | UnionTypeMatchWithPatterns SourceLocationRange
    | InvalidTypeMatch SourceLocationRange
    | NoSuchMemberOnType SourceLocationRange String String
    | FunctionNotExposed SourceLocationRange String
    | TypeNotExposed SourceLocationRange String
    | BadIntType SourceLocationRange Int
    | BadArrayType SourceLocationRange Int


toString : String -> Problem -> String
toString source problem =
    case problem of
        UnknownFunctionRef range functionRef ->
            ">> "
................................................................................
                ++ "\n\n"
                ++ SourceLocation.extractFromString source range.start range.end
                ++ "\n\n"
                ++ "Referencing '"
                ++ typeRef
                ++ "' but this type is not exposed."

        BadIntType range num ->
            ">> "
                ++ range.source
                ++ "\n\n"
                ++ SourceLocation.extractFromString source range.start range.end
                ++ "\n\n"
                ++ "An Int takes no type parameters, you've provided "
                ++ String.fromInt num
                ++ "."

        BadArrayType range num ->
            ">> "
                ++ range.source
                ++ "\n\n"
                ++ SourceLocation.extractFromString source range.start range.end
                ++ "\n\n"
                ++ "An Array requires exactly one type parameter, you've provided "
                ++ String.fromInt num
                ++ "."


sourceLocationRef : Problem -> String
sourceLocationRef problem =
    case problem of
        UnknownFunctionRef range _ ->
            range.source

................................................................................
            range.source

        FunctionNotExposed range _ ->
            range.source

        TypeNotExposed range _ ->
            range.source

        BadIntType range _ ->
            range.source

        BadArrayType range _ ->
            range.source

Modified tests/Test/Qualifier/Errors.elm from [064ee3fb26] to [5ffe1b5acb].

84
85
86
87
88
89
90

























































91
92
93
94
95
96
97
                        : { one two }

                        def: one
                        : 1
                        """
                in
                checkForError (noSuchWordReferenceError "two") source

























































        ]


noSuchWordReferenceError : String -> Problem -> Bool
noSuchWordReferenceError name problem =
    case problem of
        UnknownFunctionRef _ problemName ->







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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
150
151
152
153
154
                        : { one two }

                        def: one
                        : 1
                        """
                in
                checkForError (noSuchWordReferenceError "two") source
        , test "Bad Int type" <|
            \_ ->
                let
                    source =
                        """
                        def: main
                        type: -- (Int a)
                        : 1
                        """

                    badIntError problem =
                        case problem of
                            BadIntType _ 1 ->
                                True

                            _ ->
                                False
                in
                checkForError badIntError source
        , test "Bad Array type" <|
            \_ ->
                let
                    source =
                        """
                        def: main
                        type: -- (Array a b)
                        : { 1 { 2 } }
                        """

                    badArrayError problem =
                        case problem of
                            BadArrayType _ 2 ->
                                True

                            _ ->
                                False
                in
                checkForError badArrayError source
        , test "Bad Array type (no arguments)" <|
            \_ ->
                let
                    source =
                        """
                        def: main
                        type: -- Array
                        : { 1 2 }
                        """

                    badArrayError problem =
                        case problem of
                            BadArrayType _ 0 ->
                                True

                            _ ->
                                False
                in
                checkForError badArrayError source
        ]


noSuchWordReferenceError : String -> Problem -> Bool
noSuchWordReferenceError name problem =
    case problem of
        UnknownFunctionRef _ problemName ->

Modified wasm_tests/array.test.js from [89a278769b] to [ec17f90b23].

142
143
144
145
146
147
148
149




























          swap drop
    `);

    const result = await compiler.run(wat, 'main');

    expect(result.stackElement()).toBe(20);
});





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
175
176
177
          swap drop
    `);

    const result = await compiler.run(wat, 'main');

    expect(result.stackElement()).toBe(20);
});

test('Type annotation', async () => {
    const wat = await compiler.toWat('main', `
        def: main
        type: -- Int
        : { 5 6 7 8 } array-length
    `);

    const result = await compiler.run(wat, 'main');

    expect(result.stackElement()).toBe(4);
});

test('Type tightening', async () => {
    const wat = await compiler.toWat('main', `
        def: main
        type: -- Int
        : empty array-length

        def: empty
        type: -- (Array Int)
        : {}
    `);

    const result = await compiler.run(wat, 'main');

    expect(result.stackElement()).toBe(0);
});