module Hydra.Langs.Scala.Coder (moduleToScala) where

import Hydra.Kernel
import Hydra.Dsl.Terms
import Hydra.Langs.Scala.Language
import Hydra.Langs.Scala.Utils
import Hydra.Adapters
import Hydra.Tools.Serialization
import Hydra.Langs.Scala.Serde
import qualified Hydra.Dsl.Types as Types
import qualified Hydra.Langs.Scala.Meta as Scala
import qualified Hydra.Lib.Strings as Strings

import qualified Control.Monad as CM
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Maybe as Y


moduleToScala :: Module -> Flow (Graph) (M.Map FilePath String)
moduleToScala :: Module -> Flow Graph (Map FilePath FilePath)
moduleToScala Module
mod = do
  Pkg
pkg <- Module -> Flow Graph Pkg
moduleToScalaPackage Module
mod
  let s :: FilePath
s = Expr -> FilePath
printExpr (Expr -> FilePath) -> Expr -> FilePath
forall a b. (a -> b) -> a -> b
$ Expr -> Expr
parenthesize (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ Pkg -> Expr
writePkg Pkg
pkg
  Map FilePath FilePath -> Flow Graph (Map FilePath FilePath)
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Map FilePath FilePath -> Flow Graph (Map FilePath FilePath))
-> Map FilePath FilePath -> Flow Graph (Map FilePath FilePath)
forall a b. (a -> b) -> a -> b
$ [(FilePath, FilePath)] -> Map FilePath FilePath
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(Bool -> FileExtension -> Namespace -> FilePath
namespaceToFilePath Bool
False (FilePath -> FileExtension
FileExtension FilePath
"scala") (Namespace -> FilePath) -> Namespace -> FilePath
forall a b. (a -> b) -> a -> b
$ Module -> Namespace
moduleNamespace Module
mod, FilePath
s)]

moduleToScalaPackage :: Module -> Flow (Graph) Scala.Pkg
moduleToScalaPackage :: Module -> Flow Graph Pkg
moduleToScalaPackage = Language
-> (Term -> Flow Graph Data)
-> (Module
    -> Map Type (Coder Graph Graph Term Data)
    -> [(Element, TypedTerm)]
    -> Flow Graph Pkg)
-> Module
-> Flow Graph Pkg
forall e d.
Language
-> (Term -> Flow Graph e)
-> (Module
    -> Map Type (Coder Graph Graph Term e)
    -> [(Element, TypedTerm)]
    -> Flow Graph d)
-> Module
-> Flow Graph d
transformModule Language
scalaLanguage Term -> Flow Graph Data
encodeUntypedTerm Module
-> Map Type (Coder Graph Graph Term Data)
-> [(Element, TypedTerm)]
-> Flow Graph Pkg
constructModule

constructModule :: Module -> M.Map (Type) (Coder (Graph) (Graph) (Term) Scala.Data) -> [(Element, TypedTerm)]
  -> Flow (Graph) Scala.Pkg
constructModule :: Module
-> Map Type (Coder Graph Graph Term Data)
-> [(Element, TypedTerm)]
-> Flow Graph Pkg
constructModule Module
mod Map Type (Coder Graph Graph Term Data)
coders [(Element, TypedTerm)]
pairs = do
    [Stat]
defs <- ((Element, TypedTerm) -> Flow Graph Stat)
-> [(Element, TypedTerm)] -> Flow Graph [Stat]
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]
CM.mapM (Element, TypedTerm) -> Flow Graph Stat
toDef [(Element, TypedTerm)]
pairs
    let pname :: Data_Name
pname = FilePath -> Data_Name
toScalaName (FilePath -> Data_Name) -> FilePath -> Data_Name
forall a b. (a -> b) -> a -> b
$ Namespace -> FilePath
h (Namespace -> FilePath) -> Namespace -> FilePath
forall a b. (a -> b) -> a -> b
$ Module -> Namespace
moduleNamespace Module
mod
    let pref :: Data_Ref
pref = Data_Name -> Data_Ref
Scala.Data_RefName Data_Name
pname
    [Stat]
imports <- Flow Graph [Stat]
findImports
    Pkg -> Flow Graph Pkg
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Pkg -> Flow Graph Pkg) -> Pkg -> Flow Graph Pkg
forall a b. (a -> b) -> a -> b
$ Data_Name -> Data_Ref -> [Stat] -> Pkg
Scala.Pkg Data_Name
pname Data_Ref
pref ([Stat]
imports [Stat] -> [Stat] -> [Stat]
forall a. [a] -> [a] -> [a]
++ [Stat]
defs)
  where
    h :: Namespace -> FilePath
h (Namespace FilePath
n) = FilePath
n
    findImports :: Flow Graph [Stat]
findImports = do
        Set Namespace
elImps <- Bool
-> Bool -> Bool -> Bool -> Module -> Flow Graph (Set Namespace)
moduleDependencyNamespaces Bool
False Bool
False Bool
True Bool
False Module
mod
        Set Namespace
primImps <- Bool
-> Bool -> Bool -> Bool -> Module -> Flow Graph (Set Namespace)
moduleDependencyNamespaces Bool
False Bool
True Bool
False Bool
False Module
mod
        [Stat] -> Flow Graph [Stat]
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Stat] -> Flow Graph [Stat]) -> [Stat] -> Flow Graph [Stat]
forall a b. (a -> b) -> a -> b
$ (Namespace -> Stat
toElImport (Namespace -> Stat) -> [Namespace] -> [Stat]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set Namespace -> [Namespace]
forall a. Set a -> [a]
S.toList Set Namespace
elImps) [Stat] -> [Stat] -> [Stat]
forall a. [a] -> [a] -> [a]
++ (Namespace -> Stat
toPrimImport (Namespace -> Stat) -> [Namespace] -> [Stat]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set Namespace -> [Namespace]
forall a. Set a -> [a]
S.toList Set Namespace
primImps)
      where
        toElImport :: Namespace -> Stat
toElImport (Namespace FilePath
ns) = ImportExportStat -> Stat
Scala.StatImportExport (ImportExportStat -> Stat) -> ImportExportStat -> Stat
forall a b. (a -> b) -> a -> b
$ Import -> ImportExportStat
Scala.ImportExportStatImport (Import -> ImportExportStat) -> Import -> ImportExportStat
forall a b. (a -> b) -> a -> b
$ [Importer] -> Import
Scala.Import [
          Data_Ref -> [Importee] -> Importer
Scala.Importer (Data_Name -> Data_Ref
Scala.Data_RefName (Data_Name -> Data_Ref) -> Data_Name -> Data_Ref
forall a b. (a -> b) -> a -> b
$ FilePath -> Data_Name
toScalaName FilePath
ns) [Importee
Scala.ImporteeWildcard]]
        toPrimImport :: Namespace -> Stat
toPrimImport (Namespace FilePath
ns) = ImportExportStat -> Stat
Scala.StatImportExport (ImportExportStat -> Stat) -> ImportExportStat -> Stat
forall a b. (a -> b) -> a -> b
$ Import -> ImportExportStat
Scala.ImportExportStatImport (Import -> ImportExportStat) -> Import -> ImportExportStat
forall a b. (a -> b) -> a -> b
$ [Importer] -> Import
Scala.Import [
          Data_Ref -> [Importee] -> Importer
Scala.Importer (Data_Name -> Data_Ref
Scala.Data_RefName (Data_Name -> Data_Ref) -> Data_Name -> Data_Ref
forall a b. (a -> b) -> a -> b
$ FilePath -> Data_Name
toScalaName FilePath
ns) []]
    toScalaName :: FilePath -> Data_Name
toScalaName FilePath
name = PredefString -> Data_Name
Scala.Data_Name (PredefString -> Data_Name) -> PredefString -> Data_Name
forall a b. (a -> b) -> a -> b
$ FilePath -> PredefString
Scala.PredefString (FilePath -> PredefString) -> FilePath -> PredefString
forall a b. (a -> b) -> a -> b
$ FilePath -> [FilePath] -> FilePath
forall a. [a] -> [[a]] -> [a]
L.intercalate FilePath
"." ([FilePath] -> FilePath) -> [FilePath] -> FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> [FilePath]
Strings.splitOn FilePath
"/" FilePath
name
    toDef :: (Element, TypedTerm) -> Flow Graph Stat
toDef (Element
el, TypedTerm Term
term Type
typ) = FilePath -> Flow Graph Stat -> Flow Graph Stat
forall s a. FilePath -> Flow s a -> Flow s a
withTrace (FilePath
"element " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Name -> FilePath
unName (Element -> Name
elementName Element
el)) (Flow Graph Stat -> Flow Graph Stat)
-> Flow Graph Stat -> Flow Graph Stat
forall a b. (a -> b) -> a -> b
$ do
        let coder :: Coder Graph Graph Term Data
coder = Maybe (Coder Graph Graph Term Data) -> Coder Graph Graph Term Data
forall a. HasCallStack => Maybe a -> a
Y.fromJust (Maybe (Coder Graph Graph Term Data)
 -> Coder Graph Graph Term Data)
-> Maybe (Coder Graph Graph Term Data)
-> Coder Graph Graph Term Data
forall a b. (a -> b) -> a -> b
$ Type
-> Map Type (Coder Graph Graph Term Data)
-> Maybe (Coder Graph Graph Term Data)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Type
typ Map Type (Coder Graph Graph Term Data)
coders
        Data
rhs <- Coder Graph Graph Term Data -> Term -> Flow Graph Data
forall s1 s2 v1 v2. Coder s1 s2 v1 v2 -> v1 -> Flow s1 v2
coderEncode Coder Graph Graph Term Data
coder Term
term
        Defn -> Stat
Scala.StatDefn (Defn -> Stat) -> Flow Graph Defn -> Flow Graph Stat
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case Data
rhs of
          Scala.DataApply Data_Apply
_ -> Data -> Flow Graph Defn
forall {f :: * -> *}. Applicative f => Data -> f Defn
toVal Data
rhs
          Scala.DataFunctionData Data_FunctionData
fun -> case Type -> Type
stripType Type
typ of
            TypeFunction (FunctionType Type
_ Type
cod) -> Data_FunctionData -> Type -> Flow Graph Defn
toDefn Data_FunctionData
fun Type
cod
            Type
_ -> FilePath -> Flow Graph Defn
forall a. FilePath -> Flow Graph a
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail (FilePath -> Flow Graph Defn) -> FilePath -> Flow Graph Defn
forall a b. (a -> b) -> a -> b
$ FilePath
"expected function type, but found " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Type -> FilePath
forall a. Show a => a -> FilePath
show Type
typ
          Scala.DataLit Lit
_ -> Data -> Flow Graph Defn
forall {f :: * -> *}. Applicative f => Data -> f Defn
toVal Data
rhs
          Scala.DataRef Data_Ref
_ -> Data -> Flow Graph Defn
forall {f :: * -> *}. Applicative f => Data -> f Defn
toVal Data
rhs -- TODO
          Data
_ -> FilePath -> Flow Graph Defn
forall a. FilePath -> Flow Graph a
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail (FilePath -> Flow Graph Defn) -> FilePath -> Flow Graph Defn
forall a b. (a -> b) -> a -> b
$ FilePath
"unexpected RHS: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Data -> FilePath
forall a. Show a => a -> FilePath
show Data
rhs
      where
        lname :: FilePath
lname = Name -> FilePath
localNameOfEager (Name -> FilePath) -> Name -> FilePath
forall a b. (a -> b) -> a -> b
$ Element -> Name
elementName Element
el

        freeTypeVars :: [Name]
freeTypeVars = Set Name -> [Name]
forall a. Set a -> [a]
S.toList (Set Name -> [Name]) -> Set Name -> [Name]
forall a b. (a -> b) -> a -> b
$ Type -> Set Name
freeVariablesInType Type
typ

        toDefn :: Data_FunctionData -> Type -> Flow Graph Defn
toDefn (Scala.Data_FunctionDataFunction (Scala.Data_Function [Data_Param]
params Data
body)) Type
cod = do
          let tparams :: [Type_Param]
tparams = Name -> Type_Param
stparam (Name -> Type_Param) -> [Name] -> [Type_Param]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
freeTypeVars
          Type
scod <- Type -> Flow Graph Type
encodeType Type
cod
          Defn -> Flow Graph Defn
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Defn -> Flow Graph Defn) -> Defn -> Flow Graph Defn
forall a b. (a -> b) -> a -> b
$ Defn_Def -> Defn
Scala.DefnDef (Defn_Def -> Defn) -> Defn_Def -> Defn
forall a b. (a -> b) -> a -> b
$ [Mod]
-> Data_Name
-> [Type_Param]
-> [[Data_Param]]
-> Maybe Type
-> Data
-> Defn_Def
Scala.Defn_Def []
            (PredefString -> Data_Name
Scala.Data_Name (PredefString -> Data_Name) -> PredefString -> Data_Name
forall a b. (a -> b) -> a -> b
$ FilePath -> PredefString
Scala.PredefString FilePath
lname) [Type_Param]
tparams [[Data_Param]
params] (Type -> Maybe Type
forall a. a -> Maybe a
Just Type
scod) Data
body

        toVal :: Data -> f Defn
toVal Data
rhs = Defn -> f Defn
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Defn -> f Defn) -> Defn -> f Defn
forall a b. (a -> b) -> a -> b
$ Defn_Val -> Defn
Scala.DefnVal (Defn_Val -> Defn) -> Defn_Val -> Defn
forall a b. (a -> b) -> a -> b
$ [Mod] -> [Pat] -> Maybe Type -> Data -> Defn_Val
Scala.Defn_Val [] [Pat
namePat] Maybe Type
forall a. Maybe a
Nothing Data
rhs
          where
            namePat :: Pat
namePat = Pat_Var -> Pat
Scala.PatVar (Pat_Var -> Pat) -> Pat_Var -> Pat
forall a b. (a -> b) -> a -> b
$ Data_Name -> Pat_Var
Scala.Pat_Var (Data_Name -> Pat_Var) -> Data_Name -> Pat_Var
forall a b. (a -> b) -> a -> b
$ PredefString -> Data_Name
Scala.Data_Name (PredefString -> Data_Name) -> PredefString -> Data_Name
forall a b. (a -> b) -> a -> b
$ FilePath -> PredefString
Scala.PredefString FilePath
lname

encodeFunction :: M.Map String Term -> Function -> Y.Maybe (Term) -> Flow (Graph) Scala.Data
encodeFunction :: Map FilePath Term -> Function -> Maybe Term -> Flow Graph Data
encodeFunction Map FilePath Term
meta Function
fun Maybe Term
arg = case Function
fun of
    FunctionLambda (Lambda (Name FilePath
v) Term
body) -> FilePath -> Data -> Maybe Type -> Data
slambda FilePath
v (Data -> Maybe Type -> Data)
-> Flow Graph Data -> Flow Graph (Maybe Type -> Data)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term -> Flow Graph Data
encodeTerm Term
body Flow Graph (Maybe Type -> Data)
-> Flow Graph (Maybe Type) -> Flow Graph Data
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Flow Graph (Maybe Type)
findSdom
    FunctionPrimitive Name
name -> Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ Name -> Data
sprim Name
name
    FunctionElimination Elimination
e -> case Elimination
e of
      EliminationWrap Name
name -> Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ FilePath -> Data
sname (FilePath -> Data) -> FilePath -> Data
forall a b. (a -> b) -> a -> b
$ FilePath
"ELIM-NOMINAL(" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Name -> FilePath
forall a. Show a => a -> FilePath
show Name
name FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
")" -- TODO
      EliminationOptional OptionalCases
c -> Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ FilePath -> Data
sname FilePath
"ELIM-OPTIONAL" -- TODO
      EliminationRecord Projection
p -> FilePath -> Flow Graph Data
forall a. FilePath -> Flow Graph a
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail FilePath
"unapplied projection not yet supported"
      EliminationUnion (CaseStatement Name
_ Maybe Term
def [Field]
cases) -> do
          let v :: FilePath
v = FilePath
"v"
          Type
dom <- Flow Graph Type
findDomain
          Map Name Type
ftypes <- Flow Graph (Map Name Type) -> Flow Graph (Map Name Type)
forall x. Flow Graph x -> Flow Graph x
withSchemaContext (Flow Graph (Map Name Type) -> Flow Graph (Map Name Type))
-> Flow Graph (Map Name Type) -> Flow Graph (Map Name Type)
forall a b. (a -> b) -> a -> b
$ Type -> Flow Graph (Map Name Type)
fieldTypes Type
dom
          Graph
cx <- Flow Graph Graph
forall s. Flow s s
getState
          let sn :: Maybe Name
sn = Graph -> Type -> Maybe Name
nameOfType Graph
cx Type
dom
          [Case]
scases <- (Field -> Flow Graph Case) -> [Field] -> Flow Graph [Case]
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]
CM.mapM (Map Name Type -> Maybe Name -> Field -> Flow Graph Case
encodeCase Map Name Type
ftypes Maybe Name
sn) [Field]
cases
          -- TODO: default
          case Maybe Term
arg of
            Maybe Term
Nothing -> FilePath -> Data -> Maybe Type -> Data
slambda FilePath
v (Data -> Maybe Type -> Data)
-> Flow Graph Data -> Flow Graph (Maybe Type -> Data)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Data_Match -> Data
Scala.DataMatch (Data_Match -> Data) -> Data_Match -> Data
forall a b. (a -> b) -> a -> b
$ Data -> [Case] -> Data_Match
Scala.Data_Match (FilePath -> Data
sname FilePath
v) [Case]
scases) Flow Graph (Maybe Type -> Data)
-> Flow Graph (Maybe Type) -> Flow Graph Data
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Flow Graph (Maybe Type)
findSdom
            Just Term
a -> do
              Data
sa <- Term -> Flow Graph Data
encodeTerm Term
a
              Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ Data_Match -> Data
Scala.DataMatch (Data_Match -> Data) -> Data_Match -> Data
forall a b. (a -> b) -> a -> b
$ Data -> [Case] -> Data_Match
Scala.Data_Match Data
sa [Case]
scases
        where
          encodeCase :: Map Name Type -> Maybe Name -> Field -> Flow Graph Case
encodeCase Map Name Type
ftypes Maybe Name
sn f :: Field
f@(Field Name
fname Term
fterm) = do
  --            dom <- findDomain (termMeta fterm)           -- Option #1: use type inference
              let dom :: Type
dom = Maybe Type -> Type
forall a. HasCallStack => Maybe a -> a
Y.fromJust (Maybe Type -> Type) -> Maybe Type -> Type
forall a b. (a -> b) -> a -> b
$ Name -> Map Name Type -> Maybe Type
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Name
fname Map Name Type
ftypes -- Option #2: look up the union type
              let patArgs :: [Pat]
patArgs = if Type
dom Type -> Type -> Bool
forall a. Eq a => a -> a -> Bool
== Type
Types.unit then [] else [Name -> Pat
svar Name
v]
              -- Note: PatExtract has the right syntax, though this may or may not be the Scalameta-intended way to use it
              let pat :: Pat
pat = Pat_Extract -> Pat
Scala.PatExtract (Pat_Extract -> Pat) -> Pat_Extract -> Pat
forall a b. (a -> b) -> a -> b
$ Data -> [Pat] -> Pat_Extract
Scala.Pat_Extract (FilePath -> Data
sname (FilePath -> Data) -> FilePath -> Data
forall a b. (a -> b) -> a -> b
$ FilePath -> Maybe Name -> Name -> FilePath
qualifyUnionFieldName FilePath
"MATCHED." Maybe Name
sn Name
fname) [Pat]
patArgs
              Data
body <- Term -> Flow Graph Data
encodeTerm (Term -> Flow Graph Data) -> Term -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ Term -> Name -> Term
applyVar Term
fterm Name
v
              Case -> Flow Graph Case
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Case -> Flow Graph Case) -> Case -> Flow Graph Case
forall a b. (a -> b) -> a -> b
$ Pat -> Maybe Data -> Data -> Case
Scala.Case Pat
pat Maybe Data
forall a. Maybe a
Nothing Data
body
            where
              v :: Name
v = FilePath -> Name
Name FilePath
"y"
          applyVar :: Term -> Name -> Term
applyVar Term
fterm avar :: Name
avar@(Name FilePath
v) = case Term -> Term
stripTerm Term
fterm of
            TermFunction (FunctionLambda (Lambda Name
v1 Term
body)) -> if Name -> Term -> Bool
isFreeIn Name
v1 Term
body
              then Term
body
              else Name -> Name -> Term -> Term
substituteVariable Name
v1 Name
avar Term
body
            Term
_ -> Term -> Term -> Term
apply Term
fterm (FilePath -> Term
var FilePath
v)
  where
    findSdom :: Flow Graph (Maybe Type)
findSdom = Type -> Maybe Type
forall a. a -> Maybe a
Just (Type -> Maybe Type) -> Flow Graph Type -> Flow Graph (Maybe Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Flow Graph Type
findDomain Flow Graph Type -> (Type -> Flow Graph Type) -> Flow Graph Type
forall a b. Flow Graph a -> (a -> Flow Graph b) -> Flow Graph b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Type -> Flow Graph Type
encodeType)
    findDomain :: Flow Graph Type
findDomain = do
        Graph
cx <- Flow Graph Graph
forall s. Flow s s
getState
        Maybe Type
r <- Map FilePath Term -> Flow Graph (Maybe Type)
getType Map FilePath Term
meta
        case Maybe Type
r of
          Maybe Type
Nothing -> FilePath -> Flow Graph Type
forall a. FilePath -> Flow Graph a
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail FilePath
"expected a typed term"
          Just Type
t -> Type -> Flow Graph Type
forall {f :: * -> *}. MonadFail f => Type -> f Type
domainOf Type
t
      where
        domainOf :: Type -> f Type
domainOf Type
t = case Type -> Type
stripType Type
t of
          TypeFunction (FunctionType Type
dom Type
_) -> Type -> f Type
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Type
dom
          Type
_ -> FilePath -> f Type
forall a. FilePath -> f a
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail (FilePath -> f Type) -> FilePath -> f Type
forall a b. (a -> b) -> a -> b
$ FilePath
"expected a function type, but found " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Type -> FilePath
forall a. Show a => a -> FilePath
show Type
t

encodeLiteral :: Literal -> Flow (Graph) Scala.Lit
encodeLiteral :: Literal -> Flow Graph Lit
encodeLiteral Literal
av = case Literal
av of
    LiteralBoolean Bool
b -> Lit -> Flow Graph Lit
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lit -> Flow Graph Lit) -> Lit -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ Bool -> Lit
Scala.LitBoolean Bool
b
    LiteralFloat FloatValue
fv -> case FloatValue
fv of
      FloatValueFloat32 Float
f -> Lit -> Flow Graph Lit
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lit -> Flow Graph Lit) -> Lit -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ Float -> Lit
Scala.LitFloat Float
f
      FloatValueFloat64 Double
f -> Lit -> Flow Graph Lit
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lit -> Flow Graph Lit) -> Lit -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ Double -> Lit
Scala.LitDouble Double
f
      FloatValue
_ -> FilePath -> FilePath -> Flow Graph Lit
forall s x. FilePath -> FilePath -> Flow s x
unexpected FilePath
"floating-point number" (FilePath -> Flow Graph Lit) -> FilePath -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ FloatValue -> FilePath
forall a. Show a => a -> FilePath
show FloatValue
fv
    LiteralInteger IntegerValue
iv -> case IntegerValue
iv of
      IntegerValueInt16 Int16
i -> Lit -> Flow Graph Lit
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lit -> Flow Graph Lit) -> Lit -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ Int16 -> Lit
Scala.LitShort (Int16 -> Lit) -> Int16 -> Lit
forall a b. (a -> b) -> a -> b
$ Int16 -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
i
      IntegerValueInt32 Int
i -> Lit -> Flow Graph Lit
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lit -> Flow Graph Lit) -> Lit -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ Int -> Lit
Scala.LitInt Int
i
      IntegerValueInt64 Int64
i -> Lit -> Flow Graph Lit
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lit -> Flow Graph Lit) -> Lit -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ Int64 -> Lit
Scala.LitLong (Int64 -> Lit) -> Int64 -> Lit
forall a b. (a -> b) -> a -> b
$ Int64 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i
      IntegerValueUint8 Int16
i -> Lit -> Flow Graph Lit
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lit -> Flow Graph Lit) -> Lit -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ Int8 -> Lit
Scala.LitByte (Int8 -> Lit) -> Int8 -> Lit
forall a b. (a -> b) -> a -> b
$ Int16 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
i
      IntegerValue
_ -> FilePath -> FilePath -> Flow Graph Lit
forall s x. FilePath -> FilePath -> Flow s x
unexpected FilePath
"integer" (FilePath -> Flow Graph Lit) -> FilePath -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ IntegerValue -> FilePath
forall a. Show a => a -> FilePath
show IntegerValue
iv
    LiteralString FilePath
s -> Lit -> Flow Graph Lit
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Lit -> Flow Graph Lit) -> Lit -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ FilePath -> Lit
Scala.LitString FilePath
s
    Literal
_ -> FilePath -> FilePath -> Flow Graph Lit
forall s x. FilePath -> FilePath -> Flow s x
unexpected FilePath
"literal value" (FilePath -> Flow Graph Lit) -> FilePath -> Flow Graph Lit
forall a b. (a -> b) -> a -> b
$ Literal -> FilePath
forall a. Show a => a -> FilePath
show Literal
av

encodeTerm :: Term -> Flow (Graph) Scala.Data
encodeTerm :: Term -> Flow Graph Data
encodeTerm Term
term = case Term -> Term
stripTerm Term
term of
    TermApplication (Application Term
fun Term
arg) -> case Term -> Term
stripTerm Term
fun of
        TermFunction Function
f -> case Function
f of
          FunctionElimination Elimination
e -> case Elimination
e of
            EliminationWrap Name
name -> Flow Graph Data
fallback
            EliminationOptional OptionalCases
c -> Flow Graph Data
fallback
            EliminationRecord (Projection Name
_ (Name FilePath
fname)) -> do
              Data
sarg <- Term -> Flow Graph Data
encodeTerm Term
arg
              Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ Data_Ref -> Data
Scala.DataRef (Data_Ref -> Data) -> Data_Ref -> Data
forall a b. (a -> b) -> a -> b
$ Data_Select -> Data_Ref
Scala.Data_RefSelect (Data_Select -> Data_Ref) -> Data_Select -> Data_Ref
forall a b. (a -> b) -> a -> b
$ Data -> Data_Name -> Data_Select
Scala.Data_Select Data
sarg
                (PredefString -> Data_Name
Scala.Data_Name (PredefString -> Data_Name) -> PredefString -> Data_Name
forall a b. (a -> b) -> a -> b
$ FilePath -> PredefString
Scala.PredefString FilePath
fname)
            EliminationUnion CaseStatement
_ -> do
              Graph
cx <- Flow Graph Graph
forall s. Flow s s
getState
              Map FilePath Term -> Function -> Maybe Term -> Flow Graph Data
encodeFunction (Term -> Map FilePath Term
termAnnotationInternal Term
fun) Function
f (Term -> Maybe Term
forall a. a -> Maybe a
Just Term
arg)
          Function
_ -> Flow Graph Data
fallback
        Term
_ -> Flow Graph Data
fallback
      where
        fallback :: Flow Graph Data
fallback = Data -> [Data] -> Data
sapply (Data -> [Data] -> Data)
-> Flow Graph Data -> Flow Graph ([Data] -> Data)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term -> Flow Graph Data
encodeTerm Term
fun Flow Graph ([Data] -> Data) -> Flow Graph [Data] -> Flow Graph Data
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Data -> [Data] -> [Data]
forall a. a -> [a] -> [a]
: []) (Data -> [Data]) -> Flow Graph Data -> Flow Graph [Data]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term -> Flow Graph Data
encodeTerm Term
arg)
    TermFunction Function
f -> do
      Graph
cx <- Flow Graph Graph
forall s. Flow s s
getState
      Map FilePath Term -> Function -> Maybe Term -> Flow Graph Data
encodeFunction (Term -> Map FilePath Term
termAnnotationInternal Term
term) Function
f Maybe Term
forall a. Maybe a
Nothing
    TermList [Term]
els -> Data -> [Data] -> Data
sapply (FilePath -> Data
sname FilePath
"Seq") ([Data] -> Data) -> Flow Graph [Data] -> Flow Graph Data
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Term -> Flow Graph Data) -> [Term] -> Flow Graph [Data]
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]
CM.mapM Term -> Flow Graph Data
encodeTerm [Term]
els
    TermLiteral Literal
v -> Lit -> Data
Scala.DataLit (Lit -> Data) -> Flow Graph Lit -> Flow Graph Data
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Literal -> Flow Graph Lit
encodeLiteral Literal
v
    TermMap Map Term Term
m -> Data -> [Data] -> Data
sapply (FilePath -> Data
sname FilePath
"Map") ([Data] -> Data) -> Flow Graph [Data] -> Flow Graph Data
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Term, Term) -> Flow Graph Data)
-> [(Term, Term)] -> Flow Graph [Data]
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]
CM.mapM (Term, Term) -> Flow Graph Data
toPair (Map Term Term -> [(Term, Term)]
forall k a. Map k a -> [(k, a)]
M.toList Map Term Term
m)
      where
        toPair :: (Term, Term) -> Flow Graph Data
toPair (Term
k, Term
v) = Data -> Data -> Data
sassign (Data -> Data -> Data)
-> Flow Graph Data -> Flow Graph (Data -> Data)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term -> Flow Graph Data
encodeTerm Term
k Flow Graph (Data -> Data) -> Flow Graph Data -> Flow Graph Data
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Term -> Flow Graph Data
encodeTerm Term
v
    TermWrap (WrappedTerm Name
_ Term
term') -> Term -> Flow Graph Data
encodeTerm Term
term'
    TermOptional Maybe Term
m -> case Maybe Term
m of
      Maybe Term
Nothing -> Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ FilePath -> Data
sname FilePath
"None"
      Just Term
t -> (\Data
s -> Data -> [Data] -> Data
sapply (FilePath -> Data
sname FilePath
"Some") [Data
s]) (Data -> Data) -> Flow Graph Data -> Flow Graph Data
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term -> Flow Graph Data
encodeTerm Term
t
    TermRecord (Record Name
name [Field]
fields) -> do
      let n :: FilePath
n = Bool -> Name -> FilePath
scalaTypeName Bool
False Name
name
      [Data]
args <- (Term -> Flow Graph Data) -> [Term] -> Flow Graph [Data]
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]
CM.mapM Term -> Flow Graph Data
encodeTerm (Field -> Term
fieldTerm (Field -> Term) -> [Field] -> [Term]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Field]
fields)
      Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ Data -> [Data] -> Data
sapply (FilePath -> Data
sname FilePath
n) [Data]
args
    TermSet Set Term
s -> Data -> [Data] -> Data
sapply (FilePath -> Data
sname FilePath
"Set") ([Data] -> Data) -> Flow Graph [Data] -> Flow Graph Data
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Term -> Flow Graph Data) -> [Term] -> Flow Graph [Data]
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]
CM.mapM Term -> Flow Graph Data
encodeTerm (Set Term -> [Term]
forall a. Set a -> [a]
S.toList Set Term
s)
    TermUnion (Injection Name
sn (Field Name
fn Term
ft)) -> do
      let lhs :: Data
lhs = FilePath -> Data
sname (FilePath -> Data) -> FilePath -> Data
forall a b. (a -> b) -> a -> b
$ FilePath -> Maybe Name -> Name -> FilePath
qualifyUnionFieldName FilePath
"UNION." (Name -> Maybe Name
forall a. a -> Maybe a
Just Name
sn) Name
fn
      [Data]
args <- case Term -> Term
stripTerm Term
ft of
        TermRecord (Record Name
_ []) -> [Data] -> Flow Graph [Data]
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
        Term
_ -> do
          Data
arg <- Term -> Flow Graph Data
encodeTerm Term
ft
          [Data] -> Flow Graph [Data]
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return [Data
arg]
      Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ Data -> [Data] -> Data
sapply Data
lhs [Data]
args
    TermVariable (Name FilePath
v) -> Data -> Flow Graph Data
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Data -> Flow Graph Data) -> Data -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ FilePath -> Data
sname FilePath
v
    Term
_ -> FilePath -> Flow Graph Data
forall a. FilePath -> Flow Graph a
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail (FilePath -> Flow Graph Data) -> FilePath -> Flow Graph Data
forall a b. (a -> b) -> a -> b
$ FilePath
"unexpected term: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Term -> FilePath
forall a. Show a => a -> FilePath
show Term
term


encodeType :: Type -> Flow (Graph) Scala.Type
encodeType :: Type -> Flow Graph Type
encodeType Type
t = case Type -> Type
stripType Type
t of
  TypeFunction (FunctionType Type
dom Type
cod) -> do
    Type
sdom <- Type -> Flow Graph Type
encodeType Type
dom
    Type
scod <- Type -> Flow Graph Type
encodeType Type
cod
    Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ Type_FunctionType -> Type
Scala.TypeFunctionType (Type_FunctionType -> Type) -> Type_FunctionType -> Type
forall a b. (a -> b) -> a -> b
$ Type_Function -> Type_FunctionType
Scala.Type_FunctionTypeFunction (Type_Function -> Type_FunctionType)
-> Type_Function -> Type_FunctionType
forall a b. (a -> b) -> a -> b
$ [Type] -> Type -> Type_Function
Scala.Type_Function [Type
sdom] Type
scod
  TypeList Type
lt -> Type -> Type -> Type
stapply1 (Type -> Type -> Type)
-> Flow Graph Type -> Flow Graph (Type -> Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FilePath -> Type
stref FilePath
"Seq") Flow Graph (Type -> Type) -> Flow Graph Type -> Flow Graph Type
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Flow Graph Type
encodeType Type
lt
  TypeLiteral LiteralType
lt -> case LiteralType
lt of
--    TypeBinary ->
    LiteralType
LiteralTypeBoolean -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath -> Type
stref FilePath
"Boolean"
    LiteralTypeFloat FloatType
ft -> case FloatType
ft of
--      FloatTypeBigfloat ->
      FloatType
FloatTypeFloat32 -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath -> Type
stref FilePath
"Float"
      FloatType
FloatTypeFloat64 -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath -> Type
stref FilePath
"Double"
    LiteralTypeInteger IntegerType
it -> case IntegerType
it of
--      IntegerTypeBigint ->
--      IntegerTypeInt8 ->
      IntegerType
IntegerTypeInt16 -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath -> Type
stref FilePath
"Short"
      IntegerType
IntegerTypeInt32 -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath -> Type
stref FilePath
"Int"
      IntegerType
IntegerTypeInt64 -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath -> Type
stref FilePath
"Long"
      IntegerType
IntegerTypeUint8 -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath -> Type
stref FilePath
"Byte"
--      IntegerTypeUint16 ->
--      IntegerTypeUint32 ->
--      IntegerTypeUint64 ->
    LiteralType
LiteralTypeString -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath -> Type
stref FilePath
"String"
  TypeMap (MapType Type
kt Type
vt) -> Type -> Type -> Type -> Type
stapply2 (Type -> Type -> Type -> Type)
-> Flow Graph Type -> Flow Graph (Type -> Type -> Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FilePath -> Type
stref FilePath
"Map") Flow Graph (Type -> Type -> Type)
-> Flow Graph Type -> Flow Graph (Type -> Type)
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Flow Graph Type
encodeType Type
kt Flow Graph (Type -> Type) -> Flow Graph Type -> Flow Graph Type
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Flow Graph Type
encodeType Type
vt
  TypeOptional Type
ot -> Type -> Type -> Type
stapply1 (Type -> Type -> Type)
-> Flow Graph Type -> Flow Graph (Type -> Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FilePath -> Type
stref FilePath
"Option") Flow Graph (Type -> Type) -> Flow Graph Type -> Flow Graph Type
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Flow Graph Type
encodeType Type
ot
--  TypeRecord sfields ->
  TypeSet Type
st -> Type -> Type -> Type
stapply1 (Type -> Type -> Type)
-> Flow Graph Type -> Flow Graph (Type -> Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FilePath -> Type
stref FilePath
"Set") Flow Graph (Type -> Type) -> Flow Graph Type -> Flow Graph Type
forall a b. Flow Graph (a -> b) -> Flow Graph a -> Flow Graph b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Flow Graph Type
encodeType Type
st
--  TypeUnion sfields ->
  TypeLambda (LambdaType Name
v Type
body) -> do
    Type
sbody <- Type -> Flow Graph Type
encodeType Type
body
    Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ Type_Lambda -> Type
Scala.TypeLambda (Type_Lambda -> Type) -> Type_Lambda -> Type
forall a b. (a -> b) -> a -> b
$ [Type_Param] -> Type -> Type_Lambda
Scala.Type_Lambda [Name -> Type_Param
stparam Name
v] Type
sbody
--   TypeVariable name -> pure $ stref $ scalaTypeName True name
  TypeVariable (Name FilePath
v) -> Type -> Flow Graph Type
forall a. a -> Flow Graph a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Flow Graph Type) -> Type -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ Type_Var -> Type
Scala.TypeVar (Type_Var -> Type) -> Type_Var -> Type
forall a b. (a -> b) -> a -> b
$ Type_Name -> Type_Var
Scala.Type_Var (Type_Name -> Type_Var) -> Type_Name -> Type_Var
forall a b. (a -> b) -> a -> b
$ FilePath -> Type_Name
Scala.Type_Name FilePath
v
  Type
_ -> FilePath -> Flow Graph Type
forall a. FilePath -> Flow Graph a
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail (FilePath -> Flow Graph Type) -> FilePath -> Flow Graph Type
forall a b. (a -> b) -> a -> b
$ FilePath
"can't encode unsupported type in Scala: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Type -> FilePath
forall a. Show a => a -> FilePath
show Type
t

encodeUntypedTerm :: Term -> Flow (Graph) Scala.Data
encodeUntypedTerm :: Term -> Flow Graph Data
encodeUntypedTerm Term
term = Term -> Flow Graph Term
annotateTypedTerms Term
term Flow Graph Term -> (Term -> Flow Graph Data) -> Flow Graph Data
forall a b. Flow Graph a -> (a -> Flow Graph b) -> Flow Graph b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Term -> Flow Graph Data
encodeTerm