module Language.Egison.EnvBuilder
( buildEnvironments
, EnvBuildResult(..)
) where
import Control.Monad (foldM)
import Control.Monad.Except (throwError)
import Control.Monad.State
import Data.Char (toUpper, toLower)
import qualified Data.HashMap.Strict as HashMap
import Language.Egison.AST
import Language.Egison.Data (EvalM)
import Language.Egison.EvalState (ConstructorInfo(..), ConstructorEnv, PatternConstructorEnv)
import Language.Egison.IExpr (Var(..), Index(..), stringToVar)
import Language.Egison.Desugar (transVarIndex)
import Language.Egison.Type.Env (TypeEnv, ClassEnv, PatternTypeEnv, emptyEnv, emptyClassEnv, emptyPatternEnv,
extendEnv, extendPatternEnv, addClass, addInstance, lookupClass)
import qualified Language.Egison.Type.Types as Types
import Language.Egison.Type.Types (Type(..), TyVar(..), Constraint(..), TypeScheme(..), TensorShape(..),
ClassInfo, InstanceInfo, freeTyVars, typeToName, sanitizeMethodName, typeExprToType,
capitalizeFirst, lowerFirst)
import qualified Data.Set as Set
data EnvBuildResult = EnvBuildResult
{ EnvBuildResult -> TypeEnv
ebrTypeEnv :: TypeEnv
, EnvBuildResult -> ClassEnv
ebrClassEnv :: ClassEnv
, EnvBuildResult -> ConstructorEnv
ebrConstructorEnv :: ConstructorEnv
, EnvBuildResult -> PatternConstructorEnv
ebrPatternConstructorEnv :: PatternConstructorEnv
, EnvBuildResult -> PatternConstructorEnv
ebrPatternTypeEnv :: PatternTypeEnv
} deriving (Int -> EnvBuildResult -> ShowS
[EnvBuildResult] -> ShowS
EnvBuildResult -> String
(Int -> EnvBuildResult -> ShowS)
-> (EnvBuildResult -> String)
-> ([EnvBuildResult] -> ShowS)
-> Show EnvBuildResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EnvBuildResult -> ShowS
showsPrec :: Int -> EnvBuildResult -> ShowS
$cshow :: EnvBuildResult -> String
show :: EnvBuildResult -> String
$cshowList :: [EnvBuildResult] -> ShowS
showList :: [EnvBuildResult] -> ShowS
Show)
buildEnvironments :: [TopExpr] -> EvalM EnvBuildResult
buildEnvironments :: [TopExpr] -> EvalM EnvBuildResult
buildEnvironments [TopExpr]
exprs = do
let initialResult :: EnvBuildResult
initialResult = EnvBuildResult
{ ebrTypeEnv :: TypeEnv
ebrTypeEnv = TypeEnv
emptyEnv
, ebrClassEnv :: ClassEnv
ebrClassEnv = ClassEnv
emptyClassEnv
, ebrConstructorEnv :: ConstructorEnv
ebrConstructorEnv = ConstructorEnv
forall k v. HashMap k v
HashMap.empty
, ebrPatternConstructorEnv :: PatternConstructorEnv
ebrPatternConstructorEnv = PatternConstructorEnv
emptyPatternEnv
, ebrPatternTypeEnv :: PatternConstructorEnv
ebrPatternTypeEnv = PatternConstructorEnv
emptyPatternEnv
}
(EnvBuildResult -> TopExpr -> EvalM EnvBuildResult)
-> EnvBuildResult -> [TopExpr] -> EvalM EnvBuildResult
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM EnvBuildResult -> TopExpr -> EvalM EnvBuildResult
processTopExpr EnvBuildResult
initialResult [TopExpr]
exprs
processTopExpr :: EnvBuildResult -> TopExpr -> EvalM EnvBuildResult
processTopExpr :: EnvBuildResult -> TopExpr -> EvalM EnvBuildResult
processTopExpr EnvBuildResult
result TopExpr
topExpr = case TopExpr
topExpr of
InductiveDecl String
typeName [String]
typeParams [InductiveConstructor]
constructors -> do
let typeParamVars :: [Type]
typeParamVars = (String -> Type) -> [String] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyVar -> Type
TVar (TyVar -> Type) -> (String -> TyVar) -> String -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> TyVar
TyVar) [String]
typeParams
adtType :: Type
adtType = String -> [Type] -> Type
TInductive String
typeName [Type]
typeParamVars
typeEnv :: TypeEnv
typeEnv = EnvBuildResult -> TypeEnv
ebrTypeEnv EnvBuildResult
result
ctorEnv :: ConstructorEnv
ctorEnv = EnvBuildResult -> ConstructorEnv
ebrConstructorEnv EnvBuildResult
result
(TypeEnv
typeEnv', ConstructorEnv
ctorEnv') <- ((TypeEnv, ConstructorEnv)
-> InductiveConstructor
-> StateT
EvalState (ExceptT EgisonError RuntimeM) (TypeEnv, ConstructorEnv))
-> (TypeEnv, ConstructorEnv)
-> [InductiveConstructor]
-> StateT
EvalState (ExceptT EgisonError RuntimeM) (TypeEnv, ConstructorEnv)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (String
-> [String]
-> Type
-> (TypeEnv, ConstructorEnv)
-> InductiveConstructor
-> StateT
EvalState (ExceptT EgisonError RuntimeM) (TypeEnv, ConstructorEnv)
registerConstructor String
typeName [String]
typeParams Type
adtType)
(TypeEnv
typeEnv, ConstructorEnv
ctorEnv)
[InductiveConstructor]
constructors
EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result { ebrTypeEnv = typeEnv', ebrConstructorEnv = ctorEnv' }
ClassDeclExpr (ClassDecl String
className [String
typeParam] [ConstraintExpr]
superClasses [ClassMethod]
methods) -> do
let classEnv :: ClassEnv
classEnv = EnvBuildResult -> ClassEnv
ebrClassEnv EnvBuildResult
result
typeEnv :: TypeEnv
typeEnv = EnvBuildResult -> TypeEnv
ebrTypeEnv EnvBuildResult
result
tyVar :: TyVar
tyVar = String -> TyVar
TyVar String
typeParam
superNames :: [String]
superNames = (ConstraintExpr -> String) -> [ConstraintExpr] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ConstraintExpr -> String
extractConstraintName [ConstraintExpr]
superClasses
methodsWithTypes :: [(String, Type)]
methodsWithTypes = (ClassMethod -> (String, Type))
-> [ClassMethod] -> [(String, Type)]
forall a b. (a -> b) -> [a] -> [b]
map ClassMethod -> (String, Type)
extractMethodWithType [ClassMethod]
methods
classInfo :: ClassInfo
classInfo = Types.ClassInfo
{ classSupers :: [String]
Types.classSupers = [String]
superNames
, classParam :: TyVar
Types.classParam = TyVar
tyVar
, classMethods :: [(String, Type)]
Types.classMethods = [(String, Type)]
methodsWithTypes
}
classEnv' :: ClassEnv
classEnv' = String -> ClassInfo -> ClassEnv -> ClassEnv
addClass String
className ClassInfo
classInfo ClassEnv
classEnv
typeEnv' :: TypeEnv
typeEnv' = (TypeEnv -> ClassMethod -> TypeEnv)
-> TypeEnv -> [ClassMethod] -> TypeEnv
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (TyVar -> String -> TypeEnv -> ClassMethod -> TypeEnv
registerClassMethod TyVar
tyVar String
className) TypeEnv
typeEnv [ClassMethod]
methods
EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result { ebrClassEnv = classEnv', ebrTypeEnv = typeEnv' }
ClassDeclExpr ClassDecl
_ ->
EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result
InstanceDeclExpr (InstanceDecl [ConstraintExpr]
context String
className [TypeExpr]
instTypes [InstanceMethod]
methods) -> do
let classEnv :: ClassEnv
classEnv = EnvBuildResult -> ClassEnv
ebrClassEnv EnvBuildResult
result
typeEnv :: TypeEnv
typeEnv = EnvBuildResult -> TypeEnv
ebrTypeEnv EnvBuildResult
result
mainInstType :: Type
mainInstType = case [TypeExpr]
instTypes of
[] -> Type
TAny
(TypeExpr
t:[TypeExpr]
_) -> TypeExpr -> Type
typeExprToType TypeExpr
t
instInfo :: InstanceInfo
instInfo = Types.InstanceInfo
{ instContext :: [Constraint]
Types.instContext = (ConstraintExpr -> Constraint) -> [ConstraintExpr] -> [Constraint]
forall a b. (a -> b) -> [a] -> [b]
map ConstraintExpr -> Constraint
constraintToInternal [ConstraintExpr]
context
, instClass :: String
Types.instClass = String
className
, instType :: Type
Types.instType = Type
mainInstType
, instMethods :: [(String, ())]
Types.instMethods = []
}
classEnv' :: ClassEnv
classEnv' = String -> InstanceInfo -> ClassEnv -> ClassEnv
addInstance String
className InstanceInfo
instInfo ClassEnv
classEnv
typeEnv' :: TypeEnv
typeEnv' = String
-> Type
-> [Constraint]
-> [InstanceMethod]
-> ClassEnv
-> TypeEnv
-> TypeEnv
registerInstanceMethods String
className Type
mainInstType ((ConstraintExpr -> Constraint) -> [ConstraintExpr] -> [Constraint]
forall a b. (a -> b) -> [a] -> [b]
map ConstraintExpr -> Constraint
constraintToInternal [ConstraintExpr]
context) [InstanceMethod]
methods ClassEnv
classEnv' TypeEnv
typeEnv
EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result { ebrClassEnv = classEnv', ebrTypeEnv = typeEnv' }
DefineWithType TypedVarWithIndices
typedVar Expr
_expr -> do
let name :: String
name = TypedVarWithIndices -> String
typedVarName TypedVarWithIndices
typedVar
varIndices :: [VarIndex]
varIndices = TypedVarWithIndices -> [VarIndex]
typedVarIndices TypedVarWithIndices
typedVar
indexTypes :: [Index (Maybe Var)]
indexTypes = (VarIndex -> [Index (Maybe Var)])
-> [VarIndex] -> [Index (Maybe Var)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap VarIndex -> [Index (Maybe Var)]
transVarIndex [VarIndex]
varIndices
var :: Var
var = String -> [Index (Maybe Var)] -> Var
Var String
name ((Index (Maybe Var) -> Index (Maybe Var))
-> [Index (Maybe Var)] -> [Index (Maybe Var)]
forall a b. (a -> b) -> [a] -> [b]
map ((Maybe Var -> Maybe Var) -> Index (Maybe Var) -> Index (Maybe Var)
forall a b. (a -> b) -> Index a -> Index b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Maybe Var -> Maybe Var -> Maybe Var
forall a b. a -> b -> a
const Maybe Var
forall a. Maybe a
Nothing)) [Index (Maybe Var)]
indexTypes)
params :: [TypedParam]
params = TypedVarWithIndices -> [TypedParam]
typedVarParams TypedVarWithIndices
typedVar
retType :: Type
retType = TypeExpr -> Type
typeExprToType (TypedVarWithIndices -> TypeExpr
typedVarRetType TypedVarWithIndices
typedVar)
paramTypes :: [Type]
paramTypes = (TypedParam -> Type) -> [TypedParam] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map TypedParam -> Type
typedParamToType [TypedParam]
params
funType :: Type
funType = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Type -> Type -> Type
TFun Type
retType [Type]
paramTypes
constraints :: [Constraint]
constraints = (ConstraintExpr -> Constraint) -> [ConstraintExpr] -> [Constraint]
forall a b. (a -> b) -> [a] -> [b]
map ConstraintExpr -> Constraint
constraintToInternal (TypedVarWithIndices -> [ConstraintExpr]
typedVarConstraints TypedVarWithIndices
typedVar)
freeVars :: [TyVar]
freeVars = Set TyVar -> [TyVar]
forall a. Set a -> [a]
Set.toList (Type -> Set TyVar
freeTyVars Type
funType)
typeScheme :: TypeScheme
typeScheme = [TyVar] -> [Constraint] -> Type -> TypeScheme
Types.Forall [TyVar]
freeVars [Constraint]
constraints Type
funType
typeEnv :: TypeEnv
typeEnv = EnvBuildResult -> TypeEnv
ebrTypeEnv EnvBuildResult
result
typeEnv' :: TypeEnv
typeEnv' = Var -> TypeScheme -> TypeEnv -> TypeEnv
extendEnv Var
var TypeScheme
typeScheme TypeEnv
typeEnv
EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result { ebrTypeEnv = typeEnv' }
PatternInductiveDecl String
typeName [String]
typeParams [PatternConstructor]
constructors -> do
let typeParamVars :: [Type]
typeParamVars = (String -> Type) -> [String] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TyVar -> Type
TVar (TyVar -> Type) -> (String -> TyVar) -> String -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> TyVar
TyVar) [String]
typeParams
patternType :: Type
patternType = case (String
typeName, [String]
typeParams) of
(String
"[]", [String
param]) -> Type -> Type
TCollection (TyVar -> Type
TVar (String -> TyVar
TyVar String
param))
(String
"String", []) -> Type
TString
(String, [String])
_ -> String -> [Type] -> Type
TInductive String
typeName [Type]
typeParamVars
patternCtorEnv :: PatternConstructorEnv
patternCtorEnv = EnvBuildResult -> PatternConstructorEnv
ebrPatternConstructorEnv EnvBuildResult
result
PatternConstructorEnv
patternCtorEnv' <- (PatternConstructorEnv
-> PatternConstructor
-> StateT
EvalState (ExceptT EgisonError RuntimeM) PatternConstructorEnv)
-> PatternConstructorEnv
-> [PatternConstructor]
-> StateT
EvalState (ExceptT EgisonError RuntimeM) PatternConstructorEnv
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (String
-> [String]
-> Type
-> PatternConstructorEnv
-> PatternConstructor
-> StateT
EvalState (ExceptT EgisonError RuntimeM) PatternConstructorEnv
registerPatternConstructor String
typeName [String]
typeParams Type
patternType)
PatternConstructorEnv
patternCtorEnv
[PatternConstructor]
constructors
EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result { ebrPatternConstructorEnv = patternCtorEnv' }
PatternFunctionDecl String
name [String]
typeParams [(String, TypeExpr)]
params TypeExpr
retType Pattern
_body -> do
let paramTypes :: [Type]
paramTypes = ((String, TypeExpr) -> Type) -> [(String, TypeExpr)] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (TypeExpr -> Type
typeExprToType (TypeExpr -> Type)
-> ((String, TypeExpr) -> TypeExpr) -> (String, TypeExpr) -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, TypeExpr) -> TypeExpr
forall a b. (a, b) -> b
snd) [(String, TypeExpr)]
params
retType' :: Type
retType' = TypeExpr -> Type
typeExprToType TypeExpr
retType
patternFuncType :: Type
patternFuncType = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Type -> Type -> Type
TFun Type
retType' [Type]
paramTypes
tyVars :: [TyVar]
tyVars = (String -> TyVar) -> [String] -> [TyVar]
forall a b. (a -> b) -> [a] -> [b]
map String -> TyVar
TyVar [String]
typeParams
typeScheme :: TypeScheme
typeScheme = [TyVar] -> [Constraint] -> Type -> TypeScheme
Types.Forall [TyVar]
tyVars [] Type
patternFuncType
patternEnv :: PatternConstructorEnv
patternEnv = EnvBuildResult -> PatternConstructorEnv
ebrPatternTypeEnv EnvBuildResult
result
patternEnv' :: PatternConstructorEnv
patternEnv' = String
-> TypeScheme -> PatternConstructorEnv -> PatternConstructorEnv
extendPatternEnv String
name TypeScheme
typeScheme PatternConstructorEnv
patternEnv
EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result { ebrPatternTypeEnv = patternEnv' }
Define {} -> EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result
DefineWithType {} -> EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result
Test {} -> EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result
Execute {} -> EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result
LoadFile {} -> EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result
InfixDecl {} -> EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result
DeclareSymbol [String]
names Maybe TypeExpr
mTypeExpr -> do
let ty :: Type
ty = case Maybe TypeExpr
mTypeExpr of
Just TypeExpr
texpr -> TypeExpr -> Type
typeExprToType TypeExpr
texpr
Maybe TypeExpr
Nothing -> Type
TInt
scheme :: TypeScheme
scheme = [TyVar] -> [Constraint] -> Type -> TypeScheme
Forall [] [] Type
ty
typeEnv :: TypeEnv
typeEnv = EnvBuildResult -> TypeEnv
ebrTypeEnv EnvBuildResult
result
typeEnv' :: TypeEnv
typeEnv' = (String -> TypeEnv -> TypeEnv) -> TypeEnv -> [String] -> TypeEnv
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\String
name TypeEnv
env -> Var -> TypeScheme -> TypeEnv -> TypeEnv
extendEnv (String -> Var
stringToVar String
name) TypeScheme
scheme TypeEnv
env) TypeEnv
typeEnv [String]
names
EnvBuildResult -> EvalM EnvBuildResult
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return EnvBuildResult
result { ebrTypeEnv = typeEnv' }
registerConstructor :: String -> [String] -> Type
-> (TypeEnv, ConstructorEnv) -> InductiveConstructor
-> EvalM (TypeEnv, ConstructorEnv)
registerConstructor :: String
-> [String]
-> Type
-> (TypeEnv, ConstructorEnv)
-> InductiveConstructor
-> StateT
EvalState (ExceptT EgisonError RuntimeM) (TypeEnv, ConstructorEnv)
registerConstructor String
typeName [String]
typeParams Type
resultType (TypeEnv
typeEnv, ConstructorEnv
ctorEnv)
(InductiveConstructor String
ctorName [TypeExpr]
argTypeExprs) = do
let argTypes :: [Type]
argTypes = (TypeExpr -> Type) -> [TypeExpr] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map TypeExpr -> Type
typeExprToType [TypeExpr]
argTypeExprs
constructorType :: Type
constructorType = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Type -> Type -> Type
TFun Type
resultType [Type]
argTypes
tyVars :: [TyVar]
tyVars = (String -> TyVar) -> [String] -> [TyVar]
forall a b. (a -> b) -> [a] -> [b]
map String -> TyVar
TyVar [String]
typeParams
typeScheme :: TypeScheme
typeScheme = [TyVar] -> [Constraint] -> Type -> TypeScheme
Types.Forall [TyVar]
tyVars [] Type
constructorType
typeEnv' :: TypeEnv
typeEnv' = Var -> TypeScheme -> TypeEnv -> TypeEnv
extendEnv (String -> Var
stringToVar String
ctorName) TypeScheme
typeScheme TypeEnv
typeEnv
ctorInfo :: ConstructorInfo
ctorInfo = ConstructorInfo
{ ctorTypeName :: String
ctorTypeName = String
typeName
, ctorArgTypes :: [Type]
ctorArgTypes = [Type]
argTypes
, ctorTypeParams :: [String]
ctorTypeParams = [String]
typeParams
}
ctorEnv' :: ConstructorEnv
ctorEnv' = String -> ConstructorInfo -> ConstructorEnv -> ConstructorEnv
forall k v. Hashable k => k -> v -> HashMap k v -> HashMap k v
HashMap.insert String
ctorName ConstructorInfo
ctorInfo ConstructorEnv
ctorEnv
(TypeEnv, ConstructorEnv)
-> StateT
EvalState (ExceptT EgisonError RuntimeM) (TypeEnv, ConstructorEnv)
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return (TypeEnv
typeEnv', ConstructorEnv
ctorEnv')
registerClassMethod :: TyVar -> String -> TypeEnv -> ClassMethod -> TypeEnv
registerClassMethod :: TyVar -> String -> TypeEnv -> ClassMethod -> TypeEnv
registerClassMethod TyVar
tyVar String
className TypeEnv
typeEnv (ClassMethod String
methName [TypedParam]
params TypeExpr
retType Maybe Expr
_defaultImpl) =
let paramTypes :: [Type]
paramTypes = (TypedParam -> Type) -> [TypedParam] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map TypedParam -> Type
typedParamToType [TypedParam]
params
methodType :: Type
methodType = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Type -> Type -> Type
TFun (TypeExpr -> Type
typeExprToType TypeExpr
retType) [Type]
paramTypes
constraint :: Constraint
constraint = String -> Type -> Constraint
Types.Constraint String
className (TyVar -> Type
TVar TyVar
tyVar)
typeScheme :: TypeScheme
typeScheme = [TyVar] -> [Constraint] -> Type -> TypeScheme
Types.Forall [TyVar
tyVar] [Constraint
constraint] Type
methodType
in
Var -> TypeScheme -> TypeEnv -> TypeEnv
extendEnv (String -> Var
stringToVar String
methName) TypeScheme
typeScheme TypeEnv
typeEnv
registerInstanceMethods :: String -> Type -> [Constraint] -> [InstanceMethod] -> ClassEnv -> TypeEnv -> TypeEnv
registerInstanceMethods :: String
-> Type
-> [Constraint]
-> [InstanceMethod]
-> ClassEnv
-> TypeEnv
-> TypeEnv
registerInstanceMethods String
className Type
instType [Constraint]
instConstraints [InstanceMethod]
methods ClassEnv
classEnv TypeEnv
typeEnv =
case String -> ClassEnv -> Maybe ClassInfo
lookupClass String
className ClassEnv
classEnv of
Maybe ClassInfo
Nothing -> TypeEnv
typeEnv
Just ClassInfo
classInfo ->
let typeEnv' :: TypeEnv
typeEnv' = (InstanceMethod -> TypeEnv -> TypeEnv)
-> TypeEnv -> [InstanceMethod] -> TypeEnv
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (String
-> Type
-> [Constraint]
-> ClassInfo
-> InstanceMethod
-> TypeEnv
-> TypeEnv
registerInstanceMethod String
className Type
instType [Constraint]
instConstraints ClassInfo
classInfo) TypeEnv
typeEnv [InstanceMethod]
methods
typeName' :: String
typeName' = Type -> String
Types.typeConstructorName Type
instType
dictName :: String
dictName = ShowS
lowerFirst String
className String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
typeName'
dictValueType :: Type
dictValueType = case [InstanceMethod]
methods of
[] -> Type
TAny
[InstanceMethod]
_ -> case String -> [(String, Type)] -> Maybe Type
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (InstanceMethod -> String
instanceMethodName ([InstanceMethod] -> InstanceMethod
forall a. HasCallStack => [a] -> a
head [InstanceMethod]
methods)) (ClassInfo -> [(String, Type)]
Types.classMethods ClassInfo
classInfo) of
Maybe Type
Nothing -> Type
TAny
Just Type
methodType ->
let tyVar :: TyVar
tyVar = ClassInfo -> TyVar
Types.classParam ClassInfo
classInfo
substitutedType :: Type
substitutedType = TyVar -> Type -> Type -> Type
substituteTypeVar TyVar
tyVar Type
instType Type
methodType
in Type
substitutedType
dictType :: Type
dictType = Type -> Type -> Type
THash Type
TString Type
dictValueType
freeVars :: [TyVar]
freeVars = Set TyVar -> [TyVar]
forall a. Set a -> [a]
Set.toList (Type -> Set TyVar
freeTyVars Type
dictType)
dictScheme :: TypeScheme
dictScheme = [TyVar] -> [Constraint] -> Type -> TypeScheme
Types.Forall [TyVar]
freeVars [Constraint]
instConstraints Type
dictType
in
Var -> TypeScheme -> TypeEnv -> TypeEnv
extendEnv (String -> Var
stringToVar String
dictName) TypeScheme
dictScheme TypeEnv
typeEnv'
where
instanceMethodName :: InstanceMethod -> String
instanceMethodName :: InstanceMethod -> String
instanceMethodName (InstanceMethod String
name [String]
_ Expr
_) = String
name
registerInstanceMethod :: String -> Type -> [Constraint] -> Types.ClassInfo -> InstanceMethod -> TypeEnv -> TypeEnv
registerInstanceMethod :: String
-> Type
-> [Constraint]
-> ClassInfo
-> InstanceMethod
-> TypeEnv
-> TypeEnv
registerInstanceMethod String
clsName Type
instTy [Constraint]
constraints ClassInfo
classInfo (InstanceMethod String
methName [String]
_params Expr
_body) TypeEnv
env =
case String -> [(String, Type)] -> Maybe Type
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
methName (ClassInfo -> [(String, Type)]
Types.classMethods ClassInfo
classInfo) of
Maybe Type
Nothing -> TypeEnv
env
Just Type
methodType ->
let tyVar :: TyVar
tyVar = ClassInfo -> TyVar
Types.classParam ClassInfo
classInfo
substitutedType :: Type
substitutedType = TyVar -> Type -> Type -> Type
substituteTypeVar TyVar
tyVar Type
instTy Type
methodType
typeName' :: String
typeName' = Type -> String
Types.typeConstructorName Type
instTy
sanitizedName :: String
sanitizedName = ShowS
sanitizeMethodName String
methName
generatedMethodName :: String
generatedMethodName = ShowS
lowerFirst String
clsName String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
typeName' String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
capitalizeFirst String
sanitizedName
freeVars :: [TyVar]
freeVars = Set TyVar -> [TyVar]
forall a. Set a -> [a]
Set.toList (Type -> Set TyVar
freeTyVars Type
substitutedType)
typeScheme :: TypeScheme
typeScheme = [TyVar] -> [Constraint] -> Type -> TypeScheme
Types.Forall [TyVar]
freeVars [Constraint]
constraints Type
substitutedType
in
Var -> TypeScheme -> TypeEnv -> TypeEnv
extendEnv (String -> Var
stringToVar String
generatedMethodName) TypeScheme
typeScheme TypeEnv
env
substituteTypeVar :: TyVar -> Type -> Type -> Type
substituteTypeVar :: TyVar -> Type -> Type -> Type
substituteTypeVar TyVar
oldVar Type
newType = Type -> Type
go
where
go :: Type -> Type
go Type
TInt = Type
TInt
go Type
TFloat = Type
TFloat
go Type
TBool = Type
TBool
go Type
TChar = Type
TChar
go Type
TString = Type
TString
go (TVar TyVar
v) | TyVar
v TyVar -> TyVar -> Bool
forall a. Eq a => a -> a -> Bool
== TyVar
oldVar = Type
newType
| Bool
otherwise = TyVar -> Type
TVar TyVar
v
go (TTuple [Type]
ts) = [Type] -> Type
TTuple ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
go [Type]
ts)
go (TCollection Type
t) = Type -> Type
TCollection (Type -> Type
go Type
t)
go (TInductive String
name [Type]
ts) = String -> [Type] -> Type
TInductive String
name ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
go [Type]
ts)
go (TTensor Type
t) = Type -> Type
TTensor (Type -> Type
go Type
t)
go (THash Type
k Type
v) = Type -> Type -> Type
THash (Type -> Type
go Type
k) (Type -> Type
go Type
v)
go (TMatcher Type
t) = Type -> Type
TMatcher (Type -> Type
go Type
t)
go (TFun Type
t1 Type
t2) = Type -> Type -> Type
TFun (Type -> Type
go Type
t1) (Type -> Type
go Type
t2)
go (TIO Type
t) = Type -> Type
TIO (Type -> Type
go Type
t)
go (TIORef Type
t) = Type -> Type
TIORef (Type -> Type
go Type
t)
go Type
TAny = Type
TAny
extractMethodName :: ClassMethod -> String
(ClassMethod String
name [TypedParam]
_ TypeExpr
_ Maybe Expr
_) = String
name
extractMethodWithType :: ClassMethod -> (String, Type)
(ClassMethod String
name [TypedParam]
params TypeExpr
retType Maybe Expr
_) =
let paramTypes :: [Type]
paramTypes = (TypedParam -> Type) -> [TypedParam] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map TypedParam -> Type
typedParamToType [TypedParam]
params
methodType :: Type
methodType = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Type -> Type -> Type
TFun (TypeExpr -> Type
typeExprToType TypeExpr
retType) [Type]
paramTypes
in (String
name, Type
methodType)
extractConstraintName :: ConstraintExpr -> String
(ConstraintExpr String
clsName [TypeExpr]
_) = String
clsName
constraintToInternal :: ConstraintExpr -> Types.Constraint
constraintToInternal :: ConstraintExpr -> Constraint
constraintToInternal (ConstraintExpr String
clsName [TypeExpr]
tyExprs) =
String -> Type -> Constraint
Types.Constraint String
clsName (case [TypeExpr]
tyExprs of
[] -> Type
TAny
(TypeExpr
t:[TypeExpr]
_) -> TypeExpr -> Type
typeExprToType TypeExpr
t)
registerPatternConstructor :: String -> [String] -> Type
-> PatternConstructorEnv -> PatternConstructor
-> EvalM PatternConstructorEnv
registerPatternConstructor :: String
-> [String]
-> Type
-> PatternConstructorEnv
-> PatternConstructor
-> StateT
EvalState (ExceptT EgisonError RuntimeM) PatternConstructorEnv
registerPatternConstructor String
_typeName [String]
typeParams Type
resultType PatternConstructorEnv
patternCtorEnv
(PatternConstructor String
ctorName [TypeExpr]
argTypeExprs) = do
let argTypes :: [Type]
argTypes = (TypeExpr -> Type) -> [TypeExpr] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map TypeExpr -> Type
typeExprToType [TypeExpr]
argTypeExprs
patternCtorType :: Type
patternCtorType = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Type -> Type -> Type
TFun Type
resultType [Type]
argTypes
tyVars :: [TyVar]
tyVars = (String -> TyVar) -> [String] -> [TyVar]
forall a b. (a -> b) -> [a] -> [b]
map String -> TyVar
TyVar [String]
typeParams
typeScheme :: TypeScheme
typeScheme = [TyVar] -> [Constraint] -> Type -> TypeScheme
Types.Forall [TyVar]
tyVars [] Type
patternCtorType
patternCtorEnv' :: PatternConstructorEnv
patternCtorEnv' = String
-> TypeScheme -> PatternConstructorEnv -> PatternConstructorEnv
extendPatternEnv String
ctorName TypeScheme
typeScheme PatternConstructorEnv
patternCtorEnv
PatternConstructorEnv
-> StateT
EvalState (ExceptT EgisonError RuntimeM) PatternConstructorEnv
forall a. a -> StateT EvalState (ExceptT EgisonError RuntimeM) a
forall (m :: * -> *) a. Monad m => a -> m a
return PatternConstructorEnv
patternCtorEnv'
typedParamToType :: TypedParam -> Type
typedParamToType :: TypedParam -> Type
typedParamToType (TPVar String
_ TypeExpr
ty) = TypeExpr -> Type
typeExprToType TypeExpr
ty
typedParamToType (TPInvertedVar String
_ TypeExpr
ty) = TypeExpr -> Type
typeExprToType TypeExpr
ty
typedParamToType (TPTuple [TypedParam]
elems) = [Type] -> Type
TTuple ((TypedParam -> Type) -> [TypedParam] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map TypedParam -> Type
typedParamToType [TypedParam]
elems)
typedParamToType (TPWildcard TypeExpr
ty) = TypeExpr -> Type
typeExprToType TypeExpr
ty
typedParamToType (TPUntypedVar String
_) = TyVar -> Type
TVar (String -> TyVar
TyVar String
"a")
typedParamToType TypedParam
TPUntypedWildcard = TyVar -> Type
TVar (String -> TyVar
TyVar String
"a")