@@ -65,7 +65,7 @@ spaceParser =
6565parser : Parser Context Error AST.Module
6666parser =
6767 Parser.succeed
68- (\name exports docs imports binops decls ->
68+ (\{ name, effects } exports docs imports binops decls ->
6969 let
7070 values =
7171 Array.mapAndKeepJust declarationToModuleValue decls
@@ -90,23 +90,39 @@ parser =
9090 , effects =
9191 when ports is
9292 [] ->
93- AST.NoEffects
93+ -- TODO: support both ports and effects
94+ -- currently, only kernel devs can define effects
95+ -- so don't worry about it for now
96+ effects
9497
9598 _ ->
9699 AST.Ports ports
97100 }
98101 )
99- |> Parser.skip
102+ |> Parser.keep
100103 (Parser.oneOf
101- [ Parser.succeed {}
102- |> Parser.skip (Parser.token "port" (ExpectedKeyword "port"))
104+ [ Parser.succeed (\name effects -> { name = name, effects = AST.Manager effects })
105+ |> Parser.skip (Parser.token "effect" (ExpectedKeyword "effect"))
106+ |> Parser.skip spaceParser
107+ |> Parser.skip (Parser.token "module" (ExpectedKeyword "module"))
108+ |> Parser.skip spaceParser
109+ |> Parser.keep moduleNameParser
110+ |> Parser.skip spaceParser
111+ |> Parser.keep effectParser
112+ , Parser.succeed (\name -> { name = name, effects = AST.NoEffects })
113+ |> Parser.skip
114+ (Parser.oneOf
115+ [ Parser.succeed {}
116+ |> Parser.skip (Parser.token "port" (ExpectedKeyword "port"))
117+ |> Parser.skip spaceParser
118+ , Parser.succeed {}
119+ ]
120+ )
121+ |> Parser.skip (Parser.token "module" (ExpectedKeyword "module"))
103122 |> Parser.skip spaceParser
104- , Parser.succeed {}
123+ |> Parser.keep moduleNameParser
105124 ]
106125 )
107- |> Parser.skip (Parser.token "module" (ExpectedKeyword "module"))
108- |> Parser.skip spaceParser
109- |> Parser.keep moduleNameParser
110126 |> Parser.skip spaceParser
111127 |> Parser.keep parseExposingStatement
112128 |> Parser.skip spaceParser
@@ -128,6 +144,76 @@ moduleNameParser =
128144 )
129145
130146
147+ effectParser : Parser Context Error AST.Manager
148+ effectParser =
149+ Parser.succeed identity
150+ |> Parser.skip (Parser.token "where" (ExpectedKeyword "where"))
151+ |> Parser.skip spaceParser
152+ |> Parser.skip (Parser.chompChar '{' (ExpectedChar '{'))
153+ |> Parser.skip spaceParser
154+ |> Parser.keep
155+ (Parser.oneOf
156+ [ Parser.succeed
157+ (\cmd maybeSub ->
158+ when maybeSub is
159+ Just sub ->
160+ AST.Fx { cmd = cmd, sub = sub }
161+
162+ Nothing ->
163+ AST.Cmd cmd
164+ )
165+ |> Parser.keep (cmdSubParser "command")
166+ |> Parser.skip spaceParser
167+ |> Parser.keep
168+ (Parser.oneOf
169+ [ Parser.succeed Just
170+ |> Parser.skip (Parser.chompChar ',' (ExpectedChar ','))
171+ |> Parser.skip spaceParser
172+ |> Parser.keep (cmdSubParser "subscription")
173+ , Parser.succeed Nothing
174+ ]
175+ )
176+ , Parser.succeed
177+ (\sub maybeCmd ->
178+ when maybeCmd is
179+ Just cmd ->
180+ AST.Fx { cmd = cmd, sub = sub }
181+
182+ Nothing ->
183+ AST.Sub sub
184+ )
185+ |> Parser.keep (cmdSubParser "subscription")
186+ |> Parser.skip spaceParser
187+ |> Parser.keep
188+ (Parser.oneOf
189+ [ Parser.succeed Just
190+ |> Parser.skip (Parser.chompChar ',' (ExpectedChar ','))
191+ |> Parser.skip spaceParser
192+ |> Parser.keep (cmdSubParser "command")
193+ , Parser.succeed Nothing
194+ ]
195+ )
196+ ]
197+ )
198+ |> Parser.skip spaceParser
199+ |> Parser.skip (Parser.chompChar '}' (ExpectedChar '}'))
200+
201+
202+ cmdSubParser : String -> Parser Context Error (SourcePosition.Located String)
203+ cmdSubParser fieldName =
204+ Parser.succeed identity
205+ |> Parser.skip (Parser.token fieldName (ExpectedKeyword fieldName))
206+ |> Parser.skip spaceParser
207+ |> Parser.skip (Parser.chompChar '=' (ExpectedChar '='))
208+ |> Parser.skip spaceParser
209+ |> Parser.keep ctorNameParser
210+
211+
212+ ctorNameParser : Parser Context Error (SourcePosition.Located String)
213+ ctorNameParser =
214+ SourcePosition.parser (Parser.mapError VariableError Variable.upperCase)
215+
216+
131217parseExposingStatement : Parser Context Error AST.Exposing
132218parseExposingStatement =
133219 Parser.succeed identity
0 commit comments