language-ocaml-0.1.31: lib/Language/OCaml/Definitions/Parsing/ASTHelper/Typ.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE RecordWildCards #-}
module Language.OCaml.Definitions.Parsing.ASTHelper.Typ
( MkOpts(..)
, mk
, varifyConstructors
) where
import Control.Eff
import Control.Eff.Exception
import Data.Default
import Language.OCaml.Definitions.Parsing.ASTHelper.Common
import Language.OCaml.Definitions.Parsing.ASTTypes
import Language.OCaml.Definitions.Parsing.Location
import Language.OCaml.Definitions.Parsing.ParseTree
import Language.OCaml.Utils
mk :: MkOpts -> CoreTypeDesc -> CoreType
mk (MkOpts {..}) desc =
CoreType
{ ptypDesc = desc
, ptypLoc = loc
, ptypAttributes = attrs
}
data MkOpts = MkOpts
{ loc :: Location
, attrs :: [Attribute]
}
instance Default MkOpts where
def = MkOpts
{ loc = defaultLoc
, attrs = []
}
varifyConstructors ::
(Member (Exc String) r) =>
[Loc String] -> CoreType -> Eff r CoreType
varifyConstructors varNames0 = loop
where
checkVariable :: (Member (Exc String) r) => [String] -> Location -> String -> Eff r ()
checkVariable vl pos v =
if v `elem` vl
then throwError $ "Variable in scope " ++ show v ++ " at " ++ show pos
else return ()
loopRowField :: (Member (Exc String) r) => RowField -> Eff r RowField
loopRowField = \case
Rtag label attrs flag lst -> Rtag label attrs flag <$> traverse loop lst
Rinherit t -> Rinherit <$> loop t
loopObjectField :: (Member (Exc String) r) => ObjectField -> Eff r ObjectField
loopObjectField = \case
Otag label attrs t -> Otag label attrs <$> loop t
Oinherit t -> Oinherit <$> loop t
varNames = map (\ v -> txt v) varNames0
loop:: (Member (Exc String) r) => CoreType -> Eff r CoreType
loop t = do
desc <- case ptypDesc t of
PtypAny -> return PtypAny
PtypVar x -> do
checkVariable varNames (ptypLoc t) x
return $ PtypVar x
PtypArrow label coreType coreType' -> PtypArrow label <$> loop coreType <*> loop coreType'
PtypTuple lst -> PtypTuple <$> traverse loop lst
PtypConstr (Loc { txt = Lident s }) [] | s `elem` varNames -> return $ PtypVar s
PtypConstr longident lst -> PtypConstr longident <$> traverse loop lst
PtypObject lst o -> PtypObject <$> traverse loopObjectField lst <*^> o
PtypClass longident lst -> PtypClass longident <$> traverse loop lst
PtypAlias coreType string -> do
checkVariable varNames (ptypLoc t) string
PtypAlias <$> loop coreType <*^> string
PtypVariant rowFieldList flag lblLstOption ->
PtypVariant <$> traverse loopRowField rowFieldList <*^> flag <*^> lblLstOption
PtypPoly _stringLst _coreType -> error "TODO"
PtypPackage (_longident, _lst) -> error "TODO"
PtypExtension (s, arg) -> return $ PtypExtension (s, arg)
return $ t { ptypDesc = desc }