rendered paste bodymodule Endo
where
data DNA = I | C | F | P
| Skip Integer | Match [DNA] | Braced [DNA] | RNA [DNA]
| Ref Integer Integer | RefLen Integer
deriving (Show)
charToDNA :: Char -> DNA
charToDNA 'I' = I
charToDNA 'C' = C
charToDNA 'F' = F
charToDNA 'P' = P
nat :: [DNA] -> (Integer,[DNA])
nat (P:xs) = (0,xs)
nat (I:xs) = (2*n, r) where (n,r) = nat xs
nat (F:xs) = (2*n, r) where (n,r) = nat xs
nat (C:xs) = (2*n+1,r) where (n,r) = nat xs
consts :: [DNA] -> ([DNA],[DNA])
consts (C:xs) = (I:ys,r) where (ys,r) = consts xs
consts (F:xs) = (C:ys,r) where (ys,r) = consts xs
consts (P:xs) = (F:ys,r) where (ys,r) = consts xs
consts (I:C:xs) = (P:ys,r) where (ys,r) = consts xs
consts xs = ([],xs)
pattern :: [DNA] -> ([DNA],[DNA])
pattern (C:xs) = (I:ys,r) where (ys,r) = pattern xs
pattern (F:xs) = (C:ys,r) where (ys,r) = pattern xs
pattern (P:xs) = (F:ys,r) where (ys,r) = pattern xs
pattern (I:C:xs) = (P:ys,r) where (ys,r) = pattern xs
pattern (I:P:xs) =
let (n,r1) = nat xs
(ys,r) = pattern r1
in ((Skip n):ys,r)
pattern (I:F:x:xs) =
let (m,r1) = consts xs
(ys,r) = pattern r1
in ((Match m):ys,r)
pattern (I:I:P:xs) =
let (b,r1) = pattern xs
(ys,r) = pattern r1
in ((Braced b):ys,r)
pattern (I:I:C:xs) = ([],xs)
pattern (I:I:F:xs) = ([],xs)
pattern (I:I:I:a:b:c:d:e:f:g:xs) =
((RNA [a,b,c,d,e,f,g]):ys,r) where (ys,r) = pattern xs
template :: [DNA] -> ([DNA],[DNA])
template (C:xs) = (I:ys,r) where (ys,r) = template xs
template (F:xs) = (C:ys,r) where (ys,r) = template xs
template (P:xs) = (F:ys,r) where (ys,r) = template xs
template (I:C:xs) = (P:ys,r) where (ys,r) = template xs
template (I:F:xs) =
let (l,r1) = nat xs
(n,r2) = nat r1
(ys,r) = template r2
in ((Ref n l):ys,r)
template (I:P:xs) =
let (l,r1) = nat xs
(n,r2) = nat r1
(ys,r) = template r2
in ((Ref n l):ys,r)
template (I:I:C:xs) = ([],xs)
template (I:I:F:xs) = ([],xs)
template (I:I:P:xs) =
let (n,r1) = nat xs
(ys,r) = template r1
in ((RefLen n):ys,r)
template (I:I:I:a:b:c:d:e:f:g:xs) =
((RNA [a,b,c,d,e,f,g]):ys,r) where (ys,r) = template xs
test1 = map charToDNA "ICFP"
test2 = nat $ map charToDNA "IIICCP"
test3 = pattern [I,P,I,I,C,P,C,F,P,I,C,I,P,P,I,I,C]
test4 = pattern $ map charToDNA "CIIC"
test5 = pattern $ map charToDNA "IIPIPICPIICICIIF"