module Futhark.Script
(
ScriptServer,
withScriptServer,
withScriptServer',
Func (..),
Exp (..),
parseExp,
parseExpFromText,
varsInExp,
ScriptValueType (..),
ScriptValue (..),
scriptValueType,
serverVarsInValue,
ValOrVar (..),
ExpValue,
EvalBuiltin,
scriptBuiltin,
evalExp,
getExpValue,
evalExpToGround,
valueToExp,
freeValue,
)
where
import Control.Monad
import Control.Monad.Except (MonadError (..))
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Bifunctor (bimap)
import Data.ByteString qualified as BS
import Data.ByteString.Lazy qualified as LBS
import Data.Char
import Data.Foldable (toList)
import Data.Functor
import Data.IORef
import Data.List (intersperse)
import Data.Map qualified as M
import Data.Set qualified as S
import Data.Text qualified as T
import Data.Traversable
import Data.Vector.Storable qualified as SVec
import Data.Void
import Data.Word (Word8)
import Futhark.Data.Parser qualified as V
import Futhark.Server
import Futhark.Server.Values (getValue, putValue)
import Futhark.Test.Values qualified as V
import Futhark.Util (nubOrd)
import Futhark.Util.Pretty hiding (line, sep, space, (</>))
import Language.Futhark.Core (Name, nameFromText, nameToText)
import Language.Futhark.Tuple (areTupleFields)
import System.FilePath ((</>))
import Text.Megaparsec
import Text.Megaparsec.Char (space)
import Text.Megaparsec.Char.Lexer (charLiteral)
type TypeMap = M.Map TypeName (Maybe [(Name, TypeName)])
typeMap :: (MonadIO m) => Server -> m TypeMap
typeMap :: forall (m :: * -> *). MonadIO m => Server -> m TypeMap
typeMap Server
server = do
IO TypeMap -> m TypeMap
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO TypeMap -> m TypeMap) -> IO TypeMap -> m TypeMap
forall a b. (a -> b) -> a -> b
$ (CmdFailure -> IO TypeMap)
-> ([EntryName] -> IO TypeMap)
-> Either CmdFailure [EntryName]
-> IO TypeMap
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (IO TypeMap -> CmdFailure -> IO TypeMap
forall a. a -> CmdFailure -> a
forall (f :: * -> *) a. Applicative f => a -> f a
pure IO TypeMap
forall a. Monoid a => a
mempty) [EntryName] -> IO TypeMap
onTypes (Either CmdFailure [EntryName] -> IO TypeMap)
-> IO (Either CmdFailure [EntryName]) -> IO TypeMap
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Server -> IO (Either CmdFailure [EntryName])
cmdTypes Server
server
where
onTypes :: [EntryName] -> IO TypeMap
onTypes [EntryName]
types = [(EntryName, Maybe [(Name, EntryName)])] -> TypeMap
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(EntryName, Maybe [(Name, EntryName)])] -> TypeMap)
-> ([Maybe [(Name, EntryName)]]
-> [(EntryName, Maybe [(Name, EntryName)])])
-> [Maybe [(Name, EntryName)]]
-> TypeMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [EntryName]
-> [Maybe [(Name, EntryName)]]
-> [(EntryName, Maybe [(Name, EntryName)])]
forall a b. [a] -> [b] -> [(a, b)]
zip [EntryName]
types ([Maybe [(Name, EntryName)]] -> TypeMap)
-> IO [Maybe [(Name, EntryName)]] -> IO TypeMap
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (EntryName -> IO (Maybe [(Name, EntryName)]))
-> [EntryName] -> IO [Maybe [(Name, EntryName)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM EntryName -> IO (Maybe [(Name, EntryName)])
onType [EntryName]
types
onType :: EntryName -> IO (Maybe [(Name, EntryName)])
onType EntryName
t =
(CmdFailure -> Maybe [(Name, EntryName)])
-> ([EntryName] -> Maybe [(Name, EntryName)])
-> Either CmdFailure [EntryName]
-> Maybe [(Name, EntryName)]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe [(Name, EntryName)]
-> CmdFailure -> Maybe [(Name, EntryName)]
forall a b. a -> b -> a
const Maybe [(Name, EntryName)]
forall a. Maybe a
Nothing) ([(Name, EntryName)] -> Maybe [(Name, EntryName)]
forall a. a -> Maybe a
Just ([(Name, EntryName)] -> Maybe [(Name, EntryName)])
-> ([EntryName] -> [(Name, EntryName)])
-> [EntryName]
-> Maybe [(Name, EntryName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (EntryName -> (Name, EntryName))
-> [EntryName] -> [(Name, EntryName)]
forall a b. (a -> b) -> [a] -> [b]
map EntryName -> (Name, EntryName)
onField) (Either CmdFailure [EntryName] -> Maybe [(Name, EntryName)])
-> IO (Either CmdFailure [EntryName])
-> IO (Maybe [(Name, EntryName)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Server -> EntryName -> IO (Either CmdFailure [EntryName])
cmdFields Server
server EntryName
t
onField :: EntryName -> (Name, EntryName)
onField = (EntryName -> Name)
-> (EntryName -> EntryName)
-> (EntryName, EntryName)
-> (Name, EntryName)
forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap EntryName -> Name
nameFromText (Int -> EntryName -> EntryName
T.drop Int
1) ((EntryName, EntryName) -> (Name, EntryName))
-> (EntryName -> (EntryName, EntryName))
-> EntryName
-> (Name, EntryName)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => EntryName -> EntryName -> (EntryName, EntryName)
EntryName -> EntryName -> (EntryName, EntryName)
T.breakOn EntryName
" "
isRecord :: TypeName -> TypeMap -> Maybe [(Name, TypeName)]
isRecord :: EntryName -> TypeMap -> Maybe [(Name, EntryName)]
isRecord EntryName
t TypeMap
m = Maybe (Maybe [(Name, EntryName)]) -> Maybe [(Name, EntryName)]
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Maybe (Maybe [(Name, EntryName)]) -> Maybe [(Name, EntryName)])
-> Maybe (Maybe [(Name, EntryName)]) -> Maybe [(Name, EntryName)]
forall a b. (a -> b) -> a -> b
$ EntryName -> TypeMap -> Maybe (Maybe [(Name, EntryName)])
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup EntryName
t TypeMap
m
isTuple :: TypeName -> TypeMap -> Maybe [TypeName]
isTuple :: EntryName -> TypeMap -> Maybe [EntryName]
isTuple EntryName
t TypeMap
m = Map Name EntryName -> Maybe [EntryName]
forall a. Map Name a -> Maybe [a]
areTupleFields (Map Name EntryName -> Maybe [EntryName])
-> ([(Name, EntryName)] -> Map Name EntryName)
-> [(Name, EntryName)]
-> Maybe [EntryName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Name, EntryName)] -> Map Name EntryName
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Name, EntryName)] -> Maybe [EntryName])
-> Maybe [(Name, EntryName)] -> Maybe [EntryName]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EntryName -> TypeMap -> Maybe [(Name, EntryName)]
isRecord EntryName
t TypeMap
m
data ScriptServer = ScriptServer
{ ScriptServer -> Server
scriptServer :: Server,
ScriptServer -> IORef Int
scriptCounter :: IORef Int,
ScriptServer -> TypeMap
scriptTypes :: TypeMap
}
withScriptServer' :: (MonadIO m) => Server -> (ScriptServer -> m a) -> m a
withScriptServer' :: forall (m :: * -> *) a.
MonadIO m =>
Server -> (ScriptServer -> m a) -> m a
withScriptServer' Server
server ScriptServer -> m a
f = do
IORef Int
counter <- IO (IORef Int) -> m (IORef Int)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef Int) -> m (IORef Int))
-> IO (IORef Int) -> m (IORef Int)
forall a b. (a -> b) -> a -> b
$ Int -> IO (IORef Int)
forall a. a -> IO (IORef a)
newIORef Int
0
TypeMap
types <- Server -> m TypeMap
forall (m :: * -> *). MonadIO m => Server -> m TypeMap
typeMap Server
server
ScriptServer -> m a
f (ScriptServer -> m a) -> ScriptServer -> m a
forall a b. (a -> b) -> a -> b
$ Server -> IORef Int -> TypeMap -> ScriptServer
ScriptServer Server
server IORef Int
counter TypeMap
types
withScriptServer :: ServerCfg -> (ScriptServer -> IO a) -> IO a
withScriptServer :: forall a. ServerCfg -> (ScriptServer -> IO a) -> IO a
withScriptServer ServerCfg
cfg ScriptServer -> IO a
f =
ServerCfg -> (Server -> IO a) -> IO a
forall a. ServerCfg -> (Server -> IO a) -> IO a
withServer ServerCfg
cfg ((Server -> IO a) -> IO a) -> (Server -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ (Server -> (ScriptServer -> IO a) -> IO a)
-> (ScriptServer -> IO a) -> Server -> IO a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Server -> (ScriptServer -> IO a) -> IO a
forall (m :: * -> *) a.
MonadIO m =>
Server -> (ScriptServer -> m a) -> m a
withScriptServer' ScriptServer -> IO a
f
data Func = FuncFut EntryName | FuncBuiltin T.Text
deriving (Int -> Func -> ShowS
[Func] -> ShowS
Func -> String
(Int -> Func -> ShowS)
-> (Func -> String) -> ([Func] -> ShowS) -> Show Func
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Func -> ShowS
showsPrec :: Int -> Func -> ShowS
$cshow :: Func -> String
show :: Func -> String
$cshowList :: [Func] -> ShowS
showList :: [Func] -> ShowS
Show)
data Exp
= Call Func [Exp]
| Const V.Value
| Tuple [Exp]
| Record [(T.Text, Exp)]
| StringLit T.Text
| Let [VarName] Exp Exp
|
ServerVar TypeName VarName
deriving (Int -> Exp -> ShowS
[Exp] -> ShowS
Exp -> String
(Int -> Exp -> ShowS)
-> (Exp -> String) -> ([Exp] -> ShowS) -> Show Exp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Exp -> ShowS
showsPrec :: Int -> Exp -> ShowS
$cshow :: Exp -> String
show :: Exp -> String
$cshowList :: [Exp] -> ShowS
showList :: [Exp] -> ShowS
Show)
instance Pretty Func where
pretty :: forall ann. Func -> Doc ann
pretty (FuncFut EntryName
f) = EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty EntryName
f
pretty (FuncBuiltin EntryName
f) = Doc ann
"$" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty EntryName
f
instance Pretty Exp where
pretty :: forall ann. Exp -> Doc ann
pretty = Int -> Exp -> Doc ann
forall {t} {ann}. (Ord t, Num t) => t -> Exp -> Doc ann
pprPrec (Int
0 :: Int)
where
pprPrec :: t -> Exp -> Doc ann
pprPrec t
_ (ServerVar EntryName
_ EntryName
v) = Doc ann
"$" Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty EntryName
v
pprPrec t
_ (Const Value
v) = [Doc ann] -> Doc ann
forall a. [Doc a] -> Doc a
stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ (EntryName -> Doc ann) -> [EntryName] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty ([EntryName] -> [Doc ann]) -> [EntryName] -> [Doc ann]
forall a b. (a -> b) -> a -> b
$ EntryName -> [EntryName]
T.lines (EntryName -> [EntryName]) -> EntryName -> [EntryName]
forall a b. (a -> b) -> a -> b
$ Value -> EntryName
V.valueText Value
v
pprPrec t
i (Let [EntryName]
pat Exp
e1 Exp
e2) =
Bool -> Doc ann -> Doc ann
forall a. Bool -> Doc a -> Doc a
parensIf (t
i t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0) (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ Doc ann
"let" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
forall {ann}. Doc ann
pat' Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
forall {ann}. Doc ann
equals Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e1 Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"in" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty Exp
e2
where
pat' :: Doc ann
pat' = case [EntryName]
pat of
[EntryName
x] -> EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty EntryName
x
[EntryName]
_ -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
align (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall a. [Doc a] -> Doc a
commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ (EntryName -> Doc ann) -> [EntryName] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty [EntryName]
pat
pprPrec t
_ (Call Func
v []) = Func -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Func -> Doc ann
pretty Func
v
pprPrec t
i (Call Func
v [Exp]
args) =
Bool -> Doc ann -> Doc ann
forall a. Bool -> Doc a -> Doc a
parensIf (t
i t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0) (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ Func -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Func -> Doc ann
pretty Func
v Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> [Doc ann] -> Doc ann
forall a. [Doc a] -> Doc a
hsep ((Exp -> Doc ann) -> [Exp] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map (Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
align (Doc ann -> Doc ann) -> (Exp -> Doc ann) -> Exp -> Doc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> Exp -> Doc ann
pprPrec t
1) [Exp]
args)
pprPrec t
_ (Tuple [Exp]
vs) =
Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall a. [Doc a] -> Doc a
commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ (Exp -> Doc ann) -> [Exp] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map (Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
align (Doc ann -> Doc ann) -> (Exp -> Doc ann) -> Exp -> Doc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Exp -> Doc ann
pretty) [Exp]
vs
pprPrec t
_ (StringLit EntryName
s) = String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ EntryName -> String
forall a. Show a => a -> String
show EntryName
s
pprPrec t
_ (Record [(EntryName, Exp)]
m) = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
braces (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
align (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall a. [Doc a] -> Doc a
commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ ((EntryName, Exp) -> Doc ann) -> [(EntryName, Exp)] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map (EntryName, Exp) -> Doc ann
forall {a} {a} {ann}. (Pretty a, Pretty a) => (a, a) -> Doc ann
field [(EntryName, Exp)]
m
where
field :: (a, a) -> Doc ann
field (a
k, a
v) = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
align (a -> Doc ann
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
k Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
forall {ann}. Doc ann
equals Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> a -> Doc ann
forall ann. a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty a
v)
type Parser = Parsec Void T.Text
lexeme :: Parser () -> Parser a -> Parser a
lexeme :: forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser a
p = Parser a
p Parser a -> Parser () -> Parser a
forall a b.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
-> ParsecT Void EntryName Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
sep
inParens :: Parser () -> Parser a -> Parser a
inParens :: forall a. Parser () -> Parser a -> Parser a
inParens Parser ()
sep = Parser EntryName
-> Parser EntryName
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity a
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
"(") (Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
")")
inBraces :: Parser () -> Parser a -> Parser a
inBraces :: forall a. Parser () -> Parser a -> Parser a
inBraces Parser ()
sep = Parser EntryName
-> Parser EntryName
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity a
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
"{") (Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
"}")
parseExp :: Parsec Void T.Text () -> Parsec Void T.Text Exp
parseExp :: Parser () -> Parsec Void EntryName Exp
parseExp Parser ()
sep =
[Parsec Void EntryName Exp] -> Parsec Void EntryName Exp
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
[ Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
"let"
Parser EntryName
-> ([EntryName] -> Exp -> Exp -> Exp)
-> ParsecT
Void EntryName Identity ([EntryName] -> Exp -> Exp -> Exp)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> [EntryName] -> Exp -> Exp -> Exp
Let
ParsecT Void EntryName Identity ([EntryName] -> Exp -> Exp -> Exp)
-> ParsecT Void EntryName Identity [EntryName]
-> ParsecT Void EntryName Identity (Exp -> Exp -> Exp)
forall a b.
ParsecT Void EntryName Identity (a -> b)
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void EntryName Identity [EntryName]
pPat
ParsecT Void EntryName Identity (Exp -> Exp -> Exp)
-> Parser EntryName
-> ParsecT Void EntryName Identity (Exp -> Exp -> Exp)
forall a b.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
-> ParsecT Void EntryName Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
"="
ParsecT Void EntryName Identity (Exp -> Exp -> Exp)
-> Parsec Void EntryName Exp
-> ParsecT Void EntryName Identity (Exp -> Exp)
forall a b.
ParsecT Void EntryName Identity (a -> b)
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser () -> Parsec Void EntryName Exp
parseExp Parser ()
sep
ParsecT Void EntryName Identity (Exp -> Exp)
-> Parser EntryName -> ParsecT Void EntryName Identity (Exp -> Exp)
forall a b.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
-> ParsecT Void EntryName Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
"in"
ParsecT Void EntryName Identity (Exp -> Exp)
-> Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a b.
ParsecT Void EntryName Identity (a -> b)
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser () -> Parsec Void EntryName Exp
parseExp Parser ()
sep,
Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Parsec Void EntryName Exp -> Parsec Void EntryName Exp)
-> Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a b. (a -> b) -> a -> b
$ Func -> [Exp] -> Exp
Call (Func -> [Exp] -> Exp)
-> ParsecT Void EntryName Identity Func
-> ParsecT Void EntryName Identity ([Exp] -> Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void EntryName Identity Func
parseFunc ParsecT Void EntryName Identity ([Exp] -> Exp)
-> ParsecT Void EntryName Identity [Exp]
-> Parsec Void EntryName Exp
forall a b.
ParsecT Void EntryName Identity (a -> b)
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parsec Void EntryName Exp -> ParsecT Void EntryName Identity [Exp]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many Parsec Void EntryName Exp
pAtom,
Parsec Void EntryName Exp
pAtom
]
Parsec Void EntryName Exp -> String -> Parsec Void EntryName Exp
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"expression"
where
pField :: ParsecT Void EntryName Identity (EntryName, Exp)
pField = (,) (EntryName -> Exp -> (EntryName, Exp))
-> Parser EntryName
-> ParsecT Void EntryName Identity (Exp -> (EntryName, Exp))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser EntryName
pVarName ParsecT Void EntryName Identity (Exp -> (EntryName, Exp))
-> Parsec Void EntryName Exp
-> ParsecT Void EntryName Identity (EntryName, Exp)
forall a b.
ParsecT Void EntryName Identity (a -> b)
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Parser EntryName
pEquals Parser EntryName
-> Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a b.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser () -> Parsec Void EntryName Exp
parseExp Parser ()
sep)
pEquals :: Parser EntryName
pEquals = Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
"="
pComma :: Parser EntryName
pComma = Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep Parser EntryName
","
mkTuple :: [Exp] -> Exp
mkTuple [Exp
v] = Exp
v
mkTuple [Exp]
vs = [Exp] -> Exp
Tuple [Exp]
vs
pAtom :: Parsec Void EntryName Exp
pAtom =
[Parsec Void EntryName Exp] -> Parsec Void EntryName Exp
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
[ Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Parsec Void EntryName Exp -> Parsec Void EntryName Exp)
-> Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a b. (a -> b) -> a -> b
$ Parser () -> Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a. Parser () -> Parser a -> Parser a
inParens Parser ()
sep ([Exp] -> Exp
mkTuple ([Exp] -> Exp)
-> ParsecT Void EntryName Identity [Exp]
-> Parsec Void EntryName Exp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser () -> Parsec Void EntryName Exp
parseExp Parser ()
sep Parsec Void EntryName Exp
-> Parser EntryName -> ParsecT Void EntryName Identity [Exp]
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
`sepEndBy` Parser EntryName
pComma)),
Parser () -> Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a. Parser () -> Parser a -> Parser a
inParens Parser ()
sep (Parsec Void EntryName Exp -> Parsec Void EntryName Exp)
-> Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a b. (a -> b) -> a -> b
$ Parser () -> Parsec Void EntryName Exp
parseExp Parser ()
sep,
Parser () -> Parsec Void EntryName Exp -> Parsec Void EntryName Exp
forall a. Parser () -> Parser a -> Parser a
inBraces Parser ()
sep ([(EntryName, Exp)] -> Exp
Record ([(EntryName, Exp)] -> Exp)
-> ParsecT Void EntryName Identity [(EntryName, Exp)]
-> Parsec Void EntryName Exp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT Void EntryName Identity (EntryName, Exp)
pField ParsecT Void EntryName Identity (EntryName, Exp)
-> Parser EntryName
-> ParsecT Void EntryName Identity [(EntryName, Exp)]
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
`sepEndBy` Parser EntryName
pComma)),
EntryName -> Exp
StringLit (EntryName -> Exp) -> (String -> EntryName) -> String -> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> EntryName
T.pack (String -> Exp)
-> ParsecT Void EntryName Identity String
-> Parsec Void EntryName Exp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ()
-> ParsecT Void EntryName Identity String
-> ParsecT Void EntryName Identity String
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep (Parser EntryName
"\"" Parser EntryName
-> ParsecT Void EntryName Identity String
-> ParsecT Void EntryName Identity String
forall a b.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void EntryName Identity Char
-> Parser EntryName -> ParsecT Void EntryName Identity String
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
manyTill ParsecT Void EntryName Identity Char
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m Char
charLiteral Parser EntryName
"\""),
Value -> Exp
Const (Value -> Exp)
-> ParsecT Void EntryName Identity Value
-> Parsec Void EntryName Exp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser () -> ParsecT Void EntryName Identity Value
V.parseValue Parser ()
sep,
Func -> [Exp] -> Exp
Call (Func -> [Exp] -> Exp)
-> ParsecT Void EntryName Identity Func
-> ParsecT Void EntryName Identity ([Exp] -> Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void EntryName Identity Func
parseFunc ParsecT Void EntryName Identity ([Exp] -> Exp)
-> ParsecT Void EntryName Identity [Exp]
-> Parsec Void EntryName Exp
forall a b.
ParsecT Void EntryName Identity (a -> b)
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Exp] -> ParsecT Void EntryName Identity [Exp]
forall a. a -> ParsecT Void EntryName Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
]
pPat :: ParsecT Void EntryName Identity [EntryName]
pPat =
[ParsecT Void EntryName Identity [EntryName]]
-> ParsecT Void EntryName Identity [EntryName]
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
[ Parser ()
-> ParsecT Void EntryName Identity [EntryName]
-> ParsecT Void EntryName Identity [EntryName]
forall a. Parser () -> Parser a -> Parser a
inParens Parser ()
sep (ParsecT Void EntryName Identity [EntryName]
-> ParsecT Void EntryName Identity [EntryName])
-> ParsecT Void EntryName Identity [EntryName]
-> ParsecT Void EntryName Identity [EntryName]
forall a b. (a -> b) -> a -> b
$ Parser EntryName
pVarName Parser EntryName
-> Parser EntryName -> ParsecT Void EntryName Identity [EntryName]
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
`sepEndBy` Parser EntryName
pComma,
EntryName -> [EntryName]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (EntryName -> [EntryName])
-> Parser EntryName -> ParsecT Void EntryName Identity [EntryName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser EntryName
pVarName
]
parseFunc :: ParsecT Void EntryName Identity Func
parseFunc =
[ParsecT Void EntryName Identity Func]
-> ParsecT Void EntryName Identity Func
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
[ EntryName -> Func
FuncBuiltin (EntryName -> Func)
-> Parser EntryName -> ParsecT Void EntryName Identity Func
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser EntryName
"$" Parser EntryName -> Parser EntryName -> Parser EntryName
forall a b.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser EntryName
pVarName),
EntryName -> Func
FuncFut (EntryName -> Func)
-> Parser EntryName -> ParsecT Void EntryName Identity Func
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser EntryName
pVarName
]
reserved :: [EntryName]
reserved = [EntryName
"let", EntryName
"in"]
pVarName :: Parser EntryName
pVarName = Parser () -> Parser EntryName -> Parser EntryName
forall a. Parser () -> Parser a -> Parser a
lexeme Parser ()
sep (Parser EntryName -> Parser EntryName)
-> (Parser EntryName -> Parser EntryName)
-> Parser EntryName
-> Parser EntryName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser EntryName -> Parser EntryName
forall a.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Parser EntryName -> Parser EntryName)
-> Parser EntryName -> Parser EntryName
forall a b. (a -> b) -> a -> b
$ do
EntryName
v <- (String -> EntryName)
-> ParsecT Void EntryName Identity String -> Parser EntryName
forall a b.
(a -> b)
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> EntryName
T.pack (ParsecT Void EntryName Identity String -> Parser EntryName)
-> ParsecT Void EntryName Identity String -> Parser EntryName
forall a b. (a -> b) -> a -> b
$ (:) (Char -> ShowS)
-> ParsecT Void EntryName Identity Char
-> ParsecT Void EntryName Identity ShowS
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Token EntryName -> Bool)
-> ParsecT Void EntryName Identity (Token EntryName)
forall e s (m :: * -> *).
MonadParsec e s m =>
(Token s -> Bool) -> m (Token s)
satisfy Char -> Bool
Token EntryName -> Bool
isAlpha ParsecT Void EntryName Identity ShowS
-> ParsecT Void EntryName Identity String
-> ParsecT Void EntryName Identity String
forall a b.
ParsecT Void EntryName Identity (a -> b)
-> ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void EntryName Identity Char
-> ParsecT Void EntryName Identity String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many ((Token EntryName -> Bool)
-> ParsecT Void EntryName Identity (Token EntryName)
forall e s (m :: * -> *).
MonadParsec e s m =>
(Token s -> Bool) -> m (Token s)
satisfy Char -> Bool
Token EntryName -> Bool
constituent)
Bool -> Parser ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Parser ()) -> Bool -> Parser ()
forall a b. (a -> b) -> a -> b
$ EntryName
v EntryName -> [EntryName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [EntryName]
reserved
EntryName -> Parser EntryName
forall a. a -> ParsecT Void EntryName Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EntryName
v
where
constituent :: Char -> Bool
constituent Char
c = Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\'' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_'
parseExpFromText :: FilePath -> T.Text -> Either T.Text Exp
parseExpFromText :: String -> EntryName -> Either EntryName Exp
parseExpFromText String
f EntryName
s =
(ParseErrorBundle EntryName Void -> Either EntryName Exp)
-> (Exp -> Either EntryName Exp)
-> Either (ParseErrorBundle EntryName Void) Exp
-> Either EntryName Exp
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (EntryName -> Either EntryName Exp
forall a b. a -> Either a b
Left (EntryName -> Either EntryName Exp)
-> (ParseErrorBundle EntryName Void -> EntryName)
-> ParseErrorBundle EntryName Void
-> Either EntryName Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> EntryName
T.pack (String -> EntryName)
-> (ParseErrorBundle EntryName Void -> String)
-> ParseErrorBundle EntryName Void
-> EntryName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseErrorBundle EntryName Void -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty) Exp -> Either EntryName Exp
forall a b. b -> Either a b
Right (Either (ParseErrorBundle EntryName Void) Exp
-> Either EntryName Exp)
-> Either (ParseErrorBundle EntryName Void) Exp
-> Either EntryName Exp
forall a b. (a -> b) -> a -> b
$ Parsec Void EntryName Exp
-> String
-> EntryName
-> Either (ParseErrorBundle EntryName Void) Exp
forall e s a.
Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
parse (Parser () -> Parsec Void EntryName Exp
parseExp Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space Parsec Void EntryName Exp -> Parser () -> Parsec Void EntryName Exp
forall a b.
ParsecT Void EntryName Identity a
-> ParsecT Void EntryName Identity b
-> ParsecT Void EntryName Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
forall e s (m :: * -> *). MonadParsec e s m => m ()
eof) String
f EntryName
s
readVar :: (MonadError T.Text m, MonadIO m) => Server -> VarName -> m V.Value
readVar :: forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
Server -> EntryName -> m Value
readVar Server
server EntryName
v =
(EntryName -> m Value)
-> (Value -> m Value) -> Either EntryName Value -> m Value
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either EntryName -> m Value
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError Value -> m Value
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either EntryName Value -> m Value)
-> m (Either EntryName Value) -> m Value
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO (Either EntryName Value) -> m (Either EntryName Value)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Server -> EntryName -> IO (Either EntryName Value)
getValue Server
server EntryName
v)
writeVar :: (MonadError T.Text m, MonadIO m) => Server -> VarName -> V.Value -> m ()
writeVar :: forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
Server -> EntryName -> Value -> m ()
writeVar Server
server EntryName
v Value
val =
IO (Maybe CmdFailure) -> m ()
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
IO (Maybe CmdFailure) -> m ()
cmdMaybe (IO (Maybe CmdFailure) -> m ()) -> IO (Maybe CmdFailure) -> m ()
forall a b. (a -> b) -> a -> b
$ IO (Maybe CmdFailure) -> IO (Maybe CmdFailure)
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Server -> EntryName -> Value -> IO (Maybe CmdFailure)
putValue Server
server EntryName
v Value
val)
data ScriptValue v
= SValue TypeName v
|
SFun EntryName [TypeName] [TypeName] [ScriptValue v]
deriving (Int -> ScriptValue v -> ShowS
[ScriptValue v] -> ShowS
ScriptValue v -> String
(Int -> ScriptValue v -> ShowS)
-> (ScriptValue v -> String)
-> ([ScriptValue v] -> ShowS)
-> Show (ScriptValue v)
forall v. Show v => Int -> ScriptValue v -> ShowS
forall v. Show v => [ScriptValue v] -> ShowS
forall v. Show v => ScriptValue v -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall v. Show v => Int -> ScriptValue v -> ShowS
showsPrec :: Int -> ScriptValue v -> ShowS
$cshow :: forall v. Show v => ScriptValue v -> String
show :: ScriptValue v -> String
$cshowList :: forall v. Show v => [ScriptValue v] -> ShowS
showList :: [ScriptValue v] -> ShowS
Show)
instance Functor ScriptValue where
fmap :: forall a b. (a -> b) -> ScriptValue a -> ScriptValue b
fmap = (a -> b) -> ScriptValue a -> ScriptValue b
forall (t :: * -> *) a b. Traversable t => (a -> b) -> t a -> t b
fmapDefault
instance Foldable ScriptValue where
foldMap :: forall m a. Monoid m => (a -> m) -> ScriptValue a -> m
foldMap = (a -> m) -> ScriptValue a -> m
forall (t :: * -> *) m a.
(Traversable t, Monoid m) =>
(a -> m) -> t a -> m
foldMapDefault
instance Traversable ScriptValue where
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> ScriptValue a -> f (ScriptValue b)
traverse a -> f b
f (SValue EntryName
t a
v) = EntryName -> b -> ScriptValue b
forall v. EntryName -> v -> ScriptValue v
SValue EntryName
t (b -> ScriptValue b) -> f b -> f (ScriptValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
v
traverse a -> f b
f (SFun EntryName
fname [EntryName]
ins [EntryName]
outs [ScriptValue a]
vs) =
EntryName
-> [EntryName] -> [EntryName] -> [ScriptValue b] -> ScriptValue b
forall v.
EntryName
-> [EntryName] -> [EntryName] -> [ScriptValue v] -> ScriptValue v
SFun EntryName
fname [EntryName]
ins [EntryName]
outs ([ScriptValue b] -> ScriptValue b)
-> f [ScriptValue b] -> f (ScriptValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ScriptValue a -> f (ScriptValue b))
-> [ScriptValue a] -> f [ScriptValue b]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((a -> f b) -> ScriptValue a -> f (ScriptValue b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> ScriptValue a -> f (ScriptValue b)
traverse a -> f b
f) [ScriptValue a]
vs
data ScriptValueType
= STValue TypeName
|
STFun [TypeName] [TypeName]
deriving (ScriptValueType -> ScriptValueType -> Bool
(ScriptValueType -> ScriptValueType -> Bool)
-> (ScriptValueType -> ScriptValueType -> Bool)
-> Eq ScriptValueType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ScriptValueType -> ScriptValueType -> Bool
== :: ScriptValueType -> ScriptValueType -> Bool
$c/= :: ScriptValueType -> ScriptValueType -> Bool
/= :: ScriptValueType -> ScriptValueType -> Bool
Eq, Int -> ScriptValueType -> ShowS
[ScriptValueType] -> ShowS
ScriptValueType -> String
(Int -> ScriptValueType -> ShowS)
-> (ScriptValueType -> String)
-> ([ScriptValueType] -> ShowS)
-> Show ScriptValueType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ScriptValueType -> ShowS
showsPrec :: Int -> ScriptValueType -> ShowS
$cshow :: ScriptValueType -> String
show :: ScriptValueType -> String
$cshowList :: [ScriptValueType] -> ShowS
showList :: [ScriptValueType] -> ShowS
Show)
instance Pretty ScriptValueType where
pretty :: forall ann. ScriptValueType -> Doc ann
pretty (STValue EntryName
t) = EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty EntryName
t
pretty (STFun [EntryName]
ins [EntryName]
outs) =
[Doc ann] -> Doc ann
forall a. [Doc a] -> Doc a
hsep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ Doc ann -> [Doc ann] -> [Doc ann]
forall a. a -> [a] -> [a]
intersperse Doc ann
"->" ((EntryName -> Doc ann) -> [EntryName] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty [EntryName]
ins [Doc ann] -> [Doc ann] -> [Doc ann]
forall a. [a] -> [a] -> [a]
++ [Doc ann
forall {ann}. Doc ann
outs'])
where
outs' :: Doc ann
outs' = case [EntryName]
outs of
[EntryName
out] -> EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty EntryName
out
[EntryName]
_ -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall a. [Doc a] -> Doc a
commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ (EntryName -> Doc ann) -> [EntryName] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map EntryName -> Doc ann
forall ann. EntryName -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty [EntryName]
outs
data ValOrVar = VVal V.Value | VVar VarName
deriving (Int -> ValOrVar -> ShowS
[ValOrVar] -> ShowS
ValOrVar -> String
(Int -> ValOrVar -> ShowS)
-> (ValOrVar -> String) -> ([ValOrVar] -> ShowS) -> Show ValOrVar
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ValOrVar -> ShowS
showsPrec :: Int -> ValOrVar -> ShowS
$cshow :: ValOrVar -> String
show :: ValOrVar -> String
$cshowList :: [ValOrVar] -> ShowS
showList :: [ValOrVar] -> ShowS
Show)
type ExpValue = V.Compound (ScriptValue ValOrVar)
scriptValueType :: ScriptValue v -> ScriptValueType
scriptValueType :: forall v. ScriptValue v -> ScriptValueType
scriptValueType (SValue EntryName
t v
_) = EntryName -> ScriptValueType
STValue EntryName
t
scriptValueType (SFun EntryName
_ [EntryName]
ins [EntryName]
outs [ScriptValue v]
_) = [EntryName] -> [EntryName] -> ScriptValueType
STFun [EntryName]
ins [EntryName]
outs
serverVarsInValue :: ExpValue -> S.Set VarName
serverVarsInValue :: ExpValue -> Set EntryName
serverVarsInValue = [EntryName] -> Set EntryName
forall a. Ord a => [a] -> Set a
S.fromList ([EntryName] -> Set EntryName)
-> (ExpValue -> [EntryName]) -> ExpValue -> Set EntryName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ScriptValue ValOrVar -> [EntryName])
-> [ScriptValue ValOrVar] -> [EntryName]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ScriptValue ValOrVar -> [EntryName]
isVar ([ScriptValue ValOrVar] -> [EntryName])
-> (ExpValue -> [ScriptValue ValOrVar]) -> ExpValue -> [EntryName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExpValue -> [ScriptValue ValOrVar]
forall a. Compound a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
where
isVar :: ScriptValue ValOrVar -> [EntryName]
isVar (SValue EntryName
_ (VVar EntryName
x)) = [EntryName
x]
isVar (SValue EntryName
_ (VVal Value
_)) = []
isVar (SFun EntryName
_ [EntryName]
_ [EntryName]
_ [ScriptValue ValOrVar]
closure) = (ScriptValue ValOrVar -> [EntryName])
-> [ScriptValue ValOrVar] -> [EntryName]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ScriptValue ValOrVar -> [EntryName]
isVar ([ScriptValue ValOrVar] -> [EntryName])
-> [ScriptValue ValOrVar] -> [EntryName]
forall a b. (a -> b) -> a -> b
$ [ScriptValue ValOrVar] -> [ScriptValue ValOrVar]
forall a. [a] -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList [ScriptValue ValOrVar]
closure
valueToExp :: ExpValue -> Exp
valueToExp :: ExpValue -> Exp
valueToExp (V.ValueAtom (SValue EntryName
t (VVar EntryName
v))) =
EntryName -> EntryName -> Exp
ServerVar EntryName
t EntryName
v
valueToExp (V.ValueAtom (SValue EntryName
_ (VVal Value
v))) =
Value -> Exp
Const Value
v
valueToExp (V.ValueAtom (SFun EntryName
fname [EntryName]
_ [EntryName]
_ [ScriptValue ValOrVar]
closure)) =
Func -> [Exp] -> Exp
Call (EntryName -> Func
FuncFut EntryName
fname) ([Exp] -> Exp) -> [Exp] -> Exp
forall a b. (a -> b) -> a -> b
$ (ScriptValue ValOrVar -> Exp) -> [ScriptValue ValOrVar] -> [Exp]
forall a b. (a -> b) -> [a] -> [b]
map (ExpValue -> Exp
valueToExp (ExpValue -> Exp)
-> (ScriptValue ValOrVar -> ExpValue)
-> ScriptValue ValOrVar
-> Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptValue ValOrVar -> ExpValue
forall v. v -> Compound v
V.ValueAtom) [ScriptValue ValOrVar]
closure
valueToExp (V.ValueRecord Map EntryName ExpValue
fs) =
[(EntryName, Exp)] -> Exp
Record ([(EntryName, Exp)] -> Exp) -> [(EntryName, Exp)] -> Exp
forall a b. (a -> b) -> a -> b
$ Map EntryName Exp -> [(EntryName, Exp)]
forall k a. Map k a -> [(k, a)]
M.toList (Map EntryName Exp -> [(EntryName, Exp)])
-> Map EntryName Exp -> [(EntryName, Exp)]
forall a b. (a -> b) -> a -> b
$ (ExpValue -> Exp) -> Map EntryName ExpValue -> Map EntryName Exp
forall a b k. (a -> b) -> Map k a -> Map k b
M.map ExpValue -> Exp
valueToExp Map EntryName ExpValue
fs
valueToExp (V.ValueTuple [ExpValue]
fs) =
[Exp] -> Exp
Tuple ([Exp] -> Exp) -> [Exp] -> Exp
forall a b. (a -> b) -> a -> b
$ (ExpValue -> Exp) -> [ExpValue] -> [Exp]
forall a b. (a -> b) -> [a] -> [b]
map ExpValue -> Exp
valueToExp [ExpValue]
fs
parseTypeName :: TypeName -> Maybe (Int, V.PrimType)
parseTypeName :: EntryName -> Maybe (Int, PrimType)
parseTypeName EntryName
s
| Just PrimType
pt <- EntryName -> [(EntryName, PrimType)] -> Maybe PrimType
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup EntryName
s [(EntryName, PrimType)]
m =
(Int, PrimType) -> Maybe (Int, PrimType)
forall a. a -> Maybe a
Just (Int
0, PrimType
pt)
| EntryName
"[]" EntryName -> EntryName -> Bool
`T.isPrefixOf` EntryName
s = do
(Int
d, PrimType
pt) <- EntryName -> Maybe (Int, PrimType)
parseTypeName (Int -> EntryName -> EntryName
T.drop Int
2 EntryName
s)
(Int, PrimType) -> Maybe (Int, PrimType)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
d Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, PrimType
pt)
| Bool
otherwise = Maybe (Int, PrimType)
forall a. Maybe a
Nothing
where
prims :: [PrimType]
prims = [PrimType
forall a. Bounded a => a
minBound .. PrimType
forall a. Bounded a => a
maxBound]
primtexts :: [EntryName]
primtexts = (PrimType -> EntryName) -> [PrimType] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map (ValueType -> EntryName
V.valueTypeText (ValueType -> EntryName)
-> (PrimType -> ValueType) -> PrimType -> EntryName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> PrimType -> ValueType
V.ValueType []) [PrimType]
prims
m :: [(EntryName, PrimType)]
m = [EntryName] -> [PrimType] -> [(EntryName, PrimType)]
forall a b. [a] -> [b] -> [(a, b)]
zip [EntryName]
primtexts [PrimType]
prims
coerceValue :: TypeName -> V.Value -> Maybe V.Value
coerceValue :: EntryName -> Value -> Maybe Value
coerceValue EntryName
t Value
v = do
(Int
_, PrimType
pt) <- EntryName -> Maybe (Int, PrimType)
parseTypeName EntryName
t
case Value
v of
V.I8Value Vector Int
shape Vector Int8
vs ->
PrimType -> Vector Int -> [Integer] -> Maybe Value
coerceInts PrimType
pt Vector Int
shape ([Integer] -> Maybe Value) -> [Integer] -> Maybe Value
forall a b. (a -> b) -> a -> b
$ (Int8 -> Integer) -> [Int8] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map Int8 -> Integer
forall a. Integral a => a -> Integer
toInteger ([Int8] -> [Integer]) -> [Int8] -> [Integer]
forall a b. (a -> b) -> a -> b
$ Vector Int8 -> [Int8]
forall a. Storable a => Vector a -> [a]
SVec.toList Vector Int8
vs
V.I16Value Vector Int
shape Vector Int16
vs ->
PrimType -> Vector Int -> [Integer] -> Maybe Value
coerceInts PrimType
pt Vector Int
shape ([Integer] -> Maybe Value) -> [Integer] -> Maybe Value
forall a b. (a -> b) -> a -> b
$ (Int16 -> Integer) -> [Int16] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map Int16 -> Integer
forall a. Integral a => a -> Integer
toInteger ([Int16] -> [Integer]) -> [Int16] -> [Integer]
forall a b. (a -> b) -> a -> b
$ Vector Int16 -> [Int16]
forall a. Storable a => Vector a -> [a]
SVec.toList Vector Int16
vs
V.I32Value Vector Int
shape Vector Int32
vs ->
PrimType -> Vector Int -> [Integer] -> Maybe Value
coerceInts PrimType
pt Vector Int
shape ([Integer] -> Maybe Value) -> [Integer] -> Maybe Value
forall a b. (a -> b) -> a -> b
$ (Int32 -> Integer) -> [Int32] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map Int32 -> Integer
forall a. Integral a => a -> Integer
toInteger ([Int32] -> [Integer]) -> [Int32] -> [Integer]
forall a b. (a -> b) -> a -> b
$ Vector Int32 -> [Int32]
forall a. Storable a => Vector a -> [a]
SVec.toList Vector Int32
vs
V.I64Value Vector Int
shape Vector Int64
vs ->
PrimType -> Vector Int -> [Integer] -> Maybe Value
coerceInts PrimType
pt Vector Int
shape ([Integer] -> Maybe Value) -> [Integer] -> Maybe Value
forall a b. (a -> b) -> a -> b
$ (Int64 -> Integer) -> [Int64] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map Int64 -> Integer
forall a. Integral a => a -> Integer
toInteger ([Int64] -> [Integer]) -> [Int64] -> [Integer]
forall a b. (a -> b) -> a -> b
$ Vector Int64 -> [Int64]
forall a. Storable a => Vector a -> [a]
SVec.toList Vector Int64
vs
Value
_ ->
Maybe Value
forall a. Maybe a
Nothing
where
coerceInts :: PrimType -> Vector Int -> [Integer] -> Maybe Value
coerceInts PrimType
V.I8 Vector Int
shape =
Value -> Maybe Value
forall a. a -> Maybe a
Just (Value -> Maybe Value)
-> ([Integer] -> Value) -> [Integer] -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Vector Int8 -> Value
V.I8Value Vector Int
shape (Vector Int8 -> Value)
-> ([Integer] -> Vector Int8) -> [Integer] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int8] -> Vector Int8
forall a. Storable a => [a] -> Vector a
SVec.fromList ([Int8] -> Vector Int8)
-> ([Integer] -> [Int8]) -> [Integer] -> Vector Int8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Int8) -> [Integer] -> [Int8]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Int8
forall a. Num a => Integer -> a
fromInteger
coerceInts PrimType
V.I16 Vector Int
shape =
Value -> Maybe Value
forall a. a -> Maybe a
Just (Value -> Maybe Value)
-> ([Integer] -> Value) -> [Integer] -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Vector Int16 -> Value
V.I16Value Vector Int
shape (Vector Int16 -> Value)
-> ([Integer] -> Vector Int16) -> [Integer] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int16] -> Vector Int16
forall a. Storable a => [a] -> Vector a
SVec.fromList ([Int16] -> Vector Int16)
-> ([Integer] -> [Int16]) -> [Integer] -> Vector Int16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Int16) -> [Integer] -> [Int16]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Int16
forall a. Num a => Integer -> a
fromInteger
coerceInts PrimType
V.I32 Vector Int
shape =
Value -> Maybe Value
forall a. a -> Maybe a
Just (Value -> Maybe Value)
-> ([Integer] -> Value) -> [Integer] -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Vector Int32 -> Value
V.I32Value Vector Int
shape (Vector Int32 -> Value)
-> ([Integer] -> Vector Int32) -> [Integer] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int32] -> Vector Int32
forall a. Storable a => [a] -> Vector a
SVec.fromList ([Int32] -> Vector Int32)
-> ([Integer] -> [Int32]) -> [Integer] -> Vector Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Int32) -> [Integer] -> [Int32]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Int32
forall a. Num a => Integer -> a
fromInteger
coerceInts PrimType
V.I64 Vector Int
shape =
Value -> Maybe Value
forall a. a -> Maybe a
Just (Value -> Maybe Value)
-> ([Integer] -> Value) -> [Integer] -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Vector Int64 -> Value
V.I64Value Vector Int
shape (Vector Int64 -> Value)
-> ([Integer] -> Vector Int64) -> [Integer] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int64] -> Vector Int64
forall a. Storable a => [a] -> Vector a
SVec.fromList ([Int64] -> Vector Int64)
-> ([Integer] -> [Int64]) -> [Integer] -> Vector Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Int64) -> [Integer] -> [Int64]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Int64
forall a. Num a => Integer -> a
fromInteger
coerceInts PrimType
V.F32 Vector Int
shape =
Value -> Maybe Value
forall a. a -> Maybe a
Just (Value -> Maybe Value)
-> ([Integer] -> Value) -> [Integer] -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Vector Float -> Value
V.F32Value Vector Int
shape (Vector Float -> Value)
-> ([Integer] -> Vector Float) -> [Integer] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Float] -> Vector Float
forall a. Storable a => [a] -> Vector a
SVec.fromList ([Float] -> Vector Float)
-> ([Integer] -> [Float]) -> [Integer] -> Vector Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Float) -> [Integer] -> [Float]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Float
forall a. Num a => Integer -> a
fromInteger
coerceInts PrimType
V.F64 Vector Int
shape =
Value -> Maybe Value
forall a. a -> Maybe a
Just (Value -> Maybe Value)
-> ([Integer] -> Value) -> [Integer] -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Vector Double -> Value
V.F64Value Vector Int
shape (Vector Double -> Value)
-> ([Integer] -> Vector Double) -> [Integer] -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Double] -> Vector Double
forall a. Storable a => [a] -> Vector a
SVec.fromList ([Double] -> Vector Double)
-> ([Integer] -> [Double]) -> [Integer] -> Vector Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Double) -> [Integer] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Double
forall a. Num a => Integer -> a
fromInteger
coerceInts PrimType
_ Vector Int
_ =
Maybe Value -> [Integer] -> Maybe Value
forall a b. a -> b -> a
const Maybe Value
forall a. Maybe a
Nothing
type EvalBuiltin m = T.Text -> [V.CompoundValue] -> m V.CompoundValue
loadData ::
(MonadIO m, MonadError T.Text m) =>
FilePath ->
m (V.Compound V.Value)
loadData :: forall (m :: * -> *).
(MonadIO m, MonadError EntryName m) =>
String -> m (Compound Value)
loadData String
datafile = do
ByteString
contents <- IO ByteString -> m ByteString
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> m ByteString) -> IO ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ String -> IO ByteString
LBS.readFile String
datafile
let maybe_vs :: Maybe [Value]
maybe_vs = ByteString -> Maybe [Value]
V.readValues ByteString
contents
case Maybe [Value]
maybe_vs of
Maybe [Value]
Nothing ->
EntryName -> m (Compound Value)
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> m (Compound Value))
-> EntryName -> m (Compound Value)
forall a b. (a -> b) -> a -> b
$ EntryName
"Failed to read data file " EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> String -> EntryName
T.pack String
datafile
Just [Value
v] ->
Compound Value -> m (Compound Value)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Compound Value -> m (Compound Value))
-> Compound Value -> m (Compound Value)
forall a b. (a -> b) -> a -> b
$ Value -> Compound Value
forall v. v -> Compound v
V.ValueAtom Value
v
Just [Value]
vs ->
Compound Value -> m (Compound Value)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Compound Value -> m (Compound Value))
-> Compound Value -> m (Compound Value)
forall a b. (a -> b) -> a -> b
$ [Compound Value] -> Compound Value
forall v. [Compound v] -> Compound v
V.ValueTuple ([Compound Value] -> Compound Value)
-> [Compound Value] -> Compound Value
forall a b. (a -> b) -> a -> b
$ (Value -> Compound Value) -> [Value] -> [Compound Value]
forall a b. (a -> b) -> [a] -> [b]
map Value -> Compound Value
forall v. v -> Compound v
V.ValueAtom [Value]
vs
pathArg ::
(MonadError T.Text f) =>
FilePath ->
T.Text ->
[V.Compound V.Value] ->
f FilePath
pathArg :: forall (f :: * -> *).
MonadError EntryName f =>
String -> EntryName -> [Compound Value] -> f String
pathArg String
dir EntryName
cmd [Compound Value]
vs =
case [Compound Value]
vs of
[V.ValueAtom Value
v]
| Just [Word8]
path <- Value -> Maybe [Word8]
forall t. GetValue t => Value -> Maybe t
V.getValue Value
v ->
String -> f String
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> f String) -> String -> f String
forall a b. (a -> b) -> a -> b
$ String
dir String -> ShowS
</> (Word8 -> Char) -> [Word8] -> String
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
chr (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ([Word8]
path :: [Word8])
[Compound Value]
_ ->
EntryName -> f String
forall a. EntryName -> f a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> f String) -> EntryName -> f String
forall a b. (a -> b) -> a -> b
$
EntryName
"$"
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
cmd
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
" does not accept arguments of types: "
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName -> [EntryName] -> EntryName
T.intercalate EntryName
", " ((Compound Value -> EntryName) -> [Compound Value] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map (Compound ValueType -> EntryName
forall a. Pretty a => a -> EntryName
prettyText (Compound ValueType -> EntryName)
-> (Compound Value -> Compound ValueType)
-> Compound Value
-> EntryName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> ValueType) -> Compound Value -> Compound ValueType
forall a b. (a -> b) -> Compound a -> Compound b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Value -> ValueType
V.valueType) [Compound Value]
vs)
scriptBuiltin :: (MonadIO m, MonadError T.Text m) => FilePath -> EvalBuiltin m
scriptBuiltin :: forall (m :: * -> *).
(MonadIO m, MonadError EntryName m) =>
String -> EvalBuiltin m
scriptBuiltin String
dir EntryName
"loaddata" [Compound Value]
vs = do
String -> m (Compound Value)
forall (m :: * -> *).
(MonadIO m, MonadError EntryName m) =>
String -> m (Compound Value)
loadData (String -> m (Compound Value)) -> m String -> m (Compound Value)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> EntryName -> [Compound Value] -> m String
forall (f :: * -> *).
MonadError EntryName f =>
String -> EntryName -> [Compound Value] -> f String
pathArg String
dir EntryName
"loaddata" [Compound Value]
vs
scriptBuiltin String
dir EntryName
"loadbytes" [Compound Value]
vs = do
(ByteString -> Compound Value)
-> m ByteString -> m (Compound Value)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Value -> Compound Value
forall v. v -> Compound v
V.ValueAtom (Value -> Compound Value)
-> (ByteString -> Value) -> ByteString -> Compound Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Value
forall t. PutValue1 t => t -> Value
V.putValue1) (m ByteString -> m (Compound Value))
-> (String -> m ByteString) -> String -> m (Compound Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO ByteString -> m ByteString
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> m ByteString)
-> (String -> IO ByteString) -> String -> m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ByteString
BS.readFile
(String -> m (Compound Value)) -> m String -> m (Compound Value)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> EntryName -> [Compound Value] -> m String
forall (f :: * -> *).
MonadError EntryName f =>
String -> EntryName -> [Compound Value] -> f String
pathArg String
dir EntryName
"loadbytes" [Compound Value]
vs
scriptBuiltin String
_ EntryName
f [Compound Value]
_ =
EntryName -> m (Compound Value)
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> m (Compound Value))
-> EntryName -> m (Compound Value)
forall a b. (a -> b) -> a -> b
$ EntryName
"Unknown builtin function $" EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName -> EntryName
forall a. Pretty a => a -> EntryName
prettyText EntryName
f
type VTable = M.Map VarName ExpValue
evalExp ::
forall m.
(MonadError T.Text m, MonadIO m) =>
EvalBuiltin m ->
ScriptServer ->
Exp ->
m ExpValue
evalExp :: forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
EvalBuiltin m -> ScriptServer -> Exp -> m ExpValue
evalExp EvalBuiltin m
builtin ScriptServer
sserver Exp
top_level_e = do
IORef [EntryName]
vars <- IO (IORef [EntryName]) -> m (IORef [EntryName])
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef [EntryName]) -> m (IORef [EntryName]))
-> IO (IORef [EntryName]) -> m (IORef [EntryName])
forall a b. (a -> b) -> a -> b
$ [EntryName] -> IO (IORef [EntryName])
forall a. a -> IO (IORef a)
newIORef []
let ( ScriptServer
{ scriptServer :: ScriptServer -> Server
scriptServer = Server
server,
scriptCounter :: ScriptServer -> IORef Int
scriptCounter = IORef Int
counter,
scriptTypes :: ScriptServer -> TypeMap
scriptTypes = TypeMap
types
}
) = ScriptServer
sserver
newVar :: EntryName -> m EntryName
newVar EntryName
base = IO EntryName -> m EntryName
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO EntryName -> m EntryName) -> IO EntryName -> m EntryName
forall a b. (a -> b) -> a -> b
$ do
Int
x <- IORef Int -> IO Int
forall a. IORef a -> IO a
readIORef IORef Int
counter
IORef Int -> (Int -> Int) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef Int
counter (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
let v :: EntryName
v = EntryName
base EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> Int -> EntryName
forall a. Pretty a => a -> EntryName
prettyText Int
x
IORef [EntryName] -> ([EntryName] -> [EntryName]) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef [EntryName]
vars (EntryName
v :)
EntryName -> IO EntryName
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EntryName
v
mkRecord :: EntryName -> [EntryName] -> m EntryName
mkRecord EntryName
t [EntryName]
vs = do
EntryName
v <- EntryName -> m EntryName
forall {m :: * -> *}. MonadIO m => EntryName -> m EntryName
newVar EntryName
"record"
IO (Maybe CmdFailure) -> m ()
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
IO (Maybe CmdFailure) -> m ()
cmdMaybe (IO (Maybe CmdFailure) -> m ()) -> IO (Maybe CmdFailure) -> m ()
forall a b. (a -> b) -> a -> b
$ Server
-> EntryName -> EntryName -> [EntryName] -> IO (Maybe CmdFailure)
cmdNew Server
server EntryName
v EntryName
t [EntryName]
vs
EntryName -> m EntryName
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EntryName
v
getField :: EntryName -> (Name, b) -> m EntryName
getField EntryName
from (Name
f, b
_) = do
EntryName
to <- EntryName -> m EntryName
forall {m :: * -> *}. MonadIO m => EntryName -> m EntryName
newVar EntryName
"field"
IO (Maybe CmdFailure) -> m ()
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
IO (Maybe CmdFailure) -> m ()
cmdMaybe (IO (Maybe CmdFailure) -> m ()) -> IO (Maybe CmdFailure) -> m ()
forall a b. (a -> b) -> a -> b
$ Server
-> EntryName -> EntryName -> EntryName -> IO (Maybe CmdFailure)
cmdProject Server
server EntryName
to EntryName
from (EntryName -> IO (Maybe CmdFailure))
-> EntryName -> IO (Maybe CmdFailure)
forall a b. (a -> b) -> a -> b
$ Name -> EntryName
nameToText Name
f
EntryName -> m EntryName
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EntryName
to
toVal :: ValOrVar -> m V.Value
toVal :: ValOrVar -> m Value
toVal (VVal Value
v) = Value -> m Value
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
v
toVal (VVar EntryName
v) = Server -> EntryName -> m Value
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
Server -> EntryName -> m Value
readVar Server
server EntryName
v
toVar :: ValOrVar -> m VarName
toVar :: ValOrVar -> m EntryName
toVar (VVar EntryName
v) = EntryName -> m EntryName
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EntryName
v
toVar (VVal Value
val) = do
EntryName
v <- EntryName -> m EntryName
forall {m :: * -> *}. MonadIO m => EntryName -> m EntryName
newVar EntryName
"const"
Server -> EntryName -> Value -> m ()
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
Server -> EntryName -> Value -> m ()
writeVar Server
server EntryName
v Value
val
EntryName -> m EntryName
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EntryName
v
scriptValueToValOrVar :: ScriptValue a -> m a
scriptValueToValOrVar (SFun EntryName
f [EntryName]
_ [EntryName]
_ [ScriptValue a]
_) =
EntryName -> m a
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> m a) -> EntryName -> m a
forall a b. (a -> b) -> a -> b
$ EntryName
"Function " EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
f EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
" not fully applied."
scriptValueToValOrVar (SValue EntryName
_ a
v) =
a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
v
scriptValueToVal :: ScriptValue ValOrVar -> m V.Value
scriptValueToVal :: ScriptValue ValOrVar -> m Value
scriptValueToVal = ValOrVar -> m Value
toVal (ValOrVar -> m Value)
-> (ScriptValue ValOrVar -> m ValOrVar)
-> ScriptValue ValOrVar
-> m Value
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ScriptValue ValOrVar -> m ValOrVar
forall {m :: * -> *} {a}.
MonadError EntryName m =>
ScriptValue a -> m a
scriptValueToValOrVar
scriptValueToVar :: ScriptValue ValOrVar -> m VarName
scriptValueToVar :: ScriptValue ValOrVar -> m EntryName
scriptValueToVar = ValOrVar -> m EntryName
toVar (ValOrVar -> m EntryName)
-> (ScriptValue ValOrVar -> m ValOrVar)
-> ScriptValue ValOrVar
-> m EntryName
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ScriptValue ValOrVar -> m ValOrVar
forall {m :: * -> *} {a}.
MonadError EntryName m =>
ScriptValue a -> m a
scriptValueToValOrVar
interValToVal :: ExpValue -> m V.CompoundValue
interValToVal :: ExpValue -> m (Compound Value)
interValToVal = (ScriptValue ValOrVar -> m Value) -> ExpValue -> m (Compound Value)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Compound a -> f (Compound b)
traverse ScriptValue ValOrVar -> m Value
scriptValueToVal
interValToVar :: m VarName -> TypeName -> ExpValue -> m VarName
interValToVar :: m EntryName -> EntryName -> ExpValue -> m EntryName
interValToVar m EntryName
_ EntryName
t (V.ValueAtom ScriptValue ValOrVar
v)
| EntryName -> ScriptValueType
STValue EntryName
t ScriptValueType -> ScriptValueType -> Bool
forall a. Eq a => a -> a -> Bool
== ScriptValue ValOrVar -> ScriptValueType
forall v. ScriptValue v -> ScriptValueType
scriptValueType ScriptValue ValOrVar
v = ScriptValue ValOrVar -> m EntryName
scriptValueToVar ScriptValue ValOrVar
v
interValToVar m EntryName
bad EntryName
t (V.ValueTuple [ExpValue]
vs)
| Just [EntryName]
ts <- EntryName -> TypeMap -> Maybe [EntryName]
isTuple EntryName
t TypeMap
types,
[ExpValue] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ExpValue]
vs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EntryName]
ts =
EntryName -> [EntryName] -> m EntryName
forall {m :: * -> *}.
(MonadIO m, MonadError EntryName m) =>
EntryName -> [EntryName] -> m EntryName
mkRecord EntryName
t ([EntryName] -> m EntryName) -> m [EntryName] -> m EntryName
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (EntryName -> ExpValue -> m EntryName)
-> [EntryName] -> [ExpValue] -> m [EntryName]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (m EntryName -> EntryName -> ExpValue -> m EntryName
interValToVar m EntryName
bad) [EntryName]
ts [ExpValue]
vs
interValToVar m EntryName
bad EntryName
t (V.ValueRecord Map EntryName ExpValue
vs)
| Just [(Name, EntryName)]
fs <- EntryName -> TypeMap -> Maybe [(Name, EntryName)]
isRecord EntryName
t TypeMap
types,
Just [ExpValue]
vs' <- ((Name, EntryName) -> Maybe ExpValue)
-> [(Name, EntryName)] -> Maybe [ExpValue]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((EntryName -> Map EntryName ExpValue -> Maybe ExpValue
forall k a. Ord k => k -> Map k a -> Maybe a
`M.lookup` Map EntryName ExpValue
vs) (EntryName -> Maybe ExpValue)
-> ((Name, EntryName) -> EntryName)
-> (Name, EntryName)
-> Maybe ExpValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> EntryName
nameToText (Name -> EntryName)
-> ((Name, EntryName) -> Name) -> (Name, EntryName) -> EntryName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Name, EntryName) -> Name
forall a b. (a, b) -> a
fst) [(Name, EntryName)]
fs =
EntryName -> [EntryName] -> m EntryName
forall {m :: * -> *}.
(MonadIO m, MonadError EntryName m) =>
EntryName -> [EntryName] -> m EntryName
mkRecord EntryName
t ([EntryName] -> m EntryName) -> m [EntryName] -> m EntryName
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (EntryName -> ExpValue -> m EntryName)
-> [EntryName] -> [ExpValue] -> m [EntryName]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (m EntryName -> EntryName -> ExpValue -> m EntryName
interValToVar m EntryName
bad) (((Name, EntryName) -> EntryName)
-> [(Name, EntryName)] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map (Name, EntryName) -> EntryName
forall a b. (a, b) -> b
snd [(Name, EntryName)]
fs) [ExpValue]
vs'
interValToVar m EntryName
_ EntryName
t (V.ValueAtom (SValue EntryName
vt (VVar EntryName
v)))
| Just [(Name, EntryName)]
t_fs <- EntryName -> TypeMap -> Maybe [(Name, EntryName)]
isRecord EntryName
t TypeMap
types,
Just [(Name, EntryName)]
vt_fs <- EntryName -> TypeMap -> Maybe [(Name, EntryName)]
isRecord EntryName
vt TypeMap
types,
[(Name, EntryName)]
vt_fs [(Name, EntryName)] -> [(Name, EntryName)] -> Bool
forall a. Eq a => a -> a -> Bool
== [(Name, EntryName)]
t_fs =
EntryName -> [EntryName] -> m EntryName
forall {m :: * -> *}.
(MonadIO m, MonadError EntryName m) =>
EntryName -> [EntryName] -> m EntryName
mkRecord EntryName
t ([EntryName] -> m EntryName) -> m [EntryName] -> m EntryName
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ((Name, EntryName) -> m EntryName)
-> [(Name, EntryName)] -> m [EntryName]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (EntryName -> (Name, EntryName) -> m EntryName
forall {m :: * -> *} {b}.
(MonadIO m, MonadError EntryName m) =>
EntryName -> (Name, b) -> m EntryName
getField EntryName
v) [(Name, EntryName)]
vt_fs
interValToVar m EntryName
_ EntryName
t (V.ValueAtom (SValue EntryName
_ (VVal Value
v)))
| Just Value
v' <- EntryName -> Value -> Maybe Value
coerceValue EntryName
t Value
v =
ScriptValue ValOrVar -> m EntryName
scriptValueToVar (ScriptValue ValOrVar -> m EntryName)
-> ScriptValue ValOrVar -> m EntryName
forall a b. (a -> b) -> a -> b
$ EntryName -> ValOrVar -> ScriptValue ValOrVar
forall v. EntryName -> v -> ScriptValue v
SValue EntryName
t (ValOrVar -> ScriptValue ValOrVar)
-> ValOrVar -> ScriptValue ValOrVar
forall a b. (a -> b) -> a -> b
$ Value -> ValOrVar
VVal Value
v'
interValToVar m EntryName
bad EntryName
_ ExpValue
_ = m EntryName
bad
valToInterVal :: V.CompoundValue -> ExpValue
valToInterVal :: Compound Value -> ExpValue
valToInterVal = (Value -> ScriptValue ValOrVar) -> Compound Value -> ExpValue
forall a b. (a -> b) -> Compound a -> Compound b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Value -> ScriptValue ValOrVar) -> Compound Value -> ExpValue)
-> (Value -> ScriptValue ValOrVar) -> Compound Value -> ExpValue
forall a b. (a -> b) -> a -> b
$ \Value
v ->
EntryName -> ValOrVar -> ScriptValue ValOrVar
forall v. EntryName -> v -> ScriptValue v
SValue (ValueType -> EntryName
V.valueTypeTextNoDims (Value -> ValueType
V.valueType Value
v)) (ValOrVar -> ScriptValue ValOrVar)
-> ValOrVar -> ScriptValue ValOrVar
forall a b. (a -> b) -> a -> b
$ Value -> ValOrVar
VVal Value
v
letMatch :: [VarName] -> ExpValue -> m VTable
letMatch :: [EntryName] -> ExpValue -> m (Map EntryName ExpValue)
letMatch [EntryName]
vs ExpValue
val
| [ExpValue]
vals <- ExpValue -> [ExpValue]
forall v. Compound v -> [Compound v]
V.unCompound ExpValue
val,
[EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EntryName]
vs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [ExpValue] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ExpValue]
vals =
Map EntryName ExpValue -> m (Map EntryName ExpValue)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Map EntryName ExpValue -> m (Map EntryName ExpValue))
-> Map EntryName ExpValue -> m (Map EntryName ExpValue)
forall a b. (a -> b) -> a -> b
$ [(EntryName, ExpValue)] -> Map EntryName ExpValue
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([EntryName] -> [ExpValue] -> [(EntryName, ExpValue)]
forall a b. [a] -> [b] -> [(a, b)]
zip [EntryName]
vs [ExpValue]
vals)
| Bool
otherwise =
EntryName -> m (Map EntryName ExpValue)
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> m (Map EntryName ExpValue))
-> EntryName -> m (Map EntryName ExpValue)
forall a b. (a -> b) -> a -> b
$
EntryName
"Pat: "
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> [EntryName] -> EntryName
forall a. Pretty a => a -> EntryName
prettyTextOneLine [EntryName]
vs
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
"\nDoes not match value of type: "
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> Compound ScriptValueType -> EntryName
forall a. Pretty a => a -> EntryName
prettyTextOneLine ((ScriptValue ValOrVar -> ScriptValueType)
-> ExpValue -> Compound ScriptValueType
forall a b. (a -> b) -> Compound a -> Compound b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ScriptValue ValOrVar -> ScriptValueType
forall v. ScriptValue v -> ScriptValueType
scriptValueType ExpValue
val)
evalExp' :: VTable -> Exp -> m ExpValue
evalExp' :: Map EntryName ExpValue -> Exp -> m ExpValue
evalExp' Map EntryName ExpValue
_ (ServerVar EntryName
t EntryName
v) =
ExpValue -> m ExpValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExpValue -> m ExpValue) -> ExpValue -> m ExpValue
forall a b. (a -> b) -> a -> b
$ ScriptValue ValOrVar -> ExpValue
forall v. v -> Compound v
V.ValueAtom (ScriptValue ValOrVar -> ExpValue)
-> ScriptValue ValOrVar -> ExpValue
forall a b. (a -> b) -> a -> b
$ EntryName -> ValOrVar -> ScriptValue ValOrVar
forall v. EntryName -> v -> ScriptValue v
SValue EntryName
t (ValOrVar -> ScriptValue ValOrVar)
-> ValOrVar -> ScriptValue ValOrVar
forall a b. (a -> b) -> a -> b
$ EntryName -> ValOrVar
VVar EntryName
v
evalExp' Map EntryName ExpValue
vtable (Call (FuncBuiltin EntryName
name) [Exp]
es) = do
Compound Value
v <- EvalBuiltin m
builtin EntryName
name ([Compound Value] -> m (Compound Value))
-> m [Compound Value] -> m (Compound Value)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Exp -> m (Compound Value)) -> [Exp] -> m [Compound Value]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (ExpValue -> m (Compound Value)
interValToVal (ExpValue -> m (Compound Value))
-> (Exp -> m ExpValue) -> Exp -> m (Compound Value)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Map EntryName ExpValue -> Exp -> m ExpValue
evalExp' Map EntryName ExpValue
vtable) [Exp]
es
ExpValue -> m ExpValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExpValue -> m ExpValue) -> ExpValue -> m ExpValue
forall a b. (a -> b) -> a -> b
$ Compound Value -> ExpValue
valToInterVal Compound Value
v
evalExp' Map EntryName ExpValue
vtable (Call (FuncFut EntryName
name) [Exp]
es)
| Just ExpValue
e <- EntryName -> Map EntryName ExpValue -> Maybe ExpValue
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup EntryName
name Map EntryName ExpValue
vtable = do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([Exp] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Exp]
es) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
EntryName -> m ()
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> m ()) -> EntryName -> m ()
forall a b. (a -> b) -> a -> b
$
EntryName
"Locally bound name cannot be invoked as a function: " EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName -> EntryName
forall a. Pretty a => a -> EntryName
prettyText EntryName
name
ExpValue -> m ExpValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ExpValue
e
evalExp' Map EntryName ExpValue
vtable (Call (FuncFut EntryName
name) [Exp]
es) = do
[EntryName]
in_types <- ([InputType] -> [EntryName]) -> m [InputType] -> m [EntryName]
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((InputType -> EntryName) -> [InputType] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map InputType -> EntryName
inputType) (m [InputType] -> m [EntryName]) -> m [InputType] -> m [EntryName]
forall a b. (a -> b) -> a -> b
$ IO (Either CmdFailure [InputType]) -> m [InputType]
forall (m :: * -> *) a.
(MonadError EntryName m, MonadIO m) =>
IO (Either CmdFailure a) -> m a
cmdEither (IO (Either CmdFailure [InputType]) -> m [InputType])
-> IO (Either CmdFailure [InputType]) -> m [InputType]
forall a b. (a -> b) -> a -> b
$ Server -> EntryName -> IO (Either CmdFailure [InputType])
cmdInputs Server
server EntryName
name
[EntryName]
out_types <- ([OutputType] -> [EntryName]) -> m [OutputType] -> m [EntryName]
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((OutputType -> EntryName) -> [OutputType] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map OutputType -> EntryName
outputType) (m [OutputType] -> m [EntryName])
-> m [OutputType] -> m [EntryName]
forall a b. (a -> b) -> a -> b
$ IO (Either CmdFailure [OutputType]) -> m [OutputType]
forall (m :: * -> *) a.
(MonadError EntryName m, MonadIO m) =>
IO (Either CmdFailure a) -> m a
cmdEither (IO (Either CmdFailure [OutputType]) -> m [OutputType])
-> IO (Either CmdFailure [OutputType]) -> m [OutputType]
forall a b. (a -> b) -> a -> b
$ Server -> EntryName -> IO (Either CmdFailure [OutputType])
cmdOutputs Server
server EntryName
name
[ExpValue]
es' <- (Exp -> m ExpValue) -> [Exp] -> m [ExpValue]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Map EntryName ExpValue -> Exp -> m ExpValue
evalExp' Map EntryName ExpValue
vtable) [Exp]
es
let es_types :: [Compound ScriptValueType]
es_types = (ExpValue -> Compound ScriptValueType)
-> [ExpValue] -> [Compound ScriptValueType]
forall a b. (a -> b) -> [a] -> [b]
map ((ScriptValue ValOrVar -> ScriptValueType)
-> ExpValue -> Compound ScriptValueType
forall a b. (a -> b) -> Compound a -> Compound b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ScriptValue ValOrVar -> ScriptValueType
forall v. ScriptValue v -> ScriptValueType
scriptValueType) [ExpValue]
es'
let cannotApply :: m a
cannotApply =
EntryName -> m a
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> m a) -> EntryName -> m a
forall a b. (a -> b) -> a -> b
$
EntryName
"Function \""
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
name
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
"\" expects "
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> Int -> EntryName
forall a. Pretty a => a -> EntryName
prettyText ([EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EntryName]
in_types)
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
" argument(s) of types:\n"
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName -> [EntryName] -> EntryName
T.intercalate EntryName
"\n" ((EntryName -> EntryName) -> [EntryName] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map EntryName -> EntryName
forall a. Pretty a => a -> EntryName
prettyTextOneLine [EntryName]
in_types)
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
"\nBut applied to "
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> Int -> EntryName
forall a. Pretty a => a -> EntryName
prettyText ([Compound ScriptValueType] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Compound ScriptValueType]
es_types)
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
" argument(s) of types:\n"
EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName -> [EntryName] -> EntryName
T.intercalate EntryName
"\n" ((Compound ScriptValueType -> EntryName)
-> [Compound ScriptValueType] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map Compound ScriptValueType -> EntryName
forall a. Pretty a => a -> EntryName
prettyTextOneLine [Compound ScriptValueType]
es_types)
tryApply :: [ExpValue] -> m ExpValue
tryApply [ExpValue]
args = do
[EntryName]
arg_types <- (EntryName -> ExpValue -> m EntryName)
-> [EntryName] -> [ExpValue] -> m [EntryName]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (m EntryName -> EntryName -> ExpValue -> m EntryName
interValToVar m EntryName
forall {a}. m a
cannotApply) [EntryName]
in_types [ExpValue]
args
if [EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EntryName]
in_types Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EntryName]
arg_types
then do
[EntryName]
outs <- Int -> m EntryName -> m [EntryName]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM ([EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EntryName]
out_types) (m EntryName -> m [EntryName]) -> m EntryName -> m [EntryName]
forall a b. (a -> b) -> a -> b
$ EntryName -> m EntryName
forall {m :: * -> *}. MonadIO m => EntryName -> m EntryName
newVar EntryName
"out"
m [EntryName] -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m [EntryName] -> m ()) -> m [EntryName] -> m ()
forall a b. (a -> b) -> a -> b
$ IO (Either CmdFailure [EntryName]) -> m [EntryName]
forall (m :: * -> *) a.
(MonadError EntryName m, MonadIO m) =>
IO (Either CmdFailure a) -> m a
cmdEither (IO (Either CmdFailure [EntryName]) -> m [EntryName])
-> IO (Either CmdFailure [EntryName]) -> m [EntryName]
forall a b. (a -> b) -> a -> b
$ Server
-> EntryName
-> [EntryName]
-> [EntryName]
-> IO (Either CmdFailure [EntryName])
cmdCall Server
server EntryName
name [EntryName]
outs [EntryName]
arg_types
ExpValue -> m ExpValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExpValue -> m ExpValue) -> ExpValue -> m ExpValue
forall a b. (a -> b) -> a -> b
$ [ExpValue] -> ExpValue
forall v. [Compound v] -> Compound v
V.mkCompound ([ExpValue] -> ExpValue) -> [ExpValue] -> ExpValue
forall a b. (a -> b) -> a -> b
$ (ScriptValue ValOrVar -> ExpValue)
-> [ScriptValue ValOrVar] -> [ExpValue]
forall a b. (a -> b) -> [a] -> [b]
map ScriptValue ValOrVar -> ExpValue
forall v. v -> Compound v
V.ValueAtom ([ScriptValue ValOrVar] -> [ExpValue])
-> [ScriptValue ValOrVar] -> [ExpValue]
forall a b. (a -> b) -> a -> b
$ (EntryName -> ValOrVar -> ScriptValue ValOrVar)
-> [EntryName] -> [ValOrVar] -> [ScriptValue ValOrVar]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith EntryName -> ValOrVar -> ScriptValue ValOrVar
forall v. EntryName -> v -> ScriptValue v
SValue [EntryName]
out_types ([ValOrVar] -> [ScriptValue ValOrVar])
-> [ValOrVar] -> [ScriptValue ValOrVar]
forall a b. (a -> b) -> a -> b
$ (EntryName -> ValOrVar) -> [EntryName] -> [ValOrVar]
forall a b. (a -> b) -> [a] -> [b]
map EntryName -> ValOrVar
VVar [EntryName]
outs
else
ExpValue -> m ExpValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExpValue -> m ExpValue)
-> ([ScriptValue ValOrVar] -> ExpValue)
-> [ScriptValue ValOrVar]
-> m ExpValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptValue ValOrVar -> ExpValue
forall v. v -> Compound v
V.ValueAtom (ScriptValue ValOrVar -> ExpValue)
-> ([ScriptValue ValOrVar] -> ScriptValue ValOrVar)
-> [ScriptValue ValOrVar]
-> ExpValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EntryName
-> [EntryName]
-> [EntryName]
-> [ScriptValue ValOrVar]
-> ScriptValue ValOrVar
forall v.
EntryName
-> [EntryName] -> [EntryName] -> [ScriptValue v] -> ScriptValue v
SFun EntryName
name [EntryName]
in_types [EntryName]
out_types ([ScriptValue ValOrVar] -> m ExpValue)
-> [ScriptValue ValOrVar] -> m ExpValue
forall a b. (a -> b) -> a -> b
$
(EntryName -> ValOrVar -> ScriptValue ValOrVar)
-> [EntryName] -> [ValOrVar] -> [ScriptValue ValOrVar]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith EntryName -> ValOrVar -> ScriptValue ValOrVar
forall v. EntryName -> v -> ScriptValue v
SValue [EntryName]
in_types ([ValOrVar] -> [ScriptValue ValOrVar])
-> [ValOrVar] -> [ScriptValue ValOrVar]
forall a b. (a -> b) -> a -> b
$
(EntryName -> ValOrVar) -> [EntryName] -> [ValOrVar]
forall a b. (a -> b) -> [a] -> [b]
map EntryName -> ValOrVar
VVar [EntryName]
arg_types
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Compound ScriptValueType] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Compound ScriptValueType]
es_types Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> [EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EntryName]
in_types) m ()
forall {a}. m a
cannotApply
case [ExpValue]
es' of
[V.ValueTuple [ExpValue]
es''] | [ExpValue] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ExpValue]
es'' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EntryName]
in_types -> [ExpValue] -> m ExpValue
tryApply [ExpValue]
es''
[ExpValue]
_ -> [ExpValue] -> m ExpValue
tryApply [ExpValue]
es'
evalExp' Map EntryName ExpValue
_ (StringLit EntryName
s) =
case EntryName -> Maybe Value
forall t. PutValue t => t -> Maybe Value
V.putValue EntryName
s of
Just Value
s' ->
ExpValue -> m ExpValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExpValue -> m ExpValue) -> ExpValue -> m ExpValue
forall a b. (a -> b) -> a -> b
$ ScriptValue ValOrVar -> ExpValue
forall v. v -> Compound v
V.ValueAtom (ScriptValue ValOrVar -> ExpValue)
-> ScriptValue ValOrVar -> ExpValue
forall a b. (a -> b) -> a -> b
$ EntryName -> ValOrVar -> ScriptValue ValOrVar
forall v. EntryName -> v -> ScriptValue v
SValue (ValueType -> EntryName
V.valueTypeTextNoDims (Value -> ValueType
V.valueType Value
s')) (ValOrVar -> ScriptValue ValOrVar)
-> ValOrVar -> ScriptValue ValOrVar
forall a b. (a -> b) -> a -> b
$ Value -> ValOrVar
VVal Value
s'
Maybe Value
Nothing -> String -> m ExpValue
forall a. HasCallStack => String -> a
error (String -> m ExpValue) -> String -> m ExpValue
forall a b. (a -> b) -> a -> b
$ String
"Unable to write value " String -> ShowS
forall a. [a] -> [a] -> [a]
++ EntryName -> String
forall a. Pretty a => a -> String
prettyString EntryName
s
evalExp' Map EntryName ExpValue
_ (Const Value
val) =
ExpValue -> m ExpValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExpValue -> m ExpValue) -> ExpValue -> m ExpValue
forall a b. (a -> b) -> a -> b
$ ScriptValue ValOrVar -> ExpValue
forall v. v -> Compound v
V.ValueAtom (ScriptValue ValOrVar -> ExpValue)
-> ScriptValue ValOrVar -> ExpValue
forall a b. (a -> b) -> a -> b
$ EntryName -> ValOrVar -> ScriptValue ValOrVar
forall v. EntryName -> v -> ScriptValue v
SValue (ValueType -> EntryName
V.valueTypeTextNoDims (Value -> ValueType
V.valueType Value
val)) (ValOrVar -> ScriptValue ValOrVar)
-> ValOrVar -> ScriptValue ValOrVar
forall a b. (a -> b) -> a -> b
$ Value -> ValOrVar
VVal Value
val
evalExp' Map EntryName ExpValue
vtable (Tuple [Exp]
es) =
[ExpValue] -> ExpValue
forall v. [Compound v] -> Compound v
V.ValueTuple ([ExpValue] -> ExpValue) -> m [ExpValue] -> m ExpValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Exp -> m ExpValue) -> [Exp] -> m [ExpValue]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Map EntryName ExpValue -> Exp -> m ExpValue
evalExp' Map EntryName ExpValue
vtable) [Exp]
es
evalExp' Map EntryName ExpValue
vtable e :: Exp
e@(Record [(EntryName, Exp)]
m) = do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([EntryName] -> [EntryName]
forall a. Ord a => [a] -> [a]
nubOrd (((EntryName, Exp) -> EntryName)
-> [(EntryName, Exp)] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map (EntryName, Exp) -> EntryName
forall a b. (a, b) -> a
fst [(EntryName, Exp)]
m)) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [EntryName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (((EntryName, Exp) -> EntryName)
-> [(EntryName, Exp)] -> [EntryName]
forall a b. (a -> b) -> [a] -> [b]
map (EntryName, Exp) -> EntryName
forall a b. (a, b) -> a
fst [(EntryName, Exp)]
m)) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
EntryName -> m ()
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> m ()) -> EntryName -> m ()
forall a b. (a -> b) -> a -> b
$
EntryName
"Record " EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> Exp -> EntryName
forall a. Pretty a => a -> EntryName
prettyText Exp
e EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
" has duplicate fields."
Map EntryName ExpValue -> ExpValue
forall v. Map EntryName (Compound v) -> Compound v
V.ValueRecord (Map EntryName ExpValue -> ExpValue)
-> m (Map EntryName ExpValue) -> m ExpValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Exp -> m ExpValue)
-> Map EntryName Exp -> m (Map EntryName ExpValue)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Map EntryName a -> f (Map EntryName b)
traverse (Map EntryName ExpValue -> Exp -> m ExpValue
evalExp' Map EntryName ExpValue
vtable) ([(EntryName, Exp)] -> Map EntryName Exp
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(EntryName, Exp)]
m)
evalExp' Map EntryName ExpValue
vtable (Let [EntryName]
pat Exp
e1 Exp
e2) = do
ExpValue
v <- Map EntryName ExpValue -> Exp -> m ExpValue
evalExp' Map EntryName ExpValue
vtable Exp
e1
Map EntryName ExpValue
pat_vtable <- [EntryName] -> ExpValue -> m (Map EntryName ExpValue)
letMatch [EntryName]
pat ExpValue
v
Map EntryName ExpValue -> Exp -> m ExpValue
evalExp' (Map EntryName ExpValue
pat_vtable Map EntryName ExpValue
-> Map EntryName ExpValue -> Map EntryName ExpValue
forall a. Semigroup a => a -> a -> a
<> Map EntryName ExpValue
vtable) Exp
e2
let freeNonresultVars :: ExpValue -> m ExpValue
freeNonresultVars ExpValue
v = do
let v_vars :: Set EntryName
v_vars = ExpValue -> Set EntryName
serverVarsInValue ExpValue
v
[EntryName]
to_free <- IO [EntryName] -> m [EntryName]
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [EntryName] -> m [EntryName])
-> IO [EntryName] -> m [EntryName]
forall a b. (a -> b) -> a -> b
$ (EntryName -> Bool) -> [EntryName] -> [EntryName]
forall a. (a -> Bool) -> [a] -> [a]
filter (EntryName -> Set EntryName -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.notMember` Set EntryName
v_vars) ([EntryName] -> [EntryName]) -> IO [EntryName] -> IO [EntryName]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IORef [EntryName] -> IO [EntryName]
forall a. IORef a -> IO a
readIORef IORef [EntryName]
vars
IO (Maybe CmdFailure) -> m ()
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
IO (Maybe CmdFailure) -> m ()
cmdMaybe (IO (Maybe CmdFailure) -> m ()) -> IO (Maybe CmdFailure) -> m ()
forall a b. (a -> b) -> a -> b
$ Server -> [EntryName] -> IO (Maybe CmdFailure)
cmdFree Server
server [EntryName]
to_free
ExpValue -> m ExpValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ExpValue
v
freeVarsOnError :: e -> m b
freeVarsOnError e
e = do
m (Maybe CmdFailure) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (Maybe CmdFailure) -> m ()) -> m (Maybe CmdFailure) -> m ()
forall a b. (a -> b) -> a -> b
$ IO (Maybe CmdFailure) -> m (Maybe CmdFailure)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe CmdFailure) -> m (Maybe CmdFailure))
-> IO (Maybe CmdFailure) -> m (Maybe CmdFailure)
forall a b. (a -> b) -> a -> b
$ Server -> [EntryName] -> IO (Maybe CmdFailure)
cmdFree Server
server ([EntryName] -> IO (Maybe CmdFailure))
-> IO [EntryName] -> IO (Maybe CmdFailure)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IORef [EntryName] -> IO [EntryName]
forall a. IORef a -> IO a
readIORef IORef [EntryName]
vars
e -> m b
forall a. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError e
e
(ExpValue -> m ExpValue
forall {m :: * -> *}.
(MonadIO m, MonadError EntryName m) =>
ExpValue -> m ExpValue
freeNonresultVars (ExpValue -> m ExpValue) -> m ExpValue -> m ExpValue
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Map EntryName ExpValue -> Exp -> m ExpValue
evalExp' Map EntryName ExpValue
forall a. Monoid a => a
mempty Exp
top_level_e) m ExpValue -> (EntryName -> m ExpValue) -> m ExpValue
forall a. m a -> (EntryName -> m a) -> m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
`catchError` EntryName -> m ExpValue
forall {m :: * -> *} {e} {b}.
(MonadIO m, MonadError e m) =>
e -> m b
freeVarsOnError
getExpValue ::
(MonadError T.Text m, MonadIO m) => ScriptServer -> ExpValue -> m V.CompoundValue
getExpValue :: forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
ScriptServer -> ExpValue -> m (Compound Value)
getExpValue ScriptServer
server ExpValue
e =
(ScriptValue Value -> m Value)
-> Compound (ScriptValue Value) -> m (Compound Value)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Compound a -> f (Compound b)
traverse ScriptValue Value -> m Value
forall {m :: * -> *} {a}.
MonadError EntryName m =>
ScriptValue a -> m a
toGround (Compound (ScriptValue Value) -> m (Compound Value))
-> m (Compound (ScriptValue Value)) -> m (Compound Value)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (ScriptValue ValOrVar -> m (ScriptValue Value))
-> ExpValue -> m (Compound (ScriptValue Value))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Compound a -> f (Compound b)
traverse ((ValOrVar -> m Value)
-> ScriptValue ValOrVar -> m (ScriptValue Value)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> ScriptValue a -> f (ScriptValue b)
traverse ValOrVar -> m Value
forall {m :: * -> *}.
(MonadError EntryName m, MonadIO m) =>
ValOrVar -> m Value
onLeaf) ExpValue
e
where
onLeaf :: ValOrVar -> m Value
onLeaf (VVar EntryName
v) = Server -> EntryName -> m Value
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
Server -> EntryName -> m Value
readVar (ScriptServer -> Server
scriptServer ScriptServer
server) EntryName
v
onLeaf (VVal Value
v) = Value -> m Value
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value
v
toGround :: ScriptValue a -> m a
toGround (SFun EntryName
fname [EntryName]
_ [EntryName]
_ [ScriptValue a]
_) =
EntryName -> m a
forall a. EntryName -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (EntryName -> m a) -> EntryName -> m a
forall a b. (a -> b) -> a -> b
$ EntryName
"Function " EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
fname EntryName -> EntryName -> EntryName
forall a. Semigroup a => a -> a -> a
<> EntryName
" not fully applied."
toGround (SValue EntryName
_ a
v) = a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
v
evalExpToGround ::
(MonadError T.Text m, MonadIO m) =>
EvalBuiltin m ->
ScriptServer ->
Exp ->
m (Either (V.Compound ScriptValueType) V.CompoundValue)
evalExpToGround :: forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
EvalBuiltin m
-> ScriptServer
-> Exp
-> m (Either (Compound ScriptValueType) (Compound Value))
evalExpToGround EvalBuiltin m
builtin ScriptServer
server Exp
e = do
ExpValue
v <- EvalBuiltin m -> ScriptServer -> Exp -> m ExpValue
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
EvalBuiltin m -> ScriptServer -> Exp -> m ExpValue
evalExp EvalBuiltin m
builtin ScriptServer
server Exp
e
(Compound Value
-> Either (Compound ScriptValueType) (Compound Value)
forall a b. b -> Either a b
Right (Compound Value
-> Either (Compound ScriptValueType) (Compound Value))
-> m (Compound Value)
-> m (Either (Compound ScriptValueType) (Compound Value))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ScriptServer -> ExpValue -> m (Compound Value)
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
ScriptServer -> ExpValue -> m (Compound Value)
getExpValue ScriptServer
server ExpValue
v)
m (Either (Compound ScriptValueType) (Compound Value))
-> (EntryName
-> m (Either (Compound ScriptValueType) (Compound Value)))
-> m (Either (Compound ScriptValueType) (Compound Value))
forall a. m a -> (EntryName -> m a) -> m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
`catchError` m (Either (Compound ScriptValueType) (Compound Value))
-> EntryName
-> m (Either (Compound ScriptValueType) (Compound Value))
forall a b. a -> b -> a
const (Either (Compound ScriptValueType) (Compound Value)
-> m (Either (Compound ScriptValueType) (Compound Value))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either (Compound ScriptValueType) (Compound Value)
-> m (Either (Compound ScriptValueType) (Compound Value)))
-> Either (Compound ScriptValueType) (Compound Value)
-> m (Either (Compound ScriptValueType) (Compound Value))
forall a b. (a -> b) -> a -> b
$ Compound ScriptValueType
-> Either (Compound ScriptValueType) (Compound Value)
forall a b. a -> Either a b
Left (Compound ScriptValueType
-> Either (Compound ScriptValueType) (Compound Value))
-> Compound ScriptValueType
-> Either (Compound ScriptValueType) (Compound Value)
forall a b. (a -> b) -> a -> b
$ (ScriptValue ValOrVar -> ScriptValueType)
-> ExpValue -> Compound ScriptValueType
forall a b. (a -> b) -> Compound a -> Compound b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ScriptValue ValOrVar -> ScriptValueType
forall v. ScriptValue v -> ScriptValueType
scriptValueType ExpValue
v)
varsInExp :: Exp -> S.Set EntryName
varsInExp :: Exp -> Set EntryName
varsInExp ServerVar {} = Set EntryName
forall a. Monoid a => a
mempty
varsInExp (Call (FuncFut EntryName
v) [Exp]
es) = EntryName -> Set EntryName -> Set EntryName
forall a. Ord a => a -> Set a -> Set a
S.insert EntryName
v (Set EntryName -> Set EntryName) -> Set EntryName -> Set EntryName
forall a b. (a -> b) -> a -> b
$ (Exp -> Set EntryName) -> [Exp] -> Set EntryName
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Exp -> Set EntryName
varsInExp [Exp]
es
varsInExp (Call (FuncBuiltin EntryName
_) [Exp]
es) = (Exp -> Set EntryName) -> [Exp] -> Set EntryName
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Exp -> Set EntryName
varsInExp [Exp]
es
varsInExp (Tuple [Exp]
es) = (Exp -> Set EntryName) -> [Exp] -> Set EntryName
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Exp -> Set EntryName
varsInExp [Exp]
es
varsInExp (Record [(EntryName, Exp)]
fs) = ((EntryName, Exp) -> Set EntryName)
-> [(EntryName, Exp)] -> Set EntryName
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((Exp -> Set EntryName) -> (EntryName, Exp) -> Set EntryName
forall m a. Monoid m => (a -> m) -> (EntryName, a) -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Exp -> Set EntryName
varsInExp) [(EntryName, Exp)]
fs
varsInExp Const {} = Set EntryName
forall a. Monoid a => a
mempty
varsInExp StringLit {} = Set EntryName
forall a. Monoid a => a
mempty
varsInExp (Let [EntryName]
pat Exp
e1 Exp
e2) = Exp -> Set EntryName
varsInExp Exp
e1 Set EntryName -> Set EntryName -> Set EntryName
forall a. Semigroup a => a -> a -> a
<> (EntryName -> Bool) -> Set EntryName -> Set EntryName
forall a. (a -> Bool) -> Set a -> Set a
S.filter (EntryName -> [EntryName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [EntryName]
pat) (Exp -> Set EntryName
varsInExp Exp
e2)
freeValue :: (MonadError T.Text m, MonadIO m) => ScriptServer -> ExpValue -> m ()
freeValue :: forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
ScriptServer -> ExpValue -> m ()
freeValue ScriptServer
server =
IO (Maybe CmdFailure) -> m ()
forall (m :: * -> *).
(MonadError EntryName m, MonadIO m) =>
IO (Maybe CmdFailure) -> m ()
cmdMaybe (IO (Maybe CmdFailure) -> m ())
-> (ExpValue -> IO (Maybe CmdFailure)) -> ExpValue -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Server -> [EntryName] -> IO (Maybe CmdFailure)
cmdFree (ScriptServer -> Server
scriptServer ScriptServer
server) ([EntryName] -> IO (Maybe CmdFailure))
-> (ExpValue -> [EntryName]) -> ExpValue -> IO (Maybe CmdFailure)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set EntryName -> [EntryName]
forall a. Set a -> [a]
S.toList (Set EntryName -> [EntryName])
-> (ExpValue -> Set EntryName) -> ExpValue -> [EntryName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExpValue -> Set EntryName
serverVarsInValue