Stabel

Check-in [e023dcfecb]
Login
Overview
Comment:Refactor in preperation to type check array literals.
Timelines: family | ancestors | descendants | both | arrays
Files: files | file ages | folders
SHA3-256: e023dcfecb25778a9b09563c8ab432397dd98b43a6f9bbaf57c8ee62597ac9c2
User & Date: robin.hansen on 2021-08-21 11:03:11
Other Links: branch diff | manifest | tags
Context
2021-08-22
09:59
Implement code that type check array literals, now we need to add an array type. check-in: 8e523926b1 user: robin.hansen tags: arrays
2021-08-21
11:03
Refactor in preperation to type check array literals. check-in: e023dcfecb user: robin.hansen tags: arrays
2021-08-20
17:09
Qualify nodes in an array. check-in: d2e7b4771d user: robin.hansen tags: arrays
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Stabel/Codegen.elm from [7fa0842924] to [4ff3b6f63b].

182
183
184
185
186
187
188






189
190
191
192
193
194
195
...
249
250
251
252
253
254
255






256
257
258
259
260
261
262
    let
        ( newNode, updatedContext ) =
            case node of
                AST.IntLiteral _ val ->
                    ( IntLiteral val
                    , context
                    )







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

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







                AST.Function _ _ type_ ->
                    type_

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







>
>
>
>
>
>







 







>
>
>
>
>
>







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
...
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    let
        ( newNode, updatedContext ) =
            case node of
                AST.IntLiteral _ val ->
                    ( IntLiteral val
                    , context
                    )

                AST.ArrayLiteral _ nodes ->
                    -- TODO: Dummy code to get project to compile
                    ( IntLiteral 1
                    , context
                    )

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

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

                AST.ArrayLiteral _ _ ->
                    -- TODO: Dummy code to get project to compile
                    { input = []
                    , output = [ Type.Int ]
                    }

                AST.Function _ _ type_ ->
                    type_

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

Modified src/Stabel/TypeChecker.elm from [cff285070a] to [7c3c57fca4].

53
54
55
56
57
58
59

60
61
62
63
64
65
66
...
261
262
263
264
265
266
267




268
269
270
271
272
273
274
...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
....
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178







1179
1180
1181



1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203

1204
1205

1206
1207
1208
1209
1210
1211
1212
1213
1214

1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228

1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247
1248

1249
1250
1251
1252
1253
1254

1255
1256
1257
1258
1259

1260
1261
1262
1263
1264
1265

1266
1267
1268
1269
1270
1271

1272


1273

1274
1275
1276





1277
1278
1279
1280
1281
1282
1283
    = LiteralInt Int
    | LiteralType Type
    | RecursiveMatch TypeMatch


type AstNode
    = IntLiteral SourceLocationRange Int

    | Function SourceLocationRange FunctionDefinition FunctionType
    | FunctionRef SourceLocationRange FunctionDefinition
    | Recurse SourceLocationRange
    | Cycle SourceLocationRange CycleData
    | Builtin SourceLocationRange Builtin
    | ConstructType TypeDefinition
    | SetMember TypeDefinition String Int Type
................................................................................

untypedToTypedNode : Int -> Context -> Qualifier.Node -> AstNode
untypedToTypedNode idx context untypedNode =
    case untypedNode of
        Qualifier.Integer range num ->
            IntLiteral range num





        Qualifier.Function range function ->
            let
                ( def, _ ) =
                    typeCheckDefinition function context
            in
            Function range def <|
                resolveGenericsInFunctionType idx context def.type_
................................................................................

        Qualifier.SetMember typeDef memberName memberIndex memberType ->
            SetMember typeDef memberName memberIndex memberType

        Qualifier.GetMember typeDef memberName memberIndex memberType ->
            GetMember typeDef memberName memberIndex memberType

        Qualifier.ArrayLiteral range _ ->
            -- TODO: Just get this to compile
            Recurse range


resolveGenericsInFunctionType : Int -> Context -> FunctionType -> FunctionType
resolveGenericsInFunctionType idx context wt =
    let
        replaceGenericWithBoundValue t =
            let
                boundType =
................................................................................

        Nothing ->
            context


typeCheckNode : Qualifier.FunctionDefinition -> Int -> Qualifier.Node -> Context -> Context
typeCheckNode currentDef idx node context =
    let

        addStackEffect ctx effects =
            { ctx | stackEffects = ctx.stackEffects ++ List.map (tagGenericEffect idx) effects }
    in







    case node of
        Qualifier.Integer _ _ ->
            addStackEffect context [ Push Type.Int ]




        Qualifier.Function _ untypedDef ->
            let
                ( def, contextWithTypedDef ) =
                    typeCheckDefinition untypedDef context

                newContext =
                    { contextWithTypedDef | stackEffects = context.stackEffects }
            in
            addStackEffect newContext <| functionTypeToStackEffects def.type_

        Qualifier.FunctionRef _ ref ->
            let
                stackEffectsBeforeFunctionCheck =
                    context.stackEffects

                ( def, contextAfterFunctionCheck ) =
                    typeCheckDefinition ref context

                newContext =
                    { contextAfterFunctionCheck | stackEffects = stackEffectsBeforeFunctionCheck }
            in

            addStackEffect newContext <|
                [ Push <| Type.FunctionSignature def.type_ ]


        Qualifier.Recurse _ ->
            case TypeSignature.toMaybe currentDef.typeSignature of
                Just annotatedType ->
                    addStackEffect context <| functionTypeToStackEffects annotatedType

                Nothing ->
                    let
                        problem =

                            MissingTypeAnnotationInRecursiveCallStack
                                (Maybe.withDefault SourceLocation.emptyRange currentDef.sourceLocation)
                                currentDef.name
                    in
                    { context | errors = problem :: context.errors }

        Qualifier.Cycle _ data ->
            case TypeSignature.toMaybe data.typeSignature of
                Just annotatedType ->
                    addStackEffect context <| functionTypeToStackEffects annotatedType

                Nothing ->
                    let
                        problem =

                            MissingTypeAnnotationInRecursiveCallStack
                                (Maybe.withDefault SourceLocation.emptyRange data.sourceLocation)
                                data.name
                    in
                    { context | errors = problem :: context.errors }

        Qualifier.ConstructType typeDef ->
            let
                memberTypes =
                    getStructMembers typeDef
                        |> List.map Tuple.second

                typeInQuestion =
                    getStructType typeDef
            in

            addStackEffect context <|
                functionTypeToStackEffects
                    { input = memberTypes
                    , output = [ typeInQuestion ]
                    }


        Qualifier.SetMember typeDef _ _ memberType ->
            let
                typeInQuestion =
                    getStructType typeDef
            in

            addStackEffect context <|
                functionTypeToStackEffects
                    { input = [ typeInQuestion, memberType ]
                    , output = [ typeInQuestion ]
                    }


        Qualifier.GetMember typeDef _ _ memberType ->
            let
                typeInQuestion =
                    getStructType typeDef
            in

            addStackEffect context <|
                functionTypeToStackEffects
                    { input = [ typeInQuestion ]
                    , output = [ memberType ]
                    }


        Qualifier.Builtin _ builtin ->


            addStackEffect context <| functionTypeToStackEffects <| Builtin.functionType builtin


        Qualifier.ArrayLiteral _ _ ->
            context







getStructMembers : TypeDefinition -> List ( String, Type )
getStructMembers typeDef =
    case typeDef.members of
        Qualifier.StructMembers members ->
            members







>







 







>
>
>
>







 







<
<
<
<







 







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


|
>
>
>









|












>
|
|
>




|


<
<
>
|
|
|
<
<




|


<
<
>
|
|
|
<
<










>
|
|



>






>
|
|



>






>
|
|



|
>

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







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
...
310
311
312
313
314
315
316




317
318
319
320
321
322
323
....
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178


1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224


1225
1226
1227
1228


1229
1230
1231
1232
1233
1234
1235


1236
1237
1238
1239


1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289


1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
    = LiteralInt Int
    | LiteralType Type
    | RecursiveMatch TypeMatch


type AstNode
    = IntLiteral SourceLocationRange Int
    | ArrayLiteral SourceLocationRange (List AstNode)
    | Function SourceLocationRange FunctionDefinition FunctionType
    | FunctionRef SourceLocationRange FunctionDefinition
    | Recurse SourceLocationRange
    | Cycle SourceLocationRange CycleData
    | Builtin SourceLocationRange Builtin
    | ConstructType TypeDefinition
    | SetMember TypeDefinition String Int Type
................................................................................

untypedToTypedNode : Int -> Context -> Qualifier.Node -> AstNode
untypedToTypedNode idx context untypedNode =
    case untypedNode of
        Qualifier.Integer range num ->
            IntLiteral range num

        Qualifier.ArrayLiteral range nodes ->
            ArrayLiteral range <|
                List.map (untypedToTypedNode idx context) nodes

        Qualifier.Function range function ->
            let
                ( def, _ ) =
                    typeCheckDefinition function context
            in
            Function range def <|
                resolveGenericsInFunctionType idx context def.type_
................................................................................

        Qualifier.SetMember typeDef memberName memberIndex memberType ->
            SetMember typeDef memberName memberIndex memberType

        Qualifier.GetMember typeDef memberName memberIndex memberType ->
            GetMember typeDef memberName memberIndex memberType






resolveGenericsInFunctionType : Int -> Context -> FunctionType -> FunctionType
resolveGenericsInFunctionType idx context wt =
    let
        replaceGenericWithBoundValue t =
            let
                boundType =
................................................................................

        Nothing ->
            context


typeCheckNode : Qualifier.FunctionDefinition -> Int -> Qualifier.Node -> Context -> Context
typeCheckNode currentDef idx node context =
    case nodeToStackEffect currentDef node context of
        Ok ( newContext, effects ) ->
            addStackEffect newContext idx effects



        Err error ->
            { context | errors = error :: context.errors }


nodeToStackEffect : Qualifier.FunctionDefinition -> Qualifier.Node -> Context -> Result Problem ( Context, List StackEffect )
nodeToStackEffect currentDef node context =
    case node of
        Qualifier.Integer _ _ ->
            Ok ( context, [ Push Type.Int ] )

        Qualifier.ArrayLiteral _ _ ->
            Ok ( context, [] )

        Qualifier.Function _ untypedDef ->
            let
                ( def, contextWithTypedDef ) =
                    typeCheckDefinition untypedDef context

                newContext =
                    { contextWithTypedDef | stackEffects = context.stackEffects }
            in
            Ok ( newContext, functionTypeToStackEffects def.type_ )

        Qualifier.FunctionRef _ ref ->
            let
                stackEffectsBeforeFunctionCheck =
                    context.stackEffects

                ( def, contextAfterFunctionCheck ) =
                    typeCheckDefinition ref context

                newContext =
                    { contextAfterFunctionCheck | stackEffects = stackEffectsBeforeFunctionCheck }
            in
            Ok
                ( newContext
                , [ Push <| Type.FunctionSignature def.type_ ]
                )

        Qualifier.Recurse _ ->
            case TypeSignature.toMaybe currentDef.typeSignature of
                Just annotatedType ->
                    Ok ( context, functionTypeToStackEffects annotatedType )

                Nothing ->


                    Err <|
                        MissingTypeAnnotationInRecursiveCallStack
                            (Maybe.withDefault SourceLocation.emptyRange currentDef.sourceLocation)
                            currentDef.name



        Qualifier.Cycle _ data ->
            case TypeSignature.toMaybe data.typeSignature of
                Just annotatedType ->
                    Ok ( context, functionTypeToStackEffects annotatedType )

                Nothing ->


                    Err <|
                        MissingTypeAnnotationInRecursiveCallStack
                            (Maybe.withDefault SourceLocation.emptyRange data.sourceLocation)
                            data.name



        Qualifier.ConstructType typeDef ->
            let
                memberTypes =
                    getStructMembers typeDef
                        |> List.map Tuple.second

                typeInQuestion =
                    getStructType typeDef
            in
            Ok
                ( context
                , functionTypeToStackEffects
                    { input = memberTypes
                    , output = [ typeInQuestion ]
                    }
                )

        Qualifier.SetMember typeDef _ _ memberType ->
            let
                typeInQuestion =
                    getStructType typeDef
            in
            Ok
                ( context
                , functionTypeToStackEffects
                    { input = [ typeInQuestion, memberType ]
                    , output = [ typeInQuestion ]
                    }
                )

        Qualifier.GetMember typeDef _ _ memberType ->
            let
                typeInQuestion =
                    getStructType typeDef
            in
            Ok
                ( context
                , functionTypeToStackEffects
                    { input = [ typeInQuestion ]
                    , output = [ memberType ]
                    }
                )

        Qualifier.Builtin _ builtin ->
            Ok
                ( context
                , functionTypeToStackEffects <|
                    Builtin.functionType builtin
                )




addStackEffect : Context -> Int -> List StackEffect -> Context
addStackEffect ctx idx effects =
    { ctx | stackEffects = ctx.stackEffects ++ List.map (tagGenericEffect idx) effects }


getStructMembers : TypeDefinition -> List ( String, Type )
getStructMembers typeDef =
    case typeDef.members of
        Qualifier.StructMembers members ->
            members