Skip to content

Commit 1fc56d5

Browse files
committed
Include Input in State
1 parent 86c7272 commit 1fc56d5

File tree

1 file changed

+39
-38
lines changed

1 file changed

+39
-38
lines changed

src/ZMidi/Internal/ParserMonad.fs

100755100644
Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ module ParserMonad =
4040
type State =
4141
{ Position: Pos
4242
RunningStatus: VoiceEvent
43+
Input: MidiData
4344
#if DEBUG_LASTPARSE
4445
LastParse : obj
4546
#endif
4647
}
4748
static member initial =
4849
{ Position = 0
4950
RunningStatus = VoiceEvent.StatusOff
51+
Input = [||]
5052
#if DEBUG_LASTPARSE
5153
LastParse = null
5254
#endif
@@ -86,7 +88,7 @@ module ParserMonad =
8688
)
8789

8890
type ParserMonad<'a> =
89-
ParserMonad of (MidiData -> State -> Result<'a * State, ParseError> )
91+
ParserMonad of (State -> Result<'a * State, ParseError> )
9092

9193
let nullOut = new StreamWriter(Stream.Null) :> TextWriter
9294
let mutable debug = false
@@ -97,12 +99,11 @@ module ParserMonad =
9799
fprintfn nullOut format
98100
//Unchecked.defaultof<_>
99101

100-
let inline private apply1 (parser : ParserMonad<'a>)
101-
(midiData : byte[])
102+
let inline private apply1 (parser : ParserMonad<'a>)
102103
(state : State) : Result<'a * State, ParseError> =
103104
let (ParserMonad fn) = parser
104105
try
105-
let result = fn midiData state
106+
let result = fn state
106107
let oldState = state
107108
match result with
108109
| Ok (r, state) ->
@@ -130,22 +131,22 @@ module ParserMonad =
130131
)
131132

132133
let inline mreturn (x:'a) : ParserMonad<'a> =
133-
ParserMonad <| fun _ st -> Ok (x, st)
134+
ParserMonad <| fun st -> Ok (x, st)
134135

135136
let inline private bindM (parser : ParserMonad<'a>)
136137
(next : 'a -> ParserMonad<'b>) : ParserMonad<'b> =
137-
ParserMonad <| fun input state ->
138-
match apply1 parser input state with
138+
ParserMonad <| fun state ->
139+
match apply1 parser state with
139140
| Error msg -> Error msg
140-
| Ok (ans, st1) -> apply1 (next ans) input st1
141+
| Ok (ans, st1) -> apply1 (next ans) st1
141142

142143
let mzero () : ParserMonad<'a> =
143-
ParserMonad <| fun _ state -> Error (mkParseError state (EOF "mzero"))
144+
ParserMonad <| fun state -> Error (mkParseError state (EOF "mzero"))
144145

145146
let inline mplus (parser1 : ParserMonad<'a>) (parser2 : ParserMonad<'a>) : ParserMonad<'a> =
146-
ParserMonad <| fun input state ->
147-
match apply1 parser1 input state with
148-
| Error _ -> apply1 parser2 input state
147+
ParserMonad <| fun state ->
148+
match apply1 parser1 state with
149+
| Error _ -> apply1 parser2 state
149150
| Ok res -> Ok res
150151

151152
let inline private delayM (fn:unit -> ParserMonad<'a>) : ParserMonad<'a> =
@@ -161,7 +162,7 @@ module ParserMonad =
161162
member inline self.ReturnFrom (ma:ParserMonad<'a>) : ParserMonad<'a> = ma
162163
member inline self.Return x = mreturn x
163164
member inline self.Bind (p,f) = bindM p f
164-
member inline self.Zero a = ParserMonad (fun input state -> Ok(a, state))
165+
member inline self.Zero a = ParserMonad (fun state -> Ok(a, state))
165166
//member self.Combine (ma, mb) = ma >>= mb
166167

167168
// inspired from http://www.fssnip.net/7UJ/title/ResultBuilder-Computational-Expression
@@ -183,7 +184,7 @@ module ParserMonad =
183184
let (parseMidi:ParserBuilder) = new ParserBuilder()
184185

185186
let runParser (ma:ParserMonad<'a>) input initialState =
186-
apply1 ma input initialState
187+
apply1 ma { initialState with Input = input}
187188
|> Result.map fst
188189

189190
/// Run the parser on a file.
@@ -193,11 +194,11 @@ module ParserMonad =
193194

194195
/// Throw a parse error
195196
let parseError (genMessage : Pos -> string) : ParserMonad<'a> =
196-
ParserMonad <| fun _ st -> Error (mkOtherParseError st genMessage)
197+
ParserMonad <| fun st -> Error (mkOtherParseError st genMessage)
197198

198199
let fmapM (modify: 'a -> 'b) (parser : ParserMonad<'a>) : ParserMonad<'b> =
199-
ParserMonad <| fun input state ->
200-
match apply1 parser input state with
200+
ParserMonad <| fun state ->
201+
match apply1 parser state with
201202
| Error err -> Error err
202203
| Ok (a, st2) -> Ok (modify a, st2)
203204

@@ -207,8 +208,8 @@ module ParserMonad =
207208

208209
/// Run the parser, if it fails swap the error message.
209210
let inline ( <??> ) (parser : ParserMonad<'a>) (genMessage : Pos -> string) : ParserMonad<'a> =
210-
ParserMonad <| fun input st ->
211-
match apply1 parser input st with
211+
ParserMonad <| fun st ->
212+
match apply1 parser st with
212213
| Ok result -> Ok result
213214
| Error e ->
214215
logf "oops <??>: e:%A" e
@@ -249,61 +250,61 @@ module ParserMonad =
249250

250251

251252
let fatalError err =
252-
ParserMonad <| fun _ st -> Error (mkParseError st err)
253+
ParserMonad <| fun st -> Error (mkParseError st err)
253254

254255
let getRunningEvent : ParserMonad<VoiceEvent> =
255-
ParserMonad <| fun _ st -> Ok (st.RunningStatus , st)
256+
ParserMonad <| fun st -> Ok (st.RunningStatus , st)
256257

257258
let inline setRunningEvent (runningStatus : VoiceEvent) : ParserMonad<unit> =
258-
ParserMonad <| fun _ st -> Ok ((), { st with RunningStatus = runningStatus })
259+
ParserMonad <| fun st -> Ok ((), { st with RunningStatus = runningStatus })
259260

260261
let getPos : ParserMonad<int> =
261-
ParserMonad <| fun _ st -> Ok (st.Position, st)
262+
ParserMonad <| fun st -> Ok (st.Position, st)
262263

263264
let inline private (|PositionValid|PositionInvalid|) (input: MidiData, state: State) =
264265
if state.Position >= 0 && state.Position < input.Length then
265266
PositionValid
266267
else
267268
PositionInvalid
268269

269-
let inline private checkedParseM (name: string) (f: MidiData -> State -> Result<('a * State), ParseError>) =
270+
let inline private checkedParseM (name: string) (f: State -> Result<('a * State), ParseError>) =
270271
ParserMonad
271-
(fun input state ->
272+
(fun state ->
272273
try
273-
match input,state with
274-
| PositionValid -> f input state
274+
match state.Input, state with
275+
| PositionValid -> f state
275276
| PositionInvalid -> Error (mkParseError state (EOF name))
276277
with
277278
| e -> Error (mkParseError state (Other (sprintf "%s %A" name e)))
278279
)
279280

280281
let peek : ParserMonad<byte> =
281282
checkedParseM "peek" <|
282-
fun input st -> Ok (input.[st.Position], st)
283+
fun st -> Ok (st.Input.[st.Position], st)
283284

284285
/// Conditionally gets a byte (word8). Fails if input is finished.
285286
/// Consumes data on if predicate succeeds, does not consume if
286287
/// predicate fails.
287288
let cond (test : byte -> bool) : ParserMonad<byte option> =
288289
checkedParseM "cond" <|
289-
fun input st ->
290-
let a1 = input.[st.Position]
290+
fun st ->
291+
let a1 = st.Input.[st.Position]
291292
if test a1 then
292293
Ok (Some a1, st)
293294
else Ok (None, st)
294295

295296
/// Repeats a given <see paramref="parser"/> <see paramref="length"/> times.
296297
/// Fails with accumulated errors when any encountered.
297298
let inline count (length : ^T) (parser : ParserMonad<'a>) : ParserMonad<'a []> =
298-
ParserMonad <| fun input state ->
299+
ParserMonad <| fun state ->
299300
let rec work (i : 'T)
300301
(st : State)
301302
(fk : ParseError -> Result<'a list * State, ParseError>)
302303
(sk : State -> 'a list -> Result<'a list * State, ParseError>) =
303304
if i <= LanguagePrimitives.GenericZero then
304305
sk st []
305306
else
306-
match apply1 parser input st with
307+
match apply1 parser st with
307308
| Error msg -> fk msg
308309
| Ok (a1, st1) ->
309310
work (i - LanguagePrimitives.GenericOne) st1 fk (fun st2 ac ->
@@ -313,12 +314,12 @@ module ParserMonad =
313314

314315
/// Run a parser within a bounded section of the input stream.
315316
let repeatTillPosition (maxPosition: Pos) (parser: ParserMonad<'a>) : ParserMonad<'a array> =
316-
ParserMonad <| fun input state ->
317+
ParserMonad <| fun state ->
317318
let limit = maxPosition
318319
let rec work (st : State)
319320
(fk : ParseError -> Result<'a list * State, ParseError>)
320321
(sk : State -> 'a list -> Result<'a list * State, ParseError>) =
321-
match apply1 parser input st with
322+
match apply1 parser st with
322323
| Error a -> fk a
323324
| Ok(a1, st1) ->
324325
match compare st1.Position limit with
@@ -342,13 +343,13 @@ module ParserMonad =
342343
/// Drop a byte (word8).
343344
let dropByte : ParserMonad<unit> =
344345
checkedParseM "dropByte" <|
345-
fun input st -> Ok ((), { st with Position = st.Position + 1 })
346+
fun st -> Ok ((), { st with Position = st.Position + 1 })
346347

347348
/// Parse a byte (Word8).
348349
let readByte : ParserMonad<byte> =
349350
checkedParseM "readByte" <|
350-
fun input st ->
351-
let a1 = input.[st.Position]
351+
fun st ->
352+
let a1 = st.Input.[st.Position]
352353
Ok (a1, { st with Position = st.Position + 1 })
353354

354355
/// Parse a single byte char.
@@ -401,4 +402,4 @@ module ParserMonad =
401402
let! b = readByte
402403
let! c = readByte
403404
return (word24be a b c)
404-
}
405+
}

0 commit comments

Comments
 (0)