Skip to content

Commit c20d0a1

Browse files
implement gencount
1 parent d88a744 commit c20d0a1

File tree

2 files changed

+33
-29
lines changed

2 files changed

+33
-29
lines changed

src/ZMidi/Internal/ParserMonad.fs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ module ParserMonad =
112112
match apply1 parser input st with
113113
| Ok result -> Ok result
114114
| Error _ -> Error (ParseError(st.Position, Other (genMessage st.Position)))
115-
115+
116116
let fatalError err =
117117
ParserMonad <| fun _ st -> Error (ParseError(st.Position, err))
118118

@@ -159,27 +159,23 @@ module ParserMonad =
159159

160160
/// Repeats a given <see paramref="parser"/> <see paramref="length"/> times.
161161
/// Fails with accumulated errors when any encountered.
162-
let count (length : int) (parser : ParserMonad<'a>) : ParserMonad<'a []> =
162+
let inline count (length : ^T) (parser : ParserMonad<'a>) : ParserMonad<'a []> =
163163
ParserMonad <| fun input state ->
164-
let rec work (i : int)
164+
let rec work (i : 'T)
165165
(st : State)
166166
(fk : ParseError -> Result<'a list * State, ParseError>)
167167
(sk : State -> 'a list -> Result<'a list * State, ParseError>) =
168-
if i <= 0 then
168+
if i <= LanguagePrimitives.GenericZero then
169169
sk st []
170170
else
171171
match apply1 parser input st with
172172
| Error msg -> fk msg
173173
| Ok (a1, st1) ->
174-
work (i-1) st1 fk (fun st2 ac ->
174+
work (i - LanguagePrimitives.GenericOne) st1 fk (fun st2 ac ->
175175
sk st2 (a1 :: ac))
176176
work length state (fun msg -> Error msg) (fun st ac -> Ok (ac, st))
177177
|> Result.map (fun (ans, st) -> (List.toArray ans, st))
178178

179-
/// Apply the parser for /count/ times, derive the final answer
180-
/// from the intermediate list with the supplied function.
181-
let inline gencount (plen: ParserMonad<'T>) (p: ParserMonad<'a>) (constr: ^T -> 'a array -> 'answer) : ParserMonad<'answer> =
182-
failwith "gencount: not implemented"
183179

184180
/// Run a parser within a bounded section of the input stream.
185181
let inline boundRepeat (n: ^T) (p: ParserMonad<'a>) : ParserMonad<'a array> =
@@ -190,6 +186,14 @@ module ParserMonad =
190186
l.[i] <- r
191187
return l
192188
}
189+
/// Apply the parser for /count/ times, derive the final answer
190+
/// from the intermediate list with the supplied function.
191+
let inline gencount plen p constr = //(plen: ParserMonad<'T>) (p: ParserMonad<'a>) (constr: ^T -> 'a array -> 'answer) : ParserMonad<'answer> =
192+
parseMidi {
193+
let! l = plen
194+
let! items = boundRepeat l p
195+
return constr l items
196+
}
193197

194198
/// Drop a byte (word8).
195199
let dropByte : ParserMonad<unit> =

src/ZMidi/Read.fs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,35 +74,39 @@ module ReadFile =
7474
let! _ = assertString "MTrk"
7575
return! readUInt32be
7676
}
77+
7778
let textEvent textType =
7879
parseMidi {
80+
let! a = assertWord8 2uy
81+
let! b = peek
7982
let! text = getVarlenText
8083
return TextEvent(textType, text)
8184
}
85+
8286
let metaEventSequenceNumber =
8387
parseMidi {
8488
let! a = assertWord8 2uy
8589
let! b = peek
8690
return SequenceNumber(word16be a b)
8791
}
88-
89-
let metaEventGenericText =
90-
parseMidi {
91-
let! a = assertWord8 2uy
92-
let! b = peek
93-
return! textEvent GenericText
94-
}
92+
9593
let metaEvent i =
9694
parseMidi {
9795
match i with
98-
| 0x00 -> return metaEventSequenceNumber
99-
| 0x01 -> return metaEventGenericText
96+
| 0x00 -> return! metaEventSequenceNumber
97+
| 0x01 -> return! textEvent GenericText
98+
| 0x02 -> return! textEvent CopyrightNotice
99+
| 0x03 -> return! textEvent SequenceName
100+
| 0x04 -> return! textEvent InstrumentName
101+
| 0x05 -> return! textEvent Lyrics
102+
| 0x06 -> return! textEvent Marker
103+
| 0x07 -> return! textEvent CuePoint
100104
}
105+
101106
let event : ParserMonad<MidiEvent> =
102107
parseMidi {
103108
return! fatalError (Other "event: not implemented") }
104109

105-
106110
let deltaTime =
107111
parseMidi {
108112
return! getVarlen
@@ -123,14 +127,10 @@ module ReadFile =
123127
let! length = trackHeader
124128
return! messages length
125129
}
126-
//let midiFile =
127-
// parseMidi {
128-
// let! header = P.header
129-
//
130-
// }
131130

132-
//let readMidi filename =
133-
// ParserMonad.runParseMidi
134-
//let pitchBend ch = "pitch bend" <??> (PitchBend ch) <$> P.readWord14be
135-
136-
131+
let midiFile =
132+
parseMidi {
133+
let! header = header
134+
let! tracks = count (header.trackCount) track
135+
return { header = header; tracks = tracks }
136+
}

0 commit comments

Comments
 (0)