Skip to content

Commit eb81756

Browse files
* remove rec module to narrow it to only types
* factorize a bit the existing functions
1 parent 076a4c0 commit eb81756

File tree

1 file changed

+63
-51
lines changed

1 file changed

+63
-51
lines changed

src/ZMidi/Read.fs

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module rec DataTypes
1+
module DataTypes
22
type midiportnumber = byte
33
type word8 = byte
44
type word16 = uint16
@@ -55,7 +55,7 @@ type MidiEvent =
5555
| SysRealtimeEvent of MidiSysRealtimeEvent
5656
| MetaEvent of MidiMetaEvent
5757

58-
type MidiVoiceEvent =
58+
and MidiVoiceEvent =
5959
/// Note off.
6060
///
6161
/// > 80 to 8F (0 to F is channel number) * note * velocity
@@ -112,7 +112,7 @@ type MidiVoiceEvent =
112112
| PitchBend of status: bits7 * bend: word14
113113

114114

115-
type MidiTextType =
115+
and MidiTextType =
116116
| GenericText
117117
| CopyrightNotice
118118
| SequenceName
@@ -123,48 +123,48 @@ type MidiTextType =
123123

124124

125125
/// Sequential messages with delta time 0 are played simultaneously.
126-
type MidiMessage = {
126+
and MidiMessage = {
127127
timestamp: DeltaTime
128128
event: MidiEvent
129129
}
130130

131-
type MidiTrack = MidiMessage array
131+
and MidiTrack = MidiMessage array
132132

133-
type MidiFile = {
133+
and MidiFile = {
134134
header : MidiHeader
135135
tracks : MidiTrack array
136136
}
137137

138-
type MidiSysExEvent =
139-
/// Single SysEx event.
140-
///
141-
/// > F0 * length * data
142-
///
143-
/// An uninterpreted sys-ex event.
144-
| SysExSingle of byte array
145-
146-
/// SysEx sent as (non-standard) multiple continuation
147-
/// packets.
148-
///
149-
/// > F0 * length * packet1 ... [SysExContPacket]
150-
///
151-
| SysExCont of byte array * MidiSysExContPacket array
152-
153-
/// Escape sequence of one-or-more SysEx events.
154-
///
155-
/// > F7 * length * data
156-
///
157-
| SysExEscape of byte array
138+
and MidiSysExEvent =
139+
/// Single SysEx event.
140+
///
141+
/// > F0 * length * data
142+
///
143+
/// An uninterpreted sys-ex event.
144+
| SysExSingle of byte array
145+
146+
/// SysEx sent as (non-standard) multiple continuation
147+
/// packets.
148+
///
149+
/// > F0 * length * packet1 ... [SysExContPacket]
150+
///
151+
| SysExCont of byte array * MidiSysExContPacket array
152+
153+
/// Escape sequence of one-or-more SysEx events.
154+
///
155+
/// > F7 * length * data
156+
///
157+
| SysExEscape of byte array
158158

159159
/// Continuation packet for a (non-standard) multi-part SysEx
160160
/// event.
161161
///
162162
/// Apprently this format is use by Casio.
163-
type MidiSysExContPacket = MidiSysExContPacket of DeltaTime * byte array
163+
and MidiSysExContPacket = MidiSysExContPacket of DeltaTime * byte array
164164

165165

166166

167-
type MidiMetaEvent =
167+
and MidiMetaEvent =
168168

169169
/// Text / copywright etc.
170170
///
@@ -267,7 +267,7 @@ type MidiMetaEvent =
267267
/// computer (as opposed to MIDI generated by a synthesizer or
268268
/// sequencer).
269269
///
270-
type MidiSysCommonEvent =
270+
and MidiSysCommonEvent =
271271
/// Time code quarter frame.
272272
///
273273
/// > F1 * payload
@@ -322,7 +322,7 @@ type MidiSysCommonEvent =
322322
/// These events may not be pertinent to MIDI files generated on a
323323
/// computer (as opposed to MIDI generated by a synthesizer or
324324
/// sequencer).
325-
type MidiSysRealtimeEvent =
325+
and MidiSysRealtimeEvent =
326326
/// Timing signal.
327327
///
328328
/// > F8
@@ -380,8 +380,9 @@ type MidiSysRealtimeEvent =
380380
///
381381
| SystemReset
382382

383-
[<RequireQualifiedAccess>]
384-
type MidiScaleType = Major | Minor | OtherScale of word8
383+
384+
385+
and [<RequireQualifiedAccess>] MidiScaleType = Major | Minor | OtherScale of word8
385386

386387
module Internal =
387388
module ParserMonad =
@@ -412,6 +413,7 @@ module Internal =
412413
member state.posPastEnd = state.pos >= state.input.Length
413414
member state.moved direction = { state with pos = state.pos + direction }
414415
member state.get () = state.input.[state.pos]
416+
415417
type ErrorMessage = string
416418
type ParseError = ParseError of Pos * ErrorMessage
417419

@@ -423,28 +425,38 @@ module Internal =
423425

424426
let getPos = parserM (fun state -> (Ok (state.pos), state))
425427

426-
let peek = parserM (fun ({ pos = pos; input = input } as state) ->
428+
let inline failPastEndOrResult (state: ParserState) funcName getResultAndState =
427429
if state.posPastEnd then
428-
err pos "peek - no more data", state
429-
else
430-
Ok input.[pos], state
431-
)
432-
433-
let cond pred = parserM (fun ({ pos = pos; input = input } as state) ->
434-
if state.posPastEnd then
435-
err pos "cond - no more data", state
430+
(err state.pos (funcName + " - no more data")), state
436431
else
437-
let a = state.get()
438-
(if pred a then Ok (Some a) else (Ok None)), state.moved(1)
439-
)
440-
441-
let dropW8 = parserM (fun (state) ->
442-
if state.posPastEnd then
443-
err state.pos "dropW8 - no more data", state
444-
else
445-
Ok (), state.moved(1)
446-
)
432+
let res, state = getResultAndState state
433+
Ok res, state
447434

435+
let inline checkedPastEndOrResult fName getResultAndNextState = parserM <| fun state -> failPastEndOrResult state fName getResultAndNextState
436+
437+
let peek = checkedPastEndOrResult "peek" (fun state -> state.get(), state)
438+
439+
let cond pred =
440+
checkedPastEndOrResult "cond" (
441+
fun state ->
442+
let a = state.get()
443+
(if pred a then Some a else None), state.moved(1)
444+
)
445+
446+
let dropW8 =
447+
checkedPastEndOrResult "dropW8" (
448+
fun state -> (), state.moved(1)
449+
)
450+
451+
let word8 =
452+
checkedPastEndOrResult "word8" (
453+
fun state -> state.get(), state.moved(1)
454+
)
455+
456+
let word16be : ParserM<word16> =
457+
checkedPastEndOrResult "word16be" (
458+
fun state -> failwith "uncons2!!!"
459+
)
448460

449461

450462

0 commit comments

Comments
 (0)