module Conversions.ToScala.Common where

import qualified SyntaxTrees.Haskell.Common as H
import qualified SyntaxTrees.Scala.Common   as S

import           Data.Map    (Map)
import qualified Data.Map    as Map
import           Text.Casing (quietSnake)



var :: H.Var -> S.Var
var :: Var -> Var
var (H.Var String
x) = String -> Var
S.Var forall a b. (a -> b) -> a -> b
$ String -> String
replaceNaming String
x

ctor :: H.Ctor -> S.Ctor
ctor :: Ctor -> Ctor
ctor (H.Ctor String
x) = String -> Ctor
S.Ctor forall a b. (a -> b) -> a -> b
$ String -> String
replaceNaming String
x

varOp :: H.VarOp -> S.VarOp
varOp :: VarOp -> VarOp
varOp (H.VarOp String
x) = String -> VarOp
S.VarOp forall a b. (a -> b) -> a -> b
$ String -> String
replaceNaming String
x

ctorOp :: H.CtorOp -> S.CtorOp
ctorOp :: CtorOp -> CtorOp
ctorOp (H.CtorOp String
x) = String -> CtorOp
S.CtorOp forall a b. (a -> b) -> a -> b
$ String -> String
replaceNaming String
x

class' :: H.Class -> S.TypeClass
class' :: Class -> TypeClass
class' (H.Class String
x) = String -> TypeClass
S.TypeClass String
x


module' :: H.Module -> S.Package
module' :: Module -> Package
module' (H.Module [String]
x) = [String] -> Package
S.Package forall a b. (a -> b) -> a -> b
$ (String -> String
replaceNaming forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
quietSnake) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
x

qualifier' :: H.Module -> S.Package
qualifier' :: Module -> Package
qualifier' (H.Module [String]
x) = [String] -> Package
S.Package forall a b. (a -> b) -> a -> b
$ String -> String
replaceNaming forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
x


literal :: H.Literal -> S.Literal
literal :: Literal -> Literal
literal Literal
H.UnitLit       = Literal
S.UnitLit
literal (H.BoolLit Bool
x)   = Bool -> Literal
S.BoolLit Bool
x
literal (H.IntLit String
x)    = String -> Literal
S.IntLit String
x
literal (H.FloatLit String
x)  = String -> Literal
S.FloatLit String
x
literal (H.CharLit Char
x)   = Char -> Literal
S.CharLit Char
x
literal (H.StringLit String
x) = String -> Literal
S.StringLit String
x



qVar :: H.QVar -> S.QVar
qVar :: QVar -> QVar
qVar (H.QVar Maybe Module
x Var
y) = Maybe Package -> Var -> QVar
S.QVar (Module -> Package
qualifier' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Module
x) (Var -> Var
var Var
y)

qVarOp :: H.QVarOp -> S.QVarOp
qVarOp :: QVarOp -> QVarOp
qVarOp (H.QVarOp Maybe Module
x VarOp
y) = Maybe Package -> VarOp -> QVarOp
S.QVarOp (Module -> Package
qualifier' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Module
x) (VarOp -> VarOp
varOp VarOp
y)

qCtor :: H.QCtor -> S.QCtor
qCtor :: QCtor -> QCtor
qCtor (H.QCtor Maybe Module
x Ctor
y) = Maybe Package -> Ctor -> QCtor
S.QCtor (Module -> Package
qualifier' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Module
x) (Ctor -> Ctor
ctor Ctor
y)

qCtorOp :: H.QCtorOp -> S.QCtorOp
qCtorOp :: QCtorOp -> QCtorOp
qCtorOp (H.QCtorOp Maybe Module
x CtorOp
y) = Maybe Package -> CtorOp -> QCtorOp
S.QCtorOp (Module -> Package
qualifier' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Module
x) (CtorOp -> CtorOp
ctorOp CtorOp
y)

qClass :: H.QClass -> S.QTypeClass
qClass :: QClass -> QTypeClass
qClass (H.QClass Maybe Module
x Class
y) = Maybe Package -> TypeClass -> QTypeClass
S.QTypeClass (Module -> Package
qualifier' forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Module
x) (Class -> TypeClass
class' Class
y)


replaceNaming :: String -> String
replaceNaming :: String -> String
replaceNaming String
x = forall k. Ord k => Map k k -> k -> k
find Map Char Char
charMap forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall k. Ord k => Map k k -> k -> k
find Map String String
globalMap String
x

find :: Ord k => Map k k -> k -> k
find :: forall k. Ord k => Map k k -> k -> k
find Map k k
x k
y = forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault k
y k
y Map k k
x

globalMap :: Map String String
globalMap :: Map String String
globalMap = Map String String
varOpMap forall a. Semigroup a => a -> a -> a
<> Map String String
ctorOpMap forall a. Semigroup a => a -> a -> a
<> Map String String
varMap forall a. Semigroup a => a -> a -> a
<> Map String String
ctorMap


charMap :: Map Char Char
charMap :: Map Char Char
charMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Char
'\'', Char
'$'), (Char
'$', Char
'&'), (Char
'.', Char
'|')]

varOpMap :: Map String String
varOpMap :: Map String String
varOpMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(String
"$", String
"|<|"), (String
".", String
"^"),
                         (String
"++", String
"<+>"), (String
"<>", String
"<+>"),
                         (String
",", String
"Tuple2"), (String
",,", String
"Tuple3"),
                         (String
",,,", String
"Tuple4"), (String
",,,,", String
"Tuple5")]

ctorOpMap :: Map String String
ctorOpMap :: Map String String
ctorOpMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(String
":", String
"::"), (String
"::", String
":")]

varMap :: Map String String
varMap :: Map String String
varMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(String
"type", String
"typex"), (String
"var", String
"varx"),
                       (String
"def", String
"defx"), (String
"match", String
"matchx")]

ctorMap :: Map String String
ctorMap :: Map String String
ctorMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(String
"Just", String
"Some"), (String
"Nothing", String
"None"),
                       (String
"True", String
"true"), (String
"False", String
"false")]

autoIds :: [String]
autoIds :: [String]
autoIds = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char
'x', Char
'y', Char
'z', Char
't', Char
'u', Char
'v', Char
'w', Char
'p', Char
'q', Char
'r', Char
's']