Skip to content

Commit ff6d0eb

Browse files
authored
Include Input in State
1 parent 59d1d24 commit ff6d0eb

File tree

1 file changed

+39
-38
lines changed

1 file changed

+39
-38
lines changed

src/ZMidi/Internal/ParserMonad.fs

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,12 +194,12 @@ 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
/// Run the parser, if it fails swap the error message.
199200
let inline ( <??> ) (parser : ParserMonad<'a>) (genMessage : Pos -> string) : ParserMonad<'a> =
200-
ParserMonad <| fun input st ->
201-
match apply1 parser input st with
201+
ParserMonad <| fun st ->
202+
match apply1 parser st with
202203
| Ok result -> Ok result
203204
| Error e ->
204205
logf "oops <??>: e:%A" e
@@ -239,61 +240,61 @@ module ParserMonad =
239240

240241

241242
let fatalError err =
242-
ParserMonad <| fun _ st -> Error (mkParseError st err)
243+
ParserMonad <| fun st -> Error (mkParseError st err)
243244

244245
let getRunningEvent : ParserMonad<VoiceEvent> =
245-
ParserMonad <| fun _ st -> Ok (st.RunningStatus , st)
246+
ParserMonad <| fun st -> Ok (st.RunningStatus , st)
246247

247248
let inline setRunningEvent (runningStatus : VoiceEvent) : ParserMonad<unit> =
248-
ParserMonad <| fun _ st -> Ok ((), { st with RunningStatus = runningStatus })
249+
ParserMonad <| fun st -> Ok ((), { st with RunningStatus = runningStatus })
249250

250251
let getPos : ParserMonad<int> =
251-
ParserMonad <| fun _ st -> Ok (st.Position, st)
252+
ParserMonad <| fun st -> Ok (st.Position, st)
252253

253254
let inline private (|PositionValid|PositionInvalid|) (input: MidiData, state: State) =
254255
if state.Position >= 0 && state.Position < input.Length then
255256
PositionValid
256257
else
257258
PositionInvalid
258259

259-
let inline private checkedParseM (name: string) (f: MidiData -> State -> Result<('a * State), ParseError>) =
260+
let inline private checkedParseM (name: string) (f: State -> Result<('a * State), ParseError>) =
260261
ParserMonad
261-
(fun input state ->
262+
(fun state ->
262263
try
263-
match input,state with
264-
| PositionValid -> f input state
264+
match state.Input, state with
265+
| PositionValid -> f state
265266
| PositionInvalid -> Error (mkParseError state (EOF name))
266267
with
267268
| e -> Error (mkParseError state (Other (sprintf "%s %A" name e)))
268269
)
269270

270271
let peek : ParserMonad<byte> =
271272
checkedParseM "peek" <|
272-
fun input st -> Ok (input.[st.Position], st)
273+
fun st -> Ok (st.Input.[st.Position], st)
273274

274275
/// Conditionally gets a byte (word8). Fails if input is finished.
275276
/// Consumes data on if predicate succeeds, does not consume if
276277
/// predicate fails.
277278
let cond (test : byte -> bool) : ParserMonad<byte option> =
278279
checkedParseM "cond" <|
279-
fun input st ->
280-
let a1 = input.[st.Position]
280+
fun st ->
281+
let a1 = st.Input.[st.Position]
281282
if test a1 then
282283
Ok (Some a1, st)
283284
else Ok (None, st)
284285

285286
/// Repeats a given <see paramref="parser"/> <see paramref="length"/> times.
286287
/// Fails with accumulated errors when any encountered.
287288
let inline count (length : ^T) (parser : ParserMonad<'a>) : ParserMonad<'a []> =
288-
ParserMonad <| fun input state ->
289+
ParserMonad <| fun state ->
289290
let rec work (i : 'T)
290291
(st : State)
291292
(fk : ParseError -> Result<'a list * State, ParseError>)
292293
(sk : State -> 'a list -> Result<'a list * State, ParseError>) =
293294
if i <= LanguagePrimitives.GenericZero then
294295
sk st []
295296
else
296-
match apply1 parser input st with
297+
match apply1 parser st with
297298
| Error msg -> fk msg
298299
| Ok (a1, st1) ->
299300
work (i - LanguagePrimitives.GenericOne) st1 fk (fun st2 ac ->
@@ -304,13 +305,13 @@ module ParserMonad =
304305

305306
/// Run a parser within a bounded section of the input stream.
306307
let repeatTillPosition (maxPosition: Pos) (p: ParserMonad<'a>) : ParserMonad<'a array> =
307-
ParserMonad(fun data state ->
308+
ParserMonad(fun state ->
308309
let results = ResizeArray()
309310
let mutable firstError = Ok (Array.empty, state)
310311
let mutable lastState = state
311312
let rec loop () =
312313
if lastState.Position < int maxPosition then
313-
match apply1 p data lastState with
314+
match apply1 p lastState with
314315
| Ok (result, state) ->
315316
lastState <- state
316317
results.Add result
@@ -327,7 +328,7 @@ module ParserMonad =
327328
)
328329

329330
let inline boundRepeat (n: ^T) (p: ParserMonad<'a>) : ParserMonad<'a array> =
330-
ParserMonad(fun data state ->
331+
ParserMonad(fun state ->
331332
let result = Array.zeroCreate (int n)
332333
let mutable lastState = state
333334
// revisit with a fold?
@@ -339,7 +340,7 @@ module ParserMonad =
339340
while i < n && not errorOccured do
340341
logf "bound repeat %i/%i" i n
341342

342-
match apply1 p data lastState with
343+
match apply1 p lastState with
343344
| Ok (item,state) ->
344345
lastState <- state
345346
result.[int i] <- item
@@ -366,13 +367,13 @@ module ParserMonad =
366367
/// Drop a byte (word8).
367368
let dropByte : ParserMonad<unit> =
368369
checkedParseM "dropByte" <|
369-
fun input st -> Ok ((), { st with Position = st.Position + 1 })
370+
fun st -> Ok ((), { st with Position = st.Position + 1 })
370371

371372
/// Parse a byte (Word8).
372373
let readByte : ParserMonad<byte> =
373374
checkedParseM "readByte" <|
374-
fun input st ->
375-
let a1 = input.[st.Position]
375+
fun st ->
376+
let a1 = st.Input.[st.Position]
376377
Ok (a1, { st with Position = st.Position + 1 })
377378

378379
/// Parse a single byte char.
@@ -425,4 +426,4 @@ module ParserMonad =
425426
let! b = readByte
426427
let! c = readByte
427428
return (word24be a b c)
428-
}
429+
}

0 commit comments

Comments
 (0)