module Language.Drasil.Code.Imperative.ReadInput (
sampleInputDD, readWithDataDesc
) where
import Language.Drasil hiding (Data, Matrix, CodeVarChunk)
import Language.Drasil.Code.DataDesc (DataDesc'(..), Data'(..), DataItem'(..),
Delimiter, dataDesc, junk, list, singleton')
import Language.Drasil.Chunk.Code (CodeVarChunk)
import Language.Drasil.Expr.Development (Expr(Matrix))
import Control.Lens ((^.))
import Data.List (intersperse, isPrefixOf, transpose)
import Data.List.Split (splitOn)
import Data.List.NonEmpty (NonEmpty(..), toList)
readWithDataDesc :: FilePath -> DataDesc' -> IO [Expr]
readWithDataDesc :: FilePath -> DataDesc' -> IO [Expr]
readWithDataDesc FilePath
fp DataDesc'
ddsc = do
FilePath
ins <- FilePath -> IO FilePath
readFile FilePath
fp
let readDD :: DataDesc' -> String -> [Expr]
readDD :: DataDesc' -> FilePath -> [Expr]
readDD (DD Data'
ds FilePath
dlm DataDesc'
dd) FilePath
s = let (FilePath
dat,FilePath
rest) = FilePath -> FilePath -> (FilePath, FilePath)
splitAtFirst FilePath
s FilePath
dlm in
Data' -> FilePath -> [Expr]
readData Data'
ds FilePath
dat [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ DataDesc' -> FilePath -> [Expr]
readDD DataDesc'
dd FilePath
rest
readDD (End Data'
d) FilePath
s = Data' -> FilePath -> [Expr]
readData Data'
d FilePath
s
readData :: Data' -> String -> [Expr]
readData :: Data' -> FilePath -> [Expr]
readData Data'
Junk FilePath
_ = []
readData (Datum DataItem'
d) FilePath
s = [DataItem' -> FilePath -> Expr
readDataItem DataItem'
d FilePath
s]
readData (Data NonEmpty DataItem'
dis Integer
0 FilePath
d) FilePath
s = (DataItem' -> FilePath -> Expr)
-> [DataItem'] -> [FilePath] -> [Expr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith DataItem' -> FilePath -> Expr
readDataItem (NonEmpty DataItem' -> [DataItem']
forall a. NonEmpty a -> [a]
toList NonEmpty DataItem'
dis) (FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
d FilePath
s)
readData (Data ((DI CodeVarChunk
c [FilePath
dlm1]):|[DataItem']
_) Integer
1 FilePath
dlm2) FilePath
s = ([FilePath] -> Expr) -> [[FilePath]] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (([[Expr]] -> Expr
Matrix ([[Expr]] -> Expr) -> ([Expr] -> [[Expr]]) -> [Expr] -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Expr] -> [[Expr]] -> [[Expr]]
forall a. a -> [a] -> [a]
:[])) ([Expr] -> Expr) -> ([FilePath] -> [Expr]) -> [FilePath] -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(FilePath -> Expr) -> [FilePath] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr (Space -> Space
getInnerSpace (Space -> Space) -> Space -> Space
forall a b. (a -> b) -> a -> b
$ CodeVarChunk
c CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ))) ([[FilePath]] -> [Expr]) -> [[FilePath]] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [[FilePath]] -> [[FilePath]]
forall a. [[a]] -> [[a]]
transpose ([[FilePath]] -> [[FilePath]]) -> [[FilePath]] -> [[FilePath]]
forall a b. (a -> b) -> a -> b
$
(FilePath -> [FilePath]) -> [FilePath] -> [[FilePath]]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm2) ([FilePath] -> [[FilePath]]) -> [FilePath] -> [[FilePath]]
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm1 FilePath
s
readData (Data ((DI CodeVarChunk
c [FilePath
dlm1, FilePath
dlm3]):|[DataItem']
_) Integer
1 FilePath
dlm2) FilePath
s = ([[FilePath]] -> Expr) -> [[[FilePath]]] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map ([[Expr]] -> Expr
Matrix ([[Expr]] -> Expr)
-> ([[FilePath]] -> [[Expr]]) -> [[FilePath]] -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
([FilePath] -> [Expr]) -> [[FilePath]] -> [[Expr]]
forall a b. (a -> b) -> [a] -> [b]
map ((FilePath -> Expr) -> [FilePath] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr (Space -> Space
getInnerSpace (Space -> Space) -> Space -> Space
forall a b. (a -> b) -> a -> b
$ CodeVarChunk
c CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ)))) ([[[FilePath]]] -> [Expr]) -> [[[FilePath]]] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [[[FilePath]]] -> [[[FilePath]]]
forall a. [[a]] -> [[a]]
transpose ([[[FilePath]]] -> [[[FilePath]]])
-> [[[FilePath]]] -> [[[FilePath]]]
forall a b. (a -> b) -> a -> b
$
(FilePath -> [[FilePath]]) -> [FilePath] -> [[[FilePath]]]
forall a b. (a -> b) -> [a] -> [b]
map ((FilePath -> [FilePath]) -> [FilePath] -> [[FilePath]]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm3) ([FilePath] -> [[FilePath]])
-> (FilePath -> [FilePath]) -> FilePath -> [[FilePath]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm2) ([FilePath] -> [[[FilePath]]]) -> [FilePath] -> [[[FilePath]]]
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm1 FilePath
s
readData (Data ((DI CodeVarChunk
c [FilePath
dlm1, FilePath
dlm2]):|[DataItem']
_) Integer
2 FilePath
dlm3) FilePath
s = ([[FilePath]] -> Expr) -> [[[FilePath]]] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map ([[Expr]] -> Expr
Matrix ([[Expr]] -> Expr)
-> ([[FilePath]] -> [[Expr]]) -> [[FilePath]] -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
([FilePath] -> [Expr]) -> [[FilePath]] -> [[Expr]]
forall a b. (a -> b) -> [a] -> [b]
map ((FilePath -> Expr) -> [FilePath] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr (Space -> Space
getInnerSpace (Space -> Space) -> Space -> Space
forall a b. (a -> b) -> a -> b
$ CodeVarChunk
c CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ))) ([[FilePath]] -> [[Expr]])
-> ([[FilePath]] -> [[FilePath]]) -> [[FilePath]] -> [[Expr]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[FilePath]] -> [[FilePath]]
forall a. [[a]] -> [[a]]
transpose) ([[[FilePath]]] -> [Expr]) -> [[[FilePath]]] -> [Expr]
forall a b. (a -> b) -> a -> b
$
[[[FilePath]]] -> [[[FilePath]]]
forall a. [[a]] -> [[a]]
transpose ([[[FilePath]]] -> [[[FilePath]]])
-> [[[FilePath]]] -> [[[FilePath]]]
forall a b. (a -> b) -> a -> b
$ (FilePath -> [[FilePath]]) -> [FilePath] -> [[[FilePath]]]
forall a b. (a -> b) -> [a] -> [b]
map ((FilePath -> [FilePath]) -> [FilePath] -> [[FilePath]]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm3) ([FilePath] -> [[FilePath]])
-> (FilePath -> [FilePath]) -> FilePath -> [[FilePath]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm2) ([FilePath] -> [[[FilePath]]]) -> [FilePath] -> [[[FilePath]]]
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm1 FilePath
s
readData Data'
_ FilePath
_ = FilePath -> [Expr]
forall a. HasCallStack => FilePath -> a
error FilePath
"Invalid degree of intermixing in DataDesc or list with more than 2 dimensions (not yet supported)"
readDataItem :: DataItem' -> String -> Expr
readDataItem :: DataItem' -> FilePath -> Expr
readDataItem (DI CodeVarChunk
c []) FilePath
s = Space -> FilePath -> Expr
strAsExpr (CodeVarChunk
c CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ) FilePath
s
readDataItem (DI CodeVarChunk
c [FilePath
dlm]) FilePath
s = Space -> [FilePath] -> Expr
strListAsExpr (CodeVarChunk
c CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ) (FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm FilePath
s)
readDataItem (DI CodeVarChunk
c [FilePath
dlm1, FilePath
dlm2]) FilePath
s = Space -> [[FilePath]] -> Expr
strList2DAsExpr (CodeVarChunk
c CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ)
((FilePath -> [FilePath]) -> [FilePath] -> [[FilePath]]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm2) ([FilePath] -> [[FilePath]]) -> [FilePath] -> [[FilePath]]
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> [FilePath]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm1 FilePath
s)
readDataItem (DI CodeVarChunk
_ [FilePath]
_) FilePath
_ = FilePath -> Expr
forall a. HasCallStack => FilePath -> a
error FilePath
"readWithDataDesc does not yet support lists with 3 or more dimensions"
[Expr] -> IO [Expr]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Expr] -> IO [Expr]) -> [Expr] -> IO [Expr]
forall a b. (a -> b) -> a -> b
$ DataDesc' -> FilePath -> [Expr]
readDD DataDesc'
ddsc FilePath
ins
sampleInputDD :: [CodeVarChunk] -> DataDesc'
sampleInputDD :: [CodeVarChunk] -> DataDesc'
sampleInputDD [CodeVarChunk]
ds = [Data'] -> FilePath -> DataDesc'
dataDesc (Data'
junk Data' -> [Data'] -> [Data']
forall a. a -> [a] -> [a]
: Data' -> [Data'] -> [Data']
forall a. a -> [a] -> [a]
intersperse Data'
junk ((CodeVarChunk -> Data') -> [CodeVarChunk] -> [Data']
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> Data'
toData [CodeVarChunk]
ds)) FilePath
"\n"
where toData :: CodeVarChunk -> Data'
toData CodeVarChunk
d = Space -> CodeVarChunk -> Data'
toData' (CodeVarChunk
d CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ) CodeVarChunk
d
toData' :: Space -> CodeVarChunk -> Data'
toData' t :: Space
t@(Vect Space
_) CodeVarChunk
d = CodeVarChunk -> [FilePath] -> Data'
list CodeVarChunk
d
(Int -> [FilePath] -> [FilePath]
forall a. Int -> [a] -> [a]
take (Space -> Int
getDimension Space
t) ([FilePath
", ", FilePath
"; "] [FilePath] -> [FilePath] -> [FilePath]
forall a. [a] -> [a] -> [a]
++ (FilePath -> FilePath) -> FilePath -> [FilePath]
forall a. (a -> a) -> a -> [a]
iterate (Char
':'Char -> FilePath -> FilePath
forall a. a -> [a] -> [a]
:) FilePath
":"))
toData' Space
_ CodeVarChunk
d = CodeVarChunk -> Data'
singleton' CodeVarChunk
d
strAsExpr :: Space -> String -> Expr
strAsExpr :: Space -> FilePath -> Expr
strAsExpr Space
Integer FilePath
s = Integer -> Expr
forall r. LiteralC r => Integer -> r
int (FilePath -> Integer
forall a. Read a => FilePath -> a
read FilePath
s :: Integer)
strAsExpr Space
Natural FilePath
s = Integer -> Expr
forall r. LiteralC r => Integer -> r
int (FilePath -> Integer
forall a. Read a => FilePath -> a
read FilePath
s :: Integer)
strAsExpr Space
Real FilePath
s = Double -> Expr
forall r. LiteralC r => Double -> r
dbl (FilePath -> Double
forall a. Read a => FilePath -> a
read FilePath
s :: Double)
strAsExpr Space
Rational FilePath
s = Double -> Expr
forall r. LiteralC r => Double -> r
dbl (FilePath -> Double
forall a. Read a => FilePath -> a
read FilePath
s :: Double)
strAsExpr Space
String FilePath
s = FilePath -> Expr
forall r. LiteralC r => FilePath -> r
str FilePath
s
strAsExpr Space
_ FilePath
_ = FilePath -> Expr
forall a. HasCallStack => FilePath -> a
error FilePath
"strAsExpr should only be numeric space or string"
getDimension :: Space -> Int
getDimension :: Space -> Int
getDimension (Vect Space
t) = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Space -> Int
getDimension Space
t
getDimension Space
_ = Int
0
splitAtFirst :: String -> Delimiter -> (String, String)
splitAtFirst :: FilePath -> FilePath -> (FilePath, FilePath)
splitAtFirst = FilePath -> FilePath -> FilePath -> (FilePath, FilePath)
forall {a}. Eq a => [a] -> [a] -> [a] -> ([a], [a])
splitAtFirst' []
where splitAtFirst' :: [a] -> [a] -> [a] -> ([a], [a])
splitAtFirst' [a]
acc [] [a]
_ = ([a]
acc, [])
splitAtFirst' [a]
acc s :: [a]
s@(a
h:[a]
t) [a]
d = if [a]
d [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [a]
s then
([a]
acc, [a] -> [a] -> [a]
forall {a}. Eq a => [a] -> [a] -> [a]
dropDelim [a]
d [a]
s) else [a] -> [a] -> [a] -> ([a], [a])
splitAtFirst' ([a]
acc[a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++[a
h]) [a]
t [a]
d
dropDelim :: [a] -> [a] -> [a]
dropDelim (a
d:[a]
ds) (a
s:[a]
ss) = if a
d a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
s then [a] -> [a] -> [a]
dropDelim [a]
ds [a]
ss
else FilePath -> [a]
forall a. HasCallStack => FilePath -> a
error FilePath
"impossible"
dropDelim [] [a]
s = [a]
s
dropDelim [a]
_ [] = FilePath -> [a]
forall a. HasCallStack => FilePath -> a
error FilePath
"impossible"
strListAsExpr :: Space -> [String] -> Expr
strListAsExpr :: Space -> [FilePath] -> Expr
strListAsExpr (Vect Space
t) [FilePath]
ss = [[Expr]] -> Expr
Matrix [(FilePath -> Expr) -> [FilePath] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr Space
t) [FilePath]
ss]
strListAsExpr Space
_ [FilePath]
_ = FilePath -> Expr
forall a. HasCallStack => FilePath -> a
error FilePath
"strListsAsExpr called on non-vector space"
strList2DAsExpr :: Space -> [[String]] -> Expr
strList2DAsExpr :: Space -> [[FilePath]] -> Expr
strList2DAsExpr (Vect (Vect Space
t)) [[FilePath]]
sss = [[Expr]] -> Expr
Matrix ([[Expr]] -> Expr) -> [[Expr]] -> Expr
forall a b. (a -> b) -> a -> b
$ ([FilePath] -> [Expr]) -> [[FilePath]] -> [[Expr]]
forall a b. (a -> b) -> [a] -> [b]
map ((FilePath -> Expr) -> [FilePath] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr Space
t)) [[FilePath]]
sss
strList2DAsExpr Space
_ [[FilePath]]
_ = FilePath -> Expr
forall a. HasCallStack => FilePath -> a
error FilePath
"strLists2DAsExprs called on non-2D-vector space"