Stabel

Check-in [cfcc865e48]
Login
Overview
Comment:Begin re-write of builtin handling.
Timelines: family | ancestors | descendants | both | builtin-rewrite
Files: files | file ages | folders
SHA3-256: cfcc865e48de5211d906a1d00a61a07531e256a60cfee5ee1c16c1777dfdcea5
User & Date: robin.hansen on 2021-09-26 10:01:51
Other Links: branch diff | manifest | tags
Context
2021-09-29
19:50
Fix most Elm-based tests. check-in: a382b579ce user: robin.hansen tags: builtin-rewrite
2021-09-26
10:01
Begin re-write of builtin handling. check-in: cfcc865e48 user: robin.hansen tags: builtin-rewrite
2021-09-25
12:36
Error handling for fully qualified refs. This concludes the syntax changes language proposal. [c2996... Leaf check-in: 106eea3696 user: robin.hansen tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Stabel/Qualifier.elm from [baeb6b0c2a] to [2378ef46a7].

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
....
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
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
....
1314
1315
1316
1317
1318
1319
1320









1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
....
1517
1518
1519
1520
1521
1522
1523





1524
1525
1526
1527
1528
1529
1530
    , imports : Dict String (List String)
    }


builtinDict : Dict String Builtin
builtinDict =
    Dict.fromList
        [ ( "+", Builtin.Plus )
        , ( "-", Builtin.Minus )
        , ( "*", Builtin.Multiply )
        , ( "div", Builtin.Divide )
        , ( "=", Builtin.Equal )
        , ( "swap", Builtin.StackSwap )
        , ( "dup", Builtin.StackDuplicate )
        , ( "drop", Builtin.StackDrop )
        , ( "rotate", Builtin.StackRightRotate )
        , ( "-rotate", Builtin.StackLeftRotate )
        , ( "!", Builtin.Apply )
        , ( "array-length", Builtin.ArrayLength )
        , ( "array-push", Builtin.ArrayPush )
        , ( "array-get", Builtin.ArrayGet )
        , ( "array-set", Builtin.ArraySet )
        ]


type alias RunConfig =
    { packageName : String
    , modulePath : String
    , ast : Parser.AST
................................................................................
            }

        Parser.Function loc value ->
            -- TODO: Clean this branch up
            let
                qLoc =
                    mapLoc loc
            in
            case Dict.get value builtinDict of
                Just builtin ->
                    { acc | qualifiedNodes = Ok (Builtin qLoc builtin) :: acc.qualifiedNodes }

                Nothing ->
                    let
                        qualifiedName =
                            qualifyName config value
                    in
                    case Dict.get qualifiedName acc.qualifiedFunctions of
                        Just func ->
                            { acc | qualifiedNodes = Ok (Function qLoc func) :: acc.qualifiedNodes }

                        Nothing ->
                            case resolveImportedFunction config acc.modRefs value of
                                Just mod ->
                                    if representsExternalModule mod then
                                        let
                                            path =
                                                splitExternalPackagePath mod
                                                    -- drop author/package
                                                    |> List.drop 2
                                        in
                                        qualifyNode
                                            config
                                            currentDefName
                                            (Parser.ExternalFunction loc path value)
                                            acc

                                    else
                                        let
                                            path =
                                                splitInternalPackagePath mod
                                        in
                                        qualifyNode
                                            config
                                            currentDefName
                                            (Parser.PackageFunction loc path value)
                                            acc

                                Nothing ->
                                    if value == currentDefName then
                                        { acc | qualifiedNodes = Ok (Recurse qLoc) :: acc.qualifiedNodes }

                                    else
                                        case Dict.get value config.ast.functions of
                                            Just fn ->
                                                if Set.member value acc.currentlyParsing then
                                                    case qualifyMetadata config acc.qualifiedTypes fn of
                                                        Ok ( typeSignature, exposed ) ->
                                                            { acc
                                                                | qualifiedNodes =
                                                                    Ok
                                                                        (Cycle qLoc
                                                                            { name = value
                                                                            , sourceLocation = Maybe.map mapLoc fn.sourceLocationRange
                                                                            , typeSignature = typeSignature
                                                                            , exposed = exposed
                                                                            , isMultiFunction = isMultiFunction fn
                                                                            }
                                                                        )
                                                                        :: acc.qualifiedNodes
                                                            }

                                                        Err err ->
                                                            { acc | qualifiedNodes = Err err :: acc.qualifiedNodes }

                                                else
                                                    let
                                                        qualifyDefinitionResult =
                                                            qualifyDefinitionHelp
                                                                config
                                                                acc.qualifiedTypes
                                                                acc.qualifiedFunctions
                                                                (Set.insert fn.name acc.currentlyParsing)
                                                                fn
                                                    in
                                                    case qualifyDefinitionResult.qualifiedFunction of
                                                        Ok qualifiedFunction ->
                                                            { acc
                                                                | qualifiedNodes = Ok (Function qLoc qualifiedFunction) :: acc.qualifiedNodes
                                                                , qualifiedFunctions = qualifyDefinitionResult.qualifiedFunctions
                                                                , inlineFunctionNames =
                                                                    Set.union qualifyDefinitionResult.inlineFunctionNames acc.inlineFunctionNames
                                                                , currentlyParsing = Set.remove fn.name acc.currentlyParsing
                                                            }

                                                        Err err ->
                                                            { acc
                                                                | qualifiedNodes = Err err :: acc.qualifiedNodes
                                                                , currentlyParsing = Set.remove fn.name acc.currentlyParsing
                                                            }

                                            Nothing ->
                                                { acc | qualifiedNodes = Err (UnknownFunctionRef qLoc value) :: acc.qualifiedNodes }

        Parser.PackageFunction loc path value ->
            let
                qLoc =
                    mapLoc loc

                normalizedPathPreAliasCheck =
................................................................................
                                { acc | qualifiedNodes = Err (FunctionNotExposed qLoc fullReference) :: acc.qualifiedNodes }

        Parser.FullyQualifiedFunction loc ref ->
            let
                qLoc =
                    mapLoc loc
            in









            case Dict.get ref config.inProgressAST.functions of
                Nothing ->
                    { acc | qualifiedNodes = Err (UnknownFunctionRef qLoc ref) :: acc.qualifiedNodes }

                Just def ->
                    if def.exposed then
                        { acc | qualifiedNodes = Ok (Function qLoc def) :: acc.qualifiedNodes }

                    else
                        { acc | qualifiedNodes = Err (FunctionNotExposed qLoc ref) :: acc.qualifiedNodes }

        Parser.ConstructType typeName ->
            let
                qualifiedName =
                    qualifyName config typeName
            in
            case Dict.get qualifiedName acc.qualifiedTypes of
................................................................................
                            List.map (Parser.Integer loc) stringBytes
                        , Parser.ExternalFunction loc [ "string" ] "from-bytes"
                        ]
            in
            qualifyNode config currentDefName (Parser.Function loc "!") acc
                |> qualifyNode config currentDefName stringNode







isMultiFunction : Parser.FunctionDefinition -> Bool
isMultiFunction def =
    case def.implementation of
        Parser.SoloImpl _ ->
            False








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







 







<
<
<
<

<
<
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|

|
|







 







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

|
|
|

|
|







 







>
>
>
>
>







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
....
1137
1138
1139
1140
1141
1142
1143




1144


1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
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
....
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
....
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
    , imports : Dict String (List String)
    }


builtinDict : Dict String Builtin
builtinDict =
    Dict.fromList
        [ ( "/stabel/hidden/int/+", Builtin.Plus )
        , ( "/stabel/hidden/int/-", Builtin.Minus )
        , ( "/stabel/hidden/int/*", Builtin.Multiply )
        , ( "/stabel/hidden/int/div", Builtin.Divide )
        , ( "/stabel/hidden/int/=", Builtin.Equal )
        , ( "/stabel/hidden/stack/swap", Builtin.StackSwap )
        , ( "/stabel/hidden/stack/dup", Builtin.StackDuplicate )
        , ( "/stabel/hidden/stack/drop", Builtin.StackDrop )
        , ( "/stabel/hidden/stack/rotate", Builtin.StackRightRotate )
        , ( "/stabel/hidden/stack/-rotate", Builtin.StackLeftRotate )
        , ( "/stabel/hidden/stack/!", Builtin.Apply )
        , ( "/stabel/hidden/array/length", Builtin.ArrayLength )
        , ( "/stabel/hidden/array/push", Builtin.ArrayPush )
        , ( "/stabel/hidden/array/get", Builtin.ArrayGet )
        , ( "/stabel/hidden/array/set", Builtin.ArraySet )
        ]


type alias RunConfig =
    { packageName : String
    , modulePath : String
    , ast : Parser.AST
................................................................................
            }

        Parser.Function loc value ->
            -- TODO: Clean this branch up
            let
                qLoc =
                    mapLoc loc







                qualifiedName =
                    qualifyName config value
            in
            case Dict.get qualifiedName acc.qualifiedFunctions of
                Just func ->
                    { acc | qualifiedNodes = Ok (Function qLoc func) :: acc.qualifiedNodes }

                Nothing ->
                    case resolveImportedFunction config acc.modRefs value of
                        Just mod ->
                            if representsExternalModule mod then
                                let
                                    path =
                                        splitExternalPackagePath mod
                                            -- drop author/package
                                            |> List.drop 2
                                in
                                qualifyNode
                                    config
                                    currentDefName
                                    (Parser.ExternalFunction loc path value)
                                    acc

                            else
                                let
                                    path =
                                        splitInternalPackagePath mod
                                in
                                qualifyNode
                                    config
                                    currentDefName
                                    (Parser.PackageFunction loc path value)
                                    acc

                        Nothing ->
                            if value == currentDefName then
                                { acc | qualifiedNodes = Ok (Recurse qLoc) :: acc.qualifiedNodes }

                            else
                                case Dict.get value config.ast.functions of
                                    Just fn ->
                                        if Set.member value acc.currentlyParsing then
                                            case qualifyMetadata config acc.qualifiedTypes fn of
                                                Ok ( typeSignature, exposed ) ->
                                                    { acc
                                                        | qualifiedNodes =
                                                            Ok
                                                                (Cycle qLoc
                                                                    { name = value
                                                                    , sourceLocation = Maybe.map mapLoc fn.sourceLocationRange
                                                                    , typeSignature = typeSignature
                                                                    , exposed = exposed
                                                                    , isMultiFunction = isMultiFunction fn
                                                                    }
                                                                )
                                                                :: acc.qualifiedNodes
                                                    }

                                                Err err ->
                                                    { acc | qualifiedNodes = Err err :: acc.qualifiedNodes }

                                        else
                                            let
                                                qualifyDefinitionResult =
                                                    qualifyDefinitionHelp
                                                        config
                                                        acc.qualifiedTypes
                                                        acc.qualifiedFunctions
                                                        (Set.insert fn.name acc.currentlyParsing)
                                                        fn
                                            in
                                            case qualifyDefinitionResult.qualifiedFunction of
                                                Ok qualifiedFunction ->
                                                    { acc
                                                        | qualifiedNodes = Ok (Function qLoc qualifiedFunction) :: acc.qualifiedNodes
                                                        , qualifiedFunctions = qualifyDefinitionResult.qualifiedFunctions
                                                        , inlineFunctionNames =
                                                            Set.union qualifyDefinitionResult.inlineFunctionNames acc.inlineFunctionNames
                                                        , currentlyParsing = Set.remove fn.name acc.currentlyParsing
                                                    }

                                                Err err ->
                                                    { acc
                                                        | qualifiedNodes = Err err :: acc.qualifiedNodes
                                                        , currentlyParsing = Set.remove fn.name acc.currentlyParsing
                                                    }

                                    Nothing ->
                                        { acc | qualifiedNodes = Err (UnknownFunctionRef qLoc value) :: acc.qualifiedNodes }

        Parser.PackageFunction loc path value ->
            let
                qLoc =
                    mapLoc loc

                normalizedPathPreAliasCheck =
................................................................................
                                { acc | qualifiedNodes = Err (FunctionNotExposed qLoc fullReference) :: acc.qualifiedNodes }

        Parser.FullyQualifiedFunction loc ref ->
            let
                qLoc =
                    mapLoc loc
            in
            if String.startsWith "/stabel/hidden" ref && isStandardLibrary config then
                case Dict.get ref builtinDict of
                    Just builtin ->
                        { acc | qualifiedNodes = Ok (Builtin qLoc builtin) :: acc.qualifiedNodes }

                    Nothing ->
                        { acc | qualifiedNodes = Err (UnknownFunctionRef qLoc ref) :: acc.qualifiedNodes }

            else
                case Dict.get ref config.inProgressAST.functions of
                    Nothing ->
                        { acc | qualifiedNodes = Err (UnknownFunctionRef qLoc ref) :: acc.qualifiedNodes }

                    Just def ->
                        if def.exposed then
                            { acc | qualifiedNodes = Ok (Function qLoc def) :: acc.qualifiedNodes }

                        else
                            { acc | qualifiedNodes = Err (FunctionNotExposed qLoc ref) :: acc.qualifiedNodes }

        Parser.ConstructType typeName ->
            let
                qualifiedName =
                    qualifyName config typeName
            in
            case Dict.get qualifiedName acc.qualifiedTypes of
................................................................................
                            List.map (Parser.Integer loc) stringBytes
                        , Parser.ExternalFunction loc [ "string" ] "from-bytes"
                        ]
            in
            qualifyNode config currentDefName (Parser.Function loc "!") acc
                |> qualifyNode config currentDefName stringNode


isStandardLibrary : RunConfig -> Bool
isStandardLibrary config =
    config.packageName == "stabel/standard_library"


isMultiFunction : Parser.FunctionDefinition -> Bool
isMultiFunction def =
    case def.implementation of
        Parser.SoloImpl _ ->
            False