Play

Check-in [369c9800a9]
Login
Overview
Comment:Solve remaining issues with type checker for generic function types.
Timelines: family | ancestors | descendants | both | stack-manipulation
Files: files | file ages | folders
SHA3-256: 369c9800a99b2019e96070f3042a248d9ba1dcf1b4e8329206dd3f383339528a
User & Date: robin.hansen on 2020-04-10 12:20:55
Other Links: branch diff | manifest | tags
Context
2020-04-10
12:21
Add support for stack manipulation functions and generic function types. check-in: 32f58d1269 user: robin.hansen tags: trunk
12:20
Solve remaining issues with type checker for generic function types. Closed-Leaf check-in: 369c9800a9 user: robin.hansen tags: stack-manipulation
11:06
Modularize wasm test suite. check-in: 13f590fa78 user: robin.hansen tags: stack-manipulation
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Play/TypeChecker.elm from [4d1e87ab7e] to [1a594e14f7].

226
227
228
229
230
231
232
233






234
235
236
237
238
239
240
...
334
335
336
337
338
339
340





341
342
343
344
345
346
347
348
349
350
351
352
353
    wordTypeFromStackEffectsHelper context.stackEffects ( context, { input = [], output = [] } )


wordTypeFromStackEffectsHelper : List StackEffect -> ( Context, WordType ) -> ( Context, WordType )
wordTypeFromStackEffectsHelper effects ( context, wordType ) =
    case effects of
        [] ->
            ( context, wordType )







        (Pop type_) :: remainingEffects ->
            case wordType.output of
                [] ->
                    wordTypeFromStackEffectsHelper remainingEffects <|
                        ( context, { wordType | input = type_ :: wordType.input } )

................................................................................
                |> List.foldl renameGenerics ( 'a', Dict.empty, [] )
                |> (\( _, _, ns ) -> ns)
                |> List.reverse

        reduceGenericName type_ =
            case type_ of
                Type.Generic genName ->





                    case Dict.get genName aliases of
                        Just actualName ->
                            Type.Generic actualName

                        Nothing ->
                            type_

                _ ->
                    type_

        renameGenerics type_ ( nextId, seenGenerics, acc ) =
            case type_ of
                Type.Generic genName ->







|
>
>
>
>
>
>







 







>
>
>
>
>
|
|
|

|
|







226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
...
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
    wordTypeFromStackEffectsHelper context.stackEffects ( context, { input = [], output = [] } )


wordTypeFromStackEffectsHelper : List StackEffect -> ( Context, WordType ) -> ( Context, WordType )
wordTypeFromStackEffectsHelper effects ( context, wordType ) =
    case effects of
        [] ->
            ( context
              -- TODO: Really need to get this list reverse madness figured out and solved properly
            , { wordType
                | input = wordType.input
                , output = List.reverse wordType.output
              }
            )

        (Pop type_) :: remainingEffects ->
            case wordType.output of
                [] ->
                    wordTypeFromStackEffectsHelper remainingEffects <|
                        ( context, { wordType | input = type_ :: wordType.input } )

................................................................................
                |> List.foldl renameGenerics ( 'a', Dict.empty, [] )
                |> (\( _, _, ns ) -> ns)
                |> List.reverse

        reduceGenericName type_ =
            case type_ of
                Type.Generic genName ->
                    case getGenericBinding context type_ of
                        Just boundType ->
                            boundType

                        Nothing ->
                            case Dict.get genName aliases of
                                Just actualName ->
                                    Type.Generic actualName

                                Nothing ->
                                    type_

                _ ->
                    type_

        renameGenerics type_ ( nextId, seenGenerics, acc ) =
            case type_ of
                Type.Generic genName ->

Modified tests/Test/TypeChecker.elm from [7d37d7e16e] to [d1288728ad].

279
280
281
282
283
284
285


































286
287
288
289
290
291
292
293
                                        [ QAST.Builtin Builtin.StackSwap
                                        , QAST.Builtin Builtin.StackDuplicate
                                        , QAST.Builtin Builtin.StackRightRotate
                                        ]
                                  }
                                ]
                        }


































                in
                case typeCheck input of
                    Err () ->
                        Expect.fail "Did not expect type check to fail."

                    Ok _ ->
                        Expect.pass
        ]







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








279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
                                        [ QAST.Builtin Builtin.StackSwap
                                        , QAST.Builtin Builtin.StackDuplicate
                                        , QAST.Builtin Builtin.StackRightRotate
                                        ]
                                  }
                                ]
                        }
                in
                case typeCheck input of
                    Err () ->
                        Expect.fail "Did not expect type check to fail."

                    Ok _ ->
                        Expect.pass
        , test "Generic types with type annotation" <|
            \_ ->
                let
                    input =
                        { types = Dict.empty
                        , words =
                            Dict.fromListBy .name
                                [ { name = "main"
                                  , metadata =
                                        Metadata.default
                                            |> Metadata.withType [] [ Type.Int ]
                                  , implementation =
                                        [ QAST.Integer 5
                                        , QAST.Word "square"
                                        ]
                                  }
                                , { name = "square"
                                  , metadata =
                                        Metadata.default
                                            |> Metadata.withType [ Type.Int ] [ Type.Int ]
                                  , implementation =
                                        [ QAST.Builtin Builtin.StackDuplicate
                                        , QAST.Builtin Builtin.Multiply
                                        ]
                                  }
                                ]
                        }
                in
                case typeCheck input of
                    Err () ->
                        Expect.fail "Did not expect type check to fail."

                    Ok _ ->
                        Expect.pass
        ]

Modified wasm_tests/stack.test.js from [e6217c5cce] to [493c219118].

24
25
26
27
28
29
30



















31
32
33
34
35
        type: -- Int
        : 1 2 over - + 2 =

        def: over
        type: a b -- a b a
        : swap dup rotate
    `);




















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

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







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





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
        type: -- Int
        : 1 2 over - + 2 =

        def: over
        type: a b -- a b a
        : swap dup rotate
    `);

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

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

test('Under', async() => {
    // Not sure if under is actually a known function in forth
    // This is mainly to test -rotate
    const wat = await compiler.toWat(`
        def: main
        entry: true
        type: -- Int
        : 1 2 under - + 3 =

        def: under
        type: a b -- b b a
        : dup -rotate
    `);

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

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