@@ -40,13 +40,15 @@ module ParserMonad =
40
40
type State =
41
41
{ Position: Pos
42
42
RunningStatus: VoiceEvent
43
+ Input: MidiData
43
44
#if DEBUG_ LASTPARSE
44
45
LastParse : obj
45
46
#endif
46
47
}
47
48
static member initial =
48
49
{ Position = 0
49
50
RunningStatus = VoiceEvent.StatusOff
51
+ Input = [||]
50
52
#if DEBUG_ LASTPARSE
51
53
LastParse = null
52
54
#endif
@@ -86,7 +88,7 @@ module ParserMonad =
86
88
)
87
89
88
90
type ParserMonad < 'a > =
89
- ParserMonad of ( MidiData -> State -> Result < 'a * State , ParseError > )
91
+ ParserMonad of ( State -> Result < 'a * State , ParseError > )
90
92
91
93
let nullOut = new StreamWriter( Stream.Null) :> TextWriter
92
94
let mutable debug = false
@@ -97,12 +99,11 @@ module ParserMonad =
97
99
fprintfn nullOut format
98
100
//Unchecked.defaultof<_>
99
101
100
- let inline private apply1 ( parser : ParserMonad < 'a >)
101
- ( midiData : byte [])
102
+ let inline private apply1 ( parser : ParserMonad < 'a >)
102
103
( state : State ) : Result < 'a * State , ParseError > =
103
104
let ( ParserMonad fn ) = parser
104
105
try
105
- let result = fn midiData state
106
+ let result = fn state
106
107
let oldState = state
107
108
match result with
108
109
| Ok ( r, state) ->
@@ -130,22 +131,22 @@ module ParserMonad =
130
131
)
131
132
132
133
let inline mreturn ( x : 'a ) : ParserMonad < 'a > =
133
- ParserMonad <| fun _ st -> Ok ( x, st)
134
+ ParserMonad <| fun st -> Ok ( x, st)
134
135
135
136
let inline private bindM ( parser : ParserMonad < 'a >)
136
137
( 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
139
140
| Error msg -> Error msg
140
- | Ok ( ans, st1) -> apply1 ( next ans) input st1
141
+ | Ok ( ans, st1) -> apply1 ( next ans) st1
141
142
142
143
let mzero () : ParserMonad < 'a > =
143
- ParserMonad <| fun _ state -> Error ( mkParseError state ( EOF " mzero" ))
144
+ ParserMonad <| fun state -> Error ( mkParseError state ( EOF " mzero" ))
144
145
145
146
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
149
150
| Ok res -> Ok res
150
151
151
152
let inline private delayM ( fn : unit -> ParserMonad < 'a >) : ParserMonad < 'a > =
@@ -161,7 +162,7 @@ module ParserMonad =
161
162
member inline self.ReturnFrom ( ma : ParserMonad < 'a >) : ParserMonad < 'a > = ma
162
163
member inline self.Return x = mreturn x
163
164
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))
165
166
//member self.Combine (ma, mb) = ma >>= mb
166
167
167
168
// inspired from http://www.fssnip.net/7UJ/title/ResultBuilder-Computational-Expression
@@ -183,7 +184,7 @@ module ParserMonad =
183
184
let ( parseMidi : ParserBuilder ) = new ParserBuilder()
184
185
185
186
let runParser ( ma : ParserMonad < 'a >) input initialState =
186
- apply1 ma input initialState
187
+ apply1 ma { initialState with Input = input }
187
188
|> Result.map fst
188
189
189
190
/// Run the parser on a file.
@@ -193,12 +194,12 @@ module ParserMonad =
193
194
194
195
/// Throw a parse error
195
196
let parseError ( genMessage : Pos -> string ) : ParserMonad < 'a > =
196
- ParserMonad <| fun _ st -> Error ( mkOtherParseError st genMessage)
197
+ ParserMonad <| fun st -> Error ( mkOtherParseError st genMessage)
197
198
198
199
/// Run the parser, if it fails swap the error message.
199
200
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
202
203
| Ok result -> Ok result
203
204
| Error e ->
204
205
logf " oops <??>: e:%A " e
@@ -239,61 +240,61 @@ module ParserMonad =
239
240
240
241
241
242
let fatalError err =
242
- ParserMonad <| fun _ st -> Error ( mkParseError st err)
243
+ ParserMonad <| fun st -> Error ( mkParseError st err)
243
244
244
245
let getRunningEvent : ParserMonad < VoiceEvent > =
245
- ParserMonad <| fun _ st -> Ok ( st.RunningStatus , st)
246
+ ParserMonad <| fun st -> Ok ( st.RunningStatus , st)
246
247
247
248
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 })
249
250
250
251
let getPos : ParserMonad < int > =
251
- ParserMonad <| fun _ st -> Ok ( st.Position, st)
252
+ ParserMonad <| fun st -> Ok ( st.Position, st)
252
253
253
254
let inline private (| PositionValid | PositionInvalid |) ( input : MidiData , state : State ) =
254
255
if state.Position >= 0 && state.Position < input.Length then
255
256
PositionValid
256
257
else
257
258
PositionInvalid
258
259
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 >) =
260
261
ParserMonad
261
- ( fun input state ->
262
+ ( fun state ->
262
263
try
263
- match input , state with
264
- | PositionValid -> f input state
264
+ match state.Input , state with
265
+ | PositionValid -> f state
265
266
| PositionInvalid -> Error ( mkParseError state ( EOF name))
266
267
with
267
268
| e -> Error ( mkParseError state ( Other ( sprintf " %s %A " name e)))
268
269
)
269
270
270
271
let peek : ParserMonad < byte > =
271
272
checkedParseM " peek" <|
272
- fun input st -> Ok ( input .[ st.Position], st)
273
+ fun st -> Ok ( st.Input .[ st.Position], st)
273
274
274
275
/// Conditionally gets a byte (word8). Fails if input is finished.
275
276
/// Consumes data on if predicate succeeds, does not consume if
276
277
/// predicate fails.
277
278
let cond ( test : byte -> bool ) : ParserMonad < byte option > =
278
279
checkedParseM " cond" <|
279
- fun input st ->
280
- let a1 = input .[ st.Position]
280
+ fun st ->
281
+ let a1 = st.Input .[ st.Position]
281
282
if test a1 then
282
283
Ok ( Some a1, st)
283
284
else Ok ( None, st)
284
285
285
286
/// Repeats a given <see paramref="parser"/> <see paramref="length"/> times.
286
287
/// Fails with accumulated errors when any encountered.
287
288
let inline count ( length : ^T ) ( parser : ParserMonad < 'a >) : ParserMonad < 'a []> =
288
- ParserMonad <| fun input state ->
289
+ ParserMonad <| fun state ->
289
290
let rec work ( i : 'T )
290
291
( st : State )
291
292
( fk : ParseError -> Result < 'a list * State , ParseError >)
292
293
( sk : State -> 'a list -> Result < 'a list * State , ParseError >) =
293
294
if i <= LanguagePrimitives.GenericZero then
294
295
sk st []
295
296
else
296
- match apply1 parser input st with
297
+ match apply1 parser st with
297
298
| Error msg -> fk msg
298
299
| Ok ( a1, st1) ->
299
300
work ( i - LanguagePrimitives.GenericOne) st1 fk ( fun st2 ac ->
@@ -304,13 +305,13 @@ module ParserMonad =
304
305
305
306
/// Run a parser within a bounded section of the input stream.
306
307
let repeatTillPosition ( maxPosition : Pos ) ( p : ParserMonad < 'a >) : ParserMonad < 'a array > =
307
- ParserMonad( fun data state ->
308
+ ParserMonad( fun state ->
308
309
let results = ResizeArray()
309
310
let mutable firstError = Ok ( Array.empty, state)
310
311
let mutable lastState = state
311
312
let rec loop () =
312
313
if lastState.Position < int maxPosition then
313
- match apply1 p data lastState with
314
+ match apply1 p lastState with
314
315
| Ok ( result, state) ->
315
316
lastState <- state
316
317
results.Add result
@@ -327,7 +328,7 @@ module ParserMonad =
327
328
)
328
329
329
330
let inline boundRepeat ( n : ^T ) ( p : ParserMonad < 'a >) : ParserMonad < 'a array > =
330
- ParserMonad( fun data state ->
331
+ ParserMonad( fun state ->
331
332
let result = Array.zeroCreate ( int n)
332
333
let mutable lastState = state
333
334
// revisit with a fold?
@@ -339,7 +340,7 @@ module ParserMonad =
339
340
while i < n && not errorOccured do
340
341
logf " bound repeat %i /%i " i n
341
342
342
- match apply1 p data lastState with
343
+ match apply1 p lastState with
343
344
| Ok ( item, state) ->
344
345
lastState <- state
345
346
result.[ int i] <- item
@@ -366,13 +367,13 @@ module ParserMonad =
366
367
/// Drop a byte (word8).
367
368
let dropByte : ParserMonad < unit > =
368
369
checkedParseM " dropByte" <|
369
- fun input st -> Ok ((), { st with Position = st.Position + 1 })
370
+ fun st -> Ok ((), { st with Position = st.Position + 1 })
370
371
371
372
/// Parse a byte (Word8).
372
373
let readByte : ParserMonad < byte > =
373
374
checkedParseM " readByte" <|
374
- fun input st ->
375
- let a1 = input .[ st.Position]
375
+ fun st ->
376
+ let a1 = st.Input .[ st.Position]
376
377
Ok ( a1, { st with Position = st.Position + 1 })
377
378
378
379
/// Parse a single byte char.
@@ -425,4 +426,4 @@ module ParserMonad =
425
426
let! b = readByte
426
427
let! c = readByte
427
428
return ( word24be a b c)
428
- }
429
+ }
0 commit comments