@@ -4,7 +4,8 @@ namespace ZMidi.Internal
44module ParserMonad =
55
66 open System.IO
7-
7+ open FSharpPlus
8+ open FSharpPlus.Data
89 open ZMidi.Internal .Utils
910
1011 /// Status is either OFF or the previous VoiceEvent * Channel.
@@ -87,8 +88,7 @@ module ParserMonad =
8788 #endif
8889 )
8990
90- type ParserMonad < 'a > =
91- ParserMonad of ( State -> Result < 'a * State , ParseError > )
91+ type ParserMonad < 'a > = StateT< State, Result< 'a * State, ParseError>>
9292
9393 let nullOut = new StreamWriter( Stream.Null) :> TextWriter
9494 let mutable debug = false
@@ -101,7 +101,7 @@ module ParserMonad =
101101
102102 let inline private apply1 ( parser : ParserMonad < 'a >)
103103 ( state : State ) : Result < 'a * State , ParseError > =
104- let ( ParserMonad fn) = parser
104+ let ( StateT fn) = parser
105105 try
106106 let result = fn state
107107 let oldState = state
@@ -131,20 +131,20 @@ module ParserMonad =
131131 )
132132
133133 let inline mreturn ( x : 'a ) : ParserMonad < 'a > =
134- ParserMonad <| fun st -> Ok ( x, st)
134+ StateT <| fun st -> Ok ( x, st)
135135
136136 let inline private bindM ( parser : ParserMonad < 'a >)
137137 ( next : 'a -> ParserMonad < 'b >) : ParserMonad < 'b > =
138- ParserMonad <| fun state ->
138+ StateT <| fun state ->
139139 match apply1 parser state with
140140 | Error msg -> Error msg
141141 | Ok ( ans, st1) -> apply1 ( next ans) st1
142142
143143 let mzero () : ParserMonad < 'a > =
144- ParserMonad <| fun state -> Error ( mkParseError state ( EOF " mzero" ))
144+ StateT <| fun state -> Error ( mkParseError state ( EOF " mzero" ))
145145
146146 let inline mplus ( parser1 : ParserMonad < 'a >) ( parser2 : ParserMonad < 'a >) : ParserMonad < 'a > =
147- ParserMonad <| fun state ->
147+ StateT <| fun state ->
148148 match apply1 parser1 state with
149149 | Error _ -> apply1 parser2 state
150150 | Ok res -> Ok res
@@ -158,31 +158,6 @@ module ParserMonad =
158158 let (>>= ) ( m: ParserMonad< 'a>) ( k: 'a -> ParserMonad< 'b>) : ParserMonad< 'b> =
159159 bindM m k
160160
161- type ParserBuilder () =
162- member inline self.ReturnFrom ( ma : ParserMonad < 'a >) : ParserMonad < 'a > = ma
163- member inline self.Return x = mreturn x
164- member inline self.Bind ( p , f ) = bindM p f
165- member inline self.Zero a = ParserMonad ( fun state -> Ok( a, state))
166- //member self.Combine (ma, mb) = ma >>= mb
167-
168- // inspired from http://www.fssnip.net/7UJ/title/ResultBuilder-Computational-Expression
169- // probably broken
170- member inline self.TryFinally ( m , compensation ) =
171- try self.ReturnFrom( m)
172- finally compensation()
173-
174- //member self.Delay(f: unit -> ParserMonad<'a>) : ParserMonad<'a> = f ()
175- //member self.Using(res:#System.IDisposable, body) =
176- // self.TryFinally(body res, fun () -> if not (isNull res) then res.Dispose())
177- //member self.While(guard, f) =
178- // if not (guard()) then self.Zero () else
179- // do f() |> ignore
180- // self.While(guard, f)
181- //member self.For(sequence:seq<_>, body) =
182- // self.Using(sequence.GetEnumerator(), fun enum -> self.While(enum.MoveNext, fun () -> self.Delay(fun () -> body enum.Current)))
183-
184- let ( parseMidi : ParserBuilder ) = new ParserBuilder()
185-
186161 let runParser ( ma : ParserMonad < 'a >) input initialState =
187162 apply1 ma { initialState with Input = input}
188163 |> Result.map fst
@@ -194,11 +169,11 @@ module ParserMonad =
194169
195170 /// Throw a parse error
196171 let parseError ( genMessage : Pos -> string ) : ParserMonad < 'a > =
197- ParserMonad <| fun st -> Error ( mkOtherParseError st genMessage)
172+ StateT <| fun st -> Error ( mkOtherParseError st genMessage)
198173
199174 /// Run the parser, if it fails swap the error message.
200175 let inline ( <??> ) ( parser : ParserMonad < 'a >) ( genMessage : Pos -> string ) : ParserMonad < 'a > =
201- ParserMonad <| fun st ->
176+ StateT <| fun st ->
202177 match apply1 parser st with
203178 | Ok result -> Ok result
204179 | Error e ->
@@ -207,13 +182,13 @@ module ParserMonad =
207182
208183 ///
209184 let fmap ( f : 'a -> 'b ) ( p : ParserMonad < 'a >) : ParserMonad < 'b > =
210- parseMidi {
185+ monad {
211186 let! a = p
212187 return ( f a)
213188 }
214189 let inline ( < ~> (* <$> *) ) ( a ) b = fmap a b
215190 let ( *> ) ( a : ParserMonad < 'a >) ( b : 'a -> ParserMonad < 'b >) : ParserMonad < 'b > =
216- parseMidi {
191+ monad {
217192 let! a = a
218193 return ! ( b a)
219194 }
@@ -240,16 +215,16 @@ module ParserMonad =
240215
241216
242217 let fatalError err =
243- ParserMonad <| fun st -> Error ( mkParseError st err)
218+ StateT <| fun st -> Error ( mkParseError st err)
244219
245220 let getRunningEvent : ParserMonad < VoiceEvent > =
246- ParserMonad <| fun st -> Ok ( st.RunningStatus , st)
221+ StateT <| fun st -> Ok ( st.RunningStatus , st)
247222
248223 let inline setRunningEvent ( runningStatus : VoiceEvent ) : ParserMonad < unit > =
249- ParserMonad <| fun st -> Ok ((), { st with RunningStatus = runningStatus })
224+ StateT <| fun st -> Ok ((), { st with RunningStatus = runningStatus })
250225
251226 let getPos : ParserMonad < int > =
252- ParserMonad <| fun st -> Ok ( st.Position, st)
227+ StateT <| fun st -> Ok ( st.Position, st)
253228
254229 let inline private (| PositionValid | PositionInvalid |) ( input : MidiData , state : State ) =
255230 if state.Position >= 0 && state.Position < input.Length then
@@ -258,7 +233,7 @@ module ParserMonad =
258233 PositionInvalid
259234
260235 let inline private checkedParseM ( name : string ) ( f : State -> Result <( 'a * State ), ParseError >) =
261- ParserMonad
236+ StateT
262237 ( fun state ->
263238 try
264239 match state.Input, state with
@@ -286,7 +261,7 @@ module ParserMonad =
286261 /// Repeats a given <see paramref="parser"/> <see paramref="length"/> times.
287262 /// Fails with accumulated errors when any encountered.
288263 let inline count ( length : ^T ) ( parser : ParserMonad < 'a >) : ParserMonad < 'a []> =
289- ParserMonad <| fun state ->
264+ StateT <| fun state ->
290265 let rec work ( i : 'T )
291266 ( st : State )
292267 ( fk : ParseError -> Result < 'a list * State , ParseError >)
@@ -305,7 +280,7 @@ module ParserMonad =
305280
306281 /// Run a parser within a bounded section of the input stream.
307282 let repeatTillPosition ( maxPosition : Pos ) ( p : ParserMonad < 'a >) : ParserMonad < 'a array > =
308- ParserMonad ( fun state ->
283+ StateT ( fun state ->
309284 let results = ResizeArray()
310285 let mutable firstError = Ok ( Array.empty, state)
311286 let mutable lastState = state
@@ -328,7 +303,7 @@ module ParserMonad =
328303 )
329304
330305 let inline boundRepeat ( n : ^T ) ( p : ParserMonad < 'a >) : ParserMonad < 'a array > =
331- ParserMonad ( fun state ->
306+ StateT ( fun state ->
332307 let result = Array.zeroCreate ( int n)
333308 let mutable lastState = state
334309// revisit with a fold?
@@ -357,7 +332,7 @@ module ParserMonad =
357332 /// Apply the parser for /count/ times, derive the final answer
358333 /// from the intermediate list with the supplied function.
359334 let inline gencount ( plen : ParserMonad < 'T >) ( p : ParserMonad < 'a >) ( constr : ^T -> 'a array -> 'answer ) : ParserMonad < 'answer > =
360- parseMidi {
335+ monad {
361336 let! l = plen
362337 logf " gen count: l: %i " l
363338 let! items = boundRepeat l p
@@ -378,22 +353,22 @@ module ParserMonad =
378353
379354 /// Parse a single byte char.
380355 let readChar : ParserMonad < char > =
381- parseMidi {
356+ monad {
382357 let! a = readByte
383358 return ( char a)
384359 }
385360
386361 /// Parse a string of the given length.
387362 let readString ( length : int ) : ParserMonad < string > =
388- parseMidi {
363+ monad {
389364 let! arr = count length readChar
390365 return ( System.String arr)
391366 }
392367 <??> sprintf " readString failed at %i "
393368 open ZMidi.Internal .DataTypes .FromBytes
394369 /// Parse a uint16 (big endian).
395370 let readUInt16be : ParserMonad < uint16 >=
396- parseMidi {
371+ monad {
397372 let! a = readByte
398373 let! b = readByte
399374 return word16be a b
@@ -402,7 +377,7 @@ module ParserMonad =
402377
403378 /// Parse a word14 (big endian) from 2 consecutive bytes.
404379 let readWord14be =
405- parseMidi {
380+ monad {
406381 let! a = readByte
407382 let! b = readByte
408383 return ( word14be a b)
@@ -411,7 +386,7 @@ module ParserMonad =
411386
412387 /// Parse a word32 (big endian).
413388 let readUInt32be =
414- parseMidi {
389+ monad {
415390 let! a = readByte
416391 let! b = readByte
417392 let! c = readByte
@@ -421,9 +396,9 @@ module ParserMonad =
421396
422397 /// Parse a word24 (big endian).
423398 let readWord24be =
424- parseMidi {
399+ monad {
425400 let! a = readByte
426401 let! b = readByte
427402 let! c = readByte
428403 return ( word24be a b c)
429- }
404+ }
0 commit comments