Stabel

Check-in [775ec8d96b]
Login
Overview
Comment:Box elements of array when array contains a union of types.
Timelines: family | ancestors | descendants | both | arrays
Files: files | file ages | folders
SHA3-256: 775ec8d96b93f889a0fa5789d6ca710023d15ff34dc8b5a14db4bf54ea91b1f8
User & Date: robin.hansen on 2021-08-31 19:10:14
Other Links: branch diff | manifest | tags
Context
2021-09-01
04:26
Solve remaining issue by sorting the list of types before creating a boxMap. Closed-Leaf check-in: 1a424e8e29 user: robin.hansen tags: arrays
2021-08-31
19:10
Box elements of array when array contains a union of types. check-in: 775ec8d96b user: robin.hansen tags: arrays
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
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Stabel/Codegen.elm from [2b90edb681] to [d3be6650e8].

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
194
195
196
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
...
274
275
276
277
278
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
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
417
418
419
420
421
422
423







































































424
425
426
427
428
429
430
...
732
733
734
735
736
737
738
739

















740
741


742
















743
744
745
746
747
748
749


-- Codegen


type AstNode
    = IntLiteral Int
    | ArrayLiteral (List AstNode)
    | Function Int String -- id name
    | FunctionRef Int String -- id name
    | ConstructType Int Int -- id memberQty
    | SetMember Int Int -- offset memberQty
    | GetMember Int -- offset
    | Builtin Builtin
    | Box Int Int -- stackIdx typeId
................................................................................
                            List.foldl
                                (astNodeToCodegenNode def)
                                ( [], [], context )
                                nodes

                        codeGenNodes =
                            List.reverse codeGenNodesReversed
                    in
                    case arrayType of
                        Type.Union _ members ->
                            {-
                               TODO:
                                  unionBoxMap members
                                      |> List.find (\( t, _ ) -> Type.equalBaseType t leftType)
                                      |> Maybe.map Tuple.second
                                      |> Maybe.map (Box idx)
                            -}
                            ( ArrayLiteral codeGenNodes
                            , nextContext
                            )





                        _ ->



                            ( ArrayLiteral codeGenNodes
                            , nextContext
                            )

                AST.Function _ fn _ ->
                    let
                        ( fnId, newContext ) =
                            idForFunction fn.name context
                    in
                    ( Function fnId fn.name
................................................................................

                AST.GetMember _ _ memberIndex _ ->
                    ( GetMember memberIndex
                    , context
                    )

        nodeType =
            case node of
                AST.IntLiteral _ _ ->
                    { input = []
                    , output = [ Type.Int ]
                    }

                AST.ArrayLiteral _ _ t ->
                    { input = []
                    , output = [ t ]
                    }

                AST.Function _ _ type_ ->
                    type_

                AST.FunctionRef _ fn ->
                    { input = []
                    , output = [ Type.FunctionSignature fn.type_ ]
                    }

                AST.Recurse _ ->
                    def.type_

                AST.Cycle _ data ->
                    data.typeSignature

                AST.Builtin _ builtin ->
                    Builtin.functionType builtin

                AST.ConstructType typeDef ->
                    case typeDef.members of
                        StructMembers members ->
                            { input = List.map Tuple.second members
                            , output = [ typeFromTypeDef typeDef.name typeDef.generics ]
                            }

                        UnionMembers members ->
                            -- Cannot happen
                            { input = members
                            , output = [ typeFromTypeDef typeDef.name typeDef.generics ]
                            }

                AST.SetMember typeDef _ _ memberType ->
                    let
                        type_ =
                            typeFromTypeDef typeDef.name typeDef.generics
                    in
                    { input = [ type_, memberType ]
                    , output = [ type_ ]
                    }

                AST.GetMember typeDef _ _ memberType ->
                    let
                        type_ =
                            typeFromTypeDef typeDef.name typeDef.generics
                    in
                    { input = [ type_ ]
                    , output = [ memberType ]
                    }

        typeFromTypeDef typeName gens =
            if List.isEmpty gens then
                Type.Custom typeName

            else
                Type.CustomGeneric typeName (List.map Type.Generic gens)

        stackInScope =
            List.reverse stack
                |> List.take (List.length nodeType.input)
                |> List.reverse

        stackElementsToBox =
................................................................................
                |> List.reverse
    in
    ( newStack
    , newNode :: (stackElementsToBox ++ result)
    , updatedContext
    )









































































memberSize : AST.TypeDefinition -> Int
memberSize def =
    case def.members of
        StructMembers members ->
            List.length members

................................................................................
    case node of
        IntLiteral value ->
            Wasm.Batch
                [ Wasm.I32_Const value
                , BaseModule.callStackPushFn
                ]

        ArrayLiteral nodes ->

















            Wasm.Batch <|
                BaseModule.callArrayEmptyFn


                    :: List.concatMap (\n -> [ nodeToInstruction context n, BaseModule.callArrayPushFn ]) nodes

















        Function id name ->
            Wasm.Call id name

        FunctionRef _ name ->
            let
                indexOfId =







|







 







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

<
>
>
>
|
|
|







 







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







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







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
194
195
196
197
198
199
200












201
202
203
204
205
206

207
208
209
210
211
212
213
214
215
216
217
218
219
...
268
269
270
271
272
273
274
275
































































276
277
278
279
280
281
282
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
...
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785


-- Codegen


type AstNode
    = IntLiteral Int
    | ArrayLiteral Type (List ( Type, AstNode ))
    | Function Int String -- id name
    | FunctionRef Int String -- id name
    | ConstructType Int Int -- id memberQty
    | SetMember Int Int -- offset memberQty
    | GetMember Int -- offset
    | Builtin Builtin
    | Box Int Int -- stackIdx typeId
................................................................................
                            List.foldl
                                (astNodeToCodegenNode def)
                                ( [], [], context )
                                nodes

                        codeGenNodes =
                            List.reverse codeGenNodesReversed













                        codeGenTypes =
                            nodes
                                |> List.map (typeOfNode def)
                                |> List.map (\ft -> Maybe.withDefault Type.Int <| List.head ft.output)


                        codeGenTuples =
                            List.map2 Tuple.pair codeGenTypes codeGenNodes
                    in
                    ( ArrayLiteral arrayType codeGenTuples
                    , nextContext
                    )

                AST.Function _ fn _ ->
                    let
                        ( fnId, newContext ) =
                            idForFunction fn.name context
                    in
                    ( Function fnId fn.name
................................................................................

                AST.GetMember _ _ memberIndex _ ->
                    ( GetMember memberIndex
                    , context
                    )

        nodeType =
            typeOfNode def node

































































        stackInScope =
            List.reverse stack
                |> List.take (List.length nodeType.input)
                |> List.reverse

        stackElementsToBox =
................................................................................
                |> List.reverse
    in
    ( newStack
    , newNode :: (stackElementsToBox ++ result)
    , updatedContext
    )


typeOfNode : AST.FunctionDefinition -> AST.AstNode -> Type.FunctionType
typeOfNode def node =
    case node of
        AST.IntLiteral _ _ ->
            { input = []
            , output = [ Type.Int ]
            }

        AST.ArrayLiteral _ _ t ->
            { input = []
            , output = [ t ]
            }

        AST.Function _ _ type_ ->
            type_

        AST.FunctionRef _ fn ->
            { input = []
            , output = [ Type.FunctionSignature fn.type_ ]
            }

        AST.Recurse _ ->
            def.type_

        AST.Cycle _ data ->
            data.typeSignature

        AST.Builtin _ builtin ->
            Builtin.functionType builtin

        AST.ConstructType typeDef ->
            case typeDef.members of
                StructMembers members ->
                    { input = List.map Tuple.second members
                    , output = [ typeFromTypeDef typeDef.name typeDef.generics ]
                    }

                UnionMembers members ->
                    -- Cannot happen
                    { input = members
                    , output = [ typeFromTypeDef typeDef.name typeDef.generics ]
                    }

        AST.SetMember typeDef _ _ memberType ->
            let
                type_ =
                    typeFromTypeDef typeDef.name typeDef.generics
            in
            { input = [ type_, memberType ]
            , output = [ type_ ]
            }

        AST.GetMember typeDef _ _ memberType ->
            let
                type_ =
                    typeFromTypeDef typeDef.name typeDef.generics
            in
            { input = [ type_ ]
            , output = [ memberType ]
            }


typeFromTypeDef : String -> List String -> Type
typeFromTypeDef typeName gens =
    if List.isEmpty gens then
        Type.Custom typeName

    else
        Type.CustomGeneric typeName (List.map Type.Generic gens)


memberSize : AST.TypeDefinition -> Int
memberSize def =
    case def.members of
        StructMembers members ->
            List.length members

................................................................................
    case node of
        IntLiteral value ->
            Wasm.Batch
                [ Wasm.I32_Const value
                , BaseModule.callStackPushFn
                ]

        ArrayLiteral arrayType typedNodes ->
            case arrayType of
                Type.Array (Type.Union _ unionMembers) ->
                    let
                        boxMap =
                            unionBoxMap unionMembers

                        boxedNodes =
                            List.map
                                (\( nType, n ) ->
                                    ( List.find (\( t, _ ) -> Type.equalBaseType t nType) boxMap
                                        |> Maybe.map Tuple.second
                                        |> Maybe.withDefault -1
                                    , n
                                    )
                                )
                                typedNodes
                    in
                    Wasm.Batch <|
                        BaseModule.callArrayEmptyFn
                            :: List.concatMap
                                (\( tag, n ) ->
                                    [ nodeToInstruction context n
                                    , nodeToInstruction context <| Box 0 tag
                                    , BaseModule.callArrayPushFn
                                    ]
                                )
                                boxedNodes

                _ ->
                    Wasm.Batch <|
                        BaseModule.callArrayEmptyFn
                            :: List.concatMap
                                (\( _, n ) ->
                                    [ nodeToInstruction context n
                                    , BaseModule.callArrayPushFn
                                    ]
                                )
                                typedNodes

        Function id name ->
            Wasm.Call id name

        FunctionRef _ name ->
            let
                indexOfId =