4 | import Data.ByteString
5 | import Data.Linear.Ref1
6 | import Derive.Prelude
8 | import IO.Async.Loop.Epoll
9 | import IO.Async.Loop.Posix
11 | import Text.ILex.Derive
14 | import public Text.ILex
17 | %language ElabReflection
24 | data CoordinateSystem = ZeroBased
27 | %runElab derive "CoordinateSystem" [Show,Eq]
34 | data FASTAValue : Type where
35 | NL : ByteString -> FASTAValue
36 | HeaderStart : FASTAValue
37 | HeaderValue : String -> FASTAValue
38 | Adenine : Nat -> FASTAValue
39 | Thymine : Nat -> FASTAValue
40 | Guanine : Nat -> FASTAValue
41 | Cytosine : Nat -> FASTAValue
43 | %runElab derive "FASTAValue" [Show,Eq]
45 | isHeader : FASTAValue -> Bool
46 | isHeader HeaderStart = True
47 | isHeader (HeaderValue _) = True
50 | isData : FASTAValue -> Bool
51 | isData (Adenine _) = True
52 | isData (Thymine _) = True
53 | isData (Guanine _) = True
54 | isData (Cytosine _) = True
62 | record FASTALine where
63 | constructor MkFASTALine
65 | values : List FASTAValue
67 | %runElab derive "FASTALine" [Show,Eq]
69 | Interpolation FASTALine where interpolate = show
77 | FASTA = List FASTALine
83 | linebreak : RExp True
84 | linebreak = '\n' <|> '\r' <|> "\r\n"
86 | nucleotide : RExp True
87 | nucleotide = 'A' <|> 'T' <|> 'G' <|> 'C'
98 | cytosine : RExp True
106 | record FSTCK (q : Type) where
110 | cur_ : IBuffer bufSize_
113 | from_ : Ref q (LTENat bufSize_)
114 | till_ : Ref q (LTENat bufSize_)
115 | positions_ : Ref q (SnocList BytePos)
116 | strs : Ref q (SnocList String)
117 | err : Ref q (Maybe $
BBErr Void)
118 | fastavalues : Ref q (SnocList FASTAValue)
119 | fastalines : Ref q (SnocList FASTALine)
120 | fastacounter : Ref q Nat
124 | HasBBErr FSTCK Void where
128 | HasStringLits FSTCK where
132 | HasStack FSTCK (SnocList FASTALine) where
136 | HasBytes FSTCK where
140 | prevOffset = prevOffset_
141 | curOffset = curOffset_
144 | positions = positions_
145 | copy s o bs buf rf rt sk =
150 | , curOffset_ := o + bs.size
156 | fastainit : CoordinateSystem -> (n : Nat) -> IBuffer n -> F1 q (FSTCK q)
157 | fastainit coordsys n buf = T1.do
158 | rf <- ref1 (first n)
159 | rt <- ref1 (first n)
166 | fc <- case coordsys of
167 | ZeroBased => ref1 Z
168 | OneBased => ref1 (S Z)
170 | pure (F n empty buf 0 0 rf rt ps ss er fvs fls fc ln)
176 | %runElab deriveParserState "FSz" "FST"
177 | ["FIni", "FBroken", "FHdr", "FHdrToNLR", "FHdrToNLS", "FHdrDone", "FD", "FDNL", "FEmpty", "FComplete"]
183 | fastaErr : Arr32 FSz (FSTCK q -> F1 q (BBErr Void))
185 | arr32 FSz (unexpected [])
186 | [ E FBroken $
unexpected ["character other than '>'"]
187 | , E FEmpty $
unexpected ["sequence data"]
188 | , E FHdr $
unexpected ["sequence line"]
195 | onFASTAValueHdrS : (x : FSTCK q) => FASTAValue -> F1 q FST
196 | onFASTAValueHdrS v = push1 x.fastavalues v >> pure FHdrToNLS
198 | onFASTAValueHdrR : (x : FSTCK q) => FASTAValue -> F1 q FST
199 | onFASTAValueHdrR v = push1 x.fastavalues v >> pure FHdrToNLR
201 | onFASTAValueAdenine : (x : FSTCK q) => F1 q FST
202 | onFASTAValueAdenine = T1.do
203 | fc <- read1 x.fastacounter
204 | push1 x.fastavalues (Adenine fc) >> write1 x.fastacounter (S fc) >> pure FD
206 | onFASTAValueThymine : (x : FSTCK q) => F1 q FST
207 | onFASTAValueThymine = T1.do
208 | fc <- read1 x.fastacounter
209 | push1 x.fastavalues (Thymine fc) >> write1 x.fastacounter (S fc) >> pure FD
211 | onFASTAValueGuanine : (x : FSTCK q) => F1 q FST
212 | onFASTAValueGuanine = T1.do
213 | fc <- read1 x.fastacounter
214 | push1 x.fastavalues (Guanine fc) >> write1 x.fastacounter (S fc) >> pure FD
216 | onFASTAValueCytosine : (x : FSTCK q) => F1 q FST
217 | onFASTAValueCytosine = T1.do
218 | fc <- read1 x.fastacounter
219 | push1 x.fastavalues (Cytosine fc) >> write1 x.fastacounter (S fc) >> pure FD
221 | onNLFHdr : (x : FSTCK q) => ByteString -> F1 q FST
224 | push1 x.fastavalues (NL v)
225 | fvs@(_::_) <- getList x.fastavalues | [] => pure FEmpty
226 | case Prelude.any isHeader fvs && Prelude.any isData fvs of
227 | True => pure FBroken
230 | push1 x.fastalines (MkFASTALine ln fvs)
233 | onNLFD : (x : FSTCK q) => ByteString -> F1 q FST
236 | push1 x.fastavalues (NL v)
237 | fvs@(_::_) <- getList x.fastavalues | [] => pure FEmpty
238 | case Prelude.any isHeader fvs && Prelude.any isData fvs of
239 | True => pure FBroken
242 | push1 x.fastalines (MkFASTALine ln fvs)
245 | onEOI : (x : FSTCK q) => F1 q (Either (BBErr Void) FST)
248 | fvs@(_::_) <- getList x.fastavalues
249 | | [] => arrFail FSTCK fastaErr FEmpty x
251 | push1 x.fastalines (MkFASTALine ln fvs)
252 | pure (Right FComplete)
254 | fastaInit : DFA q FSz FSTCK
257 | [ string '>' (\_ => onFASTAValueHdrS HeaderStart)
260 | fastaHdrStrStart : DFA q FSz FSTCK
263 | [ string dot (onFASTAValueHdrR . HeaderValue)
266 | fastaHdrStrRest : DFA q FSz FSTCK
269 | [ string dot (onFASTAValueHdrR . HeaderValue)
270 | , bytes linebreak (\bs => onNLFHdr bs)
273 | fastaFDInit : DFA q FSz FSTCK
276 | [ step adenine onFASTAValueAdenine
277 | , step thymine onFASTAValueThymine
278 | , step guanine onFASTAValueGuanine
279 | , step cytosine onFASTAValueCytosine
282 | fastaFD : DFA q FSz FSTCK
285 | [ bytes linebreak onNLFD
286 | , step adenine onFASTAValueAdenine
287 | , step thymine onFASTAValueThymine
288 | , step guanine onFASTAValueGuanine
289 | , step cytosine onFASTAValueCytosine
292 | fastaSteps : Lex1 q FSz FSTCK
296 | , E FHdrToNLS fastaHdrStrStart
297 | , E FHdrToNLR fastaHdrStrRest
298 | , E FHdrDone fastaFDInit
299 | , E FDNL fastaFDInit
303 | fastaEOI : FST -> FSTCK q -> F1 q (Either (BBErr Void) FASTA)
305 | case st == FIni || st == FHdr || st == FEmpty || st == FBroken of
306 | True => arrFail FSTCK fastaErr st x
309 | fasta <- getList x.fastalines
317 | fasta : CoordinateSystem -> P1 q (BBErr Void) FASTA
318 | fasta coordsys = P FIni (fastainit coordsys) fastaSteps snocChunk fastaErr fastaEOI
321 | parseFASTA : CoordinateSystem -> Origin -> String -> Either (ParseError Void) FASTA
322 | parseFASTA coordsys origin str = parseString (fasta coordsys) origin str
328 | streamFASTA : CoordinateSystem
330 | -> AsyncPull Poll Void [BBErr Void, Errno] ()
331 | streamFASTA coordsys pth =
333 | |> streamParse (fasta coordsys)
335 | |> printLnTo Stdout
337 | streamFASTAFiles : CoordinateSystem
338 | -> AsyncPull Poll String [BBErr Void, Errno] ()
339 | -> AsyncPull Poll Void [BBErr Void, Errno] ()
340 | streamFASTAFiles coordsys pths =
341 | flatMap pths (\p => readBytes p |> streamParse (fasta coordsys))
343 | |> printLnTo Stdout