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 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 = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith DataItem' -> FilePath -> Expr
readDataItem (forall a. NonEmpty a -> [a]
toList NonEmpty DataItem'
dis) (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 = forall a b. (a -> b) -> [a] -> [b]
map (([[Expr]] -> Expr
Matrix forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> [a] -> [a]
:[])) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr (Space -> Space
getInnerSpace forall a b. (a -> b) -> a -> b
$ CodeVarChunk
c forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ))) forall a b. (a -> b) -> a -> b
$ forall a. [[a]] -> [[a]]
transpose forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map (forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm2) forall a b. (a -> b) -> a -> b
$ 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 = forall a b. (a -> b) -> [a] -> [b]
map ([[Expr]] -> Expr
Matrix forall b c a. (b -> c) -> (a -> b) -> a -> c
.
forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr (Space -> Space
getInnerSpace forall a b. (a -> b) -> a -> b
$ CodeVarChunk
c forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ)))) forall a b. (a -> b) -> a -> b
$ forall a. [[a]] -> [[a]]
transpose forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map (forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm3) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm2) forall a b. (a -> b) -> a -> b
$ 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 = forall a b. (a -> b) -> [a] -> [b]
map ([[Expr]] -> Expr
Matrix forall b c a. (b -> c) -> (a -> b) -> a -> c
.
forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr (Space -> Space
getInnerSpace forall a b. (a -> b) -> a -> b
$ CodeVarChunk
c forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ))) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [[a]] -> [[a]]
transpose) forall a b. (a -> b) -> a -> b
$
forall a. [[a]] -> [[a]]
transpose forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map (forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm3) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm2) forall a b. (a -> b) -> a -> b
$ forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm1 FilePath
s
readData Data'
_ FilePath
_ = 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 forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ) FilePath
s
readDataItem (DI CodeVarChunk
c [FilePath
dlm]) FilePath
s = Space -> [FilePath] -> Expr
strListAsExpr (CodeVarChunk
c forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ) (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 forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ)
(forall a b. (a -> b) -> [a] -> [b]
map (forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm2) forall a b. (a -> b) -> a -> b
$ forall a. Eq a => [a] -> [a] -> [[a]]
splitOn FilePath
dlm1 FilePath
s)
readDataItem (DI CodeVarChunk
_ [FilePath]
_) FilePath
_ = forall a. HasCallStack => FilePath -> a
error FilePath
"readWithDataDesc does not yet support lists with 3 or more dimensions"
forall (m :: * -> *) a. Monad m => a -> m a
return 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 forall a. a -> [a] -> [a]
: forall a. a -> [a] -> [a]
intersperse Data'
junk (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 forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ) CodeVarChunk
d
toData' :: Space -> CodeVarChunk -> Data'
toData' t :: Space
t@(Vect Space
_) CodeVarChunk
d = CodeVarChunk -> [FilePath] -> Data'
list CodeVarChunk
d
(forall a. Int -> [a] -> [a]
take (Space -> Int
getDimension Space
t) ([FilePath
", ", FilePath
"; "] forall a. [a] -> [a] -> [a]
++ forall a. (a -> a) -> a -> [a]
iterate (Char
':'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 = forall r. LiteralC r => Integer -> r
int (forall a. Read a => FilePath -> a
read FilePath
s :: Integer)
strAsExpr Space
Natural FilePath
s = forall r. LiteralC r => Integer -> r
int (forall a. Read a => FilePath -> a
read FilePath
s :: Integer)
strAsExpr Space
Real FilePath
s = forall r. LiteralC r => Double -> r
dbl (forall a. Read a => FilePath -> a
read FilePath
s :: Double)
strAsExpr Space
Rational FilePath
s = forall r. LiteralC r => Double -> r
dbl (forall a. Read a => FilePath -> a
read FilePath
s :: Double)
strAsExpr Space
String FilePath
s = forall r. LiteralC r => FilePath -> r
str FilePath
s
strAsExpr Space
_ FilePath
_ = 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 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 = 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 forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [a]
s then
([a]
acc, forall {a}. Eq a => [a] -> [a] -> [a]
dropDelim [a]
d [a]
s) else [a] -> [a] -> [a] -> ([a], [a])
splitAtFirst' ([a]
accforall 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 forall a. Eq a => a -> a -> Bool
== a
s then [a] -> [a] -> [a]
dropDelim [a]
ds [a]
ss
else forall a. HasCallStack => FilePath -> a
error FilePath
"impossible"
dropDelim [] [a]
s = [a]
s
dropDelim [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 [forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr Space
t) [FilePath]
ss]
strListAsExpr Space
_ [FilePath]
_ = 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 forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map (Space -> FilePath -> Expr
strAsExpr Space
t)) [[FilePath]]
sss
strList2DAsExpr Space
_ [[FilePath]]
_ = forall a. HasCallStack => FilePath -> a
error FilePath
"strLists2DAsExprs called on non-2D-vector space"