@@ -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,11 +194,11 @@ 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
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
201
202
| Error err -> Error err
202
203
| Ok ( a, st2) -> Ok ( modify a, st2)
203
204
@@ -207,8 +208,8 @@ module ParserMonad =
207
208
208
209
/// Run the parser, if it fails swap the error message.
209
210
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
212
213
| Ok result -> Ok result
213
214
| Error e ->
214
215
logf " oops <??>: e:%A " e
@@ -249,61 +250,61 @@ module ParserMonad =
249
250
250
251
251
252
let fatalError err =
252
- ParserMonad <| fun _ st -> Error ( mkParseError st err)
253
+ ParserMonad <| fun st -> Error ( mkParseError st err)
253
254
254
255
let getRunningEvent : ParserMonad < VoiceEvent > =
255
- ParserMonad <| fun _ st -> Ok ( st.RunningStatus , st)
256
+ ParserMonad <| fun st -> Ok ( st.RunningStatus , st)
256
257
257
258
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 })
259
260
260
261
let getPos : ParserMonad < int > =
261
- ParserMonad <| fun _ st -> Ok ( st.Position, st)
262
+ ParserMonad <| fun st -> Ok ( st.Position, st)
262
263
263
264
let inline private (| PositionValid | PositionInvalid |) ( input : MidiData , state : State ) =
264
265
if state.Position >= 0 && state.Position < input.Length then
265
266
PositionValid
266
267
else
267
268
PositionInvalid
268
269
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 >) =
270
271
ParserMonad
271
- ( fun input state ->
272
+ ( fun state ->
272
273
try
273
- match input , state with
274
- | PositionValid -> f input state
274
+ match state.Input , state with
275
+ | PositionValid -> f state
275
276
| PositionInvalid -> Error ( mkParseError state ( EOF name))
276
277
with
277
278
| e -> Error ( mkParseError state ( Other ( sprintf " %s %A " name e)))
278
279
)
279
280
280
281
let peek : ParserMonad < byte > =
281
282
checkedParseM " peek" <|
282
- fun input st -> Ok ( input .[ st.Position], st)
283
+ fun st -> Ok ( st.Input .[ st.Position], st)
283
284
284
285
/// Conditionally gets a byte (word8). Fails if input is finished.
285
286
/// Consumes data on if predicate succeeds, does not consume if
286
287
/// predicate fails.
287
288
let cond ( test : byte -> bool ) : ParserMonad < byte option > =
288
289
checkedParseM " cond" <|
289
- fun input st ->
290
- let a1 = input .[ st.Position]
290
+ fun st ->
291
+ let a1 = st.Input .[ st.Position]
291
292
if test a1 then
292
293
Ok ( Some a1, st)
293
294
else Ok ( None, st)
294
295
295
296
/// Repeats a given <see paramref="parser"/> <see paramref="length"/> times.
296
297
/// Fails with accumulated errors when any encountered.
297
298
let inline count ( length : ^T ) ( parser : ParserMonad < 'a >) : ParserMonad < 'a []> =
298
- ParserMonad <| fun input state ->
299
+ ParserMonad <| fun state ->
299
300
let rec work ( i : 'T )
300
301
( st : State )
301
302
( fk : ParseError -> Result < 'a list * State , ParseError >)
302
303
( sk : State -> 'a list -> Result < 'a list * State , ParseError >) =
303
304
if i <= LanguagePrimitives.GenericZero then
304
305
sk st []
305
306
else
306
- match apply1 parser input st with
307
+ match apply1 parser st with
307
308
| Error msg -> fk msg
308
309
| Ok ( a1, st1) ->
309
310
work ( i - LanguagePrimitives.GenericOne) st1 fk ( fun st2 ac ->
@@ -313,12 +314,12 @@ module ParserMonad =
313
314
314
315
/// Run a parser within a bounded section of the input stream.
315
316
let repeatTillPosition ( maxPosition : Pos ) ( parser : ParserMonad < 'a >) : ParserMonad < 'a array > =
316
- ParserMonad <| fun input state ->
317
+ ParserMonad <| fun state ->
317
318
let limit = maxPosition
318
319
let rec work ( st : State )
319
320
( fk : ParseError -> Result < 'a list * State , ParseError >)
320
321
( sk : State -> 'a list -> Result < 'a list * State , ParseError >) =
321
- match apply1 parser input st with
322
+ match apply1 parser st with
322
323
| Error a -> fk a
323
324
| Ok( a1, st1) ->
324
325
match compare st1.Position limit with
@@ -342,13 +343,13 @@ module ParserMonad =
342
343
/// Drop a byte (word8).
343
344
let dropByte : ParserMonad < unit > =
344
345
checkedParseM " dropByte" <|
345
- fun input st -> Ok ((), { st with Position = st.Position + 1 })
346
+ fun st -> Ok ((), { st with Position = st.Position + 1 })
346
347
347
348
/// Parse a byte (Word8).
348
349
let readByte : ParserMonad < byte > =
349
350
checkedParseM " readByte" <|
350
- fun input st ->
351
- let a1 = input .[ st.Position]
351
+ fun st ->
352
+ let a1 = st.Input .[ st.Position]
352
353
Ok ( a1, { st with Position = st.Position + 1 })
353
354
354
355
/// Parse a single byte char.
@@ -401,4 +402,4 @@ module ParserMonad =
401
402
let! b = readByte
402
403
let! c = readByte
403
404
return ( word24be a b c)
404
- }
405
+ }
0 commit comments