Play

Check-in [5779464d2f]
Login
Overview
Comment:Fix remaining issues with generic types and codegen.
Timelines: family | ancestors | descendants | both | generic-types-and-unions
Files: files | file ages | folders
SHA3-256: 5779464d2f038ec9cc6fb4887d1bd0d07d5a42d5d4fb27e6e3787cf1998ec1a4
User & Date: robin.hansen on 2020-08-03 13:54:11
Other Links: branch diff | manifest | tags
Context
2020-08-03
13:55
Add support for custom types and unions with generic members. Fixes [87af6169a3]. check-in: 633b4e1088 user: robin.hansen tags: trunk
13:54
Fix remaining issues with generic types and codegen. Closed-Leaf check-in: 5779464d2f user: robin.hansen tags: generic-types-and-unions
2020-08-02
08:52
Make sure generics used in custom type or union is listed as part of the type signature. check-in: a52bd3c1b1 user: robin.hansen tags: generic-types-and-unions
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Play/Codegen.elm from [373833f264] to [ac0268c65a].

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
            let
                testForInequality =
                    makeInequalityTest type_ 0

                makeInequalityTest t_ localIdx =
                    case t_ of
                        AST.TypeMatch (Type.Custom name) conditions ->









                            let
                                typeId =
                                    Dict.get name typeInfo
                                        |> Maybe.map .id
                                        |> Maybe.withDefault 0
                            in
                            Wasm.Batch
                                [ Wasm.Local_Get localIdx
                                , Wasm.I32_Load -- Load instance id
                                , Wasm.I32_Const typeId
                                , Wasm.I32_NotEq -- Types doesn't match?
                                , Wasm.BreakIf 0 -- Move to next branch if above test is true
                                , conditions
                                    |> List.concatMap (conditionTest localIdx)
                                    |> Wasm.Batch
                                ]

                        _ ->
                            Debug.todo "Only supports custom types in when clauses"

                conditionTest localIdx ( fieldName, value ) =
                    case value of
                        AST.LiteralInt num ->
                            [ Wasm.Local_Get localIdx
                            , Wasm.Call BaseModule.stackPushFn
                            , Wasm.Call <| fieldName ++ ">"







>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<







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
            let
                testForInequality =
                    makeInequalityTest type_ 0

                makeInequalityTest t_ localIdx =
                    case t_ of
                        AST.TypeMatch (Type.Custom name) conditions ->
                            whenSetup localIdx name conditions

                        AST.TypeMatch (Type.CustomGeneric name _) conditions ->
                            whenSetup localIdx name conditions

                        _ ->
                            Debug.todo "Only supports custom types in when clauses"

                whenSetup localIdx typeName conditions =
                    let
                        typeId =
                            Dict.get typeName typeInfo
                                |> Maybe.map .id
                                |> Maybe.withDefault 0
                    in
                    Wasm.Batch
                        [ Wasm.Local_Get localIdx
                        , Wasm.I32_Load -- Load instance id
                        , Wasm.I32_Const typeId
                        , Wasm.I32_NotEq -- Types doesn't match?
                        , Wasm.BreakIf 0 -- Move to next branch if above test is true
                        , conditions
                            |> List.concatMap (conditionTest localIdx)
                            |> Wasm.Batch
                        ]




                conditionTest localIdx ( fieldName, value ) =
                    case value of
                        AST.LiteralInt num ->
                            [ Wasm.Local_Get localIdx
                            , Wasm.Call BaseModule.stackPushFn
                            , Wasm.Call <| fieldName ++ ">"

Modified src/Play/Qualifier.elm from [ea6edcf7ba] to [86fc404065].

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214








215
216
217
218
219
220
221
222
223
224
225
            Ok <| TypeMatch Type.Int []

        Parser.TypeMatch Type.Int [ ( "value", Parser.LiteralInt val ) ] ->
            Ok <| TypeMatch Type.Int [ ( "value", LiteralInt val ) ]

        Parser.TypeMatch ((Type.Custom name) as type_) patterns ->
            case Dict.get name qualifiedTypes of
                Just (CustomTypeDef _ _ members) ->
                    let
                        memberNames =
                            members
                                |> List.map Tuple.first
                                |> Set.fromList

                        qualifiedPatternsResult =
                            patterns
                                |> List.map (qualifyMatchValue qualifiedTypes memberNames)
                                |> Result.combine








                    in
                    case qualifiedPatternsResult of
                        Ok qualifiedPatterns ->
                            Ok <| TypeMatch type_ qualifiedPatterns

                        Err () ->
                            Err ()

                Just (UnionTypeDef _ _ types) ->
                    if List.isEmpty patterns then
                        Ok <| TypeMatch (Type.Union types) []







|










>
>
>
>
>
>
>
>



|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
            Ok <| TypeMatch Type.Int []

        Parser.TypeMatch Type.Int [ ( "value", Parser.LiteralInt val ) ] ->
            Ok <| TypeMatch Type.Int [ ( "value", LiteralInt val ) ]

        Parser.TypeMatch ((Type.Custom name) as type_) patterns ->
            case Dict.get name qualifiedTypes of
                Just (CustomTypeDef _ gens members) ->
                    let
                        memberNames =
                            members
                                |> List.map Tuple.first
                                |> Set.fromList

                        qualifiedPatternsResult =
                            patterns
                                |> List.map (qualifyMatchValue qualifiedTypes memberNames)
                                |> Result.combine

                        actualType =
                            case gens of
                                [] ->
                                    type_

                                _ ->
                                    Type.CustomGeneric name (List.map Type.Generic gens)
                    in
                    case qualifiedPatternsResult of
                        Ok qualifiedPatterns ->
                            Ok <| TypeMatch actualType qualifiedPatterns

                        Err () ->
                            Err ()

                Just (UnionTypeDef _ _ types) ->
                    if List.isEmpty patterns then
                        Ok <| TypeMatch (Type.Union types) []

Modified wasm_tests/multiword.test.js from [5a7041c362] to [0a33f11b91].

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    const wat = await compiler.toWat(`
        defunion: List a
        : NonEmptyList a 
        : EmptyList

        deftype: NonEmptyList a
        : first a
        : rest (List a)

        deftype: EmptyList

        defmulti: first-or-default
        when: NonEmptyList
          drop first>
        when: EmptyList







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    const wat = await compiler.toWat(`
        defunion: List a
        : NonEmptyList a 
        : EmptyList

        deftype: NonEmptyList a
        : first a
        : rest List a

        deftype: EmptyList

        defmulti: first-or-default
        when: NonEmptyList
          drop first>
        when: EmptyList