Stabel

Check-in [4a96b863d6]
Login
Overview
Comment:Parser now understands internal and external references in type signature.
Timelines: family | ancestors | descendants | both | module-definition
Files: files | file ages | folders
SHA3-256: 4a96b863d65d2004d1c96d22f3ab775a61eb9712d598075f19abc8c06dca0fdb
User & Date: robin.hansen on 2021-05-20 16:23:54
Other Links: branch diff | manifest | tags
Context
2021-05-21
14:42
Parser now understands module referenced types in pattern matches. check-in: 8a392255da user: robin.hansen tags: module-definition
2021-05-20
16:23
Parser now understands internal and external references in type signature. check-in: 4a96b863d6 user: robin.hansen tags: module-definition
2021-05-19
12:56
Fix tests. check-in: 08ceb30476 user: robin.hansen tags: module-definition
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Play/Parser.elm from [a554f04633] to [5d132bcc2b].

225
226
227
228
229
230
231

















232
233
234
235
236
237
238
...
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
432
433
434
435
...
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
                |. Parser.symbol (Token ":" NotMetadata)
                |> Parser.andThen (\_ -> Parser.problem FoundMetadata)
            , Parser.succeed identity
            ]
        |. noiseParser
        |> Parser.backtrackable



















symbolImplParser : Parser String
symbolImplParser =
    Parser.variable
        { start = \c -> not (Char.isDigit c || Set.member c invalidSymbolChars)
        , inner = validSymbolChar
        , reserved = Set.empty
................................................................................
    let
        helper value =
            Parser.oneOf
                [ Parser.succeed (StackRange value)
                    |. Parser.symbol (Token "..." NoProblem)
                    |. noiseParser
                , Parser.succeed (Generic value)

                ]
    in
    Parser.andThen helper genericParser


typeParser : Parser PossiblyQualifiedType
typeParser =
................................................................................
    Parser.succeed (\name -> LocalRef name [])
        |= typeNameParser


typeRefParser : Parser PossiblyQualifiedType
typeRefParser =
    Parser.oneOf
        [ Parser.succeed (\name binds -> LocalRef name binds)
            |= typeNameParser







            |= Parser.loop [] typeOrGenericParser
        , Parser.succeed Generic
            |= genericParser
        , Parser.succeed identity
            |. Parser.symbol (Token "(" ExpectedLeftParen)
            |. noiseParser
            |= Parser.lazy (\_ -> typeRefParser)
            |. Parser.symbol (Token ")" ExpectedRightParen)
            |. noiseParser
        ]

























typeOrGenericParser : List PossiblyQualifiedType -> Parser (Parser.Step (List PossiblyQualifiedType) (List PossiblyQualifiedType))
typeOrGenericParser types =
    Parser.oneOf
        [ Parser.succeed (\name -> Parser.Loop (LocalRef name [] :: types))
            |= typeNameParser
        , Parser.succeed (\name -> Parser.Loop (Generic name :: types))
................................................................................
typeLoopParser reverseTypes =
    let
        step type_ =
            Parser.Loop (type_ :: reverseTypes)
    in
    Parser.oneOf
        [ Parser.succeed step
            |= typeParser
        , Parser.succeed step
            |= genericOrRangeParser
        , Parser.succeed step
            |= typeRefParser
        , Parser.succeed (\wordType -> step (QuotationType wordType))
            |. Parser.symbol (Token "[" ExpectedLeftBracket)
            |. noiseParser
            |= typeSignatureParser







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







 







>







 







|

>
>
>
>
>
>
>











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







 







<
<







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
...
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
...
944
945
946
947
948
949
950


951
952
953
954
955
956
957
                |. Parser.symbol (Token ":" NotMetadata)
                |> Parser.andThen (\_ -> Parser.problem FoundMetadata)
            , Parser.succeed identity
            ]
        |. noiseParser
        |> Parser.backtrackable


symbolParser2 : Parser String
symbolParser2 =
    Parser.variable
        { start = \c -> not (Char.isDigit c || Char.isUpper c || Set.member c invalidSymbolChars)
        , inner = validSymbolChar
        , reserved = Set.empty
        , expecting = NotSymbol
        }
        |. Parser.oneOf
            [ Parser.succeed identity
                |. Parser.symbol (Token ":" NotMetadata)
                |> Parser.andThen (\_ -> Parser.problem FoundMetadata)
            , Parser.succeed identity
            ]
        |> Parser.backtrackable


symbolImplParser : Parser String
symbolImplParser =
    Parser.variable
        { start = \c -> not (Char.isDigit c || Set.member c invalidSymbolChars)
        , inner = validSymbolChar
        , reserved = Set.empty
................................................................................
    let
        helper value =
            Parser.oneOf
                [ Parser.succeed (StackRange value)
                    |. Parser.symbol (Token "..." NoProblem)
                    |. noiseParser
                , Parser.succeed (Generic value)
                    |. Parser.chompIf (\c -> Set.member c whitespaceChars) NoProblem
                ]
    in
    Parser.andThen helper genericParser


typeParser : Parser PossiblyQualifiedType
typeParser =
................................................................................
    Parser.succeed (\name -> LocalRef name [])
        |= typeNameParser


typeRefParser : Parser PossiblyQualifiedType
typeRefParser =
    Parser.oneOf
        [ Parser.succeed LocalRef
            |= typeNameParser
            |= Parser.loop [] typeOrGenericParser
        , Parser.succeed (\( path, name ) binds -> ExternalRef path name binds)
            |. Parser.symbol (Token "/" NoProblem)
            |= Parser.loop [] modularizedTypeRefParser
            |= Parser.loop [] typeOrGenericParser
        , Parser.succeed (\( path, name ) binds -> InternalRef path name binds)
            |= Parser.loop [] modularizedTypeRefParser
            |= Parser.loop [] typeOrGenericParser
        , Parser.succeed Generic
            |= genericParser
        , Parser.succeed identity
            |. Parser.symbol (Token "(" ExpectedLeftParen)
            |. noiseParser
            |= Parser.lazy (\_ -> typeRefParser)
            |. Parser.symbol (Token ")" ExpectedRightParen)
            |. noiseParser
        ]


modularizedTypeRefParser :
    List String
    -> Parser (Parser.Step (List String) ( List String, String ))
modularizedTypeRefParser reversedPath =
    let
        onType type_ =
            Parser.Done
                ( List.reverse reversedPath
                , type_
                )

        addToPath pathPiece =
            Parser.Loop (pathPiece :: reversedPath)
    in
    Parser.oneOf
        [ Parser.succeed onType
            |= typeNameParser
        , Parser.succeed addToPath
            |= symbolParser2
            |. Parser.symbol (Token "/" NoProblem)
        ]


typeOrGenericParser : List PossiblyQualifiedType -> Parser (Parser.Step (List PossiblyQualifiedType) (List PossiblyQualifiedType))
typeOrGenericParser types =
    Parser.oneOf
        [ Parser.succeed (\name -> Parser.Loop (LocalRef name [] :: types))
            |= typeNameParser
        , Parser.succeed (\name -> Parser.Loop (Generic name :: types))
................................................................................
typeLoopParser reverseTypes =
    let
        step type_ =
            Parser.Loop (type_ :: reverseTypes)
    in
    Parser.oneOf
        [ Parser.succeed step


            |= genericOrRangeParser
        , Parser.succeed step
            |= typeRefParser
        , Parser.succeed (\wordType -> step (QuotationType wordType))
            |. Parser.symbol (Token "[" ExpectedLeftBracket)
            |. noiseParser
            |= typeSignatureParser

Modified tests/Test/Parser.elm from [3e33dc568d] to [0d58f89141].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
...
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
...
902
903
904
905
906
907
908














































































909
910
911
912
913
914
915
...
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
....
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
module Test.Parser exposing (..)

import Dict
import Dict.Extra as Dict
import Expect
import Play.Data.Metadata as Metadata
import Play.Data.SourceLocation
    exposing
        ( SourceLocation
        , SourceLocationRange
        , emptyRange
        )
import Play.Data.Type as Type
import Play.Parser as AST exposing (..)
import Set
import Test exposing (Test, describe, test)
import Test.Parser.Util
    exposing
        ( addFunctionsForStructs
        , compile
................................................................................
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast
            ]
        , describe "modules" <|
            [ test "internal reference" <|
                \_ ->
                    let
                        source =
                            """
                            def: test
                            : some/module/sample
                            """
................................................................................
                    in
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast
            , test "external reference" <|
                \_ ->
                    let
                        source =
                            """
                            def: test
                            : /some/module/sample
                            """
................................................................................
                    in
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast
            , test "internal _and_ external reference" <|
                \_ ->
                    let
                        source =
                            """
                            def: test
                            : internal/sample /some/module/sample
                            """
................................................................................
                    in
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast














































































            ]
        , test "Support code comments" <|
            \_ ->
                expectCompiles
                    """
                    # Increments the passed in value by one
                    def: inc
................................................................................
                    : 1
                      # + wouldnt work here
                      -

                    # And thats it!
                     # wonder what else we should do...
                    """
        , test "definition without implementation should be legal" <|
            \_ ->
                expectCompiles
                    """
                    def: someword
                    """
        , test "Correct line information" <|
            \_ ->
................................................................................
                in
                case compileRetainLocations source of
                    Err _ ->
                        Expect.fail "Did not expect compilation to fail."

                    Ok ast ->
                        Expect.equal expectedAst ast
        , describe "Modules"
            [ test "Module definition" <|
                \_ ->
                    let
                        source =
                            """
                            defmodule:
                            alias: other /some/mod
                            alias: moar local/mod





<






<







 







|
|







 







|







 







|







 







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







 







|







 







|
|







1
2
3
4
5

6
7
8
9
10
11

12
13
14
15
16
17
18
...
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
...
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
...
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
...
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
....
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
....
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
module Test.Parser exposing (..)

import Dict
import Dict.Extra as Dict
import Expect

import Play.Data.SourceLocation
    exposing
        ( SourceLocation
        , SourceLocationRange
        , emptyRange
        )

import Play.Parser as AST exposing (..)
import Set
import Test exposing (Test, describe, test)
import Test.Parser.Util
    exposing
        ( addFunctionsForStructs
        , compile
................................................................................
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast
            ]
        , describe "Modules" <|
            [ test "Internal word reference" <|
                \_ ->
                    let
                        source =
                            """
                            def: test
                            : some/module/sample
                            """
................................................................................
                    in
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast
            , test "External word reference" <|
                \_ ->
                    let
                        source =
                            """
                            def: test
                            : /some/module/sample
                            """
................................................................................
                    in
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast
            , test "Internal _and_ external word reference" <|
                \_ ->
                    let
                        source =
                            """
                            def: test
                            : internal/sample /some/module/sample
                            """
................................................................................
                    in
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast
            , test "Internal types in type signature" <|
                \_ ->
                    let
                        source =
                            """
                            def: test
                            type: internal/Tipe -- Int
                            : drop 1
                            """

                        expectedAst =
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "test"
                                      , typeSignature =
                                            UserProvided
                                                { input = [ InternalRef [ "internal" ] "Tipe" [] ]
                                                , output = [ LocalRef "Int" [] ]
                                                }
                                      , sourceLocationRange = Nothing
                                      , aliases = Dict.empty
                                      , imports = Dict.empty
                                      , implementation =
                                            SoloImpl
                                                [ AST.Word emptyRange "drop"
                                                , AST.Integer emptyRange 1
                                                ]
                                      }
                                    ]
                            }
                    in
                    case compile source of
                        Err err ->
                            Expect.fail <| "Did not expect parsing to fail: " ++ Debug.toString err

                        Ok ast ->
                            Expect.equal expectedAst ast
            , test "External types in type signature" <|
                \_ ->
                    let
                        source =
                            """
                            def: test
                            type: /external/Tipe -- Int
                            : drop 1
                            """

                        expectedAst =
                            { moduleDefinition = AST.emptyModuleDefinition
                            , types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "test"
                                      , typeSignature =
                                            UserProvided
                                                { input = [ ExternalRef [ "external" ] "Tipe" [] ]
                                                , output = [ LocalRef "Int" [] ]
                                                }
                                      , sourceLocationRange = Nothing
                                      , aliases = Dict.empty
                                      , imports = Dict.empty
                                      , implementation =
                                            SoloImpl
                                                [ AST.Word emptyRange "drop"
                                                , AST.Integer emptyRange 1
                                                ]
                                      }
                                    ]
                            }
                    in
                    case compile source of
                        Err err ->
                            Expect.fail <| "Did not expect parsing to fail: " ++ Debug.toString err

                        Ok ast ->
                            Expect.equal expectedAst ast
            ]
        , test "Support code comments" <|
            \_ ->
                expectCompiles
                    """
                    # Increments the passed in value by one
                    def: inc
................................................................................
                    : 1
                      # + wouldnt work here
                      -

                    # And thats it!
                     # wonder what else we should do...
                    """
        , test "Definition without implementation should be legal" <|
            \_ ->
                expectCompiles
                    """
                    def: someword
                    """
        , test "Correct line information" <|
            \_ ->
................................................................................
                in
                case compileRetainLocations source of
                    Err _ ->
                        Expect.fail "Did not expect compilation to fail."

                    Ok ast ->
                        Expect.equal expectedAst ast
        , describe "Module definitions"
            [ test "Imports and aliases" <|
                \_ ->
                    let
                        source =
                            """
                            defmodule:
                            alias: other /some/mod
                            alias: moar local/mod