Play

Check-in [f477fd7e39]
Login
Overview
Comment:Parser now supports relative and absolut module references.
Timelines: family | ancestors | descendants | both | modules
Files: files | file ages | folders
SHA3-256: f477fd7e397de29112368feb700e8aed9a8cd1b0a4de841d7c1bdbf7b1e73c91
User & Date: robin.hansen on 2021-02-03 09:10:05
Other Links: branch diff | manifest | tags
Context
2021-02-03
12:46
Perform additional testing on module references to catch invalid module paths. check-in: 0f02eed1b4 user: robin.hansen tags: modules
09:10
Parser now supports relative and absolut module references. check-in: f477fd7e39 user: robin.hansen tags: modules
2021-02-01
05:29
Update dependencies check-in: 98700dab4b user: robin.hansen tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Modified src/Play/Parser.elm from [0674f5af9e] to [d6fa451fc6].

57
58
59
60
61
62
63


64
65
66
67
68
69
70
..
94
95
96
97
98
99
100

101

102
103
104
105
106
107
108
...
174
175
176
177
178
179
180




















































181
182
183
184
185
186
187
...
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
    | LiteralType Type
    | RecursiveMatch TypeMatch


type AstNode
    = Integer SourceLocationRange Int
    | Word SourceLocationRange String


    | Quotation SourceLocationRange (List AstNode)
    | ConstructType String
    | GetMember String String
    | SetMember String String


run : String -> Result (List Problem) AST
................................................................................
        , '{'
        , '}'
        , '['
        , ']'
        , '('
        , ')'
        , '.'

        , '#'

        ]


whitespaceChars : Set Char
whitespaceChars =
    Set.fromList
        [ ' '
................................................................................
                |. Parser.symbol (Token ":" NotMetadata)
                |> Parser.andThen (\_ -> Parser.problem FoundMetadata)
            , Parser.succeed identity
            ]
        |. noiseParser
        |> Parser.backtrackable






















































definitionMetadataParser : Parser String
definitionMetadataParser =
    Parser.variable
        { start = \c -> not (Char.isDigit c || Char.isUpper c || Set.member c invalidSymbolChars)
        , inner = validSymbolChar
        , reserved = Set.fromList [ "def", "defmulti", "defstruct", "defunion" ]
................................................................................
nodeParser : Parser AstNode
nodeParser =
    Parser.oneOf
        [ Parser.succeed (\startLoc value endLoc -> Integer (SourceLocationRange startLoc endLoc) value)
            |= sourceLocationParser
            |= intParser
            |= sourceLocationParser
        , Parser.succeed (\startLoc value endLoc -> Word (SourceLocationRange startLoc endLoc) value)
            |= sourceLocationParser
            |= symbolImplParser
            |= sourceLocationParser
        ]


typeDefinitionName : TypeDefinition -> String
typeDefinitionName typeDef =
    case typeDef of







>
>







 







>

>







 







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







 







|

|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
...
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
    | LiteralType Type
    | RecursiveMatch TypeMatch


type AstNode
    = Integer SourceLocationRange Int
    | Word SourceLocationRange String
    | PackageWord SourceLocationRange (List String) String
    | ExternalWord SourceLocationRange (List String) String
    | Quotation SourceLocationRange (List AstNode)
    | ConstructType String
    | GetMember String String
    | SetMember String String


run : String -> Result (List Problem) AST
................................................................................
        , '{'
        , '}'
        , '['
        , ']'
        , '('
        , ')'
        , '.'
        , ','
        , '#'
        , '/'
        ]


whitespaceChars : Set Char
whitespaceChars =
    Set.fromList
        [ ' '
................................................................................
                |. Parser.symbol (Token ":" NotMetadata)
                |> Parser.andThen (\_ -> Parser.problem FoundMetadata)
            , Parser.succeed identity
            ]
        |. noiseParser
        |> Parser.backtrackable


symbolImplParser2 : Parser (SourceLocationRange -> AstNode)
symbolImplParser2 =
    let
        externalBuilder firstSymbol ( path, reference ) =
            \loc ->
                ExternalWord loc (firstSymbol :: path) reference

        internalBuilder firstSymbol (( path, reference ) as modulePathResult) =
            \loc ->
                if modulePathResult == ( [], "" ) then
                    Word loc firstSymbol

                else
                    PackageWord loc (firstSymbol :: path) reference
    in
    Parser.oneOf
        [ Parser.succeed externalBuilder
            |. Parser.symbol (Token "/" NotMetadata)
            |= symbolImplParser
            |= Parser.loop [] modulePathParser
        , Parser.succeed internalBuilder
            |= symbolImplParser
            |= Parser.oneOf
                [ Parser.loop [] modulePathParser
                , Parser.succeed ( [], "" )
                ]
        ]


modulePathParser : List String -> Parser (Parser.Step (List String) ( List String, String ))
modulePathParser symbols =
    Parser.oneOf
        [ Parser.succeed (\name -> Parser.Loop (name :: symbols))
            |. Parser.symbol (Token "/" NotMetadata)
            |= symbolImplParser
        , Parser.succeed (Parser.Done (modulePathFinalizer symbols))
        ]


modulePathFinalizer : List String -> ( List String, String )
modulePathFinalizer symbols =
    case symbols of
        [] ->
            ( [], "" )

        [ only ] ->
            ( [], only )

        first :: rest ->
            ( List.reverse rest, first )


definitionMetadataParser : Parser String
definitionMetadataParser =
    Parser.variable
        { start = \c -> not (Char.isDigit c || Char.isUpper c || Set.member c invalidSymbolChars)
        , inner = validSymbolChar
        , reserved = Set.fromList [ "def", "defmulti", "defstruct", "defunion" ]
................................................................................
nodeParser : Parser AstNode
nodeParser =
    Parser.oneOf
        [ Parser.succeed (\startLoc value endLoc -> Integer (SourceLocationRange startLoc endLoc) value)
            |= sourceLocationParser
            |= intParser
            |= sourceLocationParser
        , Parser.succeed (\startLoc builder endLoc -> builder (SourceLocationRange startLoc endLoc))
            |= sourceLocationParser
            |= symbolImplParser2
            |= sourceLocationParser
        ]


typeDefinitionName : TypeDefinition -> String
typeDefinitionName typeDef =
    case typeDef of

Modified src/Play/Qualifier.elm from [51e4fe35b3] to [827f443bbe].

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
...
429
430
431
432
433
434
435






436
437
438
439
440
441
442

builtinDict : Dict String Builtin
builtinDict =
    Dict.fromList
        [ ( "+", Builtin.Plus )
        , ( "-", Builtin.Minus )
        , ( "*", Builtin.Multiply )
        , ( "/", Builtin.Divide )
        , ( "=", Builtin.Equal )
        , ( "swap", Builtin.StackSwap )
        , ( "dup", Builtin.StackDuplicate )
        , ( "drop", Builtin.StackDrop )
        , ( "rotate", Builtin.StackRightRotate )
        , ( "-rotate", Builtin.StackLeftRotate )
        , ( "!", Builtin.Apply )
................................................................................

                    Nothing ->
                        ( availableQuoteId
                        , qualifiedWords
                        , Err (UnknownWordRef loc value) :: qualifiedNodes
                        )







        Parser.ConstructType typeName ->
            ( availableQuoteId
            , qualifiedWords
            , Ok (ConstructType typeName) :: qualifiedNodes
            )

        Parser.SetMember typeName memberName ->







|







 







>
>
>
>
>
>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
...
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

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 )
................................................................................

                    Nothing ->
                        ( availableQuoteId
                        , qualifiedWords
                        , Err (UnknownWordRef loc value) :: qualifiedNodes
                        )

        Parser.PackageWord loc path value ->
            qualifyNode ast currentDefName (Parser.Word loc value) ( availableQuoteId, qualifiedWords, qualifiedNodes )

        Parser.ExternalWord loc path value ->
            qualifyNode ast currentDefName (Parser.Word loc value) ( availableQuoteId, qualifiedWords, qualifiedNodes )

        Parser.ConstructType typeName ->
            ( availableQuoteId
            , qualifiedWords
            , Ok (ConstructType typeName) :: qualifiedNodes
            )

        Parser.SetMember typeName memberName ->

Modified tests/Test/Parser.elm from [a3937d228f] to [183827d1df].

706
707
708
709
710
711
712


























































713
714
715
716
717
718
719
                                                  , [ AST.Word emptyRange "True" ]
                                                  )
                                                ]
                                                [ AST.Word emptyRange "False" ]
                                      }
                                    ]
                            }


























































                    in
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast







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







706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
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
                                                  , [ AST.Word emptyRange "True" ]
                                                  )
                                                ]
                                                [ AST.Word emptyRange "False" ]
                                      }
                                    ]
                            }
                    in
                    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
                            """

                        expectedAst =
                            { types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "test"
                                      , metadata = Metadata.default
                                      , implementation =
                                            SoloImpl
                                                [ AST.PackageWord emptyRange [ "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
                            """

                        expectedAst =
                            { types = Dict.empty
                            , words =
                                Dict.fromListBy .name
                                    [ { name = "test"
                                      , metadata = Metadata.default
                                      , implementation =
                                            SoloImpl
                                                [ AST.ExternalWord emptyRange [ "some", "module" ] "sample" ]
                                      }
                                    ]
                            }
                    in
                    case compile source of
                        Err _ ->
                            Expect.fail "Did not expect parsing to fail"

                        Ok ast ->
                            Expect.equal expectedAst ast

Modified tests/Test/Parser/Util.elm from [34556264c0] to [d64d255e03].

70
71
72
73
74
75
76






77
78
79
80
81
82
83
    case node of
        AST.Integer _ val ->
            AST.Integer emptyRange val

        AST.Word _ val ->
            AST.Word emptyRange val







        AST.Quotation _ val ->
            AST.Quotation emptyRange (List.map stripNodeLocation val)

        _ ->
            node









>
>
>
>
>
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
    case node of
        AST.Integer _ val ->
            AST.Integer emptyRange val

        AST.Word _ val ->
            AST.Word emptyRange val

        AST.PackageWord _ path val ->
            AST.PackageWord emptyRange path val

        AST.ExternalWord _ path val ->
            AST.ExternalWord emptyRange path val

        AST.Quotation _ val ->
            AST.Quotation emptyRange (List.map stripNodeLocation val)

        _ ->
            node


Modified wasm_tests/math.test.js from [427aff9e64] to [3440282ac4].

36
37
38
39
40
41
42
43
44
45
46
47
48
49
    expect(result.stackElement()).toBe(15);
});

test('Division', async () => {
    const wat = await compiler.toWat(`
        def: main
        entry: true
        : 10 5 /
    `);

    const result = await compiler.run(wat, 'main');

    expect(result.stackElement()).toBe(2);
});







|






36
37
38
39
40
41
42
43
44
45
46
47
48
49
    expect(result.stackElement()).toBe(15);
});

test('Division', async () => {
    const wat = await compiler.toWat(`
        def: main
        entry: true
        : 10 5 div
    `);

    const result = await compiler.run(wat, 'main');

    expect(result.stackElement()).toBe(2);
});