Stabel

Check-in [106eea3696]
Login
Overview
Comment:Error handling for fully qualified refs. This concludes the syntax changes language proposal. [c2996a5e70]
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 106eea3696dafcd1124e6c753d46c6714e0668b4fade79465294cfa3e36dd210
User & Date: robin.hansen on 2021-09-25 12:36:40
Other Links: manifest | tags
Context
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
12:16
Integration test for fully qualified functions. check-in: 7403f0755f user: robin.hansen tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Stabel/Parser.elm from [cd560c0df7] to [524d18d84c].

1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509



























































            |= qualifiedSymbolImplParser
            |= sourceLocationParser
        ]


qualifiedSymbolImplParser : Parser (SourceLocationRange -> AstNode)
qualifiedSymbolImplParser =
    let
        fullyQualifiedBuilder firstPath ( restPath, functionName ) =
            let
                path =
                    firstPath :: restPath

                ref =
                    "/" ++ String.join "/" path ++ "/" ++ functionName
            in
            if checkForUpperCaseLetterInPath path then
                Parser.problem <| InvalidModulePath <| "/" ++ String.join "/" path

            else if List.length path == 0 then
                Parser.problem <| InvalidModulePath <| ref

            else
                Parser.succeed <|
                    \loc ->
                        FullyQualifiedFunction loc ref

        externalBuilder ( path, reference ) =
            if checkForUpperCaseLetterInPath path then
                Parser.problem <| InvalidModulePath <| "/" ++ String.join "/" path

            else if List.length path == 0 then
                Parser.problem <| InvalidModulePath <| "/" ++ String.join "/" path ++ "/" ++ reference

            else
                Parser.succeed <|
                    \loc ->
                        ExternalFunction loc path reference

        internalBuilder firstSymbol (( partialPath, reference ) as modulePathResult) =
            let
                path =
                    firstSymbol :: partialPath
            in
            if checkForUpperCaseLetterInPath path && partialPath /= [] then
                Parser.problem <| InvalidModulePath <| String.join "/" path

            else
                Parser.succeed <|
                    \loc ->
                        if modulePathResult == ( [], "" ) then
                            Function loc firstSymbol

                        else
                            PackageFunction loc path reference

        checkForUpperCaseLetterInPath path =
            List.any (String.any Char.isUpper) path
    in
    Parser.oneOf
        [ Parser.succeed internalBuilder
            |= symbolImplParser
            |= Parser.loop [] modulePathParser
            |> Parser.andThen identity
        , Parser.succeed fullyQualifiedBuilder
            |. Parser.token (Token "//" ExpectedForwardSlash)
            |= symbolImplParser
            |= Parser.loop [] modulePathParser
            |> Parser.andThen identity
        , Parser.succeed identity
            |= Parser.loop [] modulePathParser
            |> Parser.andThen externalBuilder
        ]


































































<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|



|






|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1437
1438
1439
1440
1441
1442
1443




















































1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
            |= qualifiedSymbolImplParser
            |= sourceLocationParser
        ]


qualifiedSymbolImplParser : Parser (SourceLocationRange -> AstNode)
qualifiedSymbolImplParser =




















































    Parser.oneOf
        [ Parser.succeed internalRefBuilder
            |= symbolImplParser
            |= Parser.loop [] modulePathParser
            |> Parser.andThen identity
        , Parser.succeed fullyQualifiedRefBuilder
            |. Parser.token (Token "//" ExpectedForwardSlash)
            |= symbolImplParser
            |= Parser.loop [] modulePathParser
            |> Parser.andThen identity
        , Parser.succeed identity
            |= Parser.loop [] modulePathParser
            |> Parser.andThen externalRefBuilder
        ]


fullyQualifiedRefBuilder : String -> ( List String, String ) -> Parser (SourceLocationRange -> AstNode)
fullyQualifiedRefBuilder firstPath ( restPath, functionName ) =
    let
        path =
            firstPath :: restPath

        ref =
            "/" ++ String.join "/" path ++ "/" ++ functionName
    in
    if checkForUpperCaseLetterInPath path then
        Parser.problem <| InvalidModulePath <| "/" ++ String.join "/" path

    else if List.length path < 3 then
        Parser.problem <| InvalidModulePath <| ref

    else
        Parser.succeed <|
            \loc ->
                FullyQualifiedFunction loc ref


externalRefBuilder : ( List String, String ) -> Parser (SourceLocationRange -> AstNode)
externalRefBuilder ( path, reference ) =
    if checkForUpperCaseLetterInPath path then
        Parser.problem <| InvalidModulePath <| "/" ++ String.join "/" path

    else if List.length path == 0 then
        Parser.problem <| InvalidModulePath <| "/" ++ String.join "/" path ++ "/" ++ reference

    else
        Parser.succeed <|
            \loc ->
                ExternalFunction loc path reference


internalRefBuilder : String -> ( List String, String ) -> Parser (SourceLocationRange -> AstNode)
internalRefBuilder firstSymbol (( partialPath, reference ) as modulePathResult) =
    let
        path =
            firstSymbol :: partialPath
    in
    if checkForUpperCaseLetterInPath path && partialPath /= [] then
        Parser.problem <| InvalidModulePath <| String.join "/" path

    else
        Parser.succeed <|
            \loc ->
                if modulePathResult == ( [], "" ) then
                    Function loc firstSymbol

                else
                    PackageFunction loc path reference


checkForUpperCaseLetterInPath : List String -> Bool
checkForUpperCaseLetterInPath path =
    List.any (String.any Char.isUpper) path

Modified tests/Test/Parser/Errors.elm from [9aaaba3e40] to [52291c75ea].

177
178
179
180
181
182
183




























184
185
186
187
188
189
190
                        """
            , test "External reference must contain two parts" <|
                \_ ->
                    checkForError invalidModulePathError <|
                        """
                        def: sample
                        : /some




























                        """
            ]
        , describe "ModuleIsEmpty" <|
            let
                emptyModuleErr problem =
                    case problem of
                        ModuleIsEmpty ->







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







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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
                        """
            , test "External reference must contain two parts" <|
                \_ ->
                    checkForError invalidModulePathError <|
                        """
                        def: sample
                        : /some
                        """
            , test "Fully qualified reference cannot be empty" <|
                \_ ->
                    checkForError ((==) ExpectedSymbol) <|
                        """
                        def: sample
                        : //
                        """
            , test "Fully qualified reference cannot contain one part" <|
                \_ ->
                    checkForError invalidModulePathError <|
                        """
                        def: sample
                        : //some
                        """
            , test "Fully qualified reference cannot contain two parts" <|
                \_ ->
                    checkForError invalidModulePathError <|
                        """
                        def: sample
                        : //some/other
                        """
            , test "Fully qualified cannot containt three parts" <|
                \_ ->
                    checkForError invalidModulePathError <|
                        """
                        def: sample
                        : //some/other/module
                        """
            ]
        , describe "ModuleIsEmpty" <|
            let
                emptyModuleErr problem =
                    case problem of
                        ModuleIsEmpty ->