packages feed

ddc-core 0.2.1.2 → 0.3.1.1

raw patch · 81 files changed

+8778/−4705 lines, 81 filesdep +deepseqdep +directorydep ~ddc-basePVP ok

version bump matches the API change (PVP)

Dependencies added: deepseq, directory

Dependency ranges changed: ddc-base

API changes (from Hackage documentation)

- DDC.Core.Check: ErrorCaseDiscrimNotAlgebraic :: Exp a n -> Type n -> Error a n
- DDC.Core.Check: ErrorCaseDiscrimTypeMismatch :: Exp a n -> Type n -> Type n -> Error a n
- DDC.Core.Check: ErrorCaseDiscrimTypeUndeclared :: Exp a n -> Type n -> Error a n
- DDC.Core.Check: ErrorLetRegionNotRegion :: Exp a n -> Bind n -> Kind n -> Error a n
- DDC.Core.Check: ErrorLetRegionRebound :: Exp a n -> Bind n -> Error a n
- DDC.Core.Check: ErrorLetRegionWitnessOther :: Exp a n -> Bound n -> Bind n -> Error a n
- DDC.Core.Check: ErrorMaxcloMalformed :: Exp a n -> Closure n -> Error a n
- DDC.Core.Check: ErrorMaxcloNotClo :: Exp a n -> Closure n -> Kind n -> Error a n
- DDC.Core.Check: ErrorMaxeffNotEff :: Exp a n -> Effect n -> Kind n -> Error a n
- DDC.Core.Check: errorBoundRegion :: Error a n -> Bound n
- DDC.Core.Check: errorCtorBound :: Error a n -> Bound n
- DDC.Core.Check: errorTypeDiscrim :: Error a n -> Type n
- DDC.Core.Check.CheckExp: GBoundRgnCon :: (Bound n) -> TaggedClosure n
- DDC.Core.Check.CheckExp: GBoundRgnVar :: (Bound n) -> TaggedClosure n
- DDC.Core.Check.CheckExp: GBoundVal :: (Bound n) -> (TypeSum n) -> TaggedClosure n
- DDC.Core.Check.CheckExp: checkExp :: (Ord n, Pretty n) => DataDefs n -> Env n -> Env n -> Exp a n -> Either (Error a n) (Exp a n, Type n, Effect n, Closure n)
- DDC.Core.Check.CheckExp: checkExpM :: (Ord n, Pretty n) => DataDefs n -> Env n -> Env n -> Exp a n -> CheckM a n (Exp a n, Type n, TypeSum n, Set (TaggedClosure n))
- DDC.Core.Check.CheckExp: data TaggedClosure n
- DDC.Core.Check.CheckExp: type CheckM a n = CheckM (Error a n)
- DDC.Core.Check.CheckExp: typeOfExp :: (Ord n, Pretty n) => DataDefs n -> Exp a n -> Either (Error a n) (Type n)
- DDC.Core.Check.CheckWitness: checkWitness :: (Ord n, Pretty n) => DataDefs n -> Env n -> Env n -> Witness n -> Either (Error a n) (Type n)
- DDC.Core.Check.CheckWitness: checkWitnessM :: (Ord n, Pretty n) => DataDefs n -> Env n -> Env n -> Witness n -> CheckM a n (Type n)
- DDC.Core.Check.CheckWitness: type CheckM a n = CheckM (Error a n)
- DDC.Core.Check.CheckWitness: typeOfWbCon :: WbCon -> Type n
- DDC.Core.Check.CheckWitness: typeOfWiCon :: WiCon n -> Type n
- DDC.Core.Check.CheckWitness: typeOfWitness :: (Ord n, Pretty n) => DataDefs n -> Witness n -> Either (Error a n) (Type n)
- DDC.Core.Check.Error: ErrorAppMismatch :: Exp a n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorAppNotFun :: Exp a n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorCannotJoin :: Witness n -> Witness n -> Type n -> Witness n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorCaseAltResultMismatch :: Exp a n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorCaseCannotInstantiate :: Exp a n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorCaseDiscrimNotAlgebraic :: Exp a n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorCaseDiscrimTypeMismatch :: Exp a n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorCaseDiscrimTypeUndeclared :: Exp a n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorCaseFieldTypeMismatch :: Exp a n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorCaseNoAlternatives :: Exp a n -> Error a n
- DDC.Core.Check.Error: ErrorCaseNonExhaustive :: Exp a n -> [n] -> Error a n
- DDC.Core.Check.Error: ErrorCaseNonExhaustiveLarge :: Exp a n -> Error a n
- DDC.Core.Check.Error: ErrorCaseOverlapping :: Exp a n -> Error a n
- DDC.Core.Check.Error: ErrorCaseTooManyBinders :: Exp a n -> Bound n -> Int -> Int -> Error a n
- DDC.Core.Check.Error: ErrorLamBindNotData :: Exp a n -> Type n -> Kind n -> Error a n
- DDC.Core.Check.Error: ErrorLamBodyNotData :: Exp a n -> Bind n -> Type n -> Kind n -> Error a n
- DDC.Core.Check.Error: ErrorLamNotPure :: Exp a n -> Effect n -> Error a n
- DDC.Core.Check.Error: ErrorLamShadow :: Exp a n -> Bind n -> Error a n
- DDC.Core.Check.Error: ErrorLetBindingNotData :: Exp a n -> Bind n -> Kind n -> Error a n
- DDC.Core.Check.Error: ErrorLetBodyNotData :: Exp a n -> Type n -> Kind n -> Error a n
- DDC.Core.Check.Error: ErrorLetLazyNoWitness :: Exp a n -> Bind n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorLetLazyNotEmpty :: Exp a n -> Bind n -> Closure n -> Error a n
- DDC.Core.Check.Error: ErrorLetLazyNotPure :: Exp a n -> Bind n -> Effect n -> Error a n
- DDC.Core.Check.Error: ErrorLetLazyWitnessTypeMismatch :: Exp a n -> Bind n -> Type n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorLetMismatch :: Exp a n -> Bind n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorLetRegionFree :: Exp a n -> Bind n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorLetRegionNotRegion :: Exp a n -> Bind n -> Kind n -> Error a n
- DDC.Core.Check.Error: ErrorLetRegionRebound :: Exp a n -> Bind n -> Error a n
- DDC.Core.Check.Error: ErrorLetRegionWitnessConflict :: Exp a n -> Bind n -> Bind n -> Error a n
- DDC.Core.Check.Error: ErrorLetRegionWitnessInvalid :: Exp a n -> Bind n -> Error a n
- DDC.Core.Check.Error: ErrorLetRegionWitnessOther :: Exp a n -> Bound n -> Bind n -> Error a n
- DDC.Core.Check.Error: ErrorLetrecBindingNotLambda :: Exp a n -> Exp a n -> Error a n
- DDC.Core.Check.Error: ErrorMalformedExp :: Exp a n -> Error a n
- DDC.Core.Check.Error: ErrorMalformedType :: Exp a n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorMaxcloMalformed :: Exp a n -> Closure n -> Error a n
- DDC.Core.Check.Error: ErrorMaxcloNotClo :: Exp a n -> Closure n -> Kind n -> Error a n
- DDC.Core.Check.Error: ErrorMaxeffNotEff :: Exp a n -> Effect n -> Kind n -> Error a n
- DDC.Core.Check.Error: ErrorNakedType :: Exp a n -> Error a n
- DDC.Core.Check.Error: ErrorNakedWitness :: Exp a n -> Error a n
- DDC.Core.Check.Error: ErrorType :: Error n -> Error a n
- DDC.Core.Check.Error: ErrorUndefinedCtor :: Exp a n -> Error a n
- DDC.Core.Check.Error: ErrorVarAnnotMismatch :: Bound n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorWAppMismatch :: Witness n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorWAppNotCtor :: Witness n -> Type n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorWithRegionNotRegion :: Exp a n -> Bound n -> Kind n -> Error a n
- DDC.Core.Check.Error: ErrorWitnessNotEmpty :: Exp a n -> Witness n -> Type n -> Error a n
- DDC.Core.Check.Error: ErrorWitnessNotPurity :: Exp a n -> Witness n -> Type n -> Error a n
- DDC.Core.Check.Error: data Error a n
- DDC.Core.Check.Error: errorAltType1 :: Error a n -> Type n
- DDC.Core.Check.Error: errorAltType2 :: Error a n -> Type n
- DDC.Core.Check.Error: errorArgType :: Error a n -> Type n
- DDC.Core.Check.Error: errorBind :: Error a n -> Bind n
- DDC.Core.Check.Error: errorBindType :: Error a n -> Type n
- DDC.Core.Check.Error: errorBindWitness :: Error a n -> Bind n
- DDC.Core.Check.Error: errorBindWitness1 :: Error a n -> Bind n
- DDC.Core.Check.Error: errorBindWitness2 :: Error a n -> Bind n
- DDC.Core.Check.Error: errorBound :: Error a n -> Bound n
- DDC.Core.Check.Error: errorBoundRegion :: Error a n -> Bound n
- DDC.Core.Check.Error: errorChecking :: Error a n -> Exp a n
- DDC.Core.Check.Error: errorClosure :: Error a n -> Closure n
- DDC.Core.Check.Error: errorCtorBound :: Error a n -> Bound n
- DDC.Core.Check.Error: errorCtorFields :: Error a n -> Int
- DDC.Core.Check.Error: errorCtorNamesMissing :: Error a n -> [n]
- DDC.Core.Check.Error: errorEffect :: Error a n -> Effect n
- DDC.Core.Check.Error: errorExp :: Error a n -> Exp a n
- DDC.Core.Check.Error: errorKind :: Error a n -> Kind n
- DDC.Core.Check.Error: errorNotFunType :: Error a n -> Type n
- DDC.Core.Check.Error: errorParamType :: Error a n -> Type n
- DDC.Core.Check.Error: errorPatternFields :: Error a n -> Int
- DDC.Core.Check.Error: errorType :: Error a n -> Type n
- DDC.Core.Check.Error: errorTypeAnnot :: Error a n -> Type n
- DDC.Core.Check.Error: errorTypeCtor :: Error a n -> Type n
- DDC.Core.Check.Error: errorTypeDiscrim :: Error a n -> Type n
- DDC.Core.Check.Error: errorTypeEnv :: Error a n -> Type n
- DDC.Core.Check.Error: errorTypeError :: Error a n -> Error n
- DDC.Core.Check.Error: errorTypeField :: Error a n -> Type n
- DDC.Core.Check.Error: errorTypeLeft :: Error a n -> Type n
- DDC.Core.Check.Error: errorTypePattern :: Error a n -> Type n
- DDC.Core.Check.Error: errorTypeRight :: Error a n -> Type n
- DDC.Core.Check.Error: errorWitness :: Error a n -> Witness n
- DDC.Core.Check.Error: errorWitnessLeft :: Error a n -> Witness n
- DDC.Core.Check.Error: errorWitnessRight :: Error a n -> Witness n
- DDC.Core.Check.Error: errorWitnessTypeExpect :: Error a n -> Type n
- DDC.Core.Check.Error: errorWitnessTypeHave :: Error a n -> Type n
- DDC.Core.Check.Error: instance (Show a, Show n) => Show (Error a n)
- DDC.Core.Check.TaggedClosure: GBoundRgnCon :: (Bound n) -> TaggedClosure n
- DDC.Core.Check.TaggedClosure: GBoundRgnVar :: (Bound n) -> TaggedClosure n
- DDC.Core.Check.TaggedClosure: GBoundVal :: (Bound n) -> (TypeSum n) -> TaggedClosure n
- DDC.Core.Check.TaggedClosure: closureOfTagged :: TaggedClosure n -> Closure n
- DDC.Core.Check.TaggedClosure: closureOfTaggedSet :: Ord n => Set (TaggedClosure n) -> Closure n
- DDC.Core.Check.TaggedClosure: cutTaggedClosureT :: (Eq n, Ord n) => Bind n -> TaggedClosure n -> Maybe (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: cutTaggedClosureX :: (Eq n, Ord n) => Bind n -> TaggedClosure n -> Maybe (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: cutTaggedClosureXs :: (Eq n, Ord n) => [Bind n] -> TaggedClosure n -> Maybe (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: data TaggedClosure n
- DDC.Core.Check.TaggedClosure: instance (Eq n, Pretty n) => Pretty (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: instance Eq n => Eq (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: instance LowerT TaggedClosure
- DDC.Core.Check.TaggedClosure: instance Ord n => Ord (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: instance Show n => Show (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: maskFromTaggedSet :: Ord n => TypeSum n -> Set (TaggedClosure n) -> Set (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: taggedClosureOfTyArg :: (Ord n, Pretty n) => Type n -> Set (TaggedClosure n)
- DDC.Core.Check.TaggedClosure: taggedClosureOfValBound :: (Ord n, Pretty n) => Bound n -> TaggedClosure n
- DDC.Core.Check.TaggedClosure: taggedClosureOfWeakClo :: (Ord n, Pretty n) => Closure n -> Maybe (Set (TaggedClosure n))
- DDC.Core.Collect: collectSpecBinds :: (BindStruct c, Ord n) => c n -> [Bind n]
- DDC.Core.Collect: instance BindStruct (Alt a)
- DDC.Core.Collect: instance BindStruct (Exp a)
- DDC.Core.Collect: instance BindStruct Cast
- DDC.Core.Collect: instance BindStruct LetMode
- DDC.Core.Collect: instance BindStruct TyCon
- DDC.Core.Collect: instance BindStruct Type
- DDC.Core.Collect: instance BindStruct Witness
- DDC.Core.Collect: instance Eq BindWay
- DDC.Core.Collect: instance Eq BoundLevel
- DDC.Core.Collect: instance Eq n => Eq (BindTree n)
- DDC.Core.Collect: instance Show BindWay
- DDC.Core.Collect: instance Show BoundLevel
- DDC.Core.Collect: instance Show n => Show (BindTree n)
- DDC.Core.Compounds: makeXApps :: a -> Exp a n -> [Exp a n] -> Exp a n
- DDC.Core.Compounds: makeXLAMs :: a -> [Bind n] -> Exp a n -> Exp a n
- DDC.Core.Compounds: makeXLams :: a -> [Bind n] -> Exp a n -> Exp a n
- DDC.Core.DataDef: DataCtor :: n -> [Type n] -> n -> DataCtor n
- DDC.Core.DataDef: DataDef :: n -> [Kind n] -> Maybe [(n, [Type n])] -> DataDef n
- DDC.Core.DataDef: DataDefs :: Map n (DataType n) -> Map n (DataCtor n) -> DataDefs n
- DDC.Core.DataDef: DataModeLarge :: DataMode n
- DDC.Core.DataDef: DataModeSmall :: [n] -> DataMode n
- DDC.Core.DataDef: DataType :: n -> [Kind n] -> DataMode n -> DataType n
- DDC.Core.DataDef: data DataCtor n
- DDC.Core.DataDef: data DataDef n
- DDC.Core.DataDef: data DataDefs n
- DDC.Core.DataDef: data DataMode n
- DDC.Core.DataDef: data DataType n
- DDC.Core.DataDef: dataCtorFieldTypes :: DataCtor n -> [Type n]
- DDC.Core.DataDef: dataCtorName :: DataCtor n -> n
- DDC.Core.DataDef: dataCtorTypeName :: DataCtor n -> n
- DDC.Core.DataDef: dataDefCtors :: DataDef n -> Maybe [(n, [Type n])]
- DDC.Core.DataDef: dataDefParamKinds :: DataDef n -> [Kind n]
- DDC.Core.DataDef: dataDefTypeName :: DataDef n -> n
- DDC.Core.DataDef: dataDefsCtors :: DataDefs n -> Map n (DataCtor n)
- DDC.Core.DataDef: dataDefsTypes :: DataDefs n -> Map n (DataType n)
- DDC.Core.DataDef: dataTypeMode :: DataType n -> DataMode n
- DDC.Core.DataDef: dataTypeName :: DataType n -> n
- DDC.Core.DataDef: dataTypeParamKinds :: DataType n -> [Kind n]
- DDC.Core.DataDef: emptyDataDefs :: DataDefs n
- DDC.Core.DataDef: fromListDataDefs :: Ord n => [DataDef n] -> DataDefs n
- DDC.Core.DataDef: insertDataDef :: Ord n => DataDef n -> DataDefs n -> DataDefs n
- DDC.Core.DataDef: lookupModeOfDataType :: Ord n => n -> DataDefs n -> Maybe (DataMode n)
- DDC.Core.Exp: LLetRegion :: (Bind n) -> [Bind n] -> Lets a n
- DDC.Core.Exp: instance (Eq a, Eq n) => Eq (Alt a n)
- DDC.Core.Exp: instance (Eq a, Eq n) => Eq (Exp a n)
- DDC.Core.Exp: instance (Eq a, Eq n) => Eq (Lets a n)
- DDC.Core.Exp: instance (Show a, Show n) => Show (Alt a n)
- DDC.Core.Exp: instance (Show a, Show n) => Show (Exp a n)
- DDC.Core.Exp: instance (Show a, Show n) => Show (Lets a n)
- DDC.Core.Exp: instance Eq WbCon
- DDC.Core.Exp: instance Eq n => Eq (Cast n)
- DDC.Core.Exp: instance Eq n => Eq (LetMode n)
- DDC.Core.Exp: instance Eq n => Eq (Pat n)
- DDC.Core.Exp: instance Eq n => Eq (WiCon n)
- DDC.Core.Exp: instance Eq n => Eq (Witness n)
- DDC.Core.Exp: instance Show WbCon
- DDC.Core.Exp: instance Show n => Show (Cast n)
- DDC.Core.Exp: instance Show n => Show (LetMode n)
- DDC.Core.Exp: instance Show n => Show (Pat n)
- DDC.Core.Exp: instance Show n => Show (WiCon n)
- DDC.Core.Exp: instance Show n => Show (Witness n)
- DDC.Core.Parser.Lexer: isConBody :: Char -> Bool
- DDC.Core.Parser.Lexer: isConName :: String -> Bool
- DDC.Core.Parser.Lexer: isConStart :: Char -> Bool
- DDC.Core.Parser.Lexer: isVarBody :: Char -> Bool
- DDC.Core.Parser.Lexer: isVarName :: String -> Bool
- DDC.Core.Parser.Lexer: isVarStart :: Char -> Bool
- DDC.Core.Parser.Lexer: lexExp :: Int -> String -> [Token (Tok String)]
- DDC.Core.Parser.Lexer: readCon :: String -> Maybe String
- DDC.Core.Parser.Lexer: readTcConBuiltin :: String -> Maybe TcCon
- DDC.Core.Parser.Lexer: readTwConBuiltin :: String -> Maybe TwCon
- DDC.Core.Parser.Lexer: readVar :: String -> Maybe String
- DDC.Core.Parser.Lexer: readWbConBuiltin :: String -> Maybe WbCon
- DDC.Core.Parser.Tokens: KA :: !TokAtom -> Tok n
- DDC.Core.Parser.Tokens: KAmpersand :: TokAtom
- DDC.Core.Parser.Tokens: KAngleBra :: TokAtom
- DDC.Core.Parser.Tokens: KAngleColonBra :: TokAtom
- DDC.Core.Parser.Tokens: KAngleColonKet :: TokAtom
- DDC.Core.Parser.Tokens: KAngleKet :: TokAtom
- DDC.Core.Parser.Tokens: KArrowDash :: TokAtom
- DDC.Core.Parser.Tokens: KArrowEquals :: TokAtom
- DDC.Core.Parser.Tokens: KArrowTilde :: TokAtom
- DDC.Core.Parser.Tokens: KBackSlash :: TokAtom
- DDC.Core.Parser.Tokens: KBar :: TokAtom
- DDC.Core.Parser.Tokens: KBigLambda :: TokAtom
- DDC.Core.Parser.Tokens: KBotClosure :: TokAtom
- DDC.Core.Parser.Tokens: KBotEffect :: TokAtom
- DDC.Core.Parser.Tokens: KBraceBra :: TokAtom
- DDC.Core.Parser.Tokens: KBraceKet :: TokAtom
- DDC.Core.Parser.Tokens: KCase :: TokAtom
- DDC.Core.Parser.Tokens: KColon :: TokAtom
- DDC.Core.Parser.Tokens: KColonColon :: TokAtom
- DDC.Core.Parser.Tokens: KComma :: TokAtom
- DDC.Core.Parser.Tokens: KCon :: n -> TokNamed n
- DDC.Core.Parser.Tokens: KDash :: TokAtom
- DDC.Core.Parser.Tokens: KDot :: TokAtom
- DDC.Core.Parser.Tokens: KEquals :: TokAtom
- DDC.Core.Parser.Tokens: KForget :: TokAtom
- DDC.Core.Parser.Tokens: KHat :: TokAtom
- DDC.Core.Parser.Tokens: KIn :: TokAtom
- DDC.Core.Parser.Tokens: KIndex :: Int -> TokAtom
- DDC.Core.Parser.Tokens: KJunk :: Char -> Tok n
- DDC.Core.Parser.Tokens: KKindClosure :: TokAtom
- DDC.Core.Parser.Tokens: KKindEffect :: TokAtom
- DDC.Core.Parser.Tokens: KKindRegion :: TokAtom
- DDC.Core.Parser.Tokens: KKindValue :: TokAtom
- DDC.Core.Parser.Tokens: KKindWitness :: TokAtom
- DDC.Core.Parser.Tokens: KLazy :: TokAtom
- DDC.Core.Parser.Tokens: KLet :: TokAtom
- DDC.Core.Parser.Tokens: KLetRec :: TokAtom
- DDC.Core.Parser.Tokens: KLetRegion :: TokAtom
- DDC.Core.Parser.Tokens: KLit :: n -> TokNamed n
- DDC.Core.Parser.Tokens: KN :: !(TokNamed n) -> Tok n
- DDC.Core.Parser.Tokens: KOf :: TokAtom
- DDC.Core.Parser.Tokens: KPlus :: TokAtom
- DDC.Core.Parser.Tokens: KPurify :: TokAtom
- DDC.Core.Parser.Tokens: KRoundBra :: TokAtom
- DDC.Core.Parser.Tokens: KRoundKet :: TokAtom
- DDC.Core.Parser.Tokens: KSemiColon :: TokAtom
- DDC.Core.Parser.Tokens: KSortComp :: TokAtom
- DDC.Core.Parser.Tokens: KSortProp :: TokAtom
- DDC.Core.Parser.Tokens: KSquareBra :: TokAtom
- DDC.Core.Parser.Tokens: KSquareColonBra :: TokAtom
- DDC.Core.Parser.Tokens: KSquareColonKet :: TokAtom
- DDC.Core.Parser.Tokens: KSquareKet :: TokAtom
- DDC.Core.Parser.Tokens: KTcConBuiltin :: TcCon -> TokAtom
- DDC.Core.Parser.Tokens: KTwConBuiltin :: TwCon -> TokAtom
- DDC.Core.Parser.Tokens: KUnderscore :: TokAtom
- DDC.Core.Parser.Tokens: KVar :: n -> TokNamed n
- DDC.Core.Parser.Tokens: KWbConBuiltin :: WbCon -> TokAtom
- DDC.Core.Parser.Tokens: KWeakClo :: TokAtom
- DDC.Core.Parser.Tokens: KWeakEff :: TokAtom
- DDC.Core.Parser.Tokens: KWhere :: TokAtom
- DDC.Core.Parser.Tokens: KWith :: TokAtom
- DDC.Core.Parser.Tokens: KWithRegion :: TokAtom
- DDC.Core.Parser.Tokens: data Tok n
- DDC.Core.Parser.Tokens: data TokAtom
- DDC.Core.Parser.Tokens: data TokNamed n
- DDC.Core.Parser.Tokens: describeTok :: Pretty n => Tok n -> String
- DDC.Core.Parser.Tokens: describeTokAtom :: TokAtom -> String
- DDC.Core.Parser.Tokens: describeTokNamed :: Pretty n => TokNamed n -> String
- DDC.Core.Parser.Tokens: instance Eq TokAtom
- DDC.Core.Parser.Tokens: instance Eq n => Eq (Tok n)
- DDC.Core.Parser.Tokens: instance Eq n => Eq (TokNamed n)
- DDC.Core.Parser.Tokens: instance Show TokAtom
- DDC.Core.Parser.Tokens: instance Show n => Show (Tok n)
- DDC.Core.Parser.Tokens: instance Show n => Show (TokNamed n)
- DDC.Core.Parser.Tokens: renameTok :: Ord n2 => (n1 -> n2) -> Tok n1 -> Tok n2
- DDC.Core.Pretty: instance (Pretty n, Eq n) => Pretty (Cast n)
- DDC.Core.Transform.LiftW: class LiftW (c :: * -> *) where liftW n xx = liftAtDepthW n 0 xx
- DDC.Core.Transform.LiftW: instance LiftW (Alt a)
- DDC.Core.Transform.LiftW: instance LiftW (Exp a)
- DDC.Core.Transform.LiftW: instance LiftW Bound
- DDC.Core.Transform.LiftW: instance LiftW LetMode
- DDC.Core.Transform.LiftW: instance LiftW Witness
- DDC.Core.Transform.LiftW: liftAtDepthW :: (LiftW c, Ord n) => Int -> Int -> c n -> c n
- DDC.Core.Transform.LiftW: liftW :: (LiftW c, Ord n) => Int -> c n -> c n
- DDC.Core.Transform.LiftX: class LiftX (c :: * -> *) where liftX n xx = liftAtDepthX n 0 xx
- DDC.Core.Transform.LiftX: instance LiftX (Alt a)
- DDC.Core.Transform.LiftX: instance LiftX (Exp a)
- DDC.Core.Transform.LiftX: instance LiftX Bound
- DDC.Core.Transform.SpreadX: instance SpreadX Cast
- DDC.Core.Transform.SubstituteTX: instance SubstituteTX Bound
- DDC.Core.Transform.SubstituteTX: instance SubstituteTX Cast
- DDC.Core.Transform.SubstituteWX: instance SubstituteWX Cast
- DDC.Type.Check.Monad: CheckM :: (Either err a) -> CheckM err a
- DDC.Type.Check.Monad: data CheckM err a
- DDC.Type.Check.Monad: instance Monad (CheckM err)
- DDC.Type.Check.Monad: result :: CheckM err a -> Either err a
- DDC.Type.Check.Monad: throw :: err -> CheckM err a
- DDC.Type.Compounds: replaceTypeOfBound :: Type n -> Bound n -> Bound n
- DDC.Type.Compounds: typeOfBound :: Bound n -> Type n
- DDC.Type.Exp: TypeSum :: Kind n -> Array TyConHash (Set (TypeSumVarCon n)) -> Map n (Kind n) -> Map Int (Kind n) -> [Type n] -> TypeSum n
- DDC.Type.Exp: instance Eq KiCon
- DDC.Type.Exp: instance Eq SoCon
- DDC.Type.Exp: instance Eq TcCon
- DDC.Type.Exp: instance Eq TwCon
- DDC.Type.Exp: instance Eq TyConHash
- DDC.Type.Exp: instance Ix TyConHash
- DDC.Type.Exp: instance Ord TyConHash
- DDC.Type.Exp: instance Show KiCon
- DDC.Type.Exp: instance Show SoCon
- DDC.Type.Exp: instance Show TcCon
- DDC.Type.Exp: instance Show TwCon
- DDC.Type.Exp: instance Show TyConHash
- DDC.Type.Exp: instance Show n => Show (Bind n)
- DDC.Type.Exp: instance Show n => Show (Binder n)
- DDC.Type.Exp: instance Show n => Show (Bound n)
- DDC.Type.Exp: instance Show n => Show (TyCon n)
- DDC.Type.Exp: instance Show n => Show (Type n)
- DDC.Type.Exp: instance Show n => Show (TypeSum n)
- DDC.Type.Exp: instance Show n => Show (TypeSumVarCon n)
- DDC.Type.Parser: pBinder :: Ord n => Parser n (Binder n)
- DDC.Type.Parser: pIndex :: Parser n Int
- DDC.Type.Parser: pTok :: TokAtom -> Parser n ()
- DDC.Type.Parser: pTokAs :: TokAtom -> a -> Parser n a
- DDC.Type.Parser: pType :: Ord n => Parser n (Type n)
- DDC.Type.Parser: pTypeApp :: Ord n => Parser n (Type n)
- DDC.Type.Parser: pTypeAtom :: Ord n => Parser n (Type n)
- DDC.Type.Parser: type Parser n a = Parser (Tok n) a
- DDC.Type.Rewrite: BindStack :: [Bind n] -> [Bind n] -> Int -> Int -> BindStack n
- DDC.Type.Rewrite: Sub :: Bound n -> Bool -> Set n -> Set n -> BindStack n -> BindStack n -> Sub n
- DDC.Type.Rewrite: bind0 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)
- DDC.Type.Rewrite: bind0s :: Ord n => Sub n -> [Bind n] -> (Sub n, [Bind n])
- DDC.Type.Rewrite: bind1 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)
- DDC.Type.Rewrite: class Rewrite (c :: * -> *)
- DDC.Type.Rewrite: data BindStack n
- DDC.Type.Rewrite: data Sub n
- DDC.Type.Rewrite: instance Rewrite Bind
- DDC.Type.Rewrite: instance Rewrite Bound
- DDC.Type.Rewrite: instance Rewrite Cast
- DDC.Type.Rewrite: instance Rewrite LetMode
- DDC.Type.Rewrite: instance Rewrite Type
- DDC.Type.Rewrite: instance Rewrite TypeSum
- DDC.Type.Rewrite: instance Rewrite Witness
- DDC.Type.Rewrite: pushBind :: Ord n => Set n -> BindStack n -> Bind n -> (BindStack n, Bind n)
- DDC.Type.Rewrite: pushBinds :: Ord n => Set n -> BindStack n -> [Bind n] -> (BindStack n, [Bind n])
- DDC.Type.Rewrite: rewriteWith :: (Rewrite c, Ord n) => Sub n -> c n -> c n
- DDC.Type.Rewrite: stackAll :: BindStack n -> [Bind n]
- DDC.Type.Rewrite: stackAnons :: BindStack n -> Int
- DDC.Type.Rewrite: stackBinds :: BindStack n -> [Bind n]
- DDC.Type.Rewrite: stackNamed :: BindStack n -> Int
- DDC.Type.Rewrite: subBound :: Sub n -> Bound n
- DDC.Type.Rewrite: subConflict0 :: Sub n -> Set n
- DDC.Type.Rewrite: subConflict1 :: Sub n -> Set n
- DDC.Type.Rewrite: subShadow0 :: Sub n -> Bool
- DDC.Type.Rewrite: subStack0 :: Sub n -> BindStack n
- DDC.Type.Rewrite: subStack1 :: Sub n -> BindStack n
- DDC.Type.Rewrite: substBound :: Ord n => BindStack n -> Bound n -> Bound n -> Either (Bound n) Int
- DDC.Type.Rewrite: use0 :: Ord n => Sub n -> Bound n -> Bound n
- DDC.Type.Rewrite: use1 :: Ord n => Sub n -> Bound n -> Bound n
- DDC.Type.Sum: makeSumArrayElem :: TyConHash -> TypeSumVarCon n -> Type n
- DDC.Type.Sum: takeSumArrayElem :: Type n -> Maybe (TyConHash, TypeSumVarCon n)
- DDC.Type.Transform.LiftT: class LiftT (c :: * -> *) where liftT n xx = liftAtDepthT n 0 xx
- DDC.Type.Transform.LiftT: instance LiftT Bind
- DDC.Type.Transform.LiftT: instance LiftT Bound
- DDC.Type.Transform.LiftT: instance LiftT Type
- DDC.Type.Transform.LiftT: instance LiftT TypeSum
- DDC.Type.Transform.LowerT: class LowerT (c :: * -> *) where lowerT n xx = lowerAtDepthT n 0 xx
- DDC.Type.Transform.LowerT: instance LowerT Bind
- DDC.Type.Transform.LowerT: instance LowerT Bound
- DDC.Type.Transform.LowerT: instance LowerT Type
- DDC.Type.Transform.LowerT: instance LowerT TypeSum
- DDC.Type.Transform.LowerT: lowerAtDepthT :: (LowerT c, Ord n) => Int -> Int -> c n -> c n
- DDC.Type.Transform.LowerT: lowerT :: (LowerT c, Ord n) => Int -> c n -> c n
+ DDC.Core.Check: AnTEC :: (Type n) -> (Effect n) -> (Closure n) -> a -> AnTEC a n
+ DDC.Core.Check: Config :: DataDefs n -> KindEnv n -> TypeEnv n -> Bool -> Config n
+ DDC.Core.Check: ErrorCaseScrutineeNotAlgebraic :: Exp a n -> Type n -> Error a n
+ DDC.Core.Check: ErrorCaseScrutineeTypeMismatch :: Exp a n -> Type n -> Type n -> Error a n
+ DDC.Core.Check: ErrorCaseScrutineeTypeUndeclared :: Exp a n -> Type n -> Error a n
+ DDC.Core.Check: ErrorExportMismatch :: n -> Type n -> Type n -> Error a n
+ DDC.Core.Check: ErrorExportUndefined :: n -> Error a n
+ DDC.Core.Check: ErrorLetRegionWitnessFree :: Exp a n -> Bind n -> Error a n
+ DDC.Core.Check: ErrorLetRegionsNotRegion :: Exp a n -> [Bind n] -> [Kind n] -> Error a n
+ DDC.Core.Check: ErrorLetRegionsRebound :: Exp a n -> [Bind n] -> Error a n
+ DDC.Core.Check: ErrorLetRegionsWitnessOther :: Exp a n -> [Bound n] -> Bind n -> Error a n
+ DDC.Core.Check: ErrorLetrecRebound :: Exp a n -> Bind n -> Error a n
+ DDC.Core.Check: ErrorUndefinedVar :: Bound n -> Universe -> Error a n
+ DDC.Core.Check: ErrorWeakEffNotEff :: Exp a n -> Effect n -> Kind n -> Error a n
+ DDC.Core.Check: ErrorWithRegionFree :: Exp a n -> Bound n -> Type n -> Error a n
+ DDC.Core.Check: annotClosure :: AnTEC a n -> (Closure n)
+ DDC.Core.Check: annotEffect :: AnTEC a n -> (Effect n)
+ DDC.Core.Check: annotTail :: AnTEC a n -> a
+ DDC.Core.Check: annotType :: AnTEC a n -> (Type n)
+ DDC.Core.Check: checkModule :: (Ord n, Show n, Pretty n) => Config n -> Module a n -> Either (Error a n) (Module (AnTEC a n) n)
+ DDC.Core.Check: configOfProfile :: Profile n -> Config n
+ DDC.Core.Check: configPrimDataDefs :: Config n -> DataDefs n
+ DDC.Core.Check: configPrimKinds :: Config n -> KindEnv n
+ DDC.Core.Check: configPrimTypes :: Config n -> TypeEnv n
+ DDC.Core.Check: configSuppressClosures :: Config n -> Bool
+ DDC.Core.Check: data AnTEC a n
+ DDC.Core.Check: data Config n
+ DDC.Core.Check: errorBinds :: Error a n -> [Bind n]
+ DDC.Core.Check: errorBoundRegions :: Error a n -> [Bound n]
+ DDC.Core.Check: errorCtorDaCon :: Error a n -> DaCon n
+ DDC.Core.Check: errorDefType :: Error a n -> Type n
+ DDC.Core.Check: errorExportType :: Error a n -> Type n
+ DDC.Core.Check: errorKinds :: Error a n -> [Kind n]
+ DDC.Core.Check: errorName :: Error a n -> n
+ DDC.Core.Check: errorSpecOrWit :: Error a n -> Bool
+ DDC.Core.Check: errorTypeScrutinee :: Error a n -> Type n
+ DDC.Core.Check: errorUniverse :: Error a n -> Universe
+ DDC.Core.Collect: Support :: Set (Bound n) -> Set (Bound n) -> Set (Bound n) -> Set (Bound n) -> Set (Bound n) -> Set (Bound n) -> Support n
+ DDC.Core.Collect: class SupportX (c :: * -> *)
+ DDC.Core.Collect: collectBinds :: (BindStruct c, Ord n) => c n -> ([Bind n], [Bind n])
+ DDC.Core.Collect: data Support n
+ DDC.Core.Collect: support :: (SupportX c, Ord n) => KindEnv n -> TypeEnv n -> c n -> Support n
+ DDC.Core.Collect: supportDaVar :: Support n -> Set (Bound n)
+ DDC.Core.Collect: supportSpVar :: Support n -> Set (Bound n)
+ DDC.Core.Collect: supportSpVarXArg :: Support n -> Set (Bound n)
+ DDC.Core.Collect: supportTyCon :: Support n -> Set (Bound n)
+ DDC.Core.Collect: supportTyConXArg :: Support n -> Set (Bound n)
+ DDC.Core.Collect: supportWiVar :: Support n -> Set (Bound n)
+ DDC.Core.Compounds: makeXAppsWithAnnots :: Exp a n -> [(Exp a n, a)] -> Exp a n
+ DDC.Core.Compounds: splitXLets :: Exp a n -> ([Lets a n], Exp a n)
+ DDC.Core.Compounds: takeAnnotOfExp :: Exp a n -> Maybe a
+ DDC.Core.Compounds: takePrimWiConApps :: Witness n -> Maybe (n, [Witness n])
+ DDC.Core.Compounds: takeWAppsAsList :: Witness n -> [Witness n]
+ DDC.Core.Compounds: takeXApps1 :: Exp a n -> Exp a n -> (Exp a n, [Exp a n])
+ DDC.Core.Compounds: takeXAppsAsList :: Exp a n -> [Exp a n]
+ DDC.Core.Compounds: takeXAppsWithAnnots :: Exp a n -> (Exp a n, [(Exp a n, a)])
+ DDC.Core.Compounds: takeXType :: Exp a n -> Maybe (Type n)
+ DDC.Core.Compounds: takeXWitness :: Exp a n -> Maybe (Witness n)
+ DDC.Core.Compounds: wApp :: Witness n -> Witness n -> Witness n
+ DDC.Core.Compounds: wApps :: Witness n -> [Witness n] -> Witness n
+ DDC.Core.Compounds: xApps :: a -> Exp a n -> [Exp a n] -> Exp a n
+ DDC.Core.Compounds: xLAMs :: a -> [Bind n] -> Exp a n -> Exp a n
+ DDC.Core.Compounds: xLams :: a -> [Bind n] -> Exp a n -> Exp a n
+ DDC.Core.Compounds: xLets :: a -> [Lets a n] -> Exp a n -> Exp a n
+ DDC.Core.Compounds: xUnit :: a -> Exp a n
+ DDC.Core.DaCon: DaCon :: !(DaConName n) -> !(Type n) -> !Bool -> DaCon n
+ DDC.Core.DaCon: DaConNamed :: n -> DaConName n
+ DDC.Core.DaCon: DaConUnit :: DaConName n
+ DDC.Core.DaCon: daConIsAlgebraic :: DaCon n -> !Bool
+ DDC.Core.DaCon: daConName :: DaCon n -> !(DaConName n)
+ DDC.Core.DaCon: daConType :: DaCon n -> !(Type n)
+ DDC.Core.DaCon: data DaCon n
+ DDC.Core.DaCon: data DaConName n
+ DDC.Core.DaCon: dcUnit :: DaCon n
+ DDC.Core.DaCon: instance Eq n => Eq (DaConName n)
+ DDC.Core.DaCon: instance NFData n => NFData (DaCon n)
+ DDC.Core.DaCon: instance NFData n => NFData (DaConName n)
+ DDC.Core.DaCon: instance Show n => Show (DaCon n)
+ DDC.Core.DaCon: instance Show n => Show (DaConName n)
+ DDC.Core.DaCon: mkDaConAlg :: n -> Type n -> DaCon n
+ DDC.Core.DaCon: mkDaConSolid :: n -> Type n -> DaCon n
+ DDC.Core.DaCon: takeNameOfDaCon :: DaCon n -> Maybe n
+ DDC.Core.DaCon: typeOfDaCon :: DaCon n -> Type n
+ DDC.Core.Exp: DaCon :: !(DaConName n) -> !(Type n) -> !Bool -> DaCon n
+ DDC.Core.Exp: DaConNamed :: n -> DaConName n
+ DDC.Core.Exp: DaConUnit :: DaConName n
+ DDC.Core.Exp: LLetRegions :: ![Bind n] -> ![Bind n] -> Lets a n
+ DDC.Core.Exp: daConIsAlgebraic :: DaCon n -> !Bool
+ DDC.Core.Exp: daConName :: DaCon n -> !(DaConName n)
+ DDC.Core.Exp: daConType :: DaCon n -> !(Type n)
+ DDC.Core.Exp: data DaCon n
+ DDC.Core.Exp: data DaConName n
+ DDC.Core.Fragment: DebruijnBinders :: Feature
+ DDC.Core.Fragment: ErrorNakedType :: !(Type n) -> Error n
+ DDC.Core.Fragment: ErrorNakedWitness :: !(Witness n) -> Error n
+ DDC.Core.Fragment: ErrorShadowedBind :: !n -> Error n
+ DDC.Core.Fragment: ErrorUndefinedPrim :: !n -> Error n
+ DDC.Core.Fragment: ErrorUndefinedVar :: !n -> Error n
+ DDC.Core.Fragment: ErrorUnsupported :: !Feature -> Error n
+ DDC.Core.Fragment: ErrorUnusedBind :: !n -> Error n
+ DDC.Core.Fragment: Features :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Features
+ DDC.Core.Fragment: Fragment :: Profile n -> String -> (String -> Maybe n) -> (String -> Int -> String -> [Token (Tok n)]) -> (String -> Int -> String -> [Token (Tok n)]) -> (forall a. Module a n -> Maybe (err a)) -> (forall a. Exp a n -> Maybe (err a)) -> Fragment n
+ DDC.Core.Fragment: GeneralApplication :: Feature
+ DDC.Core.Fragment: LazyBindings :: Feature
+ DDC.Core.Fragment: NameShadowing :: Feature
+ DDC.Core.Fragment: NestedFunctions :: Feature
+ DDC.Core.Fragment: PartialApplication :: Feature
+ DDC.Core.Fragment: PartialPrims :: Feature
+ DDC.Core.Fragment: Profile :: !String -> !Features -> !(DataDefs n) -> !(KindEnv n) -> !(TypeEnv n) -> !(Type n -> Bool) -> Profile n
+ DDC.Core.Fragment: UnboundLevel0Vars :: Feature
+ DDC.Core.Fragment: UnboxedInstantiation :: Feature
+ DDC.Core.Fragment: UntrackedClosures :: Feature
+ DDC.Core.Fragment: UntrackedEffects :: Feature
+ DDC.Core.Fragment: UnusedBindings :: Feature
+ DDC.Core.Fragment: UnusedMatches :: Feature
+ DDC.Core.Fragment: class Complies (c :: * -> * -> *)
+ DDC.Core.Fragment: complies :: (Ord n, Show n, Complies c) => Profile n -> c a n -> Maybe (Error n)
+ DDC.Core.Fragment: compliesWithEnvs :: (Ord n, Show n, Complies c) => Profile n -> KindEnv n -> TypeEnv n -> c a n -> Maybe (Error n)
+ DDC.Core.Fragment: data Error n
+ DDC.Core.Fragment: data Feature
+ DDC.Core.Fragment: data Features
+ DDC.Core.Fragment: data Fragment n (err :: * -> *)
+ DDC.Core.Fragment: data Profile n
+ DDC.Core.Fragment: featuresDebruijnBinders :: Features -> Bool
+ DDC.Core.Fragment: featuresGeneralApplication :: Features -> Bool
+ DDC.Core.Fragment: featuresLazyBindings :: Features -> Bool
+ DDC.Core.Fragment: featuresNameShadowing :: Features -> Bool
+ DDC.Core.Fragment: featuresNestedFunctions :: Features -> Bool
+ DDC.Core.Fragment: featuresPartialApplication :: Features -> Bool
+ DDC.Core.Fragment: featuresPartialPrims :: Features -> Bool
+ DDC.Core.Fragment: featuresUnboundLevel0Vars :: Features -> Bool
+ DDC.Core.Fragment: featuresUnboxedInstantiation :: Features -> Bool
+ DDC.Core.Fragment: featuresUntrackedClosures :: Features -> Bool
+ DDC.Core.Fragment: featuresUntrackedEffects :: Features -> Bool
+ DDC.Core.Fragment: featuresUnusedBindings :: Features -> Bool
+ DDC.Core.Fragment: featuresUnusedMatches :: Features -> Bool
+ DDC.Core.Fragment: fragmentCheckExp :: Fragment n -> forall a. Exp a n -> Maybe (err a)
+ DDC.Core.Fragment: fragmentCheckModule :: Fragment n -> forall a. Module a n -> Maybe (err a)
+ DDC.Core.Fragment: fragmentExtension :: Fragment n -> String
+ DDC.Core.Fragment: fragmentLexExp :: Fragment n -> String -> Int -> String -> [Token (Tok n)]
+ DDC.Core.Fragment: fragmentLexModule :: Fragment n -> String -> Int -> String -> [Token (Tok n)]
+ DDC.Core.Fragment: fragmentProfile :: Fragment n -> Profile n
+ DDC.Core.Fragment: fragmentReadName :: Fragment n -> String -> Maybe n
+ DDC.Core.Fragment: instance Show (Fragment n err)
+ DDC.Core.Fragment: profileFeatures :: Profile n -> !Features
+ DDC.Core.Fragment: profileName :: Profile n -> !String
+ DDC.Core.Fragment: profilePrimDataDefs :: Profile n -> !(DataDefs n)
+ DDC.Core.Fragment: profilePrimKinds :: Profile n -> !(KindEnv n)
+ DDC.Core.Fragment: profilePrimTypes :: Profile n -> !(TypeEnv n)
+ DDC.Core.Fragment: profileTypeIsUnboxed :: Profile n -> !(Type n -> Bool)
+ DDC.Core.Fragment: zeroFeatures :: Features
+ DDC.Core.Fragment: zeroProfile :: Profile n
+ DDC.Core.Lexer: lexExp :: FilePath -> Int -> String -> [Token (Tok String)]
+ DDC.Core.Lexer: lexModuleWithOffside :: FilePath -> Int -> String -> [Token (Tok String)]
+ DDC.Core.Lexer.Names: isConBody :: Char -> Bool
+ DDC.Core.Lexer.Names: isConName :: String -> Bool
+ DDC.Core.Lexer.Names: isConStart :: Char -> Bool
+ DDC.Core.Lexer.Names: isLitBody :: Char -> Bool
+ DDC.Core.Lexer.Names: isLitName :: String -> Bool
+ DDC.Core.Lexer.Names: isLitStart :: Char -> Bool
+ DDC.Core.Lexer.Names: isVarBody :: Char -> Bool
+ DDC.Core.Lexer.Names: isVarName :: String -> Bool
+ DDC.Core.Lexer.Names: isVarStart :: Char -> Bool
+ DDC.Core.Lexer.Names: keywords :: [(String, Tok n)]
+ DDC.Core.Lexer.Names: readCon :: String -> Maybe String
+ DDC.Core.Lexer.Names: readTcConBuiltin :: String -> Maybe TcCon
+ DDC.Core.Lexer.Names: readTwConBuiltin :: String -> Maybe TwCon
+ DDC.Core.Lexer.Names: readVar :: String -> Maybe String
+ DDC.Core.Lexer.Names: readWbConBuiltin :: String -> Maybe WbCon
+ DDC.Core.Lexer.Tokens: KA :: !TokAtom -> Tok n
+ DDC.Core.Lexer.Tokens: KAmpersand :: TokAtom
+ DDC.Core.Lexer.Tokens: KAngleBra :: TokAtom
+ DDC.Core.Lexer.Tokens: KAngleColonBra :: TokAtom
+ DDC.Core.Lexer.Tokens: KAngleColonKet :: TokAtom
+ DDC.Core.Lexer.Tokens: KAngleKet :: TokAtom
+ DDC.Core.Lexer.Tokens: KArrowDash :: TokAtom
+ DDC.Core.Lexer.Tokens: KArrowDashLeft :: TokAtom
+ DDC.Core.Lexer.Tokens: KArrowEquals :: TokAtom
+ DDC.Core.Lexer.Tokens: KArrowTilde :: TokAtom
+ DDC.Core.Lexer.Tokens: KBackSlash :: TokAtom
+ DDC.Core.Lexer.Tokens: KBar :: TokAtom
+ DDC.Core.Lexer.Tokens: KBigLambda :: TokAtom
+ DDC.Core.Lexer.Tokens: KBotClosure :: TokAtom
+ DDC.Core.Lexer.Tokens: KBotEffect :: TokAtom
+ DDC.Core.Lexer.Tokens: KBraceBra :: TokAtom
+ DDC.Core.Lexer.Tokens: KBraceKet :: TokAtom
+ DDC.Core.Lexer.Tokens: KCase :: TokAtom
+ DDC.Core.Lexer.Tokens: KColon :: TokAtom
+ DDC.Core.Lexer.Tokens: KColonColon :: TokAtom
+ DDC.Core.Lexer.Tokens: KComma :: TokAtom
+ DDC.Core.Lexer.Tokens: KCommentBlockEnd :: TokMeta
+ DDC.Core.Lexer.Tokens: KCommentBlockStart :: TokMeta
+ DDC.Core.Lexer.Tokens: KCommentLineStart :: TokMeta
+ DDC.Core.Lexer.Tokens: KCommentUnterminated :: TokMeta
+ DDC.Core.Lexer.Tokens: KCon :: n -> TokNamed n
+ DDC.Core.Lexer.Tokens: KDaConUnit :: TokAtom
+ DDC.Core.Lexer.Tokens: KDash :: TokAtom
+ DDC.Core.Lexer.Tokens: KDo :: TokAtom
+ DDC.Core.Lexer.Tokens: KDot :: TokAtom
+ DDC.Core.Lexer.Tokens: KElse :: TokAtom
+ DDC.Core.Lexer.Tokens: KEquals :: TokAtom
+ DDC.Core.Lexer.Tokens: KExports :: TokAtom
+ DDC.Core.Lexer.Tokens: KForget :: TokAtom
+ DDC.Core.Lexer.Tokens: KHat :: TokAtom
+ DDC.Core.Lexer.Tokens: KImports :: TokAtom
+ DDC.Core.Lexer.Tokens: KIn :: TokAtom
+ DDC.Core.Lexer.Tokens: KIndex :: Int -> TokAtom
+ DDC.Core.Lexer.Tokens: KJunk :: String -> Tok n
+ DDC.Core.Lexer.Tokens: KKindClosure :: TokAtom
+ DDC.Core.Lexer.Tokens: KKindEffect :: TokAtom
+ DDC.Core.Lexer.Tokens: KKindRegion :: TokAtom
+ DDC.Core.Lexer.Tokens: KKindValue :: TokAtom
+ DDC.Core.Lexer.Tokens: KKindWitness :: TokAtom
+ DDC.Core.Lexer.Tokens: KLazy :: TokAtom
+ DDC.Core.Lexer.Tokens: KLet :: TokAtom
+ DDC.Core.Lexer.Tokens: KLetRec :: TokAtom
+ DDC.Core.Lexer.Tokens: KLetRegion :: TokAtom
+ DDC.Core.Lexer.Tokens: KLetRegions :: TokAtom
+ DDC.Core.Lexer.Tokens: KLit :: n -> TokNamed n
+ DDC.Core.Lexer.Tokens: KM :: !TokMeta -> Tok n
+ DDC.Core.Lexer.Tokens: KMatch :: TokAtom
+ DDC.Core.Lexer.Tokens: KModule :: TokAtom
+ DDC.Core.Lexer.Tokens: KN :: !(TokNamed n) -> Tok n
+ DDC.Core.Lexer.Tokens: KNewLine :: TokMeta
+ DDC.Core.Lexer.Tokens: KOf :: TokAtom
+ DDC.Core.Lexer.Tokens: KOffsideClosingBrace :: TokMeta
+ DDC.Core.Lexer.Tokens: KPlus :: TokAtom
+ DDC.Core.Lexer.Tokens: KPurify :: TokAtom
+ DDC.Core.Lexer.Tokens: KRoundBra :: TokAtom
+ DDC.Core.Lexer.Tokens: KRoundKet :: TokAtom
+ DDC.Core.Lexer.Tokens: KSemiColon :: TokAtom
+ DDC.Core.Lexer.Tokens: KSortComp :: TokAtom
+ DDC.Core.Lexer.Tokens: KSortProp :: TokAtom
+ DDC.Core.Lexer.Tokens: KSquareBra :: TokAtom
+ DDC.Core.Lexer.Tokens: KSquareColonBra :: TokAtom
+ DDC.Core.Lexer.Tokens: KSquareColonKet :: TokAtom
+ DDC.Core.Lexer.Tokens: KSquareKet :: TokAtom
+ DDC.Core.Lexer.Tokens: KTcConBuiltin :: TcCon -> TokAtom
+ DDC.Core.Lexer.Tokens: KTwConBuiltin :: TwCon -> TokAtom
+ DDC.Core.Lexer.Tokens: KType :: TokAtom
+ DDC.Core.Lexer.Tokens: KUnderscore :: TokAtom
+ DDC.Core.Lexer.Tokens: KVar :: n -> TokNamed n
+ DDC.Core.Lexer.Tokens: KWbConBuiltin :: WbCon -> TokAtom
+ DDC.Core.Lexer.Tokens: KWeakClo :: TokAtom
+ DDC.Core.Lexer.Tokens: KWeakEff :: TokAtom
+ DDC.Core.Lexer.Tokens: KWhere :: TokAtom
+ DDC.Core.Lexer.Tokens: KWith :: TokAtom
+ DDC.Core.Lexer.Tokens: KWithRegion :: TokAtom
+ DDC.Core.Lexer.Tokens: data Tok n
+ DDC.Core.Lexer.Tokens: data TokAtom
+ DDC.Core.Lexer.Tokens: data TokMeta
+ DDC.Core.Lexer.Tokens: data TokNamed n
+ DDC.Core.Lexer.Tokens: describeTok :: Pretty n => Tok n -> String
+ DDC.Core.Lexer.Tokens: describeTokAtom :: TokAtom -> String
+ DDC.Core.Lexer.Tokens: describeTokMeta :: TokMeta -> String
+ DDC.Core.Lexer.Tokens: describeTokNamed :: Pretty n => TokNamed n -> String
+ DDC.Core.Lexer.Tokens: instance Eq TokAtom
+ DDC.Core.Lexer.Tokens: instance Eq TokMeta
+ DDC.Core.Lexer.Tokens: instance Eq n => Eq (Tok n)
+ DDC.Core.Lexer.Tokens: instance Eq n => Eq (TokNamed n)
+ DDC.Core.Lexer.Tokens: instance Show TokAtom
+ DDC.Core.Lexer.Tokens: instance Show TokMeta
+ DDC.Core.Lexer.Tokens: instance Show n => Show (Tok n)
+ DDC.Core.Lexer.Tokens: instance Show n => Show (TokNamed n)
+ DDC.Core.Lexer.Tokens: renameTok :: Ord n2 => (n1 -> Maybe n2) -> Tok n1 -> Maybe (Tok n2)
+ DDC.Core.Load: AnTEC :: (Type n) -> (Effect n) -> (Closure n) -> a -> AnTEC a n
+ DDC.Core.Load: ErrorCheckExp :: !(Error () n) -> Error n
+ DDC.Core.Load: ErrorCheckType :: !(Error n) -> Error n
+ DDC.Core.Load: ErrorCompliance :: !(Error n) -> Error n
+ DDC.Core.Load: ErrorParser :: !ParseError -> Error n
+ DDC.Core.Load: ErrorRead :: !String -> Error n
+ DDC.Core.Load: annotClosure :: AnTEC a n -> (Closure n)
+ DDC.Core.Load: annotEffect :: AnTEC a n -> (Effect n)
+ DDC.Core.Load: annotTail :: AnTEC a n -> a
+ DDC.Core.Load: annotType :: AnTEC a n -> (Type n)
+ DDC.Core.Load: data AnTEC a n
+ DDC.Core.Load: data Error n
+ DDC.Core.Load: instance (Eq n, Show n, Pretty n) => Pretty (Error n)
+ DDC.Core.Load: instance Show n => Show (Error n)
+ DDC.Core.Load: loadExp :: (Eq n, Ord n, Show n, Pretty n) => Profile n -> Map ModuleName (Module (AnTEC () n) n) -> FilePath -> [Token (Tok n)] -> Either (Error n) (Exp (AnTEC () n) n)
+ DDC.Core.Load: loadModuleFromFile :: (Eq n, Ord n, Show n, Pretty n) => Profile n -> (String -> [Token (Tok n)]) -> FilePath -> IO (Either (Error n) (Module (AnTEC () n) n))
+ DDC.Core.Load: loadModuleFromString :: (Eq n, Ord n, Show n, Pretty n) => Profile n -> (String -> [Token (Tok n)]) -> FilePath -> String -> Either (Error n) (Module (AnTEC () n) n)
+ DDC.Core.Load: loadModuleFromTokens :: (Eq n, Ord n, Show n, Pretty n) => Profile n -> FilePath -> [Token (Tok n)] -> Either (Error n) (Module (AnTEC () n) n)
+ DDC.Core.Load: loadType :: (Eq n, Ord n, Show n, Pretty n) => Profile n -> FilePath -> [Token (Tok n)] -> Either (Error n) (Type n, Kind n)
+ DDC.Core.Load: loadWitness :: (Eq n, Ord n, Show n, Pretty n) => Profile n -> FilePath -> [Token (Tok n)] -> Either (Error n) (Witness n, Type n)
+ DDC.Core.Module: ModuleCore :: !ModuleName -> !(Map n (Kind n)) -> !(Map n (Type n)) -> !(Map n (QualName n, Kind n)) -> !(Map n (QualName n, Type n)) -> !(Exp a n) -> Module a n
+ DDC.Core.Module: ModuleName :: [String] -> ModuleName
+ DDC.Core.Module: QualName :: ModuleName -> n -> QualName n
+ DDC.Core.Module: data Module a n
+ DDC.Core.Module: data ModuleName
+ DDC.Core.Module: data QualName n
+ DDC.Core.Module: instance (NFData a, NFData n) => NFData (Module a n)
+ DDC.Core.Module: instance (Show a, Show n) => Show (Module a n)
+ DDC.Core.Module: instance Eq ModuleName
+ DDC.Core.Module: instance NFData ModuleName
+ DDC.Core.Module: instance NFData n => NFData (QualName n)
+ DDC.Core.Module: instance Ord ModuleName
+ DDC.Core.Module: instance Show ModuleName
+ DDC.Core.Module: instance Show n => Show (QualName n)
+ DDC.Core.Module: instance Typeable ModuleName
+ DDC.Core.Module: instance Typeable2 Module
+ DDC.Core.Module: isMainModule :: Module a n -> Bool
+ DDC.Core.Module: isMainModuleName :: ModuleName -> Bool
+ DDC.Core.Module: moduleBody :: Module a n -> !(Exp a n)
+ DDC.Core.Module: moduleExportKinds :: Module a n -> !(Map n (Kind n))
+ DDC.Core.Module: moduleExportTypes :: Module a n -> !(Map n (Type n))
+ DDC.Core.Module: moduleImportKinds :: Module a n -> !(Map n (QualName n, Kind n))
+ DDC.Core.Module: moduleImportTypes :: Module a n -> !(Map n (QualName n, Type n))
+ DDC.Core.Module: moduleKindEnv :: Ord n => Module a n -> KindEnv n
+ DDC.Core.Module: moduleName :: Module a n -> !ModuleName
+ DDC.Core.Module: moduleTypeEnv :: Ord n => Module a n -> TypeEnv n
+ DDC.Core.Module: modulesExportKinds :: Ord n => ModuleMap a n -> KindEnv n -> KindEnv n
+ DDC.Core.Module: modulesExportTypes :: Ord n => ModuleMap a n -> TypeEnv n -> TypeEnv n
+ DDC.Core.Module: modulesGetBinds :: Ord n => Map n (Type n) -> Env n
+ DDC.Core.Module: type ModuleMap a n = Map ModuleName (Module a n)
+ DDC.Core.Parser: pBinder :: Ord n => Parser n (Binder n)
+ DDC.Core.Parser: pCon :: Parser n n
+ DDC.Core.Parser: pExpApp :: Ord n => Parser n (Exp () n)
+ DDC.Core.Parser: pExpAtom :: Ord n => Parser n (Exp () n)
+ DDC.Core.Parser: pIndex :: Parser n Int
+ DDC.Core.Parser: pLit :: Parser n n
+ DDC.Core.Parser: pModule :: (Ord n, Pretty n) => Parser n (Module () n)
+ DDC.Core.Parser: pName :: Parser n n
+ DDC.Core.Parser: pTok :: TokAtom -> Parser n ()
+ DDC.Core.Parser: pTokAs :: TokAtom -> a -> Parser n a
+ DDC.Core.Parser: pType :: Ord n => Parser n (Type n)
+ DDC.Core.Parser: pTypeApp :: Ord n => Parser n (Type n)
+ DDC.Core.Parser: pTypeAtom :: Ord n => Parser n (Type n)
+ DDC.Core.Parser: pVar :: Parser n n
+ DDC.Core.Parser: pWitnessApp :: Ord n => Parser n (Witness n)
+ DDC.Core.Parser: pWitnessAtom :: Ord n => Parser n (Witness n)
+ DDC.Core.Predicates: isXType :: Exp a n -> Bool
+ DDC.Core.Predicates: isXWitness :: Exp a n -> Bool
+ DDC.Core.Pretty: instance (Pretty n, Eq n) => Pretty (Cast a n)
+ DDC.Core.Pretty: instance (Pretty n, Eq n) => Pretty (DaCon n)
+ DDC.Core.Pretty: instance (Pretty n, Eq n) => Pretty (Module a n)
+ DDC.Core.Pretty: instance Pretty ModuleName
+ DDC.Core.Transform.LiftT: class MapBoundT (c :: * -> *) n
+ DDC.Core.Transform.LiftT: instance Ord n => MapBoundT (Alt a) n
+ DDC.Core.Transform.LiftT: instance Ord n => MapBoundT (Cast a) n
+ DDC.Core.Transform.LiftT: instance Ord n => MapBoundT (Exp a) n
+ DDC.Core.Transform.LiftT: instance Ord n => MapBoundT LetMode n
+ DDC.Core.Transform.LiftT: instance Ord n => MapBoundT Witness n
+ DDC.Core.Transform.LiftT: liftAtDepthT :: MapBoundT c n => Int -> Int -> c n -> c n
+ DDC.Core.Transform.LiftT: liftT :: MapBoundT c n => Int -> c n -> c n
+ DDC.Core.Transform.LiftT: mapBoundAtDepthT :: MapBoundT c n => (Int -> Bound n -> Bound n) -> Int -> c n -> c n
+ DDC.Core.Transform.LiftX: class MapBoundX (c :: * -> *) n
+ DDC.Core.Transform.LiftX: instance MapBoundX (Alt a) n
+ DDC.Core.Transform.LiftX: instance MapBoundX (Cast a) n
+ DDC.Core.Transform.LiftX: instance MapBoundX (Exp a) n
+ DDC.Core.Transform.LiftX: instance MapBoundX Bound n
+ DDC.Core.Transform.LiftX: instance MapBoundX LetMode n
+ DDC.Core.Transform.LiftX: instance MapBoundX Witness n
+ DDC.Core.Transform.LiftX: lowerAtDepthX :: MapBoundX c n => Int -> Int -> c n -> c n
+ DDC.Core.Transform.LiftX: lowerX :: MapBoundX c n => Int -> c n -> c n
+ DDC.Core.Transform.LiftX: mapBoundAtDepthX :: MapBoundX c n => (Int -> Bound n -> Bound n) -> Int -> c n -> c n
+ DDC.Core.Transform.Reannotate: class Reannotate c
+ DDC.Core.Transform.Reannotate: instance Reannotate Alt
+ DDC.Core.Transform.Reannotate: instance Reannotate Cast
+ DDC.Core.Transform.Reannotate: instance Reannotate Exp
+ DDC.Core.Transform.Reannotate: instance Reannotate Lets
+ DDC.Core.Transform.Reannotate: instance Reannotate Module
+ DDC.Core.Transform.Reannotate: reannotate :: Reannotate c => (a -> b) -> c a n -> c b n
+ DDC.Core.Transform.Rename: BindStack :: ![Bind n] -> ![Bind n] -> !Int -> !Int -> BindStack n
+ DDC.Core.Transform.Rename: Sub :: !(Bound n) -> !Bool -> !(Set n) -> !(Set n) -> !(BindStack n) -> !(BindStack n) -> Sub n
+ DDC.Core.Transform.Rename: bind0 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)
+ DDC.Core.Transform.Rename: bind0s :: Ord n => Sub n -> [Bind n] -> (Sub n, [Bind n])
+ DDC.Core.Transform.Rename: bind1 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)
+ DDC.Core.Transform.Rename: bind1s :: Ord n => Sub n -> [Bind n] -> (Sub n, [Bind n])
+ DDC.Core.Transform.Rename: class Rename (c :: * -> *)
+ DDC.Core.Transform.Rename: data BindStack n
+ DDC.Core.Transform.Rename: data Sub n
+ DDC.Core.Transform.Rename: instance Rename LetMode
+ DDC.Core.Transform.Rename: instance Rename Witness
+ DDC.Core.Transform.Rename: pushBind :: Ord n => Set n -> BindStack n -> Bind n -> (BindStack n, Bind n)
+ DDC.Core.Transform.Rename: pushBinds :: Ord n => Set n -> BindStack n -> [Bind n] -> (BindStack n, [Bind n])
+ DDC.Core.Transform.Rename: renameWith :: (Rename c, Ord n) => Sub n -> c n -> c n
+ DDC.Core.Transform.Rename: stackAll :: BindStack n -> ![Bind n]
+ DDC.Core.Transform.Rename: stackAnons :: BindStack n -> !Int
+ DDC.Core.Transform.Rename: stackBinds :: BindStack n -> ![Bind n]
+ DDC.Core.Transform.Rename: stackNamed :: BindStack n -> !Int
+ DDC.Core.Transform.Rename: subBound :: Sub n -> !(Bound n)
+ DDC.Core.Transform.Rename: subConflict0 :: Sub n -> !(Set n)
+ DDC.Core.Transform.Rename: subConflict1 :: Sub n -> !(Set n)
+ DDC.Core.Transform.Rename: subShadow0 :: Sub n -> !Bool
+ DDC.Core.Transform.Rename: subStack0 :: Sub n -> !(BindStack n)
+ DDC.Core.Transform.Rename: subStack1 :: Sub n -> !(BindStack n)
+ DDC.Core.Transform.Rename: substBound :: Ord n => BindStack n -> Bound n -> Bound n -> Either (Bound n) Int
+ DDC.Core.Transform.Rename: use0 :: Ord n => Sub n -> Bound n -> Bound n
+ DDC.Core.Transform.Rename: use1 :: Ord n => Sub n -> Bound n -> Bound n
+ DDC.Core.Transform.SpreadX: instance SpreadX (Cast a)
+ DDC.Core.Transform.SpreadX: instance SpreadX (Module a)
+ DDC.Core.Transform.SpreadX: instance SpreadX DaCon
+ DDC.Core.Transform.SubstituteTX: instance SubstituteTX (Cast a)
+ DDC.Core.Transform.SubstituteWX: instance SubstituteWX (Cast a)
+ DDC.Core.Transform.SubstituteXX: instance SubstituteXX Cast
+ DDC.Core.Transform.Trim: trimClosures :: Ord n => a -> [Exp a n] -> [Exp a n]
+ DDC.Core.Transform.Trim: trimX :: Ord n => Exp a n -> Exp a n
+ DDC.Type.Bind: getBindType :: Eq n => [Bind n] -> Bound n -> Maybe (Int, Type n)
+ DDC.Type.Collect: BindCasePat :: BindWay
+ DDC.Type.Collect: BindCon :: BoundLevel -> (Bound n) -> (Maybe (Kind n)) -> BindTree n
+ DDC.Type.Collect: BindDef :: BindWay -> [Bind n] -> [BindTree n] -> BindTree n
+ DDC.Type.Collect: BindForall :: BindWay
+ DDC.Type.Collect: BindLAM :: BindWay
+ DDC.Type.Collect: BindLam :: BindWay
+ DDC.Type.Collect: BindLet :: BindWay
+ DDC.Type.Collect: BindLetRec :: BindWay
+ DDC.Type.Collect: BindLetRegionWith :: BindWay
+ DDC.Type.Collect: BindLetRegions :: BindWay
+ DDC.Type.Collect: BindUse :: BoundLevel -> (Bound n) -> BindTree n
+ DDC.Type.Collect: BoundExp :: BoundLevel
+ DDC.Type.Collect: BoundSpec :: BoundLevel
+ DDC.Type.Collect: BoundWit :: BoundLevel
+ DDC.Type.Collect: bindDefT :: BindStruct c => BindWay -> [Bind n] -> [c n] -> BindTree n
+ DDC.Type.Collect: boundLevelOfBindWay :: BindWay -> BoundLevel
+ DDC.Type.Collect: class BindStruct (c :: * -> *)
+ DDC.Type.Collect: collectBinds :: (BindStruct c, Ord n) => c n -> ([Bind n], [Bind n])
+ DDC.Type.Collect: collectBound :: (BindStruct c, Ord n) => c n -> Set (Bound n)
+ DDC.Type.Collect: data BindTree n
+ DDC.Type.Collect: data BindWay
+ DDC.Type.Collect: data BoundLevel
+ DDC.Type.Collect: freeT :: (BindStruct c, Ord n) => Env n -> c n -> Set (Bound n)
+ DDC.Type.Collect: instance BindStruct TyCon
+ DDC.Type.Collect: instance BindStruct Type
+ DDC.Type.Collect: instance Eq BindWay
+ DDC.Type.Collect: instance Eq BoundLevel
+ DDC.Type.Collect: instance Eq n => Eq (BindTree n)
+ DDC.Type.Collect: instance Show BindWay
+ DDC.Type.Collect: instance Show BoundLevel
+ DDC.Type.Collect: instance Show n => Show (BindTree n)
+ DDC.Type.Collect: isBoundExpWit :: BoundLevel -> Bool
+ DDC.Type.Collect: slurpBindTree :: BindStruct c => c n -> [BindTree n]
+ DDC.Type.Compounds: arityOfType :: Type n -> Int
+ DDC.Type.Compounds: eraseTForalls :: Ord n => Type n -> Type n
+ DDC.Type.Compounds: tDistinct :: Int -> [Type n] -> Type n
+ DDC.Type.Compounds: tUnit :: Type n
+ DDC.Type.Compounds: takePrimTyConApps :: Type n -> Maybe (n, [Type n])
+ DDC.Type.Compounds: takePrimeRegion :: Type n -> Maybe (Type n)
+ DDC.Type.Compounds: takeSubstBoundsOfBinds :: [Bind n] -> [Bound n]
+ DDC.Type.Compounds: takeTFunWitArgResult :: Type n -> ([Type n], [Type n], Type n)
+ DDC.Type.DataDef: DataCtor :: !n -> !Integer -> ![Type n] -> !n -> DataCtor n
+ DDC.Type.DataDef: DataDef :: !n -> ![Kind n] -> !(Maybe [(n, [Type n])]) -> DataDef n
+ DDC.Type.DataDef: DataDefs :: !(Map n (DataType n)) -> !(Map n (DataCtor n)) -> DataDefs n
+ DDC.Type.DataDef: DataModeLarge :: DataMode n
+ DDC.Type.DataDef: DataModeSmall :: ![n] -> DataMode n
+ DDC.Type.DataDef: DataType :: !n -> ![Kind n] -> !(DataMode n) -> DataType n
+ DDC.Type.DataDef: data DataCtor n
+ DDC.Type.DataDef: data DataDef n
+ DDC.Type.DataDef: data DataDefs n
+ DDC.Type.DataDef: data DataMode n
+ DDC.Type.DataDef: data DataType n
+ DDC.Type.DataDef: dataCtorFieldTypes :: DataCtor n -> ![Type n]
+ DDC.Type.DataDef: dataCtorName :: DataCtor n -> !n
+ DDC.Type.DataDef: dataCtorTag :: DataCtor n -> !Integer
+ DDC.Type.DataDef: dataCtorTypeName :: DataCtor n -> !n
+ DDC.Type.DataDef: dataDefCtors :: DataDef n -> !(Maybe [(n, [Type n])])
+ DDC.Type.DataDef: dataDefParamKinds :: DataDef n -> ![Kind n]
+ DDC.Type.DataDef: dataDefTypeName :: DataDef n -> !n
+ DDC.Type.DataDef: dataDefsCtors :: DataDefs n -> !(Map n (DataCtor n))
+ DDC.Type.DataDef: dataDefsTypes :: DataDefs n -> !(Map n (DataType n))
+ DDC.Type.DataDef: dataTypeMode :: DataType n -> !(DataMode n)
+ DDC.Type.DataDef: dataTypeName :: DataType n -> !n
+ DDC.Type.DataDef: dataTypeParamKinds :: DataType n -> ![Kind n]
+ DDC.Type.DataDef: emptyDataDefs :: DataDefs n
+ DDC.Type.DataDef: fromListDataDefs :: Ord n => [DataDef n] -> DataDefs n
+ DDC.Type.DataDef: insertDataDef :: Ord n => DataDef n -> DataDefs n -> DataDefs n
+ DDC.Type.DataDef: instance Show n => Show (DataCtor n)
+ DDC.Type.DataDef: instance Show n => Show (DataDef n)
+ DDC.Type.DataDef: instance Show n => Show (DataDefs n)
+ DDC.Type.DataDef: instance Show n => Show (DataMode n)
+ DDC.Type.DataDef: instance Show n => Show (DataType n)
+ DDC.Type.DataDef: lookupModeOfDataType :: Ord n => n -> DataDefs n -> Maybe (DataMode n)
+ DDC.Type.Env: fromTypeMap :: Map n (Type n) -> Env n
+ DDC.Type.Env: type KindEnv n = Env n
+ DDC.Type.Env: type TypeEnv n = Env n
+ DDC.Type.Equiv: equivWithBindsT :: Ord n => [Bind n] -> [Bind n] -> Type n -> Type n -> Bool
+ DDC.Type.Exp: TcConUnit :: TcCon
+ DDC.Type.Exp: TwConDisjoint :: TwCon
+ DDC.Type.Exp: TwConDistinct :: Int -> TwCon
+ DDC.Type.Exp: TypeSumBot :: !(Kind n) -> TypeSum n
+ DDC.Type.Exp: TypeSumSet :: !(Kind n) -> !(Array TyConHash (Set (TypeSumVarCon n))) -> !(Map n (Kind n)) -> !(Map Int (Kind n)) -> ![Type n] -> TypeSum n
+ DDC.Type.Predicates: isAllocEffect :: Effect n -> Bool
+ DDC.Type.Predicates: isBAnon :: Bind n -> Bool
+ DDC.Type.Predicates: isBName :: Bind n -> Bool
+ DDC.Type.Predicates: isBNone :: Bind n -> Bool
+ DDC.Type.Predicates: isConstWitType :: Eq n => Type n -> Bool
+ DDC.Type.Predicates: isDistinctWitType :: Eq n => Type n -> Bool
+ DDC.Type.Predicates: isMutableWitType :: Eq n => Type n -> Bool
+ DDC.Type.Predicates: isReadEffect :: Effect n -> Bool
+ DDC.Type.Predicates: isSomeAllocEffect :: Effect n -> Bool
+ DDC.Type.Predicates: isSomeReadEffect :: Effect n -> Bool
+ DDC.Type.Predicates: isSomeWriteEffect :: Effect n -> Bool
+ DDC.Type.Predicates: isTVar :: Type n -> Bool
+ DDC.Type.Predicates: isWitnessType :: Eq n => Type n -> Bool
+ DDC.Type.Predicates: isWriteEffect :: Effect n -> Bool
+ DDC.Type.Transform.Crush: crushSomeT :: Ord n => Type n -> Type n
+ DDC.Type.Transform.LiftT: class MapBoundT (c :: * -> *) n
+ DDC.Type.Transform.LiftT: instance MapBoundT Bound n
+ DDC.Type.Transform.LiftT: instance Ord n => MapBoundT Bind n
+ DDC.Type.Transform.LiftT: instance Ord n => MapBoundT Type n
+ DDC.Type.Transform.LiftT: instance Ord n => MapBoundT TypeSum n
+ DDC.Type.Transform.LiftT: lowerAtDepthT :: MapBoundT c n => Int -> Int -> c n -> c n
+ DDC.Type.Transform.LiftT: lowerT :: MapBoundT c n => Int -> c n -> c n
+ DDC.Type.Transform.LiftT: mapBoundAtDepthT :: MapBoundT c n => (Int -> Bound n -> Bound n) -> Int -> c n -> c n
+ DDC.Type.Transform.Rename: BindStack :: ![Bind n] -> ![Bind n] -> !Int -> !Int -> BindStack n
+ DDC.Type.Transform.Rename: Sub :: !(Bound n) -> !Bool -> !(Set n) -> !(Set n) -> !(BindStack n) -> !(BindStack n) -> Sub n
+ DDC.Type.Transform.Rename: bind0 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)
+ DDC.Type.Transform.Rename: bind0s :: Ord n => Sub n -> [Bind n] -> (Sub n, [Bind n])
+ DDC.Type.Transform.Rename: bind1 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)
+ DDC.Type.Transform.Rename: bind1s :: Ord n => Sub n -> [Bind n] -> (Sub n, [Bind n])
+ DDC.Type.Transform.Rename: class Rename (c :: * -> *)
+ DDC.Type.Transform.Rename: data BindStack n
+ DDC.Type.Transform.Rename: data Sub n
+ DDC.Type.Transform.Rename: instance Rename Bind
+ DDC.Type.Transform.Rename: instance Rename Type
+ DDC.Type.Transform.Rename: instance Rename TypeSum
+ DDC.Type.Transform.Rename: pushBind :: Ord n => Set n -> BindStack n -> Bind n -> (BindStack n, Bind n)
+ DDC.Type.Transform.Rename: pushBinds :: Ord n => Set n -> BindStack n -> [Bind n] -> (BindStack n, [Bind n])
+ DDC.Type.Transform.Rename: renameWith :: (Rename c, Ord n) => Sub n -> c n -> c n
+ DDC.Type.Transform.Rename: stackAll :: BindStack n -> ![Bind n]
+ DDC.Type.Transform.Rename: stackAnons :: BindStack n -> !Int
+ DDC.Type.Transform.Rename: stackBinds :: BindStack n -> ![Bind n]
+ DDC.Type.Transform.Rename: stackNamed :: BindStack n -> !Int
+ DDC.Type.Transform.Rename: subBound :: Sub n -> !(Bound n)
+ DDC.Type.Transform.Rename: subConflict0 :: Sub n -> !(Set n)
+ DDC.Type.Transform.Rename: subConflict1 :: Sub n -> !(Set n)
+ DDC.Type.Transform.Rename: subShadow0 :: Sub n -> !Bool
+ DDC.Type.Transform.Rename: subStack0 :: Sub n -> !(BindStack n)
+ DDC.Type.Transform.Rename: subStack1 :: Sub n -> !(BindStack n)
+ DDC.Type.Transform.Rename: substBound :: Ord n => BindStack n -> Bound n -> Bound n -> Either (Bound n) Int
+ DDC.Type.Transform.Rename: use0 :: Ord n => Sub n -> Bound n -> Bound n
+ DDC.Type.Transform.Rename: use1 :: Ord n => Sub n -> Bound n -> Bound n
+ DDC.Type.Universe: instance Pretty Universe
- DDC.Core.Check: ErrorCaseTooManyBinders :: Exp a n -> Bound n -> Int -> Int -> Error a n
+ DDC.Core.Check: ErrorCaseTooManyBinders :: Exp a n -> DaCon n -> Int -> Int -> Error a n
- DDC.Core.Check: ErrorLamNotPure :: Exp a n -> Effect n -> Error a n
+ DDC.Core.Check: ErrorLamNotPure :: Exp a n -> Bool -> Effect n -> Error a n
- DDC.Core.Check: ErrorLetRegionFree :: Exp a n -> Bind n -> Type n -> Error a n
+ DDC.Core.Check: ErrorLetRegionFree :: Exp a n -> [Bind n] -> Type n -> Error a n
- DDC.Core.Check: ErrorVarAnnotMismatch :: Bound n -> Type n -> Error a n
+ DDC.Core.Check: ErrorVarAnnotMismatch :: Bound n -> Type n -> Type n -> Error a n
- DDC.Core.Check: checkExp :: (Ord n, Pretty n) => DataDefs n -> Env n -> Env n -> Exp a n -> Either (Error a n) (Exp a n, Type n, Effect n, Closure n)
+ DDC.Core.Check: checkExp :: (Ord n, Show n, Pretty n) => Config n -> KindEnv n -> TypeEnv n -> Exp a n -> Either (Error a n) (Exp (AnTEC a n) n, Type n, Effect n, Closure n)
- DDC.Core.Check: checkWitness :: (Ord n, Pretty n) => DataDefs n -> Env n -> Env n -> Witness n -> Either (Error a n) (Type n)
+ DDC.Core.Check: checkWitness :: (Ord n, Show n, Pretty n) => Config n -> KindEnv n -> TypeEnv n -> Witness n -> Either (Error a n) (Type n)
- DDC.Core.Check: typeOfExp :: (Ord n, Pretty n) => DataDefs n -> Exp a n -> Either (Error a n) (Type n)
+ DDC.Core.Check: typeOfExp :: (Ord n, Pretty n, Show n) => Config n -> KindEnv n -> TypeEnv n -> Exp a n -> Either (Error a n) (Type n)
- DDC.Core.Check: typeOfWitness :: (Ord n, Pretty n) => DataDefs n -> Witness n -> Either (Error a n) (Type n)
+ DDC.Core.Check: typeOfWitness :: (Ord n, Show n, Pretty n) => Config n -> Witness n -> Either (Error a n) (Type n)
- DDC.Core.Compounds: bindsOfLets :: Lets a n -> [Bind n]
+ DDC.Core.Compounds: bindsOfLets :: Lets a n -> ([Bind n], [Bind n])
- DDC.Core.Compounds: takeXApps :: Exp a n -> [Exp a n]
+ DDC.Core.Compounds: takeXApps :: Exp a n -> Maybe (Exp a n, [Exp a n])
- DDC.Core.Compounds: takeXConApps :: Exp a n -> Maybe (Bound n, [Exp a n])
+ DDC.Core.Compounds: takeXConApps :: Exp a n -> Maybe (DaCon n, [Exp a n])
- DDC.Core.Exp: AAlt :: (Pat n) -> (Exp a n) -> Alt a n
+ DDC.Core.Exp: AAlt :: !(Pat n) -> !(Exp a n) -> Alt a n
- DDC.Core.Exp: CastForget :: (Witness n) -> Cast n
+ DDC.Core.Exp: CastForget :: !(Witness n) -> Cast a n
- DDC.Core.Exp: CastPurify :: (Witness n) -> Cast n
+ DDC.Core.Exp: CastPurify :: !(Witness n) -> Cast a n
- DDC.Core.Exp: CastWeakenClosure :: (Closure n) -> Cast n
+ DDC.Core.Exp: CastWeakenClosure :: ![Exp a n] -> Cast a n
- DDC.Core.Exp: CastWeakenEffect :: (Effect n) -> Cast n
+ DDC.Core.Exp: CastWeakenEffect :: !(Effect n) -> Cast a n
- DDC.Core.Exp: LLet :: (LetMode n) -> (Bind n) -> (Exp a n) -> Lets a n
+ DDC.Core.Exp: LLet :: !(LetMode n) -> !(Bind n) -> !(Exp a n) -> Lets a n
- DDC.Core.Exp: LRec :: [(Bind n, Exp a n)] -> Lets a n
+ DDC.Core.Exp: LRec :: ![(Bind n, Exp a n)] -> Lets a n
- DDC.Core.Exp: LWithRegion :: (Bound n) -> Lets a n
+ DDC.Core.Exp: LWithRegion :: !(Bound n) -> Lets a n
- DDC.Core.Exp: LetLazy :: (Maybe (Witness n)) -> LetMode n
+ DDC.Core.Exp: LetLazy :: !(Maybe (Witness n)) -> LetMode n
- DDC.Core.Exp: PData :: (Bound n) -> [Bind n] -> Pat n
+ DDC.Core.Exp: PData :: !(DaCon n) -> ![Bind n] -> Pat n
- DDC.Core.Exp: WApp :: (Witness n) -> (Witness n) -> Witness n
+ DDC.Core.Exp: WApp :: !(Witness n) -> !(Witness n) -> Witness n
- DDC.Core.Exp: WCon :: (WiCon n) -> Witness n
+ DDC.Core.Exp: WCon :: !(WiCon n) -> Witness n
- DDC.Core.Exp: WJoin :: (Witness n) -> (Witness n) -> Witness n
+ DDC.Core.Exp: WJoin :: !(Witness n) -> !(Witness n) -> Witness n
- DDC.Core.Exp: WType :: (Type n) -> Witness n
+ DDC.Core.Exp: WType :: !(Type n) -> Witness n
- DDC.Core.Exp: WVar :: (Bound n) -> Witness n
+ DDC.Core.Exp: WVar :: !(Bound n) -> Witness n
- DDC.Core.Exp: WiConBound :: (Bound n) -> WiCon n
+ DDC.Core.Exp: WiConBound :: !(Bound n) -> !(Type n) -> WiCon n
- DDC.Core.Exp: WiConBuiltin :: WbCon -> WiCon n
+ DDC.Core.Exp: WiConBuiltin :: !WbCon -> WiCon n
- DDC.Core.Exp: XApp :: a -> (Exp a n) -> (Exp a n) -> Exp a n
+ DDC.Core.Exp: XApp :: !a -> !(Exp a n) -> !(Exp a n) -> Exp a n
- DDC.Core.Exp: XCase :: a -> (Exp a n) -> [Alt a n] -> Exp a n
+ DDC.Core.Exp: XCase :: !a -> !(Exp a n) -> ![Alt a n] -> Exp a n
- DDC.Core.Exp: XCast :: a -> (Cast n) -> (Exp a n) -> Exp a n
+ DDC.Core.Exp: XCast :: !a -> !(Cast a n) -> !(Exp a n) -> Exp a n
- DDC.Core.Exp: XCon :: a -> (Bound n) -> Exp a n
+ DDC.Core.Exp: XCon :: !a -> !(DaCon n) -> Exp a n
- DDC.Core.Exp: XLAM :: a -> (Bind n) -> (Exp a n) -> Exp a n
+ DDC.Core.Exp: XLAM :: !a -> !(Bind n) -> !(Exp a n) -> Exp a n
- DDC.Core.Exp: XLam :: a -> (Bind n) -> (Exp a n) -> Exp a n
+ DDC.Core.Exp: XLam :: !a -> !(Bind n) -> !(Exp a n) -> Exp a n
- DDC.Core.Exp: XLet :: a -> (Lets a n) -> (Exp a n) -> Exp a n
+ DDC.Core.Exp: XLet :: !a -> !(Lets a n) -> !(Exp a n) -> Exp a n
- DDC.Core.Exp: XType :: (Type n) -> Exp a n
+ DDC.Core.Exp: XType :: !(Type n) -> Exp a n
- DDC.Core.Exp: XVar :: a -> (Bound n) -> Exp a n
+ DDC.Core.Exp: XVar :: !a -> !(Bound n) -> Exp a n
- DDC.Core.Exp: XWitness :: (Witness n) -> Exp a n
+ DDC.Core.Exp: XWitness :: !(Witness n) -> Exp a n
- DDC.Core.Exp: data Cast n
+ DDC.Core.Exp: data Cast a n
- DDC.Core.Transform.LiftX: liftAtDepthX :: (LiftX c, Ord n) => Int -> Int -> c n -> c n
+ DDC.Core.Transform.LiftX: liftAtDepthX :: MapBoundX c n => Int -> Int -> c n -> c n
- DDC.Core.Transform.LiftX: liftX :: (LiftX c, Ord n) => Int -> c n -> c n
+ DDC.Core.Transform.LiftX: liftX :: MapBoundX c n => Int -> c n -> c n
- DDC.Type.Check: checkType :: (Ord n, Pretty n) => DataDefs n -> Env n -> Type n -> Either (Error n) (Kind n)
+ DDC.Type.Check: checkType :: (Ord n, Show n, Pretty n) => DataDefs n -> KindEnv n -> Type n -> Either (Error n) (Kind n)
- DDC.Type.Check: kindOfType :: (Ord n, Pretty n) => DataDefs n -> Type n -> Either (Error n) (Kind n)
+ DDC.Type.Check: kindOfType :: (Ord n, Show n, Pretty n) => DataDefs n -> Type n -> Either (Error n) (Kind n)
- DDC.Type.Env: Env :: Map n (Type n) -> [Type n] -> Int -> (n -> Maybe (Type n)) -> Env n
+ DDC.Type.Env: Env :: !(Map n (Type n)) -> ![Type n] -> !Int -> !(n -> Maybe (Type n)) -> Env n
- DDC.Type.Env: envMap :: Env n -> Map n (Type n)
+ DDC.Type.Env: envMap :: Env n -> !(Map n (Type n))
- DDC.Type.Env: envPrimFun :: Env n -> n -> Maybe (Type n)
+ DDC.Type.Env: envPrimFun :: Env n -> !(n -> Maybe (Type n))
- DDC.Type.Env: envStack :: Env n -> [Type n]
+ DDC.Type.Env: envStack :: Env n -> ![Type n]
- DDC.Type.Env: envStackLength :: Env n -> Int
+ DDC.Type.Env: envStackLength :: Env n -> !Int
- DDC.Type.Equiv: equivT :: (Ord n, Pretty n) => Type n -> Type n -> Bool
+ DDC.Type.Equiv: equivT :: Ord n => Type n -> Type n -> Bool
- DDC.Type.Exp: BAnon :: (Type n) -> Bind n
+ DDC.Type.Exp: BAnon :: !(Type n) -> Bind n
- DDC.Type.Exp: BName :: n -> (Type n) -> Bind n
+ DDC.Type.Exp: BName :: n -> !(Type n) -> Bind n
- DDC.Type.Exp: BNone :: (Type n) -> Bind n
+ DDC.Type.Exp: BNone :: !(Type n) -> Bind n
- DDC.Type.Exp: RName :: n -> Binder n
+ DDC.Type.Exp: RName :: !n -> Binder n
- DDC.Type.Exp: TApp :: (Type n) -> (Type n) -> Type n
+ DDC.Type.Exp: TApp :: !(Type n) -> !(Type n) -> Type n
- DDC.Type.Exp: TCon :: (TyCon n) -> Type n
+ DDC.Type.Exp: TCon :: !(TyCon n) -> Type n
- DDC.Type.Exp: TForall :: (Bind n) -> (Type n) -> Type n
+ DDC.Type.Exp: TForall :: !(Bind n) -> !(Type n) -> Type n
- DDC.Type.Exp: TSum :: (TypeSum n) -> Type n
+ DDC.Type.Exp: TSum :: !(TypeSum n) -> Type n
- DDC.Type.Exp: TVar :: (Bound n) -> Type n
+ DDC.Type.Exp: TVar :: !(Bound n) -> Type n
- DDC.Type.Exp: TyConBound :: (Bound n) -> TyCon n
+ DDC.Type.Exp: TyConBound :: !(Bound n) -> !(Kind n) -> TyCon n
- DDC.Type.Exp: TyConKind :: KiCon -> TyCon n
+ DDC.Type.Exp: TyConKind :: !KiCon -> TyCon n
- DDC.Type.Exp: TyConSort :: SoCon -> TyCon n
+ DDC.Type.Exp: TyConSort :: !SoCon -> TyCon n
- DDC.Type.Exp: TyConSpec :: TcCon -> TyCon n
+ DDC.Type.Exp: TyConSpec :: !TcCon -> TyCon n
- DDC.Type.Exp: TyConWitness :: TwCon -> TyCon n
+ DDC.Type.Exp: TyConWitness :: !TwCon -> TyCon n
- DDC.Type.Exp: TypeSumCon :: (Bound n) -> TypeSumVarCon n
+ DDC.Type.Exp: TypeSumCon :: !(Bound n) -> !(Type n) -> TypeSumVarCon n
- DDC.Type.Exp: TypeSumVar :: (Bound n) -> TypeSumVarCon n
+ DDC.Type.Exp: TypeSumVar :: !(Bound n) -> TypeSumVarCon n
- DDC.Type.Exp: UIx :: Int -> (Type n) -> Bound n
+ DDC.Type.Exp: UIx :: !Int -> Bound n
- DDC.Type.Exp: UName :: n -> (Type n) -> Bound n
+ DDC.Type.Exp: UName :: !n -> Bound n
- DDC.Type.Exp: UPrim :: n -> (Type n) -> Bound n
+ DDC.Type.Exp: UPrim :: !n -> !(Type n) -> Bound n
- DDC.Type.Exp: typeSumBoundAnon :: TypeSum n -> Map Int (Kind n)
+ DDC.Type.Exp: typeSumBoundAnon :: TypeSum n -> !(Map Int (Kind n))
- DDC.Type.Exp: typeSumBoundNamed :: TypeSum n -> Map n (Kind n)
+ DDC.Type.Exp: typeSumBoundNamed :: TypeSum n -> !(Map n (Kind n))
- DDC.Type.Exp: typeSumElems :: TypeSum n -> Array TyConHash (Set (TypeSumVarCon n))
+ DDC.Type.Exp: typeSumElems :: TypeSum n -> !(Array TyConHash (Set (TypeSumVarCon n)))
- DDC.Type.Exp: typeSumKind :: TypeSum n -> Kind n
+ DDC.Type.Exp: typeSumKind :: TypeSum n -> !(Kind n)
- DDC.Type.Exp: typeSumSpill :: TypeSum n -> [Type n]
+ DDC.Type.Exp: typeSumSpill :: TypeSum n -> ![Type n]
- DDC.Type.Transform.LiftT: liftAtDepthT :: (LiftT c, Ord n) => Int -> Int -> c n -> c n
+ DDC.Type.Transform.LiftT: liftAtDepthT :: MapBoundT c n => Int -> Int -> c n -> c n
- DDC.Type.Transform.LiftT: liftT :: (LiftT c, Ord n) => Int -> c n -> c n
+ DDC.Type.Transform.LiftT: liftT :: MapBoundT c n => Int -> c n -> c n
- DDC.Type.Transform.SpreadT: spreadT :: (SpreadT c, Ord n) => Env n -> c n -> c n
+ DDC.Type.Transform.SpreadT: spreadT :: (SpreadT c, Ord n) => TypeEnv n -> c n -> c n
- DDC.Type.Transform.SubstituteT: BindStack :: [Bind n] -> [Bind n] -> Int -> Int -> BindStack n
+ DDC.Type.Transform.SubstituteT: BindStack :: ![Bind n] -> ![Bind n] -> !Int -> !Int -> BindStack n
- DDC.Type.Transform.SubstituteT: stackAll :: BindStack n -> [Bind n]
+ DDC.Type.Transform.SubstituteT: stackAll :: BindStack n -> ![Bind n]
- DDC.Type.Transform.SubstituteT: stackAnons :: BindStack n -> Int
+ DDC.Type.Transform.SubstituteT: stackAnons :: BindStack n -> !Int
- DDC.Type.Transform.SubstituteT: stackBinds :: BindStack n -> [Bind n]
+ DDC.Type.Transform.SubstituteT: stackBinds :: BindStack n -> ![Bind n]
- DDC.Type.Transform.SubstituteT: stackNamed :: BindStack n -> Int
+ DDC.Type.Transform.SubstituteT: stackNamed :: BindStack n -> !Int
- DDC.Type.Universe: universeFromType1 :: Type n -> Maybe Universe
+ DDC.Type.Universe: universeFromType1 :: Ord n => Env n -> Type n -> Maybe Universe
- DDC.Type.Universe: universeOfType :: Type n -> Maybe Universe
+ DDC.Type.Universe: universeOfType :: Ord n => Env n -> Type n -> Maybe Universe

Files

DDC/Core/Check.hs view
@@ -1,17 +1,33 @@ --- | Type checker for the Disciple core language.+-- | Type checker for the Disciple Core language.+-- +--   The functions in this module do not check for language fragment compliance.+--   This needs to be done separately via "DDC.Core.Fragment".+-- module DDC.Core.Check-        ( -- * Checking Expressions-          checkExp,     typeOfExp+        ( -- * Configuration+          Config(..)+        , configOfProfile +          -- * Checking Modules+        , checkModule++          -- * Checking Expressions+        , checkExp,     typeOfExp+           -- * Checking Witnesses         , checkWitness, typeOfWitness         , typeOfWiCon +          -- * Annotations+        , AnTEC(..)+           -- * Error messages         , Error(..)) where import DDC.Core.Check.Error import DDC.Core.Check.ErrorMessage      ()+import DDC.Core.Check.CheckModule import DDC.Core.Check.CheckExp import DDC.Core.Check.CheckWitness+                
+ DDC/Core/Check/CheckDaCon.hs view
@@ -0,0 +1,50 @@++module DDC.Core.Check.CheckDaCon+        (checkDaConM)+where+import DDC.Core.Check.Error+import DDC.Core.Check.CheckWitness+import DDC.Core.DaCon+import DDC.Core.Exp+import DDC.Type.Compounds+import DDC.Type.DataDef+import DDC.Control.Monad.Check  (throw)+import Control.Monad+import Prelude                  as L+import qualified Data.Map       as Map+++-- | Check a data constructor.+--   The data constructor must be in the set of data type declarations.+checkDaConM+        :: (Ord n, Eq n, Show n)+        => Config n+        -> Exp a n              -- ^ The full expression for error messages.+        -> DaCon n              -- ^ Data constructor to check.+        -> CheckM a n ()++checkDaConM _ _ dc+ | DaConUnit    <- daConName dc+ = return ()++checkDaConM config xx dc+ | DaConNamed nCtor <- daConName dc+ , daConIsAlgebraic dc+ = let  tResult = snd $ takeTFunArgResult $ eraseTForalls $ typeOfDaCon dc+        defs    = configPrimDataDefs config+   in   case liftM fst $ takeTyConApps tResult of+         Just (TyConBound u _)+           | Just nType         <- takeNameOfBound u+           , Just dataType      <- Map.lookup nType (dataDefsTypes defs)+           -> case dataTypeMode dataType of+                DataModeSmall nsCtors+                 | L.elem nCtor nsCtors  -> return ()+                 | otherwise    -> throw $ ErrorUndefinedCtor xx++                DataModeLarge   -> return ()++         _ -> throw $ ErrorUndefinedCtor xx++checkDaConM _ _ _+ = return ()+
DDC/Core/Check/CheckExp.hs view
@@ -1,946 +1,1120 @@---- | Type checker for the Disciple Core language.-module DDC.Core.Check.CheckExp-        ( checkExp-        , typeOfExp-        , CheckM-        , checkExpM-        , TaggedClosure(..))-where-import DDC.Core.DataDef-import DDC.Core.Predicates-import DDC.Core.Compounds-import DDC.Core.Exp-import DDC.Core.Pretty-import DDC.Core.Collect-import DDC.Core.Check.Error-import DDC.Core.Check.CheckWitness-import DDC.Core.Check.TaggedClosure-import DDC.Type.Transform.SubstituteT-import DDC.Type.Transform.Crush-import DDC.Type.Transform.Trim-import DDC.Type.Transform.Instantiate-import DDC.Type.Transform.LiftT-import DDC.Type.Transform.LowerT-import DDC.Type.Equiv-import DDC.Type.Universe-import DDC.Type.Compounds-import DDC.Type.Predicates-import DDC.Type.Sum                     as Sum-import DDC.Type.Env                     (Env)-import DDC.Type.Check.Monad             (result, throw)-import DDC.Base.Pretty                  ()-import Data.Set                         (Set)-import qualified DDC.Type.Env           as Env-import qualified DDC.Type.Check         as T-import qualified Data.Set               as Set-import qualified Data.Map               as Map-import Control.Monad-import Data.List                        as L-import Data.Maybe----- Wrappers ---------------------------------------------------------------------- | Type check an expression. ------   If it's good, you get a new version with types attached to all the bound---   variables, as well its the type, effect and closure. ------   If it's bad, you get a description of the error.------   The returned expression has types attached to all variable occurrences, ---   so you can call `typeOfExp` on any open subterm.-checkExp -        :: (Ord n, Pretty n)-        => DataDefs n           -- ^ Data type definitions.-        -> Env n                -- ^ Kind environment.-        -> Env n                -- ^ Type environment.-        -> Exp a n              -- ^ Expression to check.-        -> Either (Error a n)-                  ( Exp a n-                  , Type n-                  , Effect n-                  , Closure n)--checkExp defs kenv tenv xx - = result- $ do   (xx', t, effs, clos) <- checkExpM defs kenv tenv xx-        return  ( xx'-                , t-                , TSum effs-                , closureOfTaggedSet clos)----- | Like `checkExp`, but check in an empty environment,---   and only return the value type of an expression.------   As this function is not given an environment, the types of free variables---   must be attached directly to the bound occurrences.---   This attachment is performed by `checkExp` above.----typeOfExp -        :: (Ord n, Pretty n)-        => DataDefs n-        -> Exp a n-        -> Either (Error a n) (Type n)-typeOfExp defs xx - = case checkExp defs Env.empty Env.empty xx of-        Left err           -> Left err-        Right (_, t, _, _) -> Right t----- checkExp ---------------------------------------------------------------------- | Like `checkExp` but using the `CheckM` monad to handle errors.-checkExpM -        :: (Ord n, Pretty n)-        => DataDefs n           -- ^ Data type definitions.-        -> Env n                -- ^ Kind environment.-        -> Env n                -- ^ Type environment.-        -> Exp a n              -- ^ Expression to check.-        -> CheckM a n -                ( Exp a n-                , Type n-                , TypeSum n-                , Set (TaggedClosure n))--checkExpM defs kenv tenv xx- = checkExpM' defs kenv tenv xx-{-} = do (xx', t, eff, clo) <- checkExpM' defs kenv tenv xx-      trace (pretty $ vcat -                [ text "checkExpM:  " <+> ppr xx -                , text "        ::  " <+> ppr t -                , text "        :!: " <+> ppr eff-                , text "        :$: " <+> ppr clo-                , text ""])-         $ return (xx', t, eff, clo)--}---- variables -------------------------------------checkExpM' _defs _kenv tenv (XVar a u)- = do   let tBound      = typeOfBound u-        let mtEnv       = Env.lookup u tenv--        let mkResult-             -- When annotation on the bound is bot,-             --  then use the type from the environment.-             | Just tEnv    <- mtEnv-             , isBot tBound-             = return tEnv--             -- The bound has an explicit type annotation,-             --  which matches the one from the environment.-             -- -             --  When the bound is a deBruijn index we need to lift the-             --  annotation on the original binder through any lambdas-             --  between the binding occurrence and the use.-             | Just tEnv    <- mtEnv-             , UIx i _      <- u-             , equivT tBound (liftT (i + 1) tEnv) -             = return tBound--             -- The bound has an explicit type annotation,-             --  which matches the one from the environment.-             | Just tEnv    <- mtEnv-             , equivT tBound tEnv-             = return tEnv--             -- The bound has an explicit type annotation,-             --  which does not match the one from the environment.-             --  This shouldn't happen because the parser doesn't add non-bot-             --  annotations to bound variables.-             | Just tEnv    <- mtEnv-             = throw $ ErrorVarAnnotMismatch u tEnv--             -- Variable not in environment, so use annotation.-             --  This happens when checking open terms.-             | otherwise-             = return tBound-        -        tResult  <- mkResult--        return  ( XVar a u -                , tResult-                , Sum.empty kEffect-                , Set.singleton -                        $ taggedClosureOfValBound -                        $ replaceTypeOfBound tResult u)----- constructors ----------------------------------checkExpM' defs _kenv _tenv xx@(XCon a u)-        | UName n _     <- u-        = case Map.lookup n (dataDefsCtors defs) of-           Nothing -> throw $ ErrorUndefinedCtor xx-           Just _  -            -> return  -                  ( XCon a u-                  , typeOfBound u-                  , Sum.empty kEffect-                  , Set.empty)--        | UPrim{}       <- u-        = return  ( XCon a u-                  , typeOfBound u-                  , Sum.empty kEffect-                  , Set.empty)--        -- Constructors can't be locally bound.-        | otherwise-        = throw $ ErrorMalformedExp xx----- application --------------------------------------- value-type application.-checkExpM' defs kenv tenv xx@(XApp a x1 (XType t2))- = do   (x1', t1, effs1, clos1) <- checkExpM  defs kenv tenv x1-        k2                      <- checkTypeM defs kenv t2-        case t1 of-         TForall b11 t12-          | typeOfBind b11 == k2-          -> return ( XApp a x1' (XType t2)  -                    , substituteT b11 t2 t12-                    , substituteT b11 t2 effs1-                    , clos1 `Set.union` taggedClosureOfTyArg t2)--          | otherwise   -> throw $ ErrorAppMismatch xx (typeOfBind b11) t2-         _              -> throw $ ErrorAppNotFun   xx t1 t2----- value-witness application.-checkExpM' defs kenv tenv xx@(XApp a x1 (XWitness w2))- = do   (x1', t1, effs1, clos1) <- checkExpM     defs kenv tenv x1-        t2                      <- checkWitnessM defs kenv tenv w2-        case t1 of-         TApp (TApp (TCon (TyConWitness TwConImpl)) t11) t12-          | t11 `equivT` t2   -          -> return ( XApp a x1' (XWitness w2)-                    , t12-                    , effs1-                    , clos1)--          | otherwise   -> throw $ ErrorAppMismatch xx t11 t2-         _              -> throw $ ErrorAppNotFun   xx t1 t2-                 ---- value-value application.-checkExpM' defs kenv tenv xx@(XApp a x1 x2)- = do   (x1', t1, effs1, clos1)    <- checkExpM defs kenv tenv x1-        (x2', t2, effs2, clos2)    <- checkExpM defs kenv tenv x2--        -- Note: we don't need to use the closure of the function because-        --       all of its components will already be part of clos1 above.-        case t1 of-         TApp (TApp (TApp (TApp (TCon (TyConSpec TcConFun)) t11) eff) _clo) t12-          | t11 `equivT` t2   -          , effs    <- Sum.fromList kEffect  [eff]-          -> return ( XApp a x1' x2'-                    , t12-                    , effs1 `Sum.union` effs2 `Sum.union` effs-                    , clos1 `Set.union` clos2)--          | otherwise   -> throw $ ErrorAppMismatch xx t11 t2-         _              -> throw $ ErrorAppNotFun xx t1 t2----- spec abstraction ------------------------------checkExpM' defs kenv tenv xx@(XLAM a b1 x2)- = do   let t1          = typeOfBind b1-        _               <- checkTypeM defs kenv t1--        -- Check the body-        let kenv'         = Env.extend b1 kenv-        let tenv'         = Env.lift   1  tenv-        (x2', t2, e2, c2) <- checkExpM  defs kenv' tenv' x2-        k2                <- checkTypeM defs kenv' t2--        when (Env.memberBind b1 kenv)-         $ throw $ ErrorLamShadow xx b1--        -- The body of a spec abstraction must be pure.-        when (e2 /= Sum.empty kEffect)-         $ throw $ ErrorLamNotPure xx (TSum e2)--        -- The body of a spec abstraction must have data kind.-        when (not $ isDataKind k2)-         $ throw $ ErrorLamBodyNotData xx b1 t2 k2--        -- Mask closure terms due to locally bound region vars.-        let c2_cut      = Set.fromList-                        $ mapMaybe (cutTaggedClosureT b1)-                        $ Set.toList c2--        return ( XLAM a b1 x2'-               , TForall b1 t2-               , Sum.empty kEffect-               , c2_cut)-         ---- function abstractions -------------------------checkExpM' defs kenv tenv xx@(XLam a b1 x2)- = do   let t1               =  typeOfBind b1-        k1                   <- checkTypeM defs kenv t1--        -- Check the body.-        let tenv'            =  Env.extend b1 tenv-        (x2', t2, e2, c2)    <- checkExpM  defs kenv tenv' x2   -        k2                   <- checkTypeM defs kenv t2--        -- The form of the function constructor depends on what universe the -        -- binder is in.-        case universeFromType2 k1 of-         Just UniverseData-          |  not $ isDataKind k1     -> throw $ ErrorLamBindNotData xx t1 k1-          |  not $ isDataKind k2     -> throw $ ErrorLamBodyNotData xx b1 t2 k2 -          |  otherwise-          -> let -                 -- Cut closure terms due to locally bound value vars.-                 -- This also lowers deBruijn indices in un-cut closure terms.-                 c2_cut  = Set.fromList-                         $ mapMaybe (cutTaggedClosureX b1)-                         $ Set.toList c2--                 -- Trim the closure before we annotate the returned function-                 -- type with it. -                 --  This should always succeed because trimClosure only returns-                 --  Nothing if the closure is miskinded, and we've already-                 --  allready checked that.-                 Just c2_captured-                  = trimClosure $ closureOfTaggedSet c2_cut--             in  return ( XLam a b1 x2'-                        , tFun t1 (TSum e2) c2_captured t2-                        , Sum.empty kEffect-                        , c2_cut) --         Just UniverseWitness-          | e2 /= Sum.empty kEffect  -> throw $ ErrorLamNotPure     xx (TSum e2)-          | not $ isDataKind k2      -> throw $ ErrorLamBodyNotData xx b1 t2 k2-          | otherwise                -          -> return ( XLam a b1 x2'-                    , tImpl t1 t2-                    , Sum.empty kEffect-                    , c2)--         _ -> throw $ ErrorMalformedType xx k1----- let ---------------------------------------------checkExpM' defs kenv tenv xx@(XLet a (LLet mode b11 x12) x2)- = do   -- Check the right of the binding.-        (x12', t12, effs12, clo12)  -         <- checkExpM defs kenv tenv x12--        -- Check binder annotation against the type we inferred for the right.-        (b11', k11')    -         <- checkLetBindOfTypeM xx defs kenv tenv t12 b11--        -- The right of the binding should have data kind.-        when (not $ isDataKind k11')-         $ throw $ ErrorLetBindingNotData xx b11' k11'-          -        -- Check the body expression.-        let tenv1  = Env.extend b11' tenv-        (x2', t2, effs2, c2)    <- checkExpM defs kenv tenv1 x2--        -- The body should have data kind.-        k2 <- checkTypeM defs kenv t2-        when (not $ isDataKind k2)-         $ throw $ ErrorLetBodyNotData xx t2 k2--        -- Mask closure terms due to locally bound value vars.-        let c2_cut      = Set.fromList-                        $ mapMaybe (cutTaggedClosureX b11')-                        $ Set.toList c2--        -- Check purity and emptiness for lazy bindings.-        (case mode of-          LetStrict     -> return ()-          LetLazy _-           -> do let eff12' = TSum effs12-                 when (not $ isBot eff12')-                  $ throw $ ErrorLetLazyNotPure xx b11 eff12'--                 let clo12' = closureOfTaggedSet clo12-                 when (not $ isBot clo12')-                  $ throw $ ErrorLetLazyNotEmpty xx b11 clo12')--        -- Check region witness for lazy bindings.-        (case mode of-          LetStrict     -> return ()--          -- Type of lazy binding has no head region, like Unit and (->).-          LetLazy Nothing-           -> do case takeDataTyConApps t12 of-                  Just (_tc, t1 : _)-                   ->  do k1 <- checkTypeM defs kenv t1-                          when (isRegionKind k1)-                           $ throw $ ErrorLetLazyNoWitness xx b11 t12--                  _ -> return ()--          -- Type of lazy binding might have a head region,-          -- so we need a Lazy witness for it.-          LetLazy (Just wit)-           -> do tWit        <- checkWitnessM defs kenv tenv wit-                 let tWitExp =  case takeDataTyConApps t12 of-                                 Just (_tc, tR : _ts) -> tLazy tR-                                 _                    -> tHeadLazy t12--                 when (not $ equivT tWit tWitExp)-                  $ throw $ ErrorLetLazyWitnessTypeMismatch -                                 xx b11 tWit t12 tWitExp)-                                     --        return ( XLet a (LLet mode b11' x12') x2'-               , t2-               , effs12 `Sum.union` effs2-               , clo12  `Set.union` c2_cut)----- letrec ------------------------------------------checkExpM' defs kenv tenv xx@(XLet a (LRec bxs) xBody)- = do   -        let (bs, xs)    = unzip bxs--        -- Check all the annotations.-        ks              <- mapM (checkTypeM defs kenv) -                        $  map typeOfBind bs--        -- Check all the annots have data kind.-        zipWithM_ (\b k-         -> when (not $ isDataKind k)-                $ throw $ ErrorLetBindingNotData xx b k)-                bs ks--        -- All right hand sides need to be lambdas.-        forM_ xs $ \x -         -> when (not $ (isXLam x || isXLAM x))-                $ throw $ ErrorLetrecBindingNotLambda xx x--        -- All variables are in scope in all right hand sides.-        let tenv'       = Env.extends bs tenv--        -- Check the right hand sides.-        (xsRight', tsRight, _effssBinds, clossBinds) -                <- liftM unzip4 $ mapM (checkExpM defs kenv tenv') xs--        -- Check annots on binders against inferred types of the bindings.-        zipWithM_ (\b t-                -> if not $ equivT (typeOfBind b) t-                        then throw $ ErrorLetMismatch xx b t-                        else return ())-                bs tsRight--        -- Check the body expression.-        (xBody', tBody, effsBody, closBody) -                <- checkExpM defs kenv tenv' xBody--        -- The body type must have data kind.-        kBody   <- checkTypeM defs kenv tBody-        when (not $ isDataKind kBody)-         $ throw $ ErrorLetBodyNotData xx tBody kBody--        -- Cut closure terms due to locally bound value vars.-        -- This also lowers deBruijn indices in un-cut closure terms.-        let clos_cut -                = Set.fromList-                $ mapMaybe (cutTaggedClosureXs bs)-                $ Set.toList -                $ Set.unions (closBody : clossBinds)--        return  ( XLet a (LRec (zip bs xsRight')) xBody'-                , tBody-                , effsBody-                , clos_cut)----- letregion ---------------------------------------checkExpM' defs kenv tenv xx@(XLet a (LLetRegion b bs) x)- = case takeSubstBoundOfBind b of-     Nothing     -> checkExpM defs kenv tenv x-     Just u-      -> do-        -- Check the type on the region binder.-        let k   = typeOfBind b-        checkTypeM defs kenv k--        -- The binder must have region kind.-        when (not $ isRegionKind k)-         $ throw $ ErrorLetRegionNotRegion xx b k--        -- We can't shadow region binders because we might have witnesses-        -- in the environment that conflict with the ones created here.-        when (Env.memberBind b kenv)-         $ throw $ ErrorLetRegionRebound xx b-        -        -- Check the witness types.-        let kenv'       = Env.extend b kenv-        let tenv'       = Env.lift 1 tenv-        mapM_ (checkTypeM defs kenv') $ map typeOfBind bs--        -- Check that the witnesses bound here are for the region,-        -- and they don't conflict with each other.-        checkWitnessBindsM xx u bs--        -- Check the body expression.-        let tenv2       = Env.extends bs tenv'-        (xBody', tBody, effs, clo)  <- checkExpM defs kenv' tenv2 x--        -- The body type must have data kind.-        kBody           <- checkTypeM defs kenv' tBody-        when (not $ isDataKind kBody)-         $ throw $ ErrorLetBodyNotData xx tBody kBody--        -- The bound region variable cannot be free in the body type.-        let fvsT         = freeT Env.empty tBody-        when (Set.member u fvsT)-         $ throw $ ErrorLetRegionFree xx b tBody-        -        -- Delete effects on the bound region from the result.-        let effs'       = Sum.delete (tRead  (TVar u))-                        $ Sum.delete (tWrite (TVar u))-                        $ Sum.delete (tAlloc (TVar u))-                        $ effs--        -- Delete the bound region variable from the closure.-        -- Mask closure terms due to locally bound region vars.-        let c2_cut      = Set.fromList-                        $ mapMaybe (cutTaggedClosureT b)-                        $ Set.toList clo--        return  ( XLet a (LLetRegion b bs) xBody'-                , lowerT 1 tBody-                , lowerT 1 effs'-                , c2_cut)----- withregion ------------------------------------checkExpM' defs kenv tenv xx@(XLet a (LWithRegion u) x)- = do   -- Check the type on the region handle.-        let k   = typeOfBound u-        checkTypeM defs kenv k--        -- The handle must have region kind.-        when (not $ isRegionKind k)-         $ throw $ ErrorWithRegionNotRegion xx u k-        -        -- Check the body expression.-        (xBody', tBody, effs, clo) -               <- checkExpM defs kenv tenv x--        -- The body type must have data kind.-        kBody  <- checkTypeM defs kenv tBody-        when (not $ isDataKind kBody)-         $ throw $ ErrorLetBodyNotData xx tBody kBody-        -        -- Delete effects on the bound region from the result.-        let tu          = TCon $ TyConBound u-        let effs'       = Sum.delete (tRead  tu)-                        $ Sum.delete (tWrite tu)-                        $ Sum.delete (tAlloc tu)-                        $ effs-        -        -- Delete the bound region handle from the closure.-        let clo_masked  = Set.delete (GBoundRgnCon u) clo--        return  ( XLet a (LWithRegion u) xBody'-                , tBody-                , effs'-                , clo_masked)-                ---- case expression -------------------------------checkExpM' defs kenv tenv xx@(XCase a xDiscrim alts)- = do-        -- Check the discriminant.-        (xDiscrim', tDiscrim, effsDiscrim, closDiscrim) -         <- checkExpM defs kenv tenv xDiscrim--        -- Split the type into the type constructor names and type parameters.-        -- Also check that it's algebraic data, and not a function or effect-        -- type etc. -        (nTyCon, tsArgs)-         <- case takeTyConApps tDiscrim of-                Just (tc, ts)-                 | TyConBound (UName n t) <- tc-                 , takeResultKind t == kData-                 -> return (n, ts)-                      -                 | TyConBound (UPrim n t) <- tc-                 , takeResultKind t == kData-                 -> return (n, ts)--                _ -> throw $ ErrorCaseDiscrimNotAlgebraic xx tDiscrim--        -- Get the mode of the data type, -        --   this tells us how many constructors there are.-        mode    -         <- case lookupModeOfDataType nTyCon defs of-             Nothing -> throw $ ErrorCaseDiscrimTypeUndeclared xx tDiscrim-             Just m  -> return m--        -- Check the alternatives.-        (alts', ts, effss, closs)     -                <- liftM unzip4-                $  mapM (checkAltM xx defs kenv tenv tDiscrim tsArgs) alts--        -- There must be at least one alternative-        when (null ts)-         $ throw $ ErrorCaseNoAlternatives xx--        -- All alternative result types must be identical.-        let (tAlt : _)  = ts-        forM_ ts $ \tAlt' -         -> when (not $ equivT tAlt tAlt') -             $ throw $ ErrorCaseAltResultMismatch xx tAlt tAlt'--        -- Check for overlapping alternatives.-        let pats                = [p | AAlt p _ <- alts]-        let psDefaults          = filter isPDefault pats-        let nsCtorsMatched      = mapMaybe takeCtorNameOfAlt alts--        -- Alts overlapping because there are multiple defaults.-        when (length psDefaults > 1)-         $ throw $ ErrorCaseOverlapping xx--        -- Alts overlapping because the same ctor is used multiple times.-        when (length (nub nsCtorsMatched) /= length nsCtorsMatched )-         $ throw $ ErrorCaseOverlapping xx--        -- Check for alts overlapping because a default is not last.-        -- Also check there is at least one alternative.-        (case pats of-          [] -> throw $ ErrorCaseNoAlternatives xx--          _  |  or $ map isPDefault $ init pats -             -> throw $ ErrorCaseOverlapping xx--             |  otherwise-             -> return ())--        -- Check the alternatives are exhaustive.-        (case mode of--          -- Small types have some finite number of constructors.-          DataModeSmall nsCtors-           -- If there is a default alternative then we've covered all the-           -- possibiliies. We know this we've also checked for overlap.-           | any isPDefault [p | AAlt p _ <- alts]-           -> return ()--           -- Look for unmatched constructors.-           | nsCtorsMissing <- nsCtors \\ nsCtorsMatched-           , not $ null nsCtorsMissing-           -> throw $ ErrorCaseNonExhaustive xx nsCtorsMissing--           -- All constructors were matched.-           | otherwise -           -> return ()--          -- Large types have an effectively infinite number of constructors-          -- (like integer literals), so there needs to be a default alt.-          DataModeLarge -           | any isPDefault [p | AAlt p _ <- alts] -> return ()-           | otherwise  -           -> throw $ ErrorCaseNonExhaustiveLarge xx)--        let effsMatch    -                = Sum.singleton kEffect -                $ crushEffect $ tHeadRead tDiscrim--        return  ( XCase a xDiscrim' alts'-                , tAlt-                , Sum.unions kEffect (effsDiscrim : effsMatch : effss)-                , Set.unions         (closDiscrim : closs) )----- type cast ---------------------------------------- Weaken an effect, adding in the given terms.-checkExpM' defs kenv tenv xx@(XCast a c@(CastWeakenEffect eff) x1)- = do   -        -- Check the effect term.-        kEff    <- checkTypeM defs kenv eff-        when (not $ isEffectKind kEff)-         $ throw $ ErrorMaxeffNotEff xx eff kEff--        -- Check the body.-        (x1', t1, effs, clo)    <- checkExpM defs kenv tenv x1--        return  ( XCast a c x1'-                , t1-                , Sum.insert eff effs-                , clo)----- Weaken a closure, adding in the given terms.-checkExpM' defs kenv tenv xx@(XCast a c@(CastWeakenClosure clo2) x1)- = do   -        -- Check the closure term.-        kClo    <- checkTypeM defs kenv clo2-        when (not $ isClosureKind kClo)-         $ throw $ ErrorMaxcloNotClo xx clo2 kClo--        -- The closure supplied to weakclo can only contain Use terms-        -- of region variables.-        clos2-         <- case taggedClosureOfWeakClo clo2 of-             Nothing     -> throw $ ErrorMaxcloMalformed xx clo2-             Just clos2' -> return clos2'--        -- Check the body.-        (x1', t1, effs, clos)   <- checkExpM defs kenv tenv x1--        return  ( XCast a c x1'-                , t1-                , effs-                , Set.union clos clos2)----- Purify an effect, given a witness that it is pure.-checkExpM' defs kenv tenv xx@(XCast a c@(CastPurify w) x1)- = do   tW                   <- checkWitnessM defs kenv tenv w-        (x1', t1, effs, clo) <- checkExpM     defs kenv tenv x1-                -        effs' <- case tW of-                  TApp (TCon (TyConWitness TwConPure)) effMask-                    -> return $ Sum.delete effMask effs-                  _ -> throw  $ ErrorWitnessNotPurity xx w tW--        return  ( XCast a c x1'-                , t1-                , effs'-                , clo)----- Forget a closure, given a witness that it is empty.-checkExpM' defs kenv tenv xx@(XCast a c@(CastForget w) x1)- = do   tW                    <- checkWitnessM defs kenv tenv w-        (x1', t1, effs, clos) <- checkExpM     defs kenv tenv x1--        clos' <- case tW of-                  TApp (TCon (TyConWitness TwConEmpty)) cloMask-                    -> return $ maskFromTaggedSet -                                        (Sum.singleton kClosure cloMask)-                                        clos--                  _ -> throw $ ErrorWitnessNotEmpty xx w tW--        return  ( XCast a c x1'-                , t1-                , effs-                , clos')----- Type and witness expressions can only appear as the arguments --- to  applications.-checkExpM' _defs _kenv _tenv xx@(XType _)-        = throw $ ErrorNakedType xx --checkExpM' _defs _kenv _tenv xx@(XWitness _)-        = throw $ ErrorNakedWitness xx------------------------------------------------------------------------------------- | Check a case alternative.-checkAltM -        :: (Pretty n, Ord n) -        => Exp a n              -- ^ Whole case expression, for error messages.-        -> DataDefs n           -- ^ Data type definitions.-        -> Env n                -- ^ Kind environment.-        -> Env n                -- ^ Type environment.-        -> Type n               -- ^ Type of discriminant.-        -> [Type n]             -- ^ Args to type constructor of discriminant.-        -> Alt a n              -- ^ Alternative to check.-        -> CheckM a n -                ( Alt a n-                , Type n-                , TypeSum n-                , Set (TaggedClosure n))--checkAltM _xx defs kenv tenv _tDiscrim _tsArgs (AAlt PDefault xBody)- = do   (xBody', tBody, effBody, cloBody)-                <- checkExpM defs kenv tenv xBody--        return  ( AAlt PDefault xBody'-                , tBody-                , effBody-                , cloBody)--checkAltM xx defs kenv tenv tDiscrim tsArgs (AAlt (PData uCon bsArg) xBody)- = do   -        -- Take the type of the constructor and instantiate it with the -        -- type arguments we got from the discriminant. -        -- If the ctor type doesn't instantiate then it won't have enough foralls -        -- on the front, which should have been checked by the def checker.-        let tCtor       = typeOfBound uCon-        tCtor_inst      -         <- case instantiateTs tCtor tsArgs of-             Nothing -> throw $ ErrorCaseCannotInstantiate xx tDiscrim tCtor-             Just t  -> return t-        -        -- Split the constructor type into the field and result types.-        let (tsFields_ctor, tResult) -                        = takeTFunArgResult tCtor_inst--        -- The result type of the constructor must match the discriminant type.-        --  If it doesn't then the constructor in the pattern probably isn't for-        --  the discriminant type.-        when (not $ equivT tDiscrim tResult)-         $ throw $ ErrorCaseDiscrimTypeMismatch xx tDiscrim tResult--        -- There must be at least as many fields as variables in the pattern.-        -- It's ok to bind less fields than provided by the constructor.-        when (length tsFields_ctor < length bsArg)-         $ throw $ ErrorCaseTooManyBinders xx uCon -                        (length tsFields_ctor)-                        (length bsArg)--        -- Merge the field types we get by instantiating the constructor-        -- type with possible annotations from the source program.-        -- If the annotations don't match, then we throw an error.-        tsFields        <- zipWithM (mergeAnnot xx)-                            (map typeOfBind bsArg)-                            tsFields_ctor        --        -- Extend the environment with the field types.-        let bsArg'      = zipWith replaceTypeOfBind tsFields bsArg-        let tenv'       = Env.extends bsArg' tenv-        -        -- Check the body in this new environment.-        (xBody', tBody, effsBody, closBody)-                <- checkExpM defs kenv tenv' xBody--        -- Cut closure terms due to locally bound value vars.-        -- This also lowers deBruijn indices in un-cut closure terms.-        let closBody_cut -                = Set.fromList-                $ mapMaybe (cutTaggedClosureXs bsArg')-                $ Set.toList closBody--        return  ( AAlt (PData uCon bsArg') xBody'-                , tBody-                , effsBody-                , closBody_cut)----- | Merge a type annotation on a pattern field with a type we get by---   instantiating the constructor type.-mergeAnnot :: Eq n => Exp a n -> Type n -> Type n -> CheckM a n (Type n)-mergeAnnot xx tAnnot tActual-        -- Annotation is bottom, so just use the real type.-        | isBot tAnnot      = return tActual--        -- Annotation matches actual type, all good.-        | tAnnot == tActual = return tActual--        -- Annotation does not match actual type.-        | otherwise       -        = throw $ ErrorCaseFieldTypeMismatch xx tAnnot tActual------------------------------------------------------------------------------------- | Check the set of witness bindings bound in a letregion for conflicts.-checkWitnessBindsM :: Ord n => Exp a n -> Bound n -> [Bind n] -> CheckM a n ()-checkWitnessBindsM xx nRegion bsWits- = mapM_ (checkWitnessBindM xx nRegion bsWits) bsWits---checkWitnessBindM -        :: Ord n -        => Exp a n-        -> Bound n              -- ^ Region variable bound in the letregion.-        -> [Bind n]             -- ^ Other witness bindings in the same set.-        -> Bind  n              -- ^ The witness binding to check.-        -> CheckM a n ()--checkWitnessBindM xx uRegion bsWit bWit- = let btsWit   -        = [(typeOfBind b, b) | b <- bsWit]--       -- Check the argument of a witness type is for the region we're-       -- introducing here.-       checkWitnessArg t-        = case t of-            TVar u'-             | uRegion /= u'    -> throw $ ErrorLetRegionWitnessOther xx uRegion bWit-             | otherwise        -> return ()--            TCon (TyConBound u')-             | uRegion /= u'    -> throw $ ErrorLetRegionWitnessOther xx uRegion bWit-             | otherwise        -> return ()--            -- The parser should ensure the right of a witness is a -            -- constructor or variable.-            _ -> throw $ ErrorLetRegionWitnessInvalid xx bWit--   in  case typeOfBind bWit of-        TApp (TCon (TyConWitness TwConGlobal))  t2-         -> checkWitnessArg t2--        TApp (TCon (TyConWitness TwConConst))   t2-         | Just bConflict <- L.lookup (tMutable t2) btsWit-         -> throw $ ErrorLetRegionWitnessConflict xx bWit bConflict-         | otherwise    -> checkWitnessArg t2--        TApp (TCon (TyConWitness TwConMutable)) t2-         | Just bConflict <- L.lookup (tConst t2)   btsWit-         -> throw $ ErrorLetRegionWitnessConflict xx bWit bConflict-         | otherwise    -> checkWitnessArg t2--        TApp (TCon (TyConWitness TwConLazy))    t2-         | Just bConflict <- L.lookup (tManifest t2)  btsWit-         -> throw $ ErrorLetRegionWitnessConflict xx bWit bConflict-         | otherwise    -> checkWitnessArg t2--        TApp (TCon (TyConWitness TwConManifest))  t2-         | Just bConflict <- L.lookup (tLazy t2)    btsWit-         -> throw $ ErrorLetRegionWitnessConflict xx bWit bConflict-         | otherwise    -> checkWitnessArg t2--        _ -> throw $ ErrorLetRegionWitnessInvalid xx bWit------------------------------------------------------------------------------------- | Check a type in the exp checking monad.-checkTypeM :: (Ord n, Pretty n) -           => DataDefs n -           -> Env n -           -> Type n -           -> CheckM a n (Kind n)--checkTypeM defs kenv tt- = case T.checkType defs kenv tt of-        Left err        -> throw $ ErrorType err-        Right k         -> return k------------------------------------------------------------------------------------- | Check the type annotation of a let bound variable against the type---   inferred for the right of the binding.---   If the annotation is Bot then we just replace the annotation,---   otherwise it must match that for the right of the binding.-checkLetBindOfTypeM -        :: (Eq n, Ord n, Pretty n) -        => Exp a n -        -> DataDefs n           -- Data type definitions.-        -> Env n                -- Kind environment. -        -> Env n                -- Type environment.-        -> Type n -        -> Bind n -        -> CheckM a n (Bind n, Kind n)--checkLetBindOfTypeM xx defs kenv _tenv tRight b-        -- If the annotation is Bot then just replace it.-        | isBot (typeOfBind b)-        = do    k       <- checkTypeM defs kenv tRight-                return  ( replaceTypeOfBind tRight b -                        , k)--        -- The type of the binder must match that of the right of the binding.-        | not $ equivT (typeOfBind b) tRight-        = throw $ ErrorLetMismatch xx b tRight--        | otherwise-        = do    k       <- checkTypeM defs kenv (typeOfBind b)-                return (b, k)-+-- | Type checker for the Disciple Core language.+module DDC.Core.Check.CheckExp+        ( Config (..)+        , AnTEC  (..)+        , checkExp+        , typeOfExp+        , CheckM+        , checkExpM+        , TaggedClosure(..))+where+import DDC.Core.Predicates+import DDC.Core.Compounds+import DDC.Core.Collect+import DDC.Core.Pretty+import DDC.Core.Exp+import DDC.Core.Check.Error+import DDC.Core.Check.CheckDaCon+import DDC.Core.Check.CheckWitness+import DDC.Core.Check.TaggedClosure+import DDC.Type.Transform.SubstituteT+import DDC.Type.Transform.Crush+import DDC.Type.Transform.Trim+import DDC.Type.Transform.Instantiate+import DDC.Type.Transform.LiftT+import DDC.Type.DataDef+import DDC.Type.Equiv+import DDC.Type.Universe+import DDC.Type.Sum                     as Sum+import DDC.Type.Env                     (Env, KindEnv, TypeEnv)+import DDC.Control.Monad.Check          (throw, result)+import Data.Set                         (Set)+import qualified DDC.Type.Env           as Env+import qualified Data.Set               as Set+import Control.Monad+import DDC.Data.ListUtils+import Data.List                        as L+import Data.Maybe+import Data.Typeable+import Control.DeepSeq+++-- Annot ----------------------------------------------------------------------+-- | The type checker adds this annotation to every node in the AST, +--   giving its type, effect and closure.+---+--   NOTE: We wwant to leave the components lazy so that the checker+--         doesn't actualy need to produce the type components if they're+--         not needed.+data AnTEC a n+        = AnTEC+        { annotType     :: (Type    n)+        , annotEffect   :: (Effect  n)+        , annotClosure  :: (Closure n)+        , annotTail     :: a }+        deriving (Show, Typeable)+++instance (NFData a, NFData n) => NFData (AnTEC a n) where+ rnf !an+        =     rnf (annotType    an)+        `seq` rnf (annotEffect  an)+        `seq` rnf (annotClosure an)+        `seq` rnf (annotTail    an)+++instance Pretty (AnTEC a n) where+ ppr _ = text "AnTEC"        ++++-- Wrappers -------------------------------------------------------------------+-- | Type check an expression. +--+--   If it's good, you get a new version with types attached to all the bound+--   variables, as well its the type, effect and closure. +--+--   If it's bad, you get a description of the error.+--+--   The returned expression has types attached to all variable occurrences, +--   so you can call `typeOfExp` on any open subterm.+--+--   The kinds and types of primitives are added to the environments +--   automatically, you don't need to supply these as part of the +--   starting environments.+--+checkExp +        :: (Ord n, Show n, Pretty n)+        => Config n             -- ^ Static configuration.+        -> KindEnv n            -- ^ Starting Kind environment.+        -> TypeEnv n            -- ^ Strating Type environment.+        -> Exp a n              -- ^ Expression to check.+        -> Either (Error a n)+                  ( Exp (AnTEC a n) n+                  , Type n+                  , Effect n+                  , Closure n)++checkExp !config !kenv !tenv !xx + = result+ $ do   (xx', t, effs, clos) +                <- checkExpM config +                        (Env.union kenv (configPrimKinds config))+                        (Env.union tenv (configPrimTypes config))+                        xx+        return  ( xx'+                , t+                , TSum effs+                , closureOfTaggedSet clos)+++-- | Like `checkExp`, but only return the value type of an expression.+typeOfExp +        :: (Ord n, Pretty n, Show n)+        => Config n             -- ^ Static configuration.+        -> KindEnv n            -- ^ Starting Kind environment+        -> TypeEnv n            -- ^ Starting Type environment.+        -> Exp a n              -- ^ Expression to check.+        -> Either (Error a n) (Type n)+typeOfExp !config !kenv !tenv !xx + = case checkExp config kenv tenv xx of+        Left err           -> Left err+        Right (_, t, _, _) -> Right t+++-- checkExp -------------------------------------------------------------------+-- | Like `checkExp` but using the `CheckM` monad to handle errors.+checkExpM +        :: (Show n, Pretty n, Ord n)+        => Config n             -- ^ Static config.+        -> Env n                -- ^ Kind environment.+        -> Env n                -- ^ Type environment.+        -> Exp a n              -- ^ Expression to check.+        -> CheckM a n +                ( Exp (AnTEC a n) n+                , Type n+                , TypeSum n+                , Set (TaggedClosure n))++checkExpM !config !kenv !tenv !xx+ = {-# SCC checkExpM #-}+   checkExpM' config kenv tenv xx++-- variables ------------------------------------+checkExpM' !_config !_kenv !tenv (XVar a u)+ = case Env.lookup u tenv of+        Nothing -> throw $ ErrorUndefinedVar u UniverseData+        Just t  +         -> returnX a +                (\z -> XVar z u)+                t+                (Sum.empty kEffect)+                (Set.singleton $ taggedClosureOfValBound t u)+++-- constructors ---------------------------------+checkExpM' !config !_kenv !_tenv xx@(XCon a dc)+ = do   +        -- All data constructors need to have valid type annotations.+        when (isBot $ daConType dc)+         $ throw $ ErrorUndefinedCtor xx++        -- Check that the constructor is in the data type declarations.+        checkDaConM config xx dc++        -- Type of the data constructor.+        let tResult     +                = typeOfDaCon dc++        returnX a+                (\z -> XCon z dc)+                tResult+                (Sum.empty kEffect)+                Set.empty+++-- application ------------------------------------+-- value-type application.+--+-- Note: We don't need to substitute into the effect of x1 (effs1)+--       because the body of a type abstraction is required to be pure.+-- +--       We don't need to substitute into the closure either, because+--       the bound type variable is not visible outside the abstraction.+--       thus we can't be sharing objects that have it in its type.+--+checkExpM' !config !kenv !tenv xx@(XApp a x1 (XType t2))+ = do   (x1', t1, effs1, clos1) <- checkExpM  config kenv tenv x1++        -- Check the type argument.+        k2                      <- checkTypeM config kenv t2++        -- Take any Use annots from a region arg.+        --   This always matches because we just checked 't2'+        let Just t2_clo         = taggedClosureOfTyArg kenv t2++        case t1 of+         TForall b11 t12+          | typeOfBind b11 == k2+          -> returnX a+                (\z -> XApp z x1' (XType t2))+                (substituteT b11 t2 t12)+                effs1   +                (clos1 `Set.union` t2_clo)++          | otherwise   -> throw $ ErrorAppMismatch xx (typeOfBind b11) t2+         _              -> throw $ ErrorAppNotFun   xx t1 t2+++-- value-witness application.+checkExpM' !config !kenv !tenv xx@(XApp a x1 (XWitness w2))+ = do   (x1', t1, effs1, clos1) <- checkExpM     config kenv tenv x1+        t2                      <- checkWitnessM config kenv tenv w2+        case t1 of+         TApp (TApp (TCon (TyConWitness TwConImpl)) t11) t12+          | t11 `equivT` t2   +          -> returnX a+                (\z -> XApp z x1' (XWitness w2))+                t12 effs1 clos1++          | otherwise   -> throw $ ErrorAppMismatch xx t11 t2+         _              -> throw $ ErrorAppNotFun   xx t1 t2+                 ++-- value-value application.+checkExpM' !config !kenv !tenv xx@(XApp a x1 x2)+ = do   (x1', t1, effs1, clos1)    <- checkExpM config kenv tenv x1+        (x2', t2, effs2, clos2)    <- checkExpM config kenv tenv x2++        -- Note: we don't need to use the closure of the function because+        --       all of its components will already be part of clos1 above.+        case t1 of+         TApp (TApp (TApp (TApp (TCon (TyConSpec TcConFun)) t11) eff) _clo) t12+          | t11 `equivT` t2   +          , effs    <- Sum.fromList kEffect  [eff]+          -> returnX a+                (\z -> XApp z x1' x2')+                t12+                (effs1 `Sum.union` effs2 `Sum.union` effs)+                (clos1 `Set.union` clos2)++          | otherwise   -> throw $ ErrorAppMismatch xx t11 t2+         _              -> throw $ ErrorAppNotFun xx t1 t2+++-- spec abstraction -----------------------------+checkExpM' !config !kenv !tenv xx@(XLAM a b1 x2)+ = do   let t1            = typeOfBind b1+        _                 <- checkTypeM config kenv t1++        -- Check the body+        let kenv'         = Env.extend b1 kenv+        let tenv'         = Env.lift   1  tenv+        (x2', t2, e2, c2) <- checkExpM  config kenv' tenv' x2+        k2                <- checkTypeM config kenv' t2++        when (Env.memberBind b1 kenv)+         $ throw $ ErrorLamShadow xx b1++        -- The body of a spec abstraction must be pure.+        when (e2 /= Sum.empty kEffect)+         $ throw $ ErrorLamNotPure xx True (TSum e2)++        -- The body of a spec abstraction must have data kind.+        when (not $ isDataKind k2)+         $ throw $ ErrorLamBodyNotData xx b1 t2 k2++        -- Mask closure terms due to locally bound region vars.+        let c2_cut      = Set.fromList+                        $ mapMaybe (cutTaggedClosureT b1)+                        $ Set.toList c2++        returnX a+                (\z -> XLAM z b1 x2')+                (TForall b1 t2)+                (Sum.empty kEffect)+                c2_cut+         ++-- function abstraction -------------------------+checkExpM' !config !kenv !tenv xx@(XLam a b1 x2)+ = do   +        -- Check the type of the binder.+        let t1  =  typeOfBind b1+        k1      <- checkTypeM config kenv t1++        -- Check the body.+        let tenv'            =  Env.extend b1 tenv+        (x2', t2, e2, c2)    <- checkExpM  config kenv tenv' x2   ++        -- The typing rules guarantee that the checked type of an +        -- expression is well kinded, but we need to check it again+        -- to find out what that kind is.+        k2      <- checkTypeM config kenv t2++        -- The form of the function constructor depends on what universe the +        -- binder is in.+        case universeFromType2 k1 of++         -- This is a data abstraction.+         Just UniverseData++          -- The body of a data abstraction must accept data.+          |  not $ isDataKind k1+          -> throw $ ErrorLamBindNotData xx t1 k1++          -- The body of a data abstraction must produce data.+          |  not $ isDataKind k2+          -> throw $ ErrorLamBodyNotData xx b1 t2 k2 ++          -- Looks good.+          |  otherwise+          -> let +                 -- Cut closure terms due to locally bound value vars.+                 -- This also lowers deBruijn indices in un-cut closure terms.+                 c2_cut  = Set.fromList+                         $ mapMaybe (cutTaggedClosureX b1)+                         $ Set.toList c2++                 -- Trim the closure before we annotate the returned function+                 -- type with it. This should always succeed because trimClosure+                 -- only returns Nothing if the closure is miskinded, and we've+                 -- already already checked that.+                 Just c2_captured++                  -- If we're suppressing closures then just drop them on the+                  -- floor. The consumer of this core program doesn't care.+                  | configSuppressClosures config+                  = Just $ tBot kClosure++                  | otherwise+                  = trimClosure $ closureOfTaggedSet c2_cut++             in  returnX a+                        (\z -> XLam z b1 x2')+                        (tFun t1 (TSum e2) c2_captured t2)+                        (Sum.empty kEffect)+                        c2_cut++         -- This is a witness abstraction.+         Just UniverseWitness++          -- The body of a witness abstraction must be pure.+          | e2 /= Sum.empty kEffect  +          -> throw $ ErrorLamNotPure  xx False (TSum e2)++          -- The body of a witness abstraction must produce data.+          | not $ isDataKind k2      +          -> throw $ ErrorLamBodyNotData xx b1 t2 k2++          -- Looks good.+          | otherwise                +          ->    returnX a+                        (\z -> XLam z b1 x2')+                        (tImpl t1 t2)+                        (Sum.empty kEffect)+                        c2++         _ -> throw $ ErrorMalformedType xx k1+++-- let --------------------------------------------+checkExpM' !config !kenv !tenv xx@(XLet a lts x2)+ | case lts of+        LLet{}  -> True+        LRec{}  -> True+        _       -> False++ = do+        -- Check the bindings+        (lts', bs', effs12, clo12)+                <- checkLetsM xx config kenv tenv lts++        -- Check the body expression.+        let tenv1  = Env.extends bs' tenv+        (x2', t2, effs2, c2)    <- checkExpM config kenv tenv1 x2++        -- The body should have data kind.+        k2       <- checkTypeM config kenv t2+        when (not $ isDataKind k2)+         $ throw $ ErrorLetBodyNotData xx t2 k2++        -- Mask closure terms due to locally bound value vars.+        let c2_cut      = Set.fromList+                        $ mapMaybe (cutTaggedClosureXs bs')+                        $ Set.toList c2++        returnX a+                (\z -> XLet z lts' x2')+                t2+                (effs12 `Sum.union` effs2)+                (clo12  `Set.union` c2_cut)+++-- letregion --------------------------------------+checkExpM' !config !kenv !tenv xx@(XLet a (LLetRegions bsRgn bsWit) x)+ = case takeSubstBoundsOfBinds bsRgn of+    []   -> checkExpM config kenv tenv x     +    us   -> do+        -- +        let depth = length $ map isBAnon bsRgn++        -- Check the type on the region binders.+        let ks    = map typeOfBind bsRgn+        mapM_ (checkTypeM config kenv) ks++        -- The binders must have region kind.+        when (any (not . isRegionKind) ks) +         $ throw $ ErrorLetRegionsNotRegion xx bsRgn ks++        -- We can't shadow region binders because we might have witnesses+        -- in the environment that conflict with the ones created here.+        let rebounds = filter (flip Env.memberBind kenv) bsRgn+        when (not $ null rebounds)+         $ throw $ ErrorLetRegionsRebound xx rebounds+        +        -- Check the witness types.+        let kenv'       = Env.extends bsRgn kenv+        let tenv'       = Env.lift depth tenv+        mapM_ (checkTypeM config kenv') $ map typeOfBind bsWit++        -- Check that the witnesses bound here are for the region,+        -- and they don't conflict with each other.+        checkWitnessBindsM kenv xx us bsWit++        -- Check the body expression.+        let tenv2       = Env.extends bsWit tenv'+        (xBody', tBody, effs, clo)  <- checkExpM config kenv' tenv2 x++        -- The body type must have data kind.+        kBody           <- checkTypeM config kenv' tBody+        when (not $ isDataKind kBody)+         $ throw $ ErrorLetBodyNotData xx tBody kBody++        -- The bound region variable cannot be free in the body type.+        let fvsT         = freeT Env.empty tBody+        when (any (flip Set.member fvsT) us)+         $ throw $ ErrorLetRegionFree xx bsRgn tBody+        +        -- Delete effects on the bound region from the result.+        let delEff es u = Sum.delete (tRead  (TVar u))+                        $ Sum.delete (tWrite (TVar u))+                        $ Sum.delete (tAlloc (TVar u))+                        $ es+        let effs'       = foldl delEff effs us ++        -- Delete the bound region variable from the closure.+        -- Mask closure terms due to locally bound region vars.+        let cutClo c r  = mapMaybe (cutTaggedClosureT r) c+        let c2_cut      = Set.fromList +                        $ foldl cutClo (Set.toList clo) bsRgn++        returnX a+                (\z -> XLet z (LLetRegions bsRgn bsWit) xBody')+                (lowerT depth tBody)+                (lowerT depth effs')+                c2_cut+++-- withregion -----------------------------------+checkExpM' !config !kenv !tenv xx@(XLet a (LWithRegion u) x)+ = do+        -- The handle must have region kind.+        (case Env.lookup u kenv of+          Nothing -> throw $ ErrorUndefinedVar u UniverseSpec++          Just k  |  not $ isRegionKind k+                  -> throw $ ErrorWithRegionNotRegion xx u k++          _       -> return ())+        +        -- Check the body expression.+        (xBody', tBody, effs, clo) +               <- checkExpM config kenv tenv x++        -- The body type must have data kind.+        kBody  <- checkTypeM config kenv tBody+        when (not $ isDataKind kBody)+         $ throw $ ErrorLetBodyNotData xx tBody kBody+        +        -- The bound region variable cannot be free in the body type.+        let tcs         = supportTyCon+                        $ support Env.empty Env.empty tBody+        when (Set.member u tcs)+         $ throw $ ErrorWithRegionFree xx u tBody++        -- Delete effects on the bound region from the result.+        let tu          = TCon $ TyConBound u kRegion+        let effs'       = Sum.delete (tRead  tu)+                        $ Sum.delete (tWrite tu)+                        $ Sum.delete (tAlloc tu)+                        $ effs+        +        -- Delete the bound region handle from the closure.+        let clo_masked  = Set.delete (GBoundRgnCon u) clo++        returnX a+                (\z -> XLet z (LWithRegion u) xBody')+                tBody+                effs'+                clo_masked+                ++-- case expression ------------------------------+checkExpM' !config !kenv !tenv xx@(XCase a xDiscrim alts)+ = do   +        -- Check the discriminant.+        (xDiscrim', tDiscrim, effsDiscrim, closDiscrim) +         <- checkExpM config kenv tenv xDiscrim++        -- Split the type into the type constructor names and type parameters.+        -- Also check that it's algebraic data, and not a function or effect+        -- type etc. +        (mmode, tsArgs)+         <- case takeTyConApps tDiscrim of+                Just (tc, ts)+                 | TyConSpec TcConUnit         <- tc+                 -> return ( Just (DataModeSmall [])+                           , [] )+                        -- ISSUE #269: Refactor DataModeSmall to hold DaCons instead of names.+                        --  The DataModeSmall should hold DaCons instead of+                        --  names, as we don't have a name for Unit.++                 | TyConBound (UName nTyCon) k <- tc+                 , takeResultKind k == kData+                 -> return ( lookupModeOfDataType nTyCon (configPrimDataDefs config)+                           , ts )+                      +                 | TyConBound (UPrim nTyCon _) k <- tc+                 , takeResultKind k == kData+                 -> return ( lookupModeOfDataType nTyCon (configPrimDataDefs config)+                           , ts )++                _ -> throw $ ErrorCaseScrutineeNotAlgebraic xx tDiscrim++        -- Get the mode of the data type, +        --   this tells us how many constructors there are.+        mode    +         <- case mmode of+             Nothing -> throw $ ErrorCaseScrutineeTypeUndeclared xx tDiscrim+             Just m  -> return m++        -- Check the alternatives.+        (alts', ts, effss, closs)     +                <- liftM unzip4+                $  mapM (checkAltM xx config kenv tenv tDiscrim tsArgs) alts++        -- There must be at least one alternative+        when (null ts)+         $ throw $ ErrorCaseNoAlternatives xx++        -- All alternative result types must be identical.+        let (tAlt : _)  = ts+        forM_ ts $ \tAlt' +         -> when (not $ equivT tAlt tAlt') +             $ throw $ ErrorCaseAltResultMismatch xx tAlt tAlt'++        -- Check for overlapping alternatives.+        let pats                = [p | AAlt p _ <- alts]+        let psDefaults          = filter isPDefault pats+        let nsCtorsMatched      = mapMaybe takeCtorNameOfAlt alts++        -- Alts overlapping because there are multiple defaults.+        when (length psDefaults > 1)+         $ throw $ ErrorCaseOverlapping xx++        -- Alts overlapping because the same ctor is used multiple times.+        when (length (nub nsCtorsMatched) /= length nsCtorsMatched )+         $ throw $ ErrorCaseOverlapping xx++        -- Check for alts overlapping because a default is not last.+        -- Also check there is at least one alternative.+        (case pats of+          [] -> throw $ ErrorCaseNoAlternatives xx++          _  |  Just patsInit <- takeInit pats+             ,  or $ map isPDefault $ patsInit+             -> throw $ ErrorCaseOverlapping xx++             |  otherwise+             -> return ())++        -- Check the alternatives are exhaustive.+        (case mode of++          -- Small types have some finite number of constructors.+          DataModeSmall nsCtors+           -- If there is a default alternative then we've covered all the+           -- possibiliies. We know this we've also checked for overlap.+           | any isPDefault [p | AAlt p _ <- alts]+           -> return ()++           -- Look for unmatched constructors.+           | nsCtorsMissing <- nsCtors \\ nsCtorsMatched+           , not $ null nsCtorsMissing+           -> throw $ ErrorCaseNonExhaustive xx nsCtorsMissing++           -- All constructors were matched.+           | otherwise +           -> return ()++          -- Large types have an effectively infinite number of constructors+          -- (like integer literals), so there needs to be a default alt.+          DataModeLarge +           | any isPDefault [p | AAlt p _ <- alts] -> return ()+           | otherwise  +           -> throw $ ErrorCaseNonExhaustiveLarge xx)++        let effsMatch    +                = Sum.singleton kEffect +                $ crushEffect $ tHeadRead tDiscrim++        returnX a+                (\z -> XCase z xDiscrim' alts')+                tAlt+                (Sum.unions kEffect (effsDiscrim : effsMatch : effss))+                (Set.unions         (closDiscrim : closs))+++-- type cast -------------------------------------+-- Weaken an effect, adding in the given terms.+checkExpM' !config !kenv !tenv xx@(XCast a (CastWeakenEffect eff) x1)+ = do+        -- Check the effect term.+        kEff    <- checkTypeM config kenv eff+        when (not $ isEffectKind kEff)+         $ throw $ ErrorWeakEffNotEff xx eff kEff++        -- Check the body.+        (x1', t1, effs, clo)    <- checkExpM config kenv tenv x1+        let c'                  = CastWeakenEffect eff++        returnX a+                (\z -> XCast z c' x1')+                t1+                (Sum.insert eff effs)+                clo+++-- Weaken a closure, adding in the given terms.+checkExpM' !config !kenv !tenv (XCast a (CastWeakenClosure xs) x1)+ = do+        -- Check the contained expressions.+        (xs', closs)+                <- liftM unzip+                $ mapM (checkArgM config kenv tenv) xs++        -- Check the body.+        (x1', t1, effs, clos)   <- checkExpM config kenv tenv x1+        let c'                  = CastWeakenClosure xs'++        returnX a+                (\z -> XCast z c' x1')+                t1+                effs+                (Set.unions (clos : closs))+++-- Purify an effect, given a witness that it is pure.+checkExpM' !config !kenv !tenv xx@(XCast a (CastPurify w) x1)+ = do+        tW                   <- checkWitnessM config kenv tenv w+        (x1', t1, effs, clo) <- checkExpM     config kenv tenv x1+                +        effs' <- case tW of+                  TApp (TCon (TyConWitness TwConPure)) effMask+                    -> return $ Sum.delete effMask effs+                  _ -> throw  $ ErrorWitnessNotPurity xx w tW++        let c'  = CastPurify w++        returnX a+                (\z -> XCast z c' x1')+                t1 effs' clo+++-- Forget a closure, given a witness that it is empty.+checkExpM' !config !kenv !tenv xx@(XCast a (CastForget w) x1)+ = do   +        tW                    <- checkWitnessM config kenv tenv w+        (x1', t1, effs, clos) <- checkExpM     config kenv tenv x1++        clos' <- case tW of+                  TApp (TCon (TyConWitness TwConEmpty)) cloMask+                    -> return $ maskFromTaggedSet +                                        (Sum.singleton kClosure cloMask)+                                        clos++                  _ -> throw $ ErrorWitnessNotEmpty xx w tW++        let c'  = CastForget w++        returnX a+                (\z -> XCast z c' x1')+                t1 effs clos'+++-- Type and witness expressions can only appear as the arguments +-- to  applications.+checkExpM' !_config !_kenv !_tenv xx@(XType _)+        = throw $ ErrorNakedType xx ++checkExpM' !_config !_kenv !_tenv xx@(XWitness _)+        = throw $ ErrorNakedWitness xx++checkExpM' _ _ _ _+        = error "checkExpM: bogus warning killer"+++-- | Like `checkExp` but we allow naked types and witnesses.+checkArgM +        :: (Show n, Pretty n, Ord n)+        => Config n             -- ^ Static config.+        -> Env n                -- ^ Kind environment.+        -> Env n                -- ^ Type environment.+        -> Exp a n              -- ^ Expression to check.+        -> CheckM a n +                ( Exp (AnTEC a n) n+                , Set (TaggedClosure n))++checkArgM !config !kenv !tenv !xx+ = case xx of+        XType t+         -> do  checkTypeM config kenv t+                let Just clo = taggedClosureOfTyArg kenv t++                return  ( XType t+                        , clo)++        XWitness w+         -> do  checkWitnessM config kenv tenv w+                return  ( XWitness w+                        , Set.empty)++        _ -> do+                (xx', _, _, clos) <- checkExpM config kenv tenv xx+                return  ( xx'+                        , clos)+++-- | Helper function for building the return value of checkExpM'+--   It builts the AnTEC annotation and attaches it to the new AST node,+--   as well as returning the current effect and closure in the appropriate+--   form as part of the tuple.+returnX :: Ord n +        => a+        -> (AnTEC a n -> Exp (AnTEC a n) n)+        -> Type n +        -> TypeSum n+        -> Set (TaggedClosure n)+        -> CheckM a n +                ( Exp (AnTEC a n) n+                , Type n+                , TypeSum n+                , Set (TaggedClosure n))++returnX !a !f !t !es !cs+ = let  e       = TSum es+        c       = closureOfTaggedSet cs+   in   return  (f (AnTEC t e c a)+                , t, es, cs)+{-# INLINE returnX #-}++-------------------------------------------------------------------------------+-- | Check some let bindings.+checkLetsM +        :: (Show n, Pretty n, Ord n)+        => Exp a n              -- ^ Enclosing expression, for error messages.+        -> Config n             -- ^ Static config.+        -> Env n                -- ^ Kind environment.+        -> Env n                -- ^ Type environment.+        -> Lets a n+        -> CheckM a n+                ( Lets (AnTEC a n) n+                , [Bind n]+                , TypeSum n+                , Set (TaggedClosure n))++checkLetsM !xx !config !kenv !tenv (LLet mode b11 x12)+ = do   +        -- Check the right of the binding.+        (x12', t12, effs12, clo12)  +         <- checkExpM config kenv tenv x12++        -- Check binder annotation against the type we inferred for the right.+        (b11', k11')    +         <- checkLetBindOfTypeM xx config kenv tenv t12 b11++        -- The right of the binding should have data kind.+        when (not $ isDataKind k11')+         $ throw $ ErrorLetBindingNotData xx b11' k11'+          +        -- Check purity and emptiness for lazy bindings.+        (case mode of+          LetStrict     -> return ()+          LetLazy _+           -> do let eff12' = TSum effs12+                 when (not $ isBot eff12')+                  $ throw $ ErrorLetLazyNotPure xx b11 eff12'++                 let clo12' = closureOfTaggedSet clo12+                 when (not $ isBot clo12')+                  $ throw $ ErrorLetLazyNotEmpty xx b11 clo12')++        -- Check region witness for lazy bindings.+        (case mode of+          LetStrict     -> return ()++          -- Type of lazy binding has no head region, like Unit and (->).+          LetLazy Nothing+           -> do case takeDataTyConApps t12 of+                  Just (_tc, t1 : _)+                   ->  do k1 <- checkTypeM config kenv t1+                          when (isRegionKind k1)+                           $ throw $ ErrorLetLazyNoWitness xx b11 t12++                  _ -> return ()++          -- Type of lazy binding might have a head region,+          -- so we need a Lazy witness for it.+          LetLazy (Just wit)+           -> do tWit        <- checkWitnessM config kenv tenv wit+                 let tWitExp =  case takeDataTyConApps t12 of+                                 Just (_tc, tR : _ts) -> tLazy tR+                                 _                    -> tHeadLazy t12++                 when (not $ equivT tWit tWitExp)+                  $ throw $ ErrorLetLazyWitnessTypeMismatch +                                 xx b11 tWit t12 tWitExp)+        +        return  ( LLet mode b11' x12'+                , [b11']+                , effs12+                , clo12)++-- letrec ---------------------------------------+checkLetsM !xx !config !kenv !tenv (LRec bxs)+ = do   +        let (bs, xs)    = unzip bxs++        -- No named binders can be multiply defined.+        (case duplicates $ filter isBName bs of+          []    -> return ()+          b : _ -> throw $ ErrorLetrecRebound xx b)++        -- Check the types on all the binders.+        ks              <- mapM (checkTypeM config kenv) +                        $  map typeOfBind bs++        -- Check all the binders have data kind.+        zipWithM_ (\b k+         -> when (not $ isDataKind k)+                $ throw $ ErrorLetBindingNotData xx b k)+                bs ks++        -- All right hand sides need to be lambdas.+        forM_ xs $ \x +         -> when (not $ (isXLam x || isXLAM x))+                $ throw $ ErrorLetrecBindingNotLambda xx x++        -- All variables are in scope in all right hand sides.+        let tenv'       = Env.extends bs tenv++        -- Check the right hand sides.+        (xsRight', tsRight, _effssBinds, clossBinds) +                <- liftM unzip4 $ mapM (checkExpM config kenv tenv') xs++        -- Check annots on binders against inferred types of the bindings.+        zipWithM_ (\b t+                -> if not $ equivT (typeOfBind b) t+                        then throw $ ErrorLetMismatch xx b t+                        else return ())+                bs tsRight++        -- Cut closure terms due to locally bound value vars.+        let clos_cut +                = Set.fromList+                $ mapMaybe (cutTaggedClosureXs bs)+                $ Set.toList +                $ Set.unions clossBinds++        return  ( LRec (zip bs xsRight')+                , zipWith replaceTypeOfBind tsRight bs+                , Sum.empty kEffect+                , clos_cut)++checkLetsM _xx _config _kenv _tenv _lts+        = error "checkLetsM: case should have been handled in checkExpM"+++-- | Take elements of a list that have more than once occurrence.+duplicates :: Eq a => [a] -> [a]+duplicates []           = []+duplicates (x : xs)+        | L.elem x xs   = x : duplicates (filter (/= x) xs)+        | otherwise     = duplicates xs+++-------------------------------------------------------------------------------+-- | Check a case alternative.+checkAltM +        :: (Show n, Pretty n, Ord n) +        => Exp a n              -- ^ Whole case expression, for error messages.+        -> Config n             -- ^ Data type definitions.+        -> Env n                -- ^ Kind environment.+        -> Env n                -- ^ Type environment.+        -> Type n               -- ^ Type of discriminant.+        -> [Type n]             -- ^ Args to type constructor of discriminant.+        -> Alt a n              -- ^ Alternative to check.+        -> CheckM a n +                ( Alt (AnTEC a n) n+                , Type n+                , TypeSum n+                , Set (TaggedClosure n))++checkAltM !_xx !config !kenv !tenv !_tDiscrim !_tsArgs (AAlt PDefault xBody)+ = do   (xBody', tBody, effBody, cloBody)+                <- checkExpM config kenv tenv xBody++        return  ( AAlt PDefault xBody'+                , tBody+                , effBody+                , cloBody)++checkAltM !xx !config !kenv !tenv !tDiscrim !tsArgs (AAlt (PData dc bsArg) xBody)+ = do   +        let Just aCase  = takeAnnotOfExp xx++        -- If the data constructor isn't defined then the spread +        --  transform won't have given it a proper type.+        --  Note that we can't simply check whether the constructor is in the+        --  environment because literals like 42# never are.+        (if isBot (daConType dc)+                then throw $ ErrorUndefinedCtor $ XCon aCase dc+                else return ())++        -- Take the type of the constructor and instantiate it with the +        -- type arguments we got from the discriminant. +        -- If the ctor type doesn't instantiate then it won't have enough foralls +        -- on the front, which should have been checked by the def checker.+        let tCtor = daConType dc++        tCtor_inst      +         <- case instantiateTs tCtor tsArgs of+             Nothing -> throw $ ErrorCaseCannotInstantiate xx tDiscrim tCtor+             Just t  -> return t+        +        -- Split the constructor type into the field and result types.+        let (tsFields_ctor, tResult) +                        = takeTFunArgResult tCtor_inst++        -- The result type of the constructor must match the discriminant type.+        --  If it doesn't then the constructor in the pattern probably isn't for+        --  the discriminant type.+        when (not $ equivT tDiscrim tResult)+         $ throw $ ErrorCaseScrutineeTypeMismatch xx tDiscrim tResult++        -- There must be at least as many fields as variables in the pattern.+        -- It's ok to bind less fields than provided by the constructor.+        when (length tsFields_ctor < length bsArg)+         $ throw $ ErrorCaseTooManyBinders xx dc+                        (length tsFields_ctor)+                        (length bsArg)++        -- Merge the field types we get by instantiating the constructor+        -- type with possible annotations from the source program.+        -- If the annotations don't match, then we throw an error.+        tsFields        <- zipWithM (mergeAnnot xx)+                            (map typeOfBind bsArg)+                            tsFields_ctor        ++        -- Extend the environment with the field types.+        let bsArg'      = zipWith replaceTypeOfBind tsFields bsArg+        let tenv'       = Env.extends bsArg' tenv+        +        -- Check the body in this new environment.+        (xBody', tBody, effsBody, closBody)+                <- checkExpM config kenv tenv' xBody++        -- Cut closure terms due to locally bound value vars.+        -- This also lowers deBruijn indices in un-cut closure terms.+        let closBody_cut +                = Set.fromList+                $ mapMaybe (cutTaggedClosureXs bsArg')+                $ Set.toList closBody++        return  ( AAlt (PData dc bsArg') xBody'+                , tBody+                , effsBody+                , closBody_cut)+++-- | Merge a type annotation on a pattern field with a type we get by+--   instantiating the constructor type.+mergeAnnot :: Eq n => Exp a n -> Type n -> Type n -> CheckM a n (Type n)+mergeAnnot !xx !tAnnot !tActual+        -- Annotation is bottom, so just use the real type.+        | isBot tAnnot      = return tActual++        -- Annotation matches actual type, all good.+        | tAnnot == tActual = return tActual++        -- Annotation does not match actual type.+        | otherwise       +        = throw $ ErrorCaseFieldTypeMismatch xx tAnnot tActual+++-------------------------------------------------------------------------------+-- | Check the set of witness bindings bound in a letregion for conflicts.+checkWitnessBindsM +        :: (Show n, Ord n) +        => KindEnv n +        -> Exp a n +        -> [Bound n] +        -> [Bind n] +        -> CheckM a n ()++checkWitnessBindsM !kenv !xx !nRegions !bsWits+ = mapM_ (checkWitnessBindM kenv xx nRegions bsWits) bsWits+++checkWitnessBindM +        :: (Show n, Ord n)+        => Env n+        -> Exp a n+        -> [Bound n]            -- ^ Region variables bound in the letregion.+        -> [Bind n]             -- ^ Other witness bindings in the same set.+        -> Bind  n              -- ^ The witness binding to check.+        -> CheckM a n ()++checkWitnessBindM !kenv !xx !uRegions !bsWit !bWit+ = let btsWit   +        = [(typeOfBind b, b) | b <- bsWit]++       -- Check the argument of a witness type is for the region we're+       -- introducing here.+       checkWitnessArg t+        = case t of+            TVar u'+             | all (/= u') uRegions -> throw $ ErrorLetRegionsWitnessOther xx uRegions bWit+             | otherwise            -> return ()++            TCon (TyConBound u' _)+             | all (/= u') uRegions -> throw $ ErrorLetRegionsWitnessOther xx uRegions bWit+             | otherwise            -> return ()+            +            -- The parser should ensure the right of a witness is a +            -- constructor or variable.+            _ -> throw $ ErrorLetRegionWitnessInvalid xx bWit+            +       inEnv t+        = case t of+            TVar u'                | Env.member u' kenv -> True+            TCon (TyConBound u' _) | Env.member u' kenv -> True+            _                                           -> False +       +   in  case typeOfBind bWit of+        TApp (TCon (TyConWitness TwConGlobal))  t2+         -> checkWitnessArg t2++        TApp (TCon (TyConWitness TwConConst))   t2+         | Just bConflict <- L.lookup (tMutable t2) btsWit+         -> throw $ ErrorLetRegionWitnessConflict xx bWit bConflict+         | otherwise    -> checkWitnessArg t2++        TApp (TCon (TyConWitness TwConMutable)) t2+         | Just bConflict <- L.lookup (tConst t2)   btsWit+         -> throw $ ErrorLetRegionWitnessConflict xx bWit bConflict+         | otherwise    -> checkWitnessArg t2++        TApp (TCon (TyConWitness TwConLazy))    t2+         | Just bConflict <- L.lookup (tManifest t2)  btsWit+         -> throw $ ErrorLetRegionWitnessConflict xx bWit bConflict+         | otherwise    -> checkWitnessArg t2++        TApp (TCon (TyConWitness TwConManifest))  t2+         | Just bConflict <- L.lookup (tLazy t2)    btsWit+         -> throw $ ErrorLetRegionWitnessConflict xx bWit bConflict+         | otherwise    -> checkWitnessArg t2+         +        (takeTyConApps -> Just (TyConWitness (TwConDistinct 2), [t1, t2]))+         | inEnv t1  -> checkWitnessArg t2+         | inEnv t2  -> checkWitnessArg t1+         | t1 /= t2  -> mapM_ checkWitnessArg [t1, t2]+         | otherwise -> throw $ ErrorLetRegionWitnessInvalid xx bWit++        (takeTyConApps -> Just (TyConWitness (TwConDistinct _), ts))+          -> mapM_ checkWitnessArg ts++        _ -> throw $ ErrorLetRegionWitnessInvalid xx bWit+++-------------------------------------------------------------------------------+-- | Check the type annotation of a let bound variable against the type+--   inferred for the right of the binding.+--   If the annotation is Bot then we just replace the annotation,+--   otherwise it must match that for the right of the binding.+checkLetBindOfTypeM +        :: (Ord n, Show n, Pretty n) +        => Exp a n +        -> Config n             -- Data type definitions.+        -> Env n                -- Kind environment. +        -> Env n                -- Type environment.+        -> Type n +        -> Bind n +        -> CheckM a n (Bind n, Kind n)++checkLetBindOfTypeM !xx !config !kenv !_tenv !tRight b+        -- If the annotation is Bot then just replace it.+        | isBot (typeOfBind b)+        = do    k       <- checkTypeM config kenv tRight+                return  ( replaceTypeOfBind tRight b +                        , k)++        -- The type of the binder must match that of the right of the binding.+        | not $ equivT (typeOfBind b) tRight+        = throw $ ErrorLetMismatch xx b tRight++        | otherwise+        = do    k       <- checkTypeM config kenv (typeOfBind b)+                return (b, k)
+ DDC/Core/Check/CheckModule.hs view
@@ -0,0 +1,159 @@++module DDC.Core.Check.CheckModule+        ( checkModule+        , checkModuleM)+where+import DDC.Core.Module+import DDC.Core.Exp+import DDC.Core.Check.CheckExp+import DDC.Core.Check.Error+import DDC.Type.Compounds+import DDC.Base.Pretty+import DDC.Type.Equiv+import DDC.Type.Env             (KindEnv, TypeEnv)+import DDC.Control.Monad.Check  (result, throw)+import Data.Map                 (Map)+import qualified DDC.Type.Check as T+import qualified DDC.Type.Env   as Env+import qualified Data.Map       as Map+++-- Wrappers -------------------------------------------------------------------+-- | Type check a module.+--+--   If it's good, you get a new version with types attached to all the bound+--   variables+--+--   If it's bad, you get a description of the error.+checkModule+        :: (Ord n, Show n, Pretty n)+        => Config n             -- ^ Static configuration.+        -> Module a n           -- ^ Module to check.+        -> Either (Error a n) (Module (AnTEC a n) n)++checkModule !config !xx +        = result +        $ checkModuleM +                config +                (configPrimKinds config)+                (configPrimTypes config)+                xx+++-- checkModule ----------------------------------------------------------------+-- | Like `checkModule` but using the `CheckM` monad to handle errors.+checkModuleM +        :: (Ord n, Show n, Pretty n)+        => Config n             -- ^ Static configuration.+        -> KindEnv n            -- ^ Starting kind environment.+        -> TypeEnv n            -- ^ Starting type environment.+        -> Module a n           -- ^ Module to check.+        -> CheckM a n (Module (AnTEC a n) n)++checkModuleM !config !kenv !tenv mm@ModuleCore{}+ = do   +        -- Convert the imported kind and type map to a list of binds.+        let bksImport  = [BName n k |  (n, (_, k)) <- Map.toList $ moduleImportKinds mm]+        let btsImport  = [BName n t |  (n, (_, t)) <- Map.toList $ moduleImportTypes mm]++        -- Check the imported kinds and types.+        --  The imported types are in scope in both imported and exported signatures.+        mapM_ (checkTypeM config kenv) $ map typeOfBind bksImport+        let kenv' = Env.union kenv $ Env.fromList bksImport++        mapM_ (checkTypeM config kenv') $ map typeOfBind btsImport+        let tenv' = Env.union tenv $ Env.fromList btsImport++        -- Check the sigs for exported things.+        mapM_ (checkTypeM config kenv') $ Map.elems $ moduleExportKinds mm+        mapM_ (checkTypeM config kenv') $ Map.elems $ moduleExportTypes mm+                +        -- Check our let bindings.+        (x', _, _effs, _) <- checkExpM config kenv' tenv' (moduleBody mm)++        -- Check that each exported signature matches the type of its binding.+        envDef  <- checkModuleBinds (moduleExportKinds mm) (moduleExportTypes mm) x'++        -- Check that all exported bindings are defined by the module.+        mapM_ (checkBindDefined envDef) $ Map.keys $ moduleExportTypes mm++        -- Return the checked bindings as they have explicit type annotations.+        let mm'         = mm { moduleBody = x' }+        return mm'+++-- | Check that the exported signatures match the types of their bindings.+checkModuleBinds +        :: Ord n+        => Map n (Kind n)               -- ^ Kinds of exported types.+        -> Map n (Type n)               -- ^ Types of exported values.+        -> Exp (AnTEC a n) n+        -> CheckM a n (TypeEnv n)       -- ^ Environment of top-level bindings+                                        --   defined by the module++checkModuleBinds !ksExports !tsExports !xx+ = case xx of+        XLet _ (LLet _ b _) x2     +         -> do  checkModuleBind  ksExports tsExports b+                env     <- checkModuleBinds ksExports tsExports x2+                return  $ Env.extend b env++        XLet _ (LRec bxs) x2+         -> do  mapM_ (checkModuleBind ksExports tsExports) $ map fst bxs+                env     <- checkModuleBinds ksExports tsExports x2+                return  $ Env.extends (map fst bxs) env++        XLet _ (LLetRegions _ _) x2+         ->     checkModuleBinds ksExports tsExports x2++        _ ->    return Env.empty+++-- | If some bind is exported, then check that it matches the exported version.+checkModuleBind +        :: Ord n+        => Map n (Kind n)       -- ^ Kinds of exported types.+        -> Map n (Type n)       -- ^ Types of exported values.+        -> Bind n+        -> CheckM a n ()++checkModuleBind !_ksExports !tsExports !b+ | BName n tDef <- b+ = case Map.lookup n tsExports of+        Nothing                 -> return ()+        Just tExport +         | equivT tDef tExport  -> return ()+         | otherwise            -> throw $ ErrorExportMismatch n tExport tDef++ -- Only named bindings can be exported, + --  so we don't need to worry about non-named ones.+ | otherwise+ = return ()+++-- | Check that a top-level binding is actually defined by the module.+checkBindDefined +        :: Ord n+        => TypeEnv n            -- ^ Types defined by the module.+        -> n                    -- ^ Name of an exported binding.+        -> CheckM a n ()++checkBindDefined env n+ = case Env.lookup (UName n) env of+        Just _  -> return ()+        _       -> throw $ ErrorExportUndefined n+++-------------------------------------------------------------------------------+-- | Check a type in the exp checking monad.+checkTypeM :: (Ord n, Show n, Pretty n) +           => Config n +           -> KindEnv n +           -> Type n +           -> CheckM a n (Kind n)++checkTypeM !config !kenv !tt+ = case T.checkType (configPrimDataDefs config) kenv tt of+        Left err        -> throw $ ErrorType err+        Right k         -> return k+
DDC/Core/Check/CheckWitness.hs view
@@ -1,31 +1,34 @@- -- | Type checker for witness expressions. module DDC.Core.Check.CheckWitness-        ( checkWitness+        ( Config(..)+        , configOfProfile++        , checkWitness         , typeOfWitness         , typeOfWiCon         , typeOfWbCon          , CheckM-        , checkWitnessM)+        , checkWitnessM++        , checkTypeM) where-import DDC.Core.DataDef import DDC.Core.Exp import DDC.Core.Pretty import DDC.Core.Check.Error-import DDC.Core.Check.ErrorMessage      ()+import DDC.Core.Check.ErrorMessage              ()+import DDC.Type.DataDef import DDC.Type.Transform.SubstituteT import DDC.Type.Compounds-import DDC.Type.Predicates-import DDC.Type.Equiv-import DDC.Type.Transform.LiftT-import DDC.Type.Sum                     as Sum-import DDC.Type.Env                     (Env)-import DDC.Type.Check.Monad             (result, throw)-import DDC.Base.Pretty                  ()-import qualified DDC.Type.Env           as Env-import qualified DDC.Type.Check         as T-import qualified DDC.Type.Check.Monad   as G+import DDC.Type.Universe+import DDC.Type.Sum                             as Sum+import DDC.Type.Env                             (KindEnv, TypeEnv)+import DDC.Control.Monad.Check                  (throw, result)+import DDC.Base.Pretty                          ()+import qualified DDC.Control.Monad.Check        as G+import qualified DDC.Type.Env                   as Env+import qualified DDC.Type.Check                 as T+import qualified DDC.Core.Fragment              as F   -- | Type checker monad. @@ -33,6 +36,46 @@ type CheckM a n   = G.CheckM (Error a n)  +-- Config ---------------------------------------------------------------------+-- | Static configuration for the type checker.+--   These fields don't change as we decend into the tree.+--+--   The starting configuration should be converted from the profile that+--   defines the language fragment you are checking. +--   See "DDC.Core.Fragment" and use `configOfProfile` below.+data Config n+        = Config+        { -- | Data type definitions.+          configPrimDataDefs            :: DataDefs n ++          -- | Kinds of primitive types.+        , configPrimKinds               :: KindEnv n++          -- | Types of primitive operators.+        , configPrimTypes               :: TypeEnv n++          -- | Suppress all closure information, +          --   annotating all functions with an empty closure.+          --   +          --   This is used when checking the Disciple Core Salt fragment,+          --   as transforms in this language don't use the closure+          --   information.+        , configSuppressClosures        :: Bool }+++-- | Convert a langage profile to a type checker configuration.+configOfProfile :: F.Profile n -> Config n+configOfProfile profile+        = Config+        { configPrimDataDefs    = F.profilePrimDataDefs profile+        , configPrimKinds       = F.profilePrimKinds profile+        , configPrimTypes       = F.profilePrimTypes profile++        , configSuppressClosures      +                = F.featuresUntrackedClosures+                $ F.profileFeatures profile }++ -- Wrappers -------------------------------------------------------------------- -- | Check a witness. --   @@ -44,16 +87,20 @@ --   The returned expression has types attached to all variable occurrences,  --   so you can call `typeOfWitness` on any open subterm. --+--   The kinds and types of primitives are added to the environments +--   automatically, you don't need to supply these as part of the +--   starting environments.+-- checkWitness-        :: (Ord n, Pretty n)-        => DataDefs n           -- ^ Data type definitions.-        -> Env n                -- ^ Kind Environment.-        -> Env n                -- ^ Type Environment.+        :: (Ord n, Show n, Pretty n)+        => Config n             -- ^ Static configuration.+        -> KindEnv n            -- ^ Starting Kind Environment.+        -> TypeEnv n            -- ^ Strating Type Environment.         -> Witness n            -- ^ Witness to check.         -> Either (Error a n) (Type n) -checkWitness defs kenv tenv xx-        = result $ checkWitnessM defs kenv tenv xx+checkWitness config kenv tenv xx+        = result $ checkWitnessM config kenv tenv xx   -- | Like `checkWitness`, but check in an empty environment.@@ -63,78 +110,38 @@ --   This attachment is performed by `checkWitness` above. -- typeOfWitness -        :: (Ord n, Pretty n) -        => DataDefs n+        :: (Ord n, Show n, Pretty n) +        => Config n         -> Witness n          -> Either (Error a n) (Type n) -typeOfWitness defs ww +typeOfWitness config ww          = result -        $ checkWitnessM defs Env.empty Env.empty ww+        $ checkWitnessM config Env.empty Env.empty ww   ------------------------------------------------------------------------------ -- | Like `checkWitness` but using the `CheckM` monad to manage errors. checkWitnessM -        :: (Ord n, Pretty n)-        => DataDefs n           -- ^ Data type definitions.-        -> Env n                -- ^ Kind environment.-        -> Env n                -- ^ Type environment.+        :: (Ord n, Show n, Pretty n)+        => Config n             -- ^ Data type definitions.+        -> KindEnv n            -- ^ Kind environment.+        -> TypeEnv n            -- ^ Type environment.         -> Witness n            -- ^ Witness to check.         -> CheckM a n (Type n) -checkWitnessM _defs _kenv tenv (WVar u)- = do   let tBound      = typeOfBound u-        let mtEnv       = Env.lookup u tenv--        let mkResult-             -- When annotation on the bound is bot,-             --  then use the type from the environment.-             | Just tEnv    <- mtEnv-             , isBot tBound-             = return tEnv--             -- The bound has an explicit type annotation,-             --  which matches the one from the environment.-             -- -             --  When the bound is a deBruijn index we need to lift the-             --  annotation on the original binder through any lambdas-             --  between the binding occurrence and the use.-             | Just tEnv    <- mtEnv-             , UIx i _      <- u-             , equivT tBound (liftT (i + 1) tEnv) -             = return tBound--             -- The bound has an explicit type annotation,-             --  which matches the one from the environment.-             | Just tEnv    <- mtEnv-             , equivT tBound tEnv-             = return tEnv--             -- The bound has an explicit type annotation,-             --  which does not match the one from the environment.-             --  This shouldn't happen because the parser doesn't add non-bot-             --  annotations to bound variables.-             | Just tEnv    <- mtEnv-             = throw $ ErrorVarAnnotMismatch u tEnv--             -- Variable not in environment, so use annotation.-             --  This happens when checking open terms.-             | otherwise-             = return tBound-        -        tResult  <- mkResult-        return tResult-+checkWitnessM !_config !_kenv !tenv (WVar u)+ = case Env.lookup u tenv of+        Nothing -> throw $ ErrorUndefinedVar u UniverseWitness+        Just t  -> return t -checkWitnessM _defs _kenv _tenv (WCon wc)+checkWitnessM !_config !_kenv !_tenv (WCon wc)  = return $ typeOfWiCon wc-   --- value-type application-checkWitnessM defs kenv tenv ww@(WApp w1 (WType t2))- = do   t1      <- checkWitnessM  defs kenv tenv w1-        k2      <- checkTypeM     defs kenv t2+-- witness-type application+checkWitnessM !config !kenv !tenv ww@(WApp w1 (WType t2))+ = do   t1      <- checkWitnessM  config kenv tenv w1+        k2      <- checkTypeM     config kenv t2         case t1 of          TForall b11 t12           |  typeOfBind b11 == k2@@ -144,9 +151,9 @@          _              -> throw $ ErrorWAppNotCtor  ww t1 t2  -- witness-witness application-checkWitnessM defs kenv tenv ww@(WApp w1 w2)- = do   t1      <- checkWitnessM defs kenv tenv w1-        t2      <- checkWitnessM defs kenv tenv w2+checkWitnessM !config !kenv !tenv ww@(WApp w1 w2)+ = do   t1      <- checkWitnessM config kenv tenv w1+        t2      <- checkWitnessM config kenv tenv w2         case t1 of          TApp (TApp (TCon (TyConWitness TwConImpl)) t11) t12           |  t11 == t2   @@ -156,9 +163,9 @@          _              -> throw $ ErrorWAppNotCtor  ww t1 t2  -- witness joining-checkWitnessM defs kenv tenv ww@(WJoin w1 w2)- = do   t1      <- checkWitnessM defs kenv tenv w1-        t2      <- checkWitnessM defs kenv tenv w2+checkWitnessM !config !kenv !tenv ww@(WJoin w1 w2)+ = do   t1      <- checkWitnessM config kenv tenv w1+        t2      <- checkWitnessM config kenv tenv w2         case (t1, t2) of          (  TApp (TCon (TyConWitness TwConPure)) eff1           , TApp (TCon (TyConWitness TwConPure)) eff2)@@ -173,8 +180,8 @@          _ -> throw $ ErrorCannotJoin ww w1 t1 w2 t2  -- embedded types-checkWitnessM defs kenv _tenv (WType t)- = checkTypeM defs kenv t+checkWitnessM !config !kenv !_tenv (WType t)+ = checkTypeM config kenv t           -- | Take the type of a witness constructor.@@ -182,7 +189,7 @@ typeOfWiCon wc  = case wc of     WiConBuiltin wb -> typeOfWbCon wb-    WiConBound u    -> typeOfBound u+    WiConBound _ t  -> t   -- | Take the type of a builtin witness constructor.@@ -199,14 +206,14 @@ -- checkType ------------------------------------------------------------------ -- | Check a type in the exp checking monad. checkTypeM -        :: (Ord n, Pretty n) -        => DataDefs n -        -> Env n +        :: (Ord n, Show n, Pretty n) +        => Config n +        -> KindEnv n          -> Type n          -> CheckM a n (Kind n) -checkTypeM defs kenv tt- = case T.checkType defs kenv tt of+checkTypeM config kenv tt+ = case T.checkType (configPrimDataDefs config) kenv tt of         Left err        -> throw $ ErrorType err         Right k         -> return k 
DDC/Core/Check/Error.hs view
@@ -3,47 +3,65 @@         (Error(..)) where import DDC.Core.Exp+import DDC.Type.Universe import qualified DDC.Type.Check as T   -- | All the things that can go wrong when type checking an expression --   or witness. data Error a n+        -- Type -------------------------------------------         -- | Found a kind error when checking a type.         = ErrorType         { errorTypeError        :: T.Error n } -        -- | Found a malformed expression, -        --   and we don't have a more specific diagnosis.-        | ErrorMalformedExp-        { errorChecking         :: Exp a n }-         -- | Found a malformed type,         --   and we don't have a more specific diagnosis.         | ErrorMalformedType         { errorChecking         :: Exp a n         , errorType             :: Type n } -        -- | Found a naked `XType` that wasn't the argument of an application.-        | ErrorNakedType-        { errorChecking         :: Exp a n } -        -- | Found a naked `XWitness` that wasn't the argument of an application.-        | ErrorNakedWitness+        -- Module -----------------------------------------+        -- | Exported value is undefined.+        | ErrorExportUndefined+        { errorName             :: n }++        -- | Type signature of exported binding does not match the type at+        --   the definition site.+        | ErrorExportMismatch+        { errorName             :: n+        , errorExportType       :: Type n+        , errorDefType          :: Type n }+++        -- Exp --------------------------------------------+        -- | Found a malformed expression, +        --   and we don't have a more specific diagnosis.+        | ErrorMalformedExp         { errorChecking         :: Exp a n } +         -- Var ---------------------------------------------        -- | A bound occurrence of a variable who's type annotation does not match+        -- | An undefined type variable.+        | ErrorUndefinedVar+        { errorBound            :: Bound n +        , errorUniverse         :: Universe }++        -- | A bound occurrence of a variable whose type annotation does not match         --   the corresponding annotation in the environment.         | ErrorVarAnnotMismatch         { errorBound            :: Bound n+        , errorTypeAnnot        :: Type n         , errorTypeEnv          :: Type n } +         -- Con --------------------------------------------         -- | A data constructor that wasn't in the set of data definitions.         | ErrorUndefinedCtor         { errorChecking         :: Exp a n } +         -- Application ------------------------------------         -- | A function application where the parameter and argument don't match.         | ErrorAppMismatch@@ -68,6 +86,7 @@         -- | A type or witness abstraction where the body has a visible side effect.         | ErrorLamNotPure         { errorChecking         :: Exp a n+        , errorSpecOrWit        :: Bool         , errorEffect           :: Effect n }          -- | A value function where the parameter does not have data kind.@@ -140,26 +159,32 @@         { errorChecking         :: Exp a n          , errorExp              :: Exp a n } +        -- | A recursive let-expression that has more than one binding+        --   with the same name.+        | ErrorLetrecRebound+        { errorChecking         :: Exp a n+        , errorBind             :: Bind n } +         -- Letregion ---------------------------------------        -- | A letregion-expression where the bound variable does not have-        --   region kind.-        | ErrorLetRegionNotRegion+        -- | A letregion-expression where the some of the bound variables do not+        --   have region kind.+        | ErrorLetRegionsNotRegion         { errorChecking         :: Exp a n-        , errorBind             :: Bind n-        , errorKind             :: Kind n }+        , errorBinds            :: [Bind n]+        , errorKinds            :: [Kind n] } -        -- | A letregion-expression that tried to shadow a pre-existing named-        --   region variable.-        | ErrorLetRegionRebound+        -- | A letregion-expression that tried to shadow some pre-existing named+        --   region variables.+        | ErrorLetRegionsRebound         { errorChecking         :: Exp a n-        , errorBind             :: Bind n }+        , errorBinds            :: [Bind n] } -        -- | A letregion-expression where the bound region variable is free in-        --  the type of the body.+        -- | A letregion-expression where some of the the bound region variables+        --   are free in the type of the body.         | ErrorLetRegionFree         { errorChecking         :: Exp a n-        , errorBind             :: Bind n+        , errorBinds            :: [Bind n]         , errorType             :: Type n }          -- | A letregion-expression that tried to create a witness with an @@ -176,18 +201,33 @@          -- | A letregion-expression where a bound witnesses was not for the         --   the region variable being introduced.-        | ErrorLetRegionWitnessOther+        | ErrorLetRegionsWitnessOther         { errorChecking         :: Exp a n-        , errorBoundRegion      :: Bound n+        , errorBoundRegions     :: [Bound n]         , errorBindWitness      :: Bind  n } +        -- | A letregion-expression where the witness binding references some+        --   free region variable that is not the one being introduced.+        | ErrorLetRegionWitnessFree+        { errorChecking         :: Exp a n+        , errorBindWitness      :: Bind n }+        ++        -- Withregion -------------------------------------         -- | A withregion-expression where the handle does not have region kind.         | ErrorWithRegionNotRegion         { errorChecking         :: Exp a n         , errorBound            :: Bound n         , errorKind             :: Kind n } +        -- | A letregion-expression where some of the the bound region variables+        --   are free in the type of the body.+        | ErrorWithRegionFree+        { errorChecking         :: Exp a n+        , errorBound            :: Bound n+        , errorType             :: Type n } +         -- Witnesses --------------------------------------         -- | A witness application where the argument type does not match         --   the parameter type.@@ -224,16 +264,16 @@           -- Case Expressions --------------------------------        -- | A case-expression where the discriminant type is not algebraic.-        | ErrorCaseDiscrimNotAlgebraic+        -- | A case-expression where the scrutinee type is not algebraic.+        | ErrorCaseScrutineeNotAlgebraic         { errorChecking         :: Exp a n-        , errorTypeDiscrim      :: Type n }+        , errorTypeScrutinee    :: Type n } -        -- | A case-expression where the discriminant type is not in our set+        -- | A case-expression where the scrutinee type is not in our set         --   of data type declarations.-        | ErrorCaseDiscrimTypeUndeclared+        | ErrorCaseScrutineeTypeUndeclared         { errorChecking         :: Exp a n -        , errorTypeDiscrim      :: Type n }+        , errorTypeScrutinee    :: Type n }          -- | A case-expression with no alternatives.         | ErrorCaseNoAlternatives@@ -258,22 +298,22 @@         -- | A case-expression where one of the patterns has too many binders.         | ErrorCaseTooManyBinders         { errorChecking         :: Exp a n-        , errorCtorBound        :: Bound n+        , errorCtorDaCon        :: DaCon n         , errorCtorFields       :: Int         , errorPatternFields    :: Int }          -- | A case-expression where the pattern types could not be instantiated-        --   with the arguments of the discriminant type.+        --   with the arguments of the scrutinee type.         | ErrorCaseCannotInstantiate         { errorChecking         :: Exp a n-        , errorTypeCtor         :: Type n-        , errorTypeDiscrim      :: Type n }+        , errorTypeScrutinee    :: Type n +        , errorTypeCtor         :: Type n } -        -- | A case-expression where the type of the discriminant does not match+        -- | A case-expression where the type of the scrutinee does not match         --   the type of the pattern.-        | ErrorCaseDiscrimTypeMismatch+        | ErrorCaseScrutineeTypeMismatch         { errorChecking         :: Exp a n-        , errorTypeDiscrim      :: Type n+        , errorTypeScrutinee    :: Type n         , errorTypePattern      :: Type n }          -- | A case-expression where the annotation on a pattern variable binder@@ -292,22 +332,22 @@           -- Casts -------------------------------------------        -- | A maxeff-cast where the type provided does not have effect kind.-        | ErrorMaxeffNotEff+        -- | A weakeff-cast where the type provided does not have effect kind.+        | ErrorWeakEffNotEff         { errorChecking         :: Exp a n         , errorEffect           :: Effect n         , errorKind             :: Kind n } -        -- | A maxclo-cast where the type provided does not have closure kind.-        | ErrorMaxcloNotClo-        { errorChecking         :: Exp a n-        , errorClosure          :: Closure n-        , errorKind             :: Kind n } -        -- | A maxclo-case where the closure provided is malformed. -        --   It can only contain `Use` terms.-        | ErrorMaxcloMalformed-        { errorChecking         :: Exp a n -        , errorClosure          :: Closure n }+        -- Types ------------------------------------------+        -- | Found a naked `XType` that wasn't the argument of an application.+        | ErrorNakedType+        { errorChecking         :: Exp a n }+++        -- Witnesses --------------------------------------+        -- | Found a naked `XWitness` that wasn't the argument of an application.+        | ErrorNakedWitness+        { errorChecking         :: Exp a n }         deriving (Show) 
DDC/Core/Check/ErrorMessage.hs view
@@ -1,4 +1,3 @@-{-# OPTIONS_HADDOCK hide #-} -- | Errors produced when checking core expressions. module DDC.Core.Check.ErrorMessage         (Error(..))@@ -6,9 +5,11 @@ import DDC.Core.Pretty import DDC.Core.Check.Error import DDC.Type.Compounds+import DDC.Type.Universe  -instance (Pretty n, Eq n) => Pretty (Error a n) where+instance (Show n, Eq n, Pretty n) +       => Pretty (Error a n) where  ppr err   = case err of         ErrorType err'  -> ppr err'@@ -21,22 +22,38 @@                  , empty                  , text "with: "                        <> align (ppr xx) ] -        ErrorNakedType xx-         -> vcat [ text "Found naked type in core program."-                 , empty-                 , text "with: "                        <> align (ppr xx) ]+        -- Modules ---------------------------------------+        ErrorExportUndefined n+         -> vcat [ text "Exported value '" <> ppr n <> text "' is undefined." ] -        ErrorNakedWitness xx-         -> vcat [ text "Found naked witness in core program."-                 , empty-                 , text "with: "                        <> align (ppr xx) ]+        ErrorExportMismatch n tExport tDef+         -> vcat [ text "Type of exported value does not match type of definition."+                 , text "             with binding: "   <> ppr n+                 , text "           type of export: "   <> ppr tExport+                 , text "       type of definition: "   <> ppr tDef ] +         -- Variable ----------------------------------------        ErrorVarAnnotMismatch u t+        ErrorUndefinedVar  u universe+         -> case universe of+             UniverseSpec+               -> vcat [ text "Undefined spec variable: "  <> ppr u ]++             UniverseData+               -> vcat [ text "Undefined value variable: " <> ppr u ]++             UniverseWitness+               -> vcat [ text "Undefined witness variable: " <> ppr u ]++             -- Universes other than the above don't have variables,+             -- but let's not worry about that here.+             _ -> vcat [ text "Undefined variable: "    <> ppr u ]++        ErrorVarAnnotMismatch u tEnv tAnnot          -> vcat [ text "Type mismatch in annotation."                  , text "             Variable: "       <> ppr u-                 , text "       has annotation: "       <> (ppr $ typeOfBound u)-                 , text " which conflicts with: "       <> ppr t+                 , text "       has annotation: "       <> ppr tAnnot+                 , text " which conflicts with: "       <> ppr tEnv                  , text "     from environment." ]  @@ -68,11 +85,14 @@                  , text "  is already in the environment."                  , text "with: "                        <> align (ppr xx) ] -        ErrorLamNotPure xx eff-         -> vcat [ text "Impure type abstraction"-                 , text "           has effect: "       <> ppr eff-                 , empty-                 , text "with: "                        <> align (ppr xx) ]+        ErrorLamNotPure xx spec eff+         -> let universe' = if spec then text "spec"+                                    else text "witness"+            in vcat +                [ text "Impure" <+> universe' <+> text "abstraction"+                , text "           has effect: "       <> ppr eff+                , empty+                , text "with: "                        <> align (ppr xx) ]                                    ErrorLamBindNotData xx t1 k1@@ -158,29 +178,33 @@                  , empty                  , text "with: "                        <> align (ppr xx) ] +        ErrorLetrecRebound xx b+         -> vcat [ text "Redefined binder '" <> ppr b <> text "' in letrec."+                 , empty+                 , text "with: "                        <> align (ppr xx) ]          -- Letregion ---------------------------------------        ErrorLetRegionNotRegion xx b k-         -> vcat [ text "Letregion binder does not have region kind."-                 , text "        Region binder: "       <> ppr b-                 , text "             has kind: "       <> ppr k-                 , text "       but is must be: %" +        ErrorLetRegionsNotRegion xx bs ks+         -> vcat [ text "Letregion binders do not have region kind."+                 , text "        Region binders: "       <> (hcat $ map ppr bs)+                 , text "             has kinds: "       <> (hcat $ map ppr ks)+                 , text "       but they must all be: %"                   , empty-                 , text "with: "                        <> align (ppr xx) ]+                 , text "with: "                         <> align (ppr xx) ] -        ErrorLetRegionRebound xx b-         -> vcat [ text "Region variable shadows existing one."-                 , text "           Region variable: "  <> ppr b-                 , text "     is already in environment"+        ErrorLetRegionsRebound xx bs+         -> vcat [ text "Region variables shadow existing ones."+                 , text "           Region variables: "  <> (hcat $ map ppr bs)+                 , text "     are already in environment"                  , empty-                 , text "with: "                        <> align (ppr xx) ]+                 , text "with: "                         <> align (ppr xx) ] -        ErrorLetRegionFree xx b t-         -> vcat [ text "Region variable escapes scope of letregion."-                 , text "       The region variable: "  <> ppr b-                 , text "  is free in the body type: "  <> ppr t+        ErrorLetRegionFree xx bs t+         -> vcat [ text "Region variables escape scope of letregion."+                 , text "       The region variables: "  <> (hcat $ map ppr bs)+                 , text "  is free in the body type: "   <> ppr t                  , empty-                 , text "with: "                        <> align (ppr xx) ]+                 , text "with: "                         <> align (ppr xx) ]                  ErrorLetRegionWitnessInvalid xx b          -> vcat [ text "Invalid witness type with letregion."@@ -196,12 +220,27 @@                  , empty                  , text "with: "                        <> align (ppr xx) ] -        ErrorLetRegionWitnessOther xx b1 b2-         -> vcat [ text "Witness type is not for bound region."-                 , text "      letregion binds: "       <> ppr b1+        ErrorLetRegionsWitnessOther xx bs1 b2+         -> vcat [ text "Witness type is not for bound regions."+                 , text "      letregion binds: "       <> (hsep $ map ppr bs1)                  , text "  but witness type is: "       <> ppr b2                  , empty                  , text "with: "                        <> align (ppr xx) ]+                 +        ErrorLetRegionWitnessFree xx b+         -> vcat [ text "Witness type references a free region variable."+                 , text "  the binding: "               <> ppr b +                 , text "  contains free region variables."+                 , empty+                 , text "with: "                        <> align (ppr xx) ]+                 +        -- Withregion -------------------------------------+        ErrorWithRegionFree xx u t+         -> vcat [ text "Region handle escapes scope of withregion."+                 , text "         The region handle: "   <> ppr u+                 , text "  is used in the body type: "   <> ppr t+                 , empty+                 , text "with: "                         <> align (ppr xx) ]          ErrorWithRegionNotRegion xx u k          -> vcat [ text "Withregion handle does not have region kind."@@ -251,15 +290,15 @@           -- Case Expressions --------------------------------        ErrorCaseDiscrimNotAlgebraic xx tDiscrim-         -> vcat [ text "Discriminant of case expression is not algebraic data."-                 , text "     Discriminant type: "      <> ppr tDiscrim+        ErrorCaseScrutineeNotAlgebraic xx tScrutinee+         -> vcat [ text "Scrutinee of case expression is not algebraic data."+                 , text "     Scrutinee type: "         <> ppr tScrutinee                  , empty                  , text "with: "                        <> align (ppr xx) ]         -        ErrorCaseDiscrimTypeUndeclared xx tDiscrim-         -> vcat [ text "Type of discriminant does not have a data declaration."-                 , text "     Discriminant type: "      <> ppr tDiscrim+        ErrorCaseScrutineeTypeUndeclared xx tScrutinee+         -> vcat [ text "Type of scrutinee does not have a data declaration."+                 , text "     Scrutinee type: "         <> ppr tScrutinee                  , empty                  , text "with: "                        <> align (ppr xx) ] @@ -295,18 +334,18 @@                  , empty                  , text "with: "                        <> align (ppr xx) ] -        ErrorCaseCannotInstantiate xx tCtor tDiscrim-         -> vcat [ text "Cannot instantiate constructor type with discriminant type args."+        ErrorCaseCannotInstantiate xx tScrutinee tCtor+         -> vcat [ text "Cannot instantiate constructor type with scrutinee type args."                  , text " Either the constructor has an invalid type,"-                 , text " or the type of the discriminant does not match the type of the pattern."+                 , text " or the type of the scrutinee does not match the type of the pattern."+                 , text "        Scrutinee type: "      <> ppr tScrutinee                  , text "      Constructor type: "      <> ppr tCtor-                 , text "     Discriminant type: "      <> ppr tDiscrim                  , empty                  , text "with: "                        <> align (ppr xx) ] -        ErrorCaseDiscrimTypeMismatch xx tDiscrim tPattern-         -> vcat [ text "Discriminant type does not match result of pattern type."-                 , text "     Discriminant type: "      <> ppr tDiscrim+        ErrorCaseScrutineeTypeMismatch xx tScrutinee tPattern+         -> vcat [ text "Scrutinee type does not match result of pattern type."+                 , text "        Scrutinee type: "      <> ppr tScrutinee                  , text "          Pattern type: "      <> ppr tPattern                  , empty                  , text "with: "                        <> align (ppr xx) ]@@ -327,24 +366,23 @@           -- Casts -------------------------------------------        ErrorMaxeffNotEff xx eff k-         -> vcat [ text "Type provided for a 'maxeff' does not have effect kind."+        ErrorWeakEffNotEff xx eff k+         -> vcat [ text "Type provided for a 'weakeff' does not have effect kind."                  , text "           Type: "             <> ppr eff                  , text "       has kind: "             <> ppr k                  , empty                  , text "with: "                        <> align (ppr xx) ]--        ErrorMaxcloNotClo xx clo k-         -> vcat [ text "Type provided for a 'maxclo' does not have closure kind."-                 , text "           Type: "             <> ppr clo-                 , text "       has kind: "             <> ppr k+       +        -- Type -------------------------------------------+        ErrorNakedType xx+         -> vcat [ text "Found naked type in core program."                  , empty                  , text "with: "                        <> align (ppr xx) ] -        ErrorMaxcloMalformed xx clo-         -> vcat [ text "Type provided for a 'maxclo' is malformed."-                 , text "        Closure: "             <> ppr clo-                 , text " can only contain 'Use' terms."+        -- Witness ----------------------------------------+        ErrorNakedWitness xx+         -> vcat [ text "Found naked witness in core program."                  , empty                  , text "with: "                        <> align (ppr xx) ]-       ++
DDC/Core/Check/TaggedClosure.hs view
@@ -11,7 +11,7 @@         , cutTaggedClosureXs         , cutTaggedClosureT) where-import DDC.Type.Transform.LowerT+import DDC.Type.Transform.LiftT import DDC.Type.Transform.Trim import DDC.Type.Compounds import DDC.Type.Predicates@@ -20,6 +20,8 @@ import Control.Monad import Data.Maybe import Data.Set                 (Set)+import DDC.Type.Env             (Env)+import qualified DDC.Type.Env   as Env import qualified DDC.Type.Sum   as Sum import qualified Data.Set       as Set @@ -62,9 +64,9 @@         GBoundRgnCon u      -> text "CLORGNCON" <+> ppr u  -instance LowerT TaggedClosure where- lowerAtDepthT n d cc-  = let down = lowerAtDepthT n d+instance Ord n => MapBoundT TaggedClosure n where+ mapBoundAtDepthT f d cc+  = let down = mapBoundAtDepthT f d     in case cc of         GBoundVal u ts    -> GBoundVal (down u) (down ts)         GBoundRgnVar u1   -> GBoundRgnVar (down u1)@@ -77,7 +79,7 @@  = case gg of         GBoundVal _ clos  -> TSum $ clos         GBoundRgnVar u    -> tUse (TVar u)-        GBoundRgnCon u    -> tUse (TCon (TyConBound u))+        GBoundRgnCon u    -> tUse (TCon (TyConBound u kRegion))   -- | Convert a set of tagged closures to a regular closure by dropping the@@ -92,31 +94,35 @@ -- | Yield the tagged closure of a value variable. taggedClosureOfValBound          :: (Ord n, Pretty n) -        => Bound n  -> TaggedClosure n+        => Type n -> Bound n  -> TaggedClosure n -taggedClosureOfValBound u+taggedClosureOfValBound t u          = GBoundVal u          $ Sum.singleton kClosure -        $ (let clo = tDeepUse $ typeOfBound u+        $ (let clo = tDeepUse t            in  fromMaybe clo (trimClosure clo))  --- | Yield the tagged closure of a type argument.+-- | Yield the tagged closure of a type argument,+--   or `Nothing` for out-of-scope type vars. taggedClosureOfTyArg          :: (Ord n, Pretty n) -        => Type n -> Set (TaggedClosure n)+        => Env n -> Type n -> Maybe (Set (TaggedClosure n)) -taggedClosureOfTyArg tt+taggedClosureOfTyArg kenv tt  = case tt of         TVar u-         |   isRegionKind (typeOfBound u)-         ->  Set.singleton $ GBoundRgnVar u--        TCon (TyConBound u)-         |   isRegionKind (typeOfBound u)-         ->  Set.singleton $ GBoundRgnCon u+         -> case Env.lookup u kenv of+                Nothing           -> Nothing+                Just k  +                 | isRegionKind k -> Just $ Set.singleton $ GBoundRgnVar u+                 | otherwise      -> Just Set.empty+                                                    +        TCon (TyConBound u k)+         |   isRegionKind k+         ->  Just $ Set.singleton $ GBoundRgnCon u -        _ -> Set.empty+        _ -> Just $ Set.empty   -- | Convert the closure provided as a 'weakclo' to tagged form.@@ -136,8 +142,8 @@             Just (TyConSpec TcConUse, [TVar u])               -> Just $ GBoundRgnVar u -            Just (TyConSpec TcConUse, [TCon (TyConBound u)])-              -> Just $ GBoundRgnVar u+            Just (TyConSpec TcConUse, [TCon (TyConBound u _)])+              -> Just $ GBoundRgnCon u              _ -> Nothing @@ -163,7 +169,7 @@             | otherwise         -> Just gg             GBoundRgnCon u-            | Sum.elem (tUse (TCon (TyConBound u))) ts1     +            | Sum.elem (tUse (TCon (TyConBound u kRegion))) ts1                                      -> Nothing             | otherwise         -> Just gg 
DDC/Core/Collect.hs view
@@ -1,253 +1,18 @@  -- | Collecting sets of variables and constructors. module DDC.Core.Collect-        ( freeT+        ( -- * Free Variables+          freeT         , freeX-        , collectBound-        , collectSpecBinds)-where-import DDC.Type.Compounds-import DDC.Core.Exp-import DDC.Type.Env                     (Env)-import qualified DDC.Type.Env           as Env-import qualified DDC.Type.Sum           as Sum-import qualified Data.Set               as Set-import Data.Set                         (Set) ---- freeT ------------------------------------------------------------------------- | Collect the free Spec variables in a thing (level-1).-freeT   :: (BindStruct c, Ord n) -        => Env n -> c n -> Set (Bound n)-freeT tenv xx = Set.unions $ map (freeOfTreeT tenv) $ slurpBindTree xx--freeOfTreeT :: Ord n => Env n -> BindTree n -> Set (Bound n)-freeOfTreeT kenv tt- = case tt of-        BindDef way bs ts-         |  BoundSpec   <- boundLevelOfBindWay way-         ,  kenv'       <- Env.extends bs kenv-         -> Set.unions $ map (freeOfTreeT kenv') ts--        BindDef _ _ ts-         -> Set.unions $ map (freeOfTreeT kenv) ts--        BindUse BoundSpec u-         | Env.member u kenv -> Set.empty-         | otherwise         -> Set.singleton u-        _                    -> Set.empty----- freeX ------------------------------------------------------------------------- | Collect the free Data and Witness variables in a thing (level-0).-freeX   :: (BindStruct c, Ord n) -        => Env n -> c n -> Set (Bound n)-freeX tenv xx = Set.unions $ map (freeOfTreeX tenv) $ slurpBindTree xx--freeOfTreeX :: Ord n => Env n -> BindTree n -> Set (Bound n)-freeOfTreeX tenv tt- = case tt of-        BindDef way bs ts-         |  BoundExpWit <- boundLevelOfBindWay way-         ,  tenv'       <- Env.extends bs tenv-         -> Set.unions $ map (freeOfTreeX tenv') ts--        BindDef _ _ ts-         -> Set.unions $ map (freeOfTreeX  tenv) ts--        BindUse BoundExpWit u-         | Env.member u tenv -> Set.empty-         | otherwise         -> Set.singleton u-        _                    -> Set.empty----- collectBound ------------------------------------------------------------------ | Collect all the bound variables in a thing, ---   independent of whether they are free or not.-collectBound :: (BindStruct c, Ord n) => c n -> Set (Bound n)-collectBound -        = Set.unions . map collectBoundOfTree . slurpBindTree --collectBoundOfTree :: Ord n => BindTree n -> Set (Bound n)-collectBoundOfTree tt- = case tt of-        BindDef _ _ ts  -> Set.unions $ map collectBoundOfTree ts-        BindUse _ u     -> Set.singleton u-        BindCon _ u     -> Set.singleton u----- collectSpecBinds -------------------------------------------------------------- | Collect all the Spec binders in a thing.-collectSpecBinds :: (BindStruct c, Ord n) => c n -> [Bind n]-collectSpecBinds -        = concatMap collectSpecBindsOfTree . slurpBindTree-        --collectSpecBindsOfTree :: Ord n => BindTree n -> [Bind n]-collectSpecBindsOfTree tt- = case tt of-        BindDef way bs ts-         |   BoundSpec <- boundLevelOfBindWay way-         ->  concat ( bs-                    : map collectSpecBindsOfTree ts)--         | otherwise-         ->  concatMap collectSpecBindsOfTree ts--        _ -> []------------------------------------------------------------------------------------- | A description of the binding structure of some type or expression.-data BindTree n-        -- | An abstract binding expression.-        = BindDef BindWay    [Bind n] [BindTree n]--        -- | Use of a variable.-        | BindUse BoundLevel (Bound n)--        -- | Use of a constructor.-        | BindCon BoundLevel (Bound n)-        deriving (Eq, Show)----- | Describes how a variable was bound.-data BindWay-        = BindForall-        | BindLAM-        | BindLam-        | BindLet-        | BindLetRec-        | BindLetRegion-        | BindLetRegionWith-        | BindCasePat-        deriving (Eq, Show)----- | What level this binder is at.-data BoundLevel-        = BoundSpec-        | BoundExpWit-        deriving (Eq, Show)----- | Get the `BoundLevel` corresponding to a `BindWay`.-boundLevelOfBindWay :: BindWay -> BoundLevel-boundLevelOfBindWay way- = case way of-        BindForall              -> BoundSpec-        BindLAM                 -> BoundSpec-        BindLam                 -> BoundExpWit-        BindLet                 -> BoundExpWit-        BindLetRec              -> BoundExpWit-        BindLetRegion           -> BoundSpec-        BindLetRegionWith       -> BoundExpWit-        BindCasePat             -> BoundExpWit----- BindStruct ------------------------------------------------------------------class BindStruct (c :: * -> *) where- slurpBindTree :: c n -> [BindTree n]---instance BindStruct Type where- slurpBindTree tt-  = case tt of-        TVar u          -> [BindUse BoundSpec u]-        TCon tc         -> slurpBindTree tc-        TForall b t     -> [bindDefT BindForall [b] [t]]-        TApp t1 t2      -> slurpBindTree t1 ++ slurpBindTree t2-        TSum ts         -> concatMap slurpBindTree $ Sum.toList ts---instance BindStruct TyCon where- slurpBindTree tc-  = case tc of-        TyConBound u    -> [BindCon BoundSpec u]-        _               -> []---instance BindStruct (Exp a) where- slurpBindTree xx-  = case xx of-        XVar _ u        -> [BindUse BoundExpWit u]-        XCon _ u        -> [BindCon BoundExpWit u]-        XApp _ x1 x2    -> slurpBindTree x1 ++ slurpBindTree x2-        XLAM _ b x      -> [bindDefT BindLAM [b] [x]]-        XLam _ b x      -> [bindDefX BindLam [b] [x]]      --        XLet _ (LLet m b x1) x2-         -> slurpBindTree m-         ++ slurpBindTree x1-         ++ [bindDefX BindLet [b] [x2]]--        XLet _ (LRec bxs) x2-         -> [bindDefX BindLetRec -                     (map fst bxs) -                     (map snd bxs ++ [x2])]-        -        XLet _ (LLetRegion b bs) x2-         -> [ BindDef  BindLetRegion [b]-             [bindDefX BindLetRegionWith bs [x2]]]--        XLet _ (LWithRegion u) x2-         -> BindUse BoundExpWit u : slurpBindTree x2--        XCase _ x alts  -> slurpBindTree x ++ concatMap slurpBindTree alts-        XCast _ c x     -> slurpBindTree c ++ slurpBindTree x-        XType t         -> slurpBindTree t-        XWitness w      -> slurpBindTree w---instance BindStruct LetMode where- slurpBindTree mm-  = case mm of-        LetLazy (Just w) -> slurpBindTree w-        _                -> []---instance BindStruct Cast where- slurpBindTree cc-  = case cc of-        CastWeakenEffect eff    -> slurpBindTree eff-        CastWeakenClosure clo   -> slurpBindTree clo-        CastPurify w            -> slurpBindTree w-        CastForget w            -> slurpBindTree w---instance BindStruct (Alt a) where- slurpBindTree alt-  = case alt of-        AAlt PDefault x-         -> slurpBindTree x--        AAlt (PData _ bs) x-         -> [bindDefX BindCasePat bs [x]]---instance BindStruct Witness where- slurpBindTree ww-  = case ww of-        WVar u          -> [BindUse BoundExpWit u]-        WCon{}          -> []-        WApp  w1 w2     -> slurpBindTree w1 ++ slurpBindTree w2-        WJoin w1 w2     -> slurpBindTree w1 ++ slurpBindTree w2-        WType t         -> slurpBindTree t----- | Helper for constructing the `BindTree` for an expression or witness binder.-bindDefX :: BindStruct c -         => BindWay -> [Bind n] -> [c n] -> BindTree n-bindDefX way bs xs-        = BindDef way bs-        $   concatMap (slurpBindTree . typeOfBind) bs-        ++  concatMap slurpBindTree xs----- | Helper for constructing the `BindTree` for a type binder.-bindDefT :: BindStruct c-         => BindWay -> [Bind n] -> [c n] -> BindTree n-bindDefT way bs xs-        = BindDef way bs $ concatMap slurpBindTree xs-+          -- * Bounds and Binds+        , collectBound+        , collectBinds +          -- * Support+        , Support       (..)+        , SupportX      (..))+where+import DDC.Core.Collect.Free+import DDC.Core.Collect.Support+import DDC.Type.Collect
+ DDC/Core/Collect/Free.hs view
@@ -0,0 +1,128 @@+-- | Collecting sets of variables and constructors.+module DDC.Core.Collect.Free+        (freeX)+where+import DDC.Type.Collect+import DDC.Type.Compounds+import DDC.Core.Module+import DDC.Core.Exp+import DDC.Type.Env                     (Env)+import qualified DDC.Type.Env           as Env+import qualified Data.Set               as Set+import Data.Set                         (Set)+++-- freeX ----------------------------------------------------------------------+-- | Collect the free Data and Witness variables in a thing (level-0).+freeX   :: (BindStruct c, Ord n) +        => Env n -> c n -> Set (Bound n)+freeX tenv xx = Set.unions $ map (freeOfTreeX tenv) $ slurpBindTree xx++freeOfTreeX :: Ord n => Env n -> BindTree n -> Set (Bound n)+freeOfTreeX tenv tt+ = {-# SCC freeOfTreeX #-}+   case tt of+        BindDef way bs ts+         |  isBoundExpWit $ boundLevelOfBindWay way+         ,  tenv'        <- Env.extends bs tenv+         -> Set.unions $ map (freeOfTreeX tenv') ts++        BindDef _ _ ts+         -> Set.unions $ map (freeOfTreeX  tenv) ts++        BindUse bl u+         | isBoundExpWit bl+         , Env.member u tenv -> Set.empty+         | isBoundExpWit bl  -> Set.singleton u+        _                    -> Set.empty+++-- Module ---------------------------------------------------------------------+instance BindStruct (Module a) where+ slurpBindTree mm+        = slurpBindTree $ moduleBody mm+++-- Exp ------------------------------------------------------------------------+instance BindStruct (Exp a) where+ slurpBindTree xx+  = case xx of+        XVar _ u+         -> [BindUse BoundExp u]++        XCon _ dc+         -> case daConName dc of+                DaConUnit               -> []+                DaConNamed n            -> [BindCon BoundExp (UName n) Nothing]++        XApp _ x1 x2            -> slurpBindTree x1 ++ slurpBindTree x2+        XLAM _ b x              -> [bindDefT BindLAM [b] [x]]+        XLam _ b x              -> [bindDefX BindLam [b] [x]]      ++        XLet _ (LLet m b x1) x2+         -> slurpBindTree m+         ++ slurpBindTree x1+         ++ [bindDefX BindLet [b] [x2]]++        XLet _ (LRec bxs) x2+         -> [bindDefX BindLetRec +                     (map fst bxs) +                     (map snd bxs ++ [x2])]+        +        XLet _ (LLetRegions b bs) x2+         -> [ BindDef  BindLetRegions b+             [bindDefX BindLetRegionWith bs [x2]]]++        XLet _ (LWithRegion u) x2+         -> BindUse BoundExp u : slurpBindTree x2++        XCase _ x alts  -> slurpBindTree x ++ concatMap slurpBindTree alts+        XCast _ c x     -> slurpBindTree c ++ slurpBindTree x+        XType t         -> slurpBindTree t+        XWitness w      -> slurpBindTree w+++instance BindStruct LetMode where+ slurpBindTree mode+  = case mode of+        LetStrict               -> []+        LetLazy Nothing         -> []+        LetLazy (Just ww)       -> slurpBindTree ww+++instance BindStruct (Cast a) where+ slurpBindTree cc+  = case cc of+        CastWeakenEffect  eff   -> slurpBindTree eff+        CastWeakenClosure xs    -> concatMap slurpBindTree xs+        CastPurify w            -> slurpBindTree w+        CastForget w            -> slurpBindTree w+++instance BindStruct (Alt a) where+ slurpBindTree alt+  = case alt of+        AAlt PDefault x+         -> slurpBindTree x++        AAlt (PData _ bs) x+         -> [bindDefX BindCasePat bs [x]]+++instance BindStruct Witness where+ slurpBindTree ww+  = case ww of+        WVar u          -> [BindUse BoundWit u]+        WCon{}          -> []+        WApp  w1 w2     -> slurpBindTree w1 ++ slurpBindTree w2+        WJoin w1 w2     -> slurpBindTree w1 ++ slurpBindTree w2+        WType t         -> slurpBindTree t+++-- | Helper for constructing the `BindTree` for an expression or witness binder.+bindDefX :: BindStruct c +         => BindWay -> [Bind n] -> [c n] -> BindTree n+bindDefX way bs xs+        = BindDef way bs+        $   concatMap (slurpBindTree . typeOfBind) bs+        ++  concatMap slurpBindTree xs
+ DDC/Core/Collect/Support.hs view
@@ -0,0 +1,208 @@++module DDC.Core.Collect.Support+        ( Support       (..)+        , SupportX      (..))+where+import DDC.Core.Compounds+import DDC.Core.Exp+import DDC.Type.Collect.FreeT+import Data.Set                 (Set)+import DDC.Type.Env             (KindEnv, TypeEnv)+import qualified DDC.Type.Env   as Env+import qualified Data.Set       as Set+import Data.Monoid+++data Support n+        = Support+        { -- | Type constructors used in the expression.+          supportTyCon          :: Set (Bound n)++          -- | Type constructors used in the argument of a value-type application.+        , supportTyConXArg      :: Set (Bound n)++          -- | Free spec variables in an expression.+        , supportSpVar          :: Set (Bound n)++          -- | Type constructors used in the argument of a value-type application.+        , supportSpVarXArg      :: Set (Bound n)++          -- | Free witness variables in an expression.+          --   (from the Witness universe)+        , supportWiVar          :: Set (Bound n)++          -- | Free value variables in an expression.+          --   (from the Data universe)+        , supportDaVar          :: Set (Bound n) }+        deriving Show+++instance Ord n => Monoid (Support n) where+ mempty = Support+        { supportTyCon          = Set.empty+        , supportTyConXArg      = Set.empty+        , supportSpVar          = Set.empty+        , supportSpVarXArg      = Set.empty+        , supportWiVar          = Set.empty+        , supportDaVar          = Set.empty }++ mappend sp1 sp2+        = Support+        { supportTyCon          = Set.unions [supportTyCon sp1,     supportTyCon sp2]+        , supportTyConXArg      = Set.unions [supportTyConXArg sp1, supportTyConXArg sp2]+        , supportSpVar          = Set.unions [supportSpVar sp1,     supportSpVar sp2]+        , supportSpVarXArg      = Set.unions [supportSpVarXArg sp1, supportSpVarXArg sp2]+        , supportWiVar          = Set.unions [supportWiVar sp1,     supportWiVar sp2]+        , supportDaVar          = Set.unions [supportDaVar sp1,     supportDaVar sp2] }+++class SupportX (c :: * -> *) where+ support+        :: Ord n+        => KindEnv n -> TypeEnv n+        -> c n+        -> Support n+++instance SupportX Type where+ support kenv _tenv t+  = let (fvs1, tcs)     = freeVarConT kenv t+    in  mempty  { supportTyCon  = tcs+                , supportSpVar  = fvs1 }+++instance SupportX Bind where+ support kenv tenv b+  = support kenv tenv +  $ typeOfBind b+++instance SupportX (Exp a) where+ support kenv tenv xx+  = case xx of+        XVar _ u        +         | Env.member u tenv    -> mempty+         | otherwise            -> mempty { supportDaVar = Set.singleton u}++        XCon{}                  +         -> mempty++        XLAM _ b x+         -> support kenv tenv b +         <> support (Env.extend b kenv) tenv x++        XLam _ b x+         -> support kenv tenv b+         <> support kenv (Env.extend b tenv) x++        XApp _ x1 x2+         -> let s1              = support kenv tenv x1 +                s2              = support kenv tenv x2+            in  mappend s1 s2++        XLet _a lts x2+         -> let s1              = support kenv tenv lts+                (bs1, bs0)      = bindsOfLets lts+                kenv'           = Env.extends bs1 kenv+                tenv'           = Env.extends bs0 tenv+                s2              = support kenv' tenv' x2+            in  mappend s1 s2++        XCase _ x1 alts+         -> let s1              = support kenv tenv x1+                ss              = mconcat $ map (support kenv tenv) alts+            in  mappend s1 ss++        XCast _ c1 x2+         -> let s1              = support kenv tenv c1+                s2              = support kenv tenv x2+            in  mappend s1 s2++        XType t +         -> let sup = support kenv tenv t+            in  sup { supportTyConXArg  = supportTyCon sup+                    , supportSpVarXArg  = supportSpVar sup }++        XWitness w      -> support kenv tenv w+++instance SupportX (Alt a) where+ support kenv tenv aa+  = case aa of+        AAlt PDefault x+         -> support kenv tenv x++        AAlt (PData _dc bs0) x+         -> let tenv'   = Env.extends bs0 tenv+            in  support kenv tenv' x+++instance SupportX Witness where+ support kenv tenv ww+  = case ww of+        WVar u+         | Env.member u tenv    -> mempty+         | otherwise            -> mempty { supportWiVar = Set.singleton u }++        WCon{}+         -> mempty++        WApp w1 w2+         -> support kenv tenv w1+         <> support kenv tenv w2++        WJoin w1 w2+         -> support kenv tenv w1+         <> support kenv tenv w2++        WType t+         -> support kenv tenv t+++instance SupportX (Cast a) where+ support kenv tenv cc+  = case cc of+        CastWeakenEffect eff+         -> support kenv tenv eff++        CastWeakenClosure xs+         -> mconcat $ map (support kenv tenv) xs++        CastPurify w+         -> support kenv tenv w++        CastForget w+         -> support kenv tenv w+         ++instance SupportX (Lets a) where+ support kenv tenv lts+  = case lts of+        LLet m b x+         -> support kenv tenv m+         <> support kenv tenv b+         <> support kenv (Env.extend b tenv) x++        LRec bxs+         -> (mconcat $ map (support kenv tenv) $ map fst bxs)+         <> (let tenv' = Env.extends (map fst bxs) tenv+             in  mconcat $ map (support kenv tenv') $ map snd bxs)++        LLetRegions bs ws+         -> (mconcat $ map (support kenv tenv) bs)+         <> (let kenv' = Env.extends bs kenv+             in  mconcat $ map (support kenv' tenv) ws)++        LWithRegion u+         | Env.member u kenv    -> mempty+         | otherwise            -> mempty { supportSpVar = Set.singleton u }+++instance SupportX LetMode where+ support kenv tenv mm+  = case mm of+        LetStrict               -> mempty+        LetLazy Nothing         -> mempty+        LetLazy (Just w)        -> support kenv tenv w++
DDC/Core/Compounds.hs view
@@ -1,79 +1,93 @@  -- | Utilities for constructing and destructing compound expressions. module DDC.Core.Compounds -        ( -- * Lets-          bindsOfLets-        , specBindsOfLets-        , valwitBindsOfLets+        ( module DDC.Type.Compounds+        , module DDC.Core.DaCon -          -- * Patterns-        , bindsOfPat+          -- * Annotations+        , takeAnnotOfExp            -- * Lambdas-        , makeXLAMs, takeXLAMs-        , makeXLams, takeXLams-        , takeXLamFlags+        , xLAMs+        , xLams         , makeXLamFlags+        , takeXLAMs+        , takeXLams+        , takeXLamFlags            -- * Applications-        , makeXApps+        , xApps+        , makeXAppsWithAnnots         , takeXApps+        , takeXApps1+        , takeXAppsAsList+        , takeXAppsWithAnnots         , takeXConApps         , takeXPrimApps -          -- * Alternatives-        , takeCtorNameOfAlt)-where-import DDC.Type.Compounds-import DDC.Core.Exp-+          -- * Lets+        , xLets+        , splitXLets +        , bindsOfLets+        , specBindsOfLets+        , valwitBindsOfLets --- | Take the binds of a `Lets`.-bindsOfLets :: Lets a n -> [Bind n]-bindsOfLets ll- = case ll of-        LLet _ b _        -> [b]-        LRec bxs          -> map fst bxs-        LLetRegion   b bs -> b : bs-        LWithRegion{}     -> []+          -- * Patterns+        , bindsOfPat +          -- * Alternatives+        , takeCtorNameOfAlt --- | Like `bindsOfLets` but only take the type binders.-specBindsOfLets :: Lets a n -> [Bind n]-specBindsOfLets ll- = case ll of-        LLet _ _ _       -> []-        LRec _           -> []-        LLetRegion b _   -> [b]-        LWithRegion{}    -> []+          -- * Witnesses+        , wApp+        , wApps+        , takeXWitness+        , takeWAppsAsList+        , takePrimWiConApps +          -- * Types+        , takeXType --- | Like `bindsOfLets` but only take the value and witness binders.-valwitBindsOfLets :: Lets a n -> [Bind n]-valwitBindsOfLets ll- = case ll of-        LLet _ b _       -> [b]-        LRec bxs         -> map fst bxs-        LLetRegion _ bs  -> bs-        LWithRegion{}    -> []+          -- * Units+        , xUnit)+where+import DDC.Type.Compounds+import DDC.Core.Exp+import DDC.Core.DaCon  --- | Take the binds of a `Pat`.-bindsOfPat :: Pat n -> [Bind n]-bindsOfPat pp- = case pp of-        PDefault          -> []-        PData _ bs        -> bs+-- Annotations ----------------------------------------------------------------+-- | Take the outermost annotation from an expression,+--   or Nothing if this is an `XType` or `XWitness` without an annotation.+takeAnnotOfExp :: Exp a n -> Maybe a+takeAnnotOfExp xx+ = case xx of+        XVar  a _       -> Just a+        XCon  a _       -> Just a+        XLAM  a _ _     -> Just a+        XLam  a _ _     -> Just a+        XApp  a _ _     -> Just a+        XLet  a _ _     -> Just a+        XCase a _ _     -> Just a+        XCast a _ _     -> Just a+        XType{}         -> Nothing+        XWitness{}      -> Nothing   -- Lambdas ------------------------------------------------------------------------ | Make some nested type lambda abstractions.-makeXLAMs :: a -> [Bind n] -> Exp a n -> Exp a n-makeXLAMs a bs x+-- | Make some nested type lambdas.+xLAMs :: a -> [Bind n] -> Exp a n -> Exp a n+xLAMs a bs x         = foldr (XLAM a) x (reverse bs)  --- | Split nested value and witness lambdas from the front of an expression,+-- | Make some nested value or witness lambdas.+xLams :: a -> [Bind n] -> Exp a n -> Exp a n+xLams a bs x+        = foldr (XLam a) x (reverse bs)+++-- | Split type lambdas from the front of an expression, --   or `Nothing` if there aren't any. takeXLAMs :: Exp a n -> Maybe ([Bind n], Exp a n) takeXLAMs xx@@ -84,12 +98,6 @@          (bs, body)     -> Just (bs, body)  --- | Make some nested value or witness lambda abstractions.-makeXLams :: a -> [Bind n] -> Exp a n -> Exp a n-makeXLams a bs x-        = foldr (XLam a) x (reverse bs)-- -- | Split nested value or witness lambdas from the front of an expression, --   or `Nothing` if there aren't any. takeXLams :: Exp a n -> Maybe ([Bind n], Exp a n)@@ -101,6 +109,17 @@          (bs, body)     -> Just (bs, body)  +-- | Make some nested lambda abstractions,+--   using a flag to indicate whether the lambda is a+--   level-1 (True), or level-0 (False) binder.+makeXLamFlags :: a -> [(Bool, Bind n)] -> Exp a n -> Exp a n+makeXLamFlags a fbs x+ = foldr (\(f, b) x'+           -> if f then XLAM a b x'+                   else XLam a b x')+                x fbs++ -- | Split nested lambdas from the front of an expression,  --   with a flag indicating whether the lambda was a level-1 (True),  --   or level-0 (False) binder.@@ -114,59 +133,200 @@          (bs, body)     -> Just (bs, body)  --- | Make some nested lambda abstractions,---   using a flag to indicate whether the lambda is a---   level-1 (True), or level-0 (False) binder.-makeXLamFlags :: a -> [(Bool, Bind n)] -> Exp a n -> Exp a n-makeXLamFlags a fbs x- = foldr (\(f, b) x'-           -> if f then XLAM a b x'-                   else XLam a b x')-                x fbs+-- Applications ---------------------------------------------------------------+-- | Build sequence of value applications.+xApps   :: a -> Exp a n -> [Exp a n] -> Exp a n+xApps a t1 ts     = foldl (XApp a) t1 ts  --- Applications ------------------------------------------------------------------ | Build sequence of type applications.-makeXApps   :: a -> Exp a n -> [Exp a n] -> Exp a n-makeXApps a t1 ts     = foldl (XApp a) t1 ts+-- | Build sequence of applications.+--   Similar to `xApps` but also takes list of annotations for +--   the `XApp` constructors.+makeXAppsWithAnnots :: Exp a n -> [(Exp a n, a)] -> Exp a n+makeXAppsWithAnnots f xas+ = case xas of+        []              -> f+        (arg,a ) : as   -> makeXAppsWithAnnots (XApp a f arg) as  --- | Flatten an application into the function parts and arguments, if any.-takeXApps   :: Exp a n -> [Exp a n]+-- | Flatten an application into the function part and its arguments.+--+--   Returns `Nothing` if there is no outer application.+takeXApps :: Exp a n -> Maybe (Exp a n, [Exp a n]) takeXApps xx+ = case takeXAppsAsList xx of+        (x1 : xsArgs)   -> Just (x1, xsArgs)+        _               -> Nothing+++-- | Flatten an application into the function part and its arguments.+--+--   This is like `takeXApps` above, except we know there is at least one argument.+takeXApps1 :: Exp a n -> Exp a n -> (Exp a n, [Exp a n])+takeXApps1 x1 x2+ = case takeXApps x1 of+        Nothing          -> (x1,  [x2])+        Just (x11, x12s) -> (x11, x12s ++ [x2])+++-- | Flatten an application into the function parts and arguments, if any.+takeXAppsAsList  :: Exp a n -> [Exp a n]+takeXAppsAsList xx  = case xx of-        XApp _ x1 x2    -> takeXApps x1 ++ [x2]+        XApp _ x1 x2    -> takeXAppsAsList x1 ++ [x2]         _               -> [xx]  +-- | Destruct sequence of applications.+--   Similar to `takeXAppsAsList` but also keeps annotations for later.+takeXAppsWithAnnots :: Exp a n -> (Exp a n, [(Exp a n, a)])+takeXAppsWithAnnots xx+ = case xx of+        XApp a f arg+         -> let (f', args') = takeXAppsWithAnnots f+            in  (f', args' ++ [(arg,a)])++        _ -> (xx, [])++ -- | Flatten an application of a primop into the variable --   and its arguments. --    --   Returns `Nothing` if the expression isn't a primop application. takeXPrimApps :: Exp a n -> Maybe (n, [Exp a n]) takeXPrimApps xx- = case takeXApps xx of-        XVar _ (UPrim p _) : xs  -> Just (p, xs)-        _                        -> Nothing+ = case takeXAppsAsList xx of+        XVar _ (UPrim p _) : xs -> Just (p, xs)+        _                       -> Nothing  -- | Flatten an application of a data constructor into the constructor --   and its arguments.  -- --   Returns `Nothing` if the expression isn't a constructor application.-takeXConApps :: Exp a n -> Maybe (Bound n, [Exp a n])+takeXConApps :: Exp a n -> Maybe (DaCon n, [Exp a n]) takeXConApps xx- = case takeXApps xx of-        XCon _ u : xs   -> Just (u, xs)+ = case takeXAppsAsList xx of+        XCon _ dc : xs  -> Just (dc, xs)         _               -> Nothing  +-- Lets -----------------------------------------------------------------------+-- | Wrap some let-bindings around an expression.+xLets :: a -> [Lets a n] -> Exp a n -> Exp a n+xLets a lts x+ = foldr (XLet a) x lts+++-- | Split let-bindings from the front of an expression, if any.+splitXLets :: Exp a n -> ([Lets a n], Exp a n)+splitXLets xx+ = case xx of+        XLet _ lts x +         -> let (lts', x')      = splitXLets x+            in  (lts : lts', x')++        _ -> ([], xx)++-- | Take the binds of a `Lets`.+--+--   The level-1 and level-0 binders are returned separately.+bindsOfLets :: Lets a n -> ([Bind n], [Bind n])+bindsOfLets ll+ = case ll of+        LLet _ b _         -> ([],  [b])+        LRec bxs           -> ([],  map fst bxs)+        LLetRegions bs bbs -> (bs, bbs)+        LWithRegion{}      -> ([],  [])+++-- | Like `bindsOfLets` but only take the spec (level-1) binders.+specBindsOfLets :: Lets a n -> [Bind n]+specBindsOfLets ll+ = case ll of+        LLet _ _ _       -> []+        LRec _           -> []+        LLetRegions bs _ -> bs+        LWithRegion{}    -> []+++-- | Like `bindsOfLets` but only take the value and witness (level-0) binders.+valwitBindsOfLets :: Lets a n -> [Bind n]+valwitBindsOfLets ll+ = case ll of+        LLet _ b _       -> [b]+        LRec bxs         -> map fst bxs+        LLetRegions _ bs -> bs+        LWithRegion{}    -> []++ -- Alternatives --------------------------------------------------------------- -- | Take the constructor name of an alternative, if there is one. takeCtorNameOfAlt :: Alt a n -> Maybe n takeCtorNameOfAlt aa  = case aa of-        AAlt (PData u _) _      -> takeNameOfBound u+        AAlt (PData dc _) _     -> takeNameOfDaCon dc         _                       -> Nothing  +-- Patterns -------------------------------------------------------------------+-- | Take the binds of a `Pat`.+bindsOfPat :: Pat n -> [Bind n]+bindsOfPat pp+ = case pp of+        PDefault          -> []+        PData _ bs        -> bs+++-- Witnesses ------------------------------------------------------------------+-- | Construct a witness application+wApp :: Witness n -> Witness n -> Witness n+wApp = WApp+++-- | Construct a sequence of witness applications+wApps :: Witness n -> [Witness n] -> Witness n+wApps = foldl wApp+++-- | Take the witness from an `XWitness` argument, if any.+takeXWitness :: Exp a n -> Maybe (Witness n)+takeXWitness xx+ = case xx of+        XWitness t -> Just t+        _          -> Nothing+++-- | Flatten an application into the function parts and arguments, if any.+takeWAppsAsList :: Witness n -> [Witness n]+takeWAppsAsList ww+ = case ww of+        WApp w1 w2 -> takeWAppsAsList w1 ++ [w2]+        _          -> [ww]+++-- | Flatten an application of a witness into the witness constructor+--   name and its arguments.+--+--   Returns nothing if there is no witness constructor in head position.+takePrimWiConApps :: Witness n -> Maybe (n, [Witness n])+takePrimWiConApps ww+ = case takeWAppsAsList ww of+        WCon wc : args | WiConBound (UPrim n _) _ <- wc+          -> Just (n, args)+        _ -> Nothing+++-- Types ----------------------------------------------------------------------+-- | Take the type from an `XType` argument, if any.+takeXType :: Exp a n -> Maybe (Type n)+takeXType xx+ = case xx of+        XType t -> Just t+        _       -> Nothing+++-- Units -----------------------------------------------------------------------+-- | Construct a value of unit type.+xUnit   :: a -> Exp a n+xUnit a = XCon a dcUnit 
+ DDC/Core/DaCon.hs view
@@ -0,0 +1,100 @@++module DDC.Core.DaCon +        ( DaCon         (..)+        , DaConName     (..)++        , dcUnit+        , mkDaConAlg+        , mkDaConSolid+        , takeNameOfDaCon+        , typeOfDaCon)+where+import DDC.Type.Compounds+import DDC.Type.Exp+import Control.DeepSeq+++-------------------------------------------------------------------------------+-- | Data constructor names.+data DaConName n+        -- | The unit data constructor is builtin.+        = DaConUnit++        -- | Data constructor name defined by the client.+        | DaConNamed n+        deriving (Eq, Show)+++instance NFData n => NFData (DaConName n) where+ rnf dcn+  = case dcn of+        DaConUnit       -> ()+        DaConNamed n    -> rnf n+++-------------------------------------------------------------------------------+-- | Data constructors.+data DaCon n+        = DaCon+        { -- | Name of the data constructor.+          daConName             :: !(DaConName n)++          -- | Type of the data constructor.+          --   The type must be closed.+        , daConType             :: !(Type n)++          -- | Algebraic constructors can be deconstructed with case-expressions,+          --   and must have a data type declaration.+          -- +          --   Non-algebraic types like 'Float' can't be inspected with+          --   case-expressions.+        , daConIsAlgebraic      :: !Bool }+        deriving Show+++instance NFData n => NFData (DaCon n) where+ rnf !dc+        =     rnf (daConName dc)+        `seq` rnf (daConType dc)+        `seq` rnf (daConIsAlgebraic dc)+++-- | Take the name of data constructor.+takeNameOfDaCon :: DaCon n -> Maybe n+takeNameOfDaCon dc+ = case daConName dc of+        DaConUnit               -> Nothing+        DaConNamed n            -> Just n+++-- | Take the type annotation of a data constructor.+typeOfDaCon :: DaCon n -> Type n+typeOfDaCon dc  = daConType dc+++-- | The unit data constructor.+dcUnit  :: DaCon n+dcUnit  = DaCon+        { daConName             = DaConUnit+        , daConType             = tUnit+        , daConIsAlgebraic      = True }+++-- | Make an algebraic data constructor.+mkDaConAlg :: n -> Type n -> DaCon n+mkDaConAlg n t+        = DaCon+        { daConName             = DaConNamed n+        , daConType             = t+        , daConIsAlgebraic      = True }+++-- | Make a non-algebraic (solid) constructor.+--   These are used for location values in the interpreter,+--   and for floating point literals in the main compiler.+mkDaConSolid :: n -> Type n -> DaCon n+mkDaConSolid n t+        = DaCon+        { daConName             = DaConNamed n+        , daConType             = t+        , daConIsAlgebraic      = False }
− DDC/Core/DataDef.hs
@@ -1,135 +0,0 @@---- | Algebraic data type definitions.-module DDC.Core.DataDef-        ( DataDef    (..)--        -- * Data type definition table-        , DataDefs   (..)-        , DataMode   (..)-        , DataType   (..)-        , DataCtor   (..)--        , emptyDataDefs-        , insertDataDef-        , fromListDataDefs-        , lookupModeOfDataType)-where-import DDC.Type.Exp-import Data.Map                 (Map)-import qualified Data.Map       as Map-import Data.Maybe-import Control.Monad----- | The definition of a single data type.-data DataDef n-        = DataDef-        { -- | Name of the data type.-          dataDefTypeName       :: n--          -- | Kinds of type parameters.-        , dataDefParamKinds     :: [Kind n]--          -- | Constructors of the data type, or Nothing if there are-          --   too many to list (like with `Int`).-        , dataDefCtors          :: Maybe [(n, [Type n])] }------ DataDefs ---------------------------------------------------------------------- | A table of data type definitions,---   unpacked into type and data constructors so we can find them easily.-data DataDefs n-        = DataDefs-        { dataDefsTypes :: Map n (DataType n)-        , dataDefsCtors :: Map n (DataCtor n) }----- | The mode of a data type records how many data constructors there are.---   This can be set to 'Large' for large primitive types like Int and Float.---   In this case we don't ever expect them all to be enumerated---   as case alternatives.-data DataMode n-        = DataModeSmall [n]-        | DataModeLarge----- | Describes a data type constructor, used in the `DataDefs` table.-data DataType n-        = DataType -        { -- | Name of data type constructor.-          dataTypeName       :: n--          -- | Kinds of type parameters to constructor.-        , dataTypeParamKinds :: [Kind n]--          -- | Names of data constructors of this data type,-          --   or `Nothing` if it has infinitely many constructors.-        , dataTypeMode       :: DataMode n }----- | Describes a data constructor, used in the `DataDefs` table.-data DataCtor n-        = DataCtor-        { -- | Name of data constructor.-          dataCtorName       :: n--          -- | Field types of constructor.-        , dataCtorFieldTypes :: [Type n]--          -- | Name of result type of constructor.-        , dataCtorTypeName   :: n }------ | An empty table of data type definitions.-emptyDataDefs :: DataDefs n-emptyDataDefs-        = DataDefs-        { dataDefsTypes = Map.empty-        , dataDefsCtors = Map.empty }----- | Insert a data type definition into some DataDefs.-insertDataDef  :: Ord n => DataDef  n -> DataDefs n -> DataDefs n-insertDataDef (DataDef nType ks mCtors) dataDefs- = let  defType = DataType-                { dataTypeName       = nType-                , dataTypeParamKinds = ks-                , dataTypeMode       = defMode }--        defMode = case mCtors of-                   Nothing    -> DataModeLarge-                   Just ctors -> DataModeSmall (map fst ctors)--        makeDefCtor (nCtor, tsFields)-                = DataCtor-                { dataCtorName       = nCtor-                , dataCtorFieldTypes = tsFields-                , dataCtorTypeName   = nType }--        defCtors = case mCtors of-                    Nothing  -> Nothing-                    Just cs  -> Just $ map makeDefCtor cs--   in   dataDefs-         { dataDefsTypes = Map.insert nType defType (dataDefsTypes dataDefs)-         , dataDefsCtors = Map.union (dataDefsCtors dataDefs)-                         $ Map.fromList [(n, def) | def@(DataCtor n _ _) -                                          <- concat $ maybeToList defCtors] }----- | Build a `DataDefs` table from a list of `DataDef`-fromListDataDefs :: Ord n => [DataDef n] -> DataDefs n-fromListDataDefs defs-        = foldr insertDataDef emptyDataDefs defs------ | Yield the list of data constructor names for some data type, ---   or `Nothing` for large types with too many constructors to list.-lookupModeOfDataType :: Ord n => n -> DataDefs n -> Maybe (DataMode n)-lookupModeOfDataType n defs-        = liftM dataTypeMode $ Map.lookup n (dataDefsTypes defs)--
DDC/Core/Exp.hs view
@@ -5,6 +5,8 @@            -- * Computation expressions         , Exp     (..)+        , DaCon   (..)+        , DaConName(..)         , Cast    (..)         , Lets    (..)         , LetMode (..)@@ -16,183 +18,8 @@         , WiCon   (..)         , WbCon   (..)) where+import DDC.Core.Exp.Base+import DDC.Core.Exp.NFData      ()+import DDC.Core.DaCon import DDC.Type.Exp-import DDC.Type.Sum             ()----- Values ------------------------------------------------------------------------ | Well-typed expressions live in the Data universe, and their types always---   have kind '*'. --- ---   Expressions do something useful at runtime, and might diverge or cause---   side effects.-data Exp a n-        -- | Value variable   or primitive operation.-        = XVar  a  (Bound n)--        -- | Data constructor or literal.-        | XCon  a  (Bound n)--        -- | Type abstraction (level-1).-        | XLAM  a  (Bind n)   (Exp a n)--        -- | Value and Witness abstraction (level-0).-        | XLam  a  (Bind n)   (Exp a n)--        -- | Application.-        | XApp  a  (Exp a n)  (Exp a n)--        -- | Possibly recursive bindings.-        | XLet  a  (Lets a n) (Exp a n)--        -- | Case branching.-        | XCase a  (Exp a n)  [Alt a n]--        -- | Type cast.-        | XCast a  (Cast n)   (Exp a n)--        -- | Type can appear as the argument of an application.-        | XType    (Type n)--        -- | Witness can appear as the argument of an application.-        | XWitness (Witness n)-        deriving (Eq, Show)----- | Type casts.-data Cast n-        -- | Weaken the effect of an expression.-        = CastWeakenEffect  (Effect n)-        -        -- | Weaken the closure of an expression.-        | CastWeakenClosure (Closure n)--        -- | Purify the effect of an expression.-        | CastPurify (Witness n)--        -- | Hide sharing of the closure of an expression.-        | CastForget (Witness n)-        deriving (Eq, Show)----- | Possibly recursive bindings.-data Lets a n-        -- | Non-recursive expression binding.-        = LLet    (LetMode n) (Bind n) (Exp a n)--        -- | Recursive binding of lambda abstractions.-        | LRec    [(Bind n, Exp a n)]--        -- | Bind a local region variable,-        --   and witnesses to its properties.-        | LLetRegion  (Bind n) [Bind n]-        -        -- | Holds a region handle during evaluation.-        | LWithRegion (Bound n)-        deriving (Eq, Show)----- | Describes how a let binding should be evaluated.-data LetMode n-        -- | Evaluate binding before substituting the result.-        = LetStrict--        -- | Use lazy evaluation. -        --   The witness shows that the head region of the bound expression-        --   can contain thunks (is lazy), or Nothing if there is no head region.-        | LetLazy (Maybe (Witness n))-        deriving (Eq, Show)----- | Case alternatives.-data Alt a n-        = AAlt (Pat n) (Exp a n)-        deriving (Eq, Show)----- | Pattern matching.-data Pat n-        -- | The default pattern always succeeds.-        = PDefault-        -        -- | Match a data constructor and bind its arguments.-        | PData (Bound n) [Bind n]-        deriving (Eq, Show)-        ---- Witness ----------------------------------------------------------------------- | When a witness exists in the program it guarantees that a---   certain property of the program is true.-data Witness n-        -- | Witness variable.-        = WVar  (Bound n)-        -        -- | Witness constructor.-        | WCon  (WiCon n)-        -        -- | Witness application.-        | WApp  (Witness n) (Witness n)--        -- | Joining of witnesses.-        | WJoin (Witness n) (Witness n)--        -- | Type can appear as the argument of an application.-        | WType (Type n)-        deriving (Eq, Show)----- | Witness constructors.-data WiCon n-        -- | Witness constructors baked into the language.-        = WiConBuiltin WbCon--        -- | Witness constructors defined in the environment.-        --   In the interpreter we use this to hold runtime capabilities.-        | WiConBound (Bound n)-        deriving (Eq, Show)----- | Built-in witness constructors.------   These are used to convert a runtime capability into a witness that---   the corresponding property is true.-data WbCon-        -- | (axiom) The pure effect is pure.-        -- -        --   @pure     :: Pure !0@-        = WbConPure --        -- | (axiom) The empty closure is empty.-        ---        --   @empty    :: Empty $0@-        | WbConEmpty--        -- | Convert a capability guaranteeing that a region is in the global-        --   heap into a witness that a closure using this region is empty.-        --   This lets us rely on the garbage collector to reclaim objects-        --   in the region. It is needed when we suspend the evaluation of -        --   expressions that have a region in their closure, because the-        --   type of the returned thunk may not reveal that it references-        --   objects in that region.-        -- -        --  @use      :: [r: %]. Global r => Empty (Use r)@-        | WbConUse      --        -- | Convert a capability guaranteeing the constancy of a region into-        --   a witness that a read from that region is pure.-        --   This lets us suspend applications that read constant objects,-        --   because it doesn't matter if the read is delayed, we'll always-        --   get the same result.-        ---        --   @read     :: [r: %]. Const r  => Pure (Read r)@-        | WbConRead     --        -- | Convert a capability guaranteeing the constancy of a region into-        --   a witness that allocation into that region is pure.-        --   This lets us increase the sharing of constant objects,-        --   because we can't tell constant objects of the same value apart.-        -- -        --  @alloc    :: [r: %]. Const r  => Pure (Alloc r)@-        | WbConAlloc-        deriving (Eq, Show) 
+ DDC/Core/Exp/Base.hs view
@@ -0,0 +1,186 @@++module DDC.Core.Exp.Base where+import DDC.Core.DaCon+import DDC.Type.Exp+import DDC.Type.Sum             ()+++-- Values ---------------------------------------------------------------------+-- | Well-typed expressions produce `Data` values when evaluated, +--   and their types aways have kind '*' (Data)+data Exp a n+        -- | Value variable   or primitive operation.+        = XVar  !a  !(Bound n)++        -- | Data constructor or literal.+        | XCon  !a  !(DaCon n)++        -- | Type abstraction (level-1).+        | XLAM  !a  !(Bind n)   !(Exp a n)++        -- | Value and Witness abstraction (level-0).+        | XLam  !a  !(Bind n)   !(Exp a n)++        -- | Application.+        | XApp  !a  !(Exp a n)  !(Exp a n)++        -- | Possibly recursive bindings.+        | XLet  !a  !(Lets a n) !(Exp a n)++        -- | Case branching.+        | XCase !a  !(Exp a n)  ![Alt a n]++        -- | Type cast.+        | XCast !a  !(Cast a n) !(Exp a n)++        -- | Type can appear as the argument of an application.+        | XType    !(Type n)++        -- | Witness can appear as the argument of an application.+        | XWitness !(Witness n)+        deriving (Eq, Show)++deriving instance Eq n => Eq (DaCon n)+++-- | Type casts.+data Cast a n+        -- | Weaken the effect of an expression.+        --   The given effect is added to the effect+        --   of the body.+        = CastWeakenEffect  !(Effect n)+        +        -- | Weaken the closure of an expression.+        --   The closures of these expressions are added to the closure+        --   of the body.+        | CastWeakenClosure ![Exp a n]++        -- | Purify the effect (action) of an expression.+        | CastPurify !(Witness n)++        -- | Forget about the closure (sharing) of an expression.+        | CastForget !(Witness n)+        deriving (Eq, Show)+++-- | Possibly recursive bindings.+data Lets a n+        -- | Non-recursive expression binding.+        = LLet    !(LetMode n) !(Bind n) !(Exp a n)++        -- | Recursive binding of lambda abstractions.+        | LRec    ![(Bind n, Exp a n)]++        -- | Bind a local region variable,+        --   and witnesses to its properties.+        | LLetRegions ![Bind n] ![Bind n]+        +        -- | Holds a region handle during evaluation.+        | LWithRegion !(Bound n)+        deriving (Eq, Show)+++-- | Describes how a let binding should be evaluated.+data LetMode n+        -- | Evaluate binding before substituting the result.+        = LetStrict++        -- | Use lazy evaluation. +        --   The witness shows that the head region of the bound expression+        --   can contain thunks (is lazy), or Nothing if there is no head region.+        | LetLazy !(Maybe (Witness n))+        deriving (Eq, Show)+++-- | Case alternatives.+data Alt a n+        = AAlt !(Pat n) !(Exp a n)+        deriving (Eq, Show)+++-- | Pattern matching.+data Pat n+        -- | The default pattern always succeeds.+        = PDefault+        +        -- | Match a data constructor and bind its arguments.+        | PData !(DaCon n) ![Bind n]+        deriving (Eq, Show)+        ++-- Witness --------------------------------------------------------------------+-- | When a witness exists in the program it guarantees that a+--   certain property of the program is true.+data Witness n+        -- | Witness variable.+        = WVar  !(Bound n)+        +        -- | Witness constructor.+        | WCon  !(WiCon n)+        +        -- | Witness application.+        | WApp  !(Witness n) !(Witness n)++        -- | Joining of witnesses.+        | WJoin !(Witness n) !(Witness n)++        -- | Type can appear as the argument of an application.+        | WType !(Type n)+        deriving (Eq, Show)+++-- | Witness constructors.+data WiCon n+        -- | Witness constructors baked into the language.+        = WiConBuiltin !WbCon++        -- | Witness constructors defined in the environment.+        --   In the interpreter we use this to hold runtime capabilities.+        --   The attached type must be closed.+        | WiConBound !(Bound n) !(Type n)+        deriving (Eq, Show)+++-- | Built-in witness constructors.+--+--   These are used to convert a runtime capability into a witness that+--   the corresponding property is true.+data WbCon+        -- | (axiom) The pure effect is pure.+        -- +        --   @pure     :: Pure !0@+        = WbConPure ++        -- | (axiom) The empty closure is empty.+        --+        --   @empty    :: Empty $0@+        | WbConEmpty++        -- | Convert a capability guaranteeing that a region is in the global+        --   heap, into a witness that a closure using this region is empty.+        --   This lets us rely on the garbage collector to reclaim objects+        --   in the region. It is needed when we suspend the evaluation of +        --   expressions that have a region in their closure, because the+        --   type of the returned thunk may not reveal that it references+        --   objects in that region.+        -- +        --  @use      :: [r : %]. Global r => Empty (Use r)@+        | WbConUse      ++        -- | Convert a capability guaranteeing the constancy of a region, into+        --   a witness that a read from that region is pure.+        --   This lets us suspend applications that read constant objects,+        --   because it doesn't matter if the read is delayed, we'll always+        --   get the same result.+        --+        --   @read     :: [r : %]. Const r  => Pure (Read r)@+        | WbConRead     ++        -- | Convert a capability guaranteeing the constancy of a region, into+        --   a witness that allocation into that region is pure.+        --   This lets us increase the sharing of constant objects,+        --   because we can't tell constant objects of the same value apart.+        -- +        --  @alloc    :: [r : %]. Const r  => Pure (Alloc r)@+        | WbConAlloc+        deriving (Eq, Show)
+ DDC/Core/Exp/NFData.hs view
@@ -0,0 +1,82 @@++module DDC.Core.Exp.NFData where+import DDC.Core.Exp.Base+import Control.DeepSeq+++instance (NFData a, NFData n) => NFData (Exp a n) where+ rnf xx+  = case xx of+        XVar  a u       -> rnf a `seq` rnf u+        XCon  a dc      -> rnf a `seq` rnf dc+        XLAM  a b x     -> rnf a `seq` rnf b   `seq` rnf x+        XLam  a b x     -> rnf a `seq` rnf b   `seq` rnf x+        XApp  a x1 x2   -> rnf a `seq` rnf x1  `seq` rnf x2+        XLet  a lts x   -> rnf a `seq` rnf lts `seq` rnf x+        XCase a x alts  -> rnf a `seq` rnf x   `seq` rnf alts+        XCast a c x     -> rnf a `seq` rnf c   `seq` rnf x+        XType t         -> rnf t+        XWitness w      -> rnf w+++instance (NFData a, NFData n) => NFData (Cast a n) where+ rnf cc+  = case cc of+        CastWeakenEffect e      -> rnf e+        CastWeakenClosure xs    -> rnf xs+        CastPurify w            -> rnf w+        CastForget w            -> rnf w+++instance (NFData a, NFData n) => NFData (Lets a n) where+ rnf lts+  = case lts of+        LLet mode b x           -> rnf mode `seq` rnf b `seq` rnf x+        LRec bxs                -> rnf bxs+        LLetRegions bs1 bs2     -> rnf bs1  `seq` rnf bs2+        LWithRegion u           -> rnf u+++instance NFData n => NFData (LetMode n) where+ rnf mode+  = case mode of+        LetStrict               -> ()+        LetLazy mw              -> rnf mw+++instance (NFData a, NFData n) => NFData (Alt a n) where+ rnf aa+  = case aa of+        AAlt w x                -> rnf w `seq` rnf x+++instance NFData n => NFData (Pat n) where+ rnf pp+  = case pp of+        PDefault                -> ()+        PData dc bs             -> rnf dc `seq` rnf bs+++instance NFData n => NFData (Witness n) where+ rnf ww+  = case ww of+        WVar  u                 -> rnf u+        WCon  c                 -> rnf c+        WApp  w1 w2             -> rnf w1 `seq` rnf w2+        WJoin w1 w2             -> rnf w1 `seq` rnf w2+        WType tt                -> rnf tt+++instance NFData n => NFData (WiCon n) where+ rnf wi+  = case wi of+        WiConBuiltin wb         -> rnf wb+        WiConBound   u t        -> rnf u `seq` rnf t++instance NFData WbCon++++++
+ DDC/Core/Fragment.hs view
@@ -0,0 +1,65 @@++-- | The ambient Disciple Core language is specialised to concrete languages+--   by adding primitive operations and optionally restricting the set of +--   available language features. This specialisation results in user-facing+--   language fragments such as @Disciple Core Lite@ and @Disciple Core Salt@.+module DDC.Core.Fragment+        ( -- * Langauge fragments+          Fragment      (..)+        , Profile       (..)+        , zeroProfile++          -- * Fragment features+        , Feature       (..)+        , Features      (..)+        , zeroFeatures++        -- * Compliance+        , complies+        , compliesWithEnvs+        , Complies+        , Error         (..))+where+import DDC.Core.Fragment.Feature+import DDC.Core.Fragment.Compliance+import DDC.Core.Fragment.Error+import DDC.Core.Fragment.Profile+import DDC.Core.Module+import DDC.Core.Exp+import DDC.Core.Lexer+import DDC.Data.Token+++-- Fragment -------------------------------------------------------------------+-- | Carries all the information we need to work on a particular +--   fragment of the Disciple Core language.+data Fragment n (err :: * -> *)+        = Fragment+        { -- | Language profile for this fragment.+          fragmentProfile       :: Profile n++          -- | File extension to use when dumping modules in this fragment.+        , fragmentExtension     :: String++          -- | Read a name.+        , fragmentReadName      :: String -> Maybe n+        +          -- | Lex module source into tokens,+          --   given the source name and starting line number. +        , fragmentLexModule     :: String -> Int -> String -> [Token (Tok n)]++          -- | Lex expression source into tokens,+          --   given the source name and starting line number.+        , fragmentLexExp        :: String -> Int -> String -> [Token (Tok n)]++          -- | Perform language fragment specific checks on a module.+        , fragmentCheckModule   :: forall a. Module a n -> Maybe (err a)++          -- | Perform language fragment specific checks on an expression.+        , fragmentCheckExp      :: forall a. Exp a n    -> Maybe (err a) }+++instance Show (Fragment n err) where+ show frag+  = profileName $ fragmentProfile frag+
+ DDC/Core/Fragment/Compliance.hs view
@@ -0,0 +1,388 @@++module DDC.Core.Fragment.Compliance+        ( complies+	, compliesWithEnvs+        , Complies)+where+import DDC.Core.Fragment.Feature+import DDC.Core.Fragment.Profile+import DDC.Core.Fragment.Error+import DDC.Core.Compounds+import DDC.Core.Predicates+import DDC.Core.Module+import DDC.Core.Exp+import Control.Monad+import Data.Maybe+import DDC.Type.Env                     (Env)+import Data.Set                         (Set)+import qualified DDC.Type.Env           as Env+import qualified Data.Set               as Set+import qualified Data.Map.Strict        as Map+++-- | Check whether a core thing complies with a language fragment profile.+complies +        :: (Ord n, Show n, Complies c)+        => Profile n            -- ^ Fragment profile giving the supported+                                --   language features and primitive operators.+        -> c a n                -- ^ The thing to check.+        -> Maybe (Error n)++complies profile thing+ = compliesWithEnvs profile+        (profilePrimKinds profile)+        (profilePrimTypes profile)+        thing+++-- | Like `complies` but with some starting environments.+compliesWithEnvs+        :: (Ord n, Show n, Complies c)+        => Profile n            -- ^ Fragment profile giving the supported+                                --   language features and primitive operators.+	-> Env.KindEnv n        -- ^ Starting kind environment.+	-> Env.TypeEnv n        -- ^ Starting type environment.+	-> c a n                -- ^ The thing to check.+	-> Maybe (Error n)++compliesWithEnvs profile kenv tenv thing+ = let  merr    = result +                $ compliesX profile +                        kenv tenv+                        contextTop thing+   in   case merr of+         Left err -> Just err+         Right _  -> Nothing++++-- Complies -------------------------------------------------------------------+-- | Class of things we can check language fragment compliance for.+class Complies (c :: * -> * -> *) where+ -- Check compliance of a well typed term with a language profile.+ -- If it is not well typed then this can return a bad result.+ compliesX+        :: (Ord n, Show n)+        => Profile n            -- ^ Fragment profile giving the supported+                                --   language features and primitive operators.+        -> Env n                -- ^ Starting Kind environment.+        -> Env n                -- ^ Starting Type environment.+        -> Context+        -> c a n +        -> CheckM n+                (Set n, Set n)  -- Used type and value names.+++instance Complies Module where+ compliesX profile kenv tenv context mm+  = do  let bs          = [ BName n t +                                | (n, (_, t)) <- Map.toList $ moduleImportTypes mm ]+        let tenv'       = Env.extends bs tenv+        compliesX profile kenv tenv' context (moduleBody mm)+++-- We'll mark type vars that only appear in types of binders as unused.+instance Complies Exp where+ compliesX profile kenv tenv context xx+  = let has f   = f $ profileFeatures profile+        ok      = return (Set.empty, Set.empty)+    in case xx of++        -- variables ----------------------------+        XVar _ u@(UName n)+         |  not $ Env.member u tenv+         ,  not $ has featuresUnboundLevel0Vars +         -> throw $ ErrorUndefinedVar n++         |  args        <- fromMaybe 0 $ contextFunArgs context+         ,  Just t      <- Env.lookup u tenv+         ,  arity       <- arityOfType t+         ,  args < arity+         ,  not $ has featuresPartialApplication+         -> throw $ ErrorUnsupported PartialApplication++         | otherwise+         ->     return (Set.empty, Set.singleton n)++        XVar _ u@(UPrim n t)+         |  not $ Env.member u (profilePrimTypes profile)+         -> throw $ ErrorUndefinedPrim n++         |  args        <- fromMaybe 0 $ contextFunArgs context+         ,  arity       <- arityOfType t+         ,  args < arity+         ,  not $ has featuresPartialPrims+         -> throw $ ErrorUnsupported PartialPrims++         | otherwise+         -> return (Set.empty, Set.empty)++        XVar{}          -> ok++        -- constructors -------------------------+        XCon{}          -> ok++        -- spec binders -------------------------+        XLAM _ b x+         | contextAbsBody context+         , not $ has featuresNestedFunctions+         -> throw $ ErrorUnsupported NestedFunctions++         | otherwise+         -> do  +                -- If the body isn't another lambda then remember+                -- that we've entered into a function.+                let context'+                     | isXLAM x || isXLam x = context+                     | otherwise            = setBody context++                (tUsed, vUsed)  <- compliesX profile +                                        (Env.extend b kenv) tenv +                                        context' x++                tUsed'          <- checkBind profile kenv b tUsed+                return (tUsed', vUsed)++        -- value and witness abstraction --------+        XLam _ b x+         | contextAbsBody context+         , not $ has featuresNestedFunctions+         -> throw $ ErrorUnsupported NestedFunctions++         | otherwise+         -> do  +                -- If the body isn't another lambda then remember+                -- that we've entered into a function.+                let context'+                     | isXLAM x || isXLam x = context+                     | otherwise            = setBody context++                (tUsed, vUsed)  <- compliesX profile +                                        kenv (Env.extend b tenv)+                                        context' x++                vUsed'          <- checkBind profile tenv b vUsed+                return (tUsed, vUsed')+       +        -- application --------------------------+        XApp _ x1 (XType t2)+         | profileTypeIsUnboxed profile t2+         , Nothing      <- takeXPrimApps xx+         -> throw $ ErrorUnsupported UnboxedInstantiation++         | otherwise+         -> do  checkFunction profile x1+                compliesX     profile kenv tenv (addArg context) x1++        XApp _ x1 XWitness{}+         -> do  checkFunction profile x1+                compliesX     profile kenv tenv (addArg context) x1++        XApp _ x1 x2+         -> do  checkFunction profile x1+                (tUsed1, vUsed1) <- compliesX profile kenv tenv (addArg context) x1+                (tUsed2, vUsed2) <- compliesX profile kenv tenv context x2+                return  ( Set.union tUsed1 tUsed2+                        , Set.union vUsed1 vUsed2)++        -- let ----------------------------------+        XLet _ (LLet mode b1 x1) x2+         -> do  let tenv'        = Env.extend b1 tenv+                (tUsed1, vUsed1) <- compliesX profile kenv tenv  (reset context) x1+                (tUsed2, vUsed2) <- compliesX profile kenv tenv' (reset context) x2+                vUsed2'          <- checkBind profile tenv b1 vUsed2++                -- Check for unsupported lazy bindings.+                (case mode of+                  LetStrict     -> return ()+                  LetLazy _     +                   | has featuresLazyBindings -> return ()+                   | otherwise          +                   -> throw $ ErrorUnsupported LazyBindings)++                return  ( Set.union tUsed1 tUsed2+                        , Set.union vUsed1 vUsed2')++        XLet _ (LRec bxs) x2+         -> do  let (bs, xs)    = unzip bxs+                let tenv'       = Env.extends bs tenv++                (tUseds1, vUseds1) +                 <- liftM unzip+                 $  mapM (compliesX profile kenv tenv' (reset context)) +                         xs++                (tUsed2,  vUsed2) <- compliesX profile kenv tenv' (reset context) x2+                let tUseds        = Set.unions (tUsed2 : tUseds1)+                let vUseds        = Set.unions (vUsed2 : vUseds1)++                vUseds'           <- checkBinds profile tenv bs vUseds+                return (tUseds, vUseds')+++        XLet _ (LLetRegions rs bs) x2+         -> do  (tUsed2, vUsed2) +                 <- compliesX profile   (Env.extends rs  kenv) +                                        (Env.extends bs tenv) +                                        (reset context) x2+                return (tUsed2, vUsed2)++        XLet _ (LWithRegion _) x2+         -> do  (tUsed2, vUsed2) <- compliesX profile kenv tenv +                                        (reset context) x2+                return (tUsed2, vUsed2)++        -- case ---------------------------------+        XCase _ x1 alts+         -> do  (tUsed1,  vUsed1)  +                 <- compliesX profile kenv tenv (reset context) x1++                (tUseds2, vUseds2) <- liftM unzip +                                   $  mapM (compliesX profile kenv tenv (reset context)) alts++                return  ( Set.unions $ tUsed1 : tUseds2+                        , Set.unions $ vUsed1 : vUseds2)+++        -- cast ---------------------------------+        XCast _ _ x     -> compliesX profile kenv tenv (reset context) x++        -- type and witness ---------------------+        XType t         -> throw $ ErrorNakedType    t+        XWitness w      -> throw $ ErrorNakedWitness w+++instance Complies Alt where+ compliesX profile kenv tenv context aa+  = case aa of+        AAlt PDefault x+         -> do  (tUsed1, vUsed1)  <- compliesX profile kenv tenv +                                        (reset context) x+                return  (tUsed1, vUsed1)++        AAlt (PData _ bs) x+         -> do  (tUsed1, vUsed1) <- compliesX profile kenv (Env.extends bs tenv) +                                        (reset context) x+                vUsed1'          <- checkBinds profile tenv bs vUsed1 +                return (tUsed1, vUsed1')+++-- Bind -----------------------------------------------------------------------+-- | Check for compliance violations at a binding site.+checkBind +        :: Ord n +        => Profile n            -- ^ The current language profile.+        -> Env n                -- ^ The current environment+        -> Bind n               -- ^ The binder at this site.+        -> Set n                -- ^ Names used under the binder.+        -> CheckM n (Set n)     -- ^ Names used above the binder.++checkBind profile env bb used+ = let has f   = f $ profileFeatures profile+   in case bb of+        BName n _+         | not $ Set.member n used+         , not $ has featuresUnusedBindings +         -> throw $ ErrorUnusedBind n++         | Env.memberBind bb env+         , not $ has featuresNameShadowing +         -> throw $ ErrorShadowedBind n++         | otherwise+         -> return $ Set.delete n used++        BAnon{}+         | not $ has featuresDebruijnBinders+         -> throw $ ErrorUnsupported DebruijnBinders++        _ -> return used+++-- | Check for compliance violations at a binding site.+--   The binders must all be at the same level.+checkBinds +        :: Ord n  +        => Profile n +        -> Env n  -> [Bind n] -> Set n +        -> CheckM n (Set n)++checkBinds profile env bs used+ = case bs of+        []              -> return used+        (b : bs')        +         -> do  used'   <- checkBinds profile env bs' used+                checkBind profile env b used'+++-- Function -------------------------------------------------------------------+-- | Check the function part of an application.+checkFunction :: Profile n -> Exp a n -> CheckM n ()+checkFunction profile xx + = let  has f   = f $ profileFeatures profile+        ok       = return ()+   in case xx of+        XVar{}  -> ok+        XCon{}  -> ok+        XApp{}  -> ok+        XCast{} -> ok+        _+         | has featuresGeneralApplication -> return ()+         | otherwise    -> throw $ ErrorUnsupported GeneralApplication+++-- Context --------------------------------------------------------------------+data Context+        = Context+        { contextAbsBody        :: Bool +        , contextFunArgs        :: Maybe Int }+        deriving (Eq, Show)+++-- | The top level context, used at the top-level scope of a module.+contextTop :: Context+contextTop+        = Context+        { contextAbsBody        = False+        , contextFunArgs        = Nothing }+++-- | Record that we've entered into an abstraction body.+setBody :: Context -> Context+setBody context = context { contextAbsBody = True }+++-- | Record that the expression is being directly applied to an argument.+addArg  :: Context -> Context+addArg context+ = case contextFunArgs context of+        Nothing         -> context { contextFunArgs = Just 1 }+        Just args       -> context { contextFunArgs = Just (args + 1) }+++-- | Reset the argument counter of a context.+reset   :: Context -> Context+reset context   = context { contextFunArgs = Nothing } +++-- Monad ----------------------------------------------------------------------+-- | Compliance checking monad.+data CheckM n x+        = CheckM (Either (Error n) x)++instance Monad (CheckM n) where+ return x   = CheckM (Right x)+ (>>=) m f  +  = case m of+          CheckM (Left err)     -> CheckM (Left err)+          CheckM (Right x)      -> f x+++-- | Throw an error in the monad.+throw :: Error n -> CheckM n x+throw e       = CheckM $ Left e+++-- | Take the result from a check monad.+result :: CheckM n x -> Either (Error n) x+result (CheckM r)       = r
+ DDC/Core/Fragment/Error.hs view
@@ -0,0 +1,59 @@++module DDC.Core.Fragment.Error+        (Error(..))+where+import DDC.Core.Fragment.Feature+import DDC.Core.Exp+import DDC.Core.Pretty+++-- | Language fragment compliance violations.+data Error n+        -- | Found an unsupported language feature.+        = ErrorUnsupported      !Feature++        -- | Found an undefined primitive operator.+        | ErrorUndefinedPrim    !n ++        -- | Found an unbound variable.+        | ErrorUndefinedVar     !n++        -- | Found a variable binder that shadows another one at a higher scope,+        --   but the profile doesn't permit this.+        | ErrorShadowedBind     !n++        -- | Found a bound variable with no uses,+        --   but the profile doesn't permit this.+        | ErrorUnusedBind       !n++        -- | Found a naked type that isn't used as a function argument.+        | ErrorNakedType        !(Type    n)++        -- | Found a naked witness that isn't used as a function argument.+        | ErrorNakedWitness     !(Witness n)+        deriving (Eq, Show)+++instance (Pretty n, Eq n) => Pretty (Error n) where+ ppr err+  = case err of+        ErrorUnsupported feature+         -> vcat [ text "Unsupported feature: " <> text (show feature) ]++        ErrorUndefinedPrim n+         -> vcat [ text "Undefined primitive: " <> ppr n ]++        ErrorUndefinedVar n+         -> vcat [ text "Undefined variable: " <> ppr n ]++        ErrorShadowedBind n+         -> vcat [ text "Binding shadows existing name: " <> ppr n ]++        ErrorUnusedBind n+         -> vcat [ text "Bound name is not used: " <> ppr n ]++        ErrorNakedType t+         -> vcat [ text "Naked type is not a function argument: " <> ppr t]++        ErrorNakedWitness w+         -> vcat [ text "Naked witness is not a function argument: " <> ppr w ]
+ DDC/Core/Fragment/Feature.hs view
@@ -0,0 +1,63 @@++module DDC.Core.Fragment.Feature+        (Feature(..))+where+++-- | Language feature supported by a fragment.+data Feature+        -- Type system features ---------------------------+        -- | Assume all functions perform global side effects, +        --   and don't generate effect terms in types.+        = UntrackedEffects++        -- | Assume all functions share data invisibly,+        --   and don't generate closure terms in types.+        | UntrackedClosures++        -- General features -------------------------------+        -- | Partially applied primitive operators.+        | PartialPrims++        -- | Partially applied functions+        | PartialApplication++        -- | Function application where the thing being applied+        --   is not a variable.+        --   Most backend languages (like LLVM) don't support this.+        | GeneralApplication++        -- | Nested function bindings.+        --   The output of the lambda-lifter should not contain these.+        | NestedFunctions++        -- | Lazy let-bindings.+        --   Turning this off means the runtime system won't need to build+        --   suspensions.+        | LazyBindings++        -- | Debruijn binders.+        --   Most backends will want to use real names, instead of indexed+        --   binders.+        | DebruijnBinders++        -- | Allow data and witness vars without binding occurrences if+        --   they are annotated directly with their types. This lets+        --   us work with open terms.+        | UnboundLevel0Vars++        -- | Allow non-primitive functions to be instantiated at unboxed types.+        --   Our existing backends can't handle this, because boxed and unboxed+        --   objects have different representations.+        | UnboxedInstantiation++        -- Sanity -----------------------------------------+        -- | Allow name shadowing.+        | NameShadowing++        -- | Allow unused named data and witness bindings.+        | UnusedBindings++        -- | Allow unused named matches.+        | UnusedMatches+        deriving (Eq, Ord, Show)
+ DDC/Core/Fragment/Profile.hs view
@@ -0,0 +1,111 @@++-- | A fragment profile determines what features a program can use.+module DDC.Core.Fragment.Profile+        ( Profile (..)+        , zeroProfile++        , Features(..)+        , zeroFeatures+        , setFeature)+where+import DDC.Core.Fragment.Feature+import DDC.Type.DataDef+import DDC.Type.Exp+import DDC.Type.Env                     (KindEnv, TypeEnv)+import qualified DDC.Type.Env           as Env+++-- | The fragment profile describes the language features and +--   primitive operators available in the language.+data Profile n+        = Profile+        { -- | The name of this profile.+          profileName                   :: !String++          -- | Permitted language features.+        , profileFeatures               :: !Features++          -- | Primitive data type declarations.+        , profilePrimDataDefs           :: !(DataDefs n)++          -- | Kinds of primitive types.+        , profilePrimKinds              :: !(KindEnv n)++          -- | Types of primitive operators.+        , profilePrimTypes              :: !(TypeEnv n)++          -- | Check whether a type is an unboxed type.+          --   Some fragments limit how these can be used.+        , profileTypeIsUnboxed          :: !(Type n -> Bool) }+++-- | A language profile with no features or primitive operators.+--+--   This provides a simple first-order language.+zeroProfile :: Profile n+zeroProfile+        = Profile+        { profileName                   = "Zero"+        , profileFeatures               = zeroFeatures+        , profilePrimDataDefs           = emptyDataDefs+        , profilePrimKinds              = Env.empty+        , profilePrimTypes              = Env.empty+        , profileTypeIsUnboxed          = const False }+++-- | A flattened set of features, for easy lookup.+data Features +        = Features+        { featuresUntrackedEffects      :: Bool+        , featuresUntrackedClosures     :: Bool+        , featuresPartialPrims          :: Bool+        , featuresPartialApplication    :: Bool+        , featuresGeneralApplication    :: Bool+        , featuresNestedFunctions       :: Bool+        , featuresLazyBindings          :: Bool+        , featuresDebruijnBinders       :: Bool+        , featuresUnboundLevel0Vars     :: Bool+        , featuresUnboxedInstantiation  :: Bool+        , featuresNameShadowing         :: Bool+        , featuresUnusedBindings        :: Bool+        , featuresUnusedMatches         :: Bool+        }+++-- | An emtpy feature set, with all flags set to `False`.+zeroFeatures :: Features+zeroFeatures+        = Features+        { featuresUntrackedEffects      = False+        , featuresUntrackedClosures     = False+        , featuresPartialPrims          = False+        , featuresPartialApplication    = False+        , featuresGeneralApplication    = False+        , featuresNestedFunctions       = False+        , featuresLazyBindings          = False+        , featuresDebruijnBinders       = False+        , featuresUnboundLevel0Vars     = False+        , featuresUnboxedInstantiation  = False+        , featuresNameShadowing         = False+        , featuresUnusedBindings        = False+        , featuresUnusedMatches         = False }+++-- | Set a language `Flag` in the `Profile`.+setFeature :: Feature -> Bool -> Features -> Features+setFeature feature val features+ = case feature of+        UntrackedEffects        -> features { featuresUntrackedEffects     = val }+        UntrackedClosures       -> features { featuresUntrackedClosures    = val }+        PartialPrims            -> features { featuresPartialPrims         = val }+        PartialApplication      -> features { featuresPartialApplication   = val }+        GeneralApplication      -> features { featuresGeneralApplication   = val }+        NestedFunctions         -> features { featuresNestedFunctions      = val }+        LazyBindings            -> features { featuresLazyBindings         = val }+        DebruijnBinders         -> features { featuresDebruijnBinders      = val }+        UnboundLevel0Vars       -> features { featuresUnboundLevel0Vars    = val }+        UnboxedInstantiation    -> features { featuresUnboxedInstantiation = val }+        NameShadowing           -> features { featuresNameShadowing        = val }+        UnusedBindings          -> features { featuresUnusedBindings       = val }+        UnusedMatches           -> features { featuresUnusedMatches        = val }+
+ DDC/Core/Lexer.hs view
@@ -0,0 +1,215 @@++-- | Reference lexer for core langauge parser. Slow but Simple.+--+--   The lexers here all use 'String' in place of a real name type.+--   After applying these functions to the program text, we need+--   to use `renameTok` tok convert the strings in `TokNamed` tokens+--   into the name type specific to the langauge fragment to be parsed.+--+module DDC.Core.Lexer+        ( module DDC.Core.Lexer.Tokens+        , module DDC.Core.Lexer.Names++          -- * Lexer+        , lexModuleWithOffside+        , lexExp)+where+import DDC.Core.Lexer.Offside+import DDC.Core.Lexer.Comments+import DDC.Core.Lexer.Names+import DDC.Core.Lexer.Tokens+import DDC.Data.SourcePos+import DDC.Data.Token+import Data.Char+++-- Module ---------------------------------------------------------------------+-- | Lex a module and apply the offside rule.+--+--   Automatically drop comments from the token stream along the way.+--+lexModuleWithOffside +        :: FilePath     -- ^ Path to source file, for error messages.+        -> Int          -- ^ Starting line number.+        -> String       -- ^ String containing program text.+        -> [Token (Tok String)]++lexModuleWithOffside sourceName lineStart str+ = {-# SCC lexWithOffside #-}+        applyOffside [] +        $ addStarts+        $ dropComments +        $ lexString sourceName lineStart str+++-- Exp ------------------------------------------------------------------------+-- | Lex a string into tokens.+--+--   Automatically drop comments from the token stream along the way.+--+lexExp  :: FilePath     -- ^ Path to source file, for error messages.+        -> Int          -- ^ Starting line number.+        -> String       -- ^ String containing program text.+        -> [Token (Tok String)]++lexExp sourceName lineStart str+ = {-# SCC lexExp #-}+        dropNewLines+        $ dropComments+        $ lexString sourceName lineStart str+++-- Generic --------------------------------------------------------------------+lexString :: String -> Int -> String -> [Token (Tok String)]+lexString sourceName lineStart str+        = lexWord lineStart 1 str+ where +  lexWord :: Int -> Int -> String -> [Token (Tok String)]+  lexWord line column w+   = let  tok t = Token t (SourcePos sourceName line column)+          tokM  = tok . KM+          tokA  = tok . KA+          tokN  = tok . KN++          lexMore n rest+           = lexWord line (column + n) rest++     in case w of+        []               -> []        ++        -- Whitespace+        ' '  : w'        -> lexMore 1 w'+        '\t' : w'        -> lexMore 8 w'++        -- Literal values+        -- This needs to come before the rule for '-'+        c : cs+         | isDigit c+         , (body, rest)         <- span isLitBody cs+         -> tokN (KLit (c:body))                 : lexMore (length (c:body)) rest++        '-' : c : cs+         | isDigit c+         , (body, rest)         <- span isLitBody cs+         -> tokN (KLit ('-':c:body))                 : lexMore (length (c:body)) rest++        -- Meta tokens+        '{'  : '-' : w'  -> tokM KCommentBlockStart : lexMore 2 w'+        '-'  : '}' : w'  -> tokM KCommentBlockEnd   : lexMore 2 w'+        '-'  : '-' : w'  -> tokM KCommentLineStart  : lexMore 2 w'+        '\n' : w'        -> tokM KNewLine           : lexWord (line + 1) 1 w'+++        -- The unit data constructor+        '(' : ')' : w'   -> tokA KDaConUnit      : lexMore 2 w'++        -- Compound Parens+        '['  : ':' : w'  -> tokA KSquareColonBra : lexMore 2 w'+        ':'  : ']' : w'  -> tokA KSquareColonKet : lexMore 2 w'+        '<'  : ':' : w'  -> tokA KAngleColonBra  : lexMore 2 w'+        ':'  : '>' : w'  -> tokA KAngleColonKet  : lexMore 2 w'++        -- Function Constructors+        '~'  : '>'  : w' -> tokA KArrowTilde     : lexMore 2 w'+        '-'  : '>'  : w' -> tokA KArrowDash      : lexMore 2 w'+        '<'  : '-'  : w' -> tokA KArrowDashLeft  : lexMore 2 w'+        '='  : '>'  : w' -> tokA KArrowEquals    : lexMore 2 w'++        -- Compound symbols+        ':'  : ':'  : w' -> tokA KColonColon     : lexMore 2 w'+        '/'  : '\\' : w' -> tokA KBigLambda      : lexMore 2 w'++        -- Debruijn indices+        '^'  : cs+         |  (ds, rest)   <- span isDigit cs+         ,  length ds >= 1+         -> tokA (KIndex (read ds))              : lexMore (1 + length ds) rest         ++        -- Parens+        '('  : w'       -> tokA KRoundBra        : lexMore 1 w'+        ')'  : w'       -> tokA KRoundKet        : lexMore 1 w'+        '['  : w'       -> tokA KSquareBra       : lexMore 1 w'+        ']'  : w'       -> tokA KSquareKet       : lexMore 1 w'+        '{'  : w'       -> tokA KBraceBra        : lexMore 1 w'+        '}'  : w'       -> tokA KBraceKet        : lexMore 1 w'+        '<'  : w'       -> tokA KAngleBra        : lexMore 1 w'+        '>'  : w'       -> tokA KAngleKet        : lexMore 1 w'            ++        -- Punctuation+        '.'  : w'       -> tokA KDot             : lexMore 1 w'+        '|'  : w'       -> tokA KBar             : lexMore 1 w'+        '^'  : w'       -> tokA KHat             : lexMore 1 w'+        '+'  : w'       -> tokA KPlus            : lexMore 1 w'+        ':'  : w'       -> tokA KColon           : lexMore 1 w'+        ','  : w'       -> tokA KComma           : lexMore 1 w'+        '\\' : w'       -> tokA KBackSlash       : lexMore 1 w'+        ';'  : w'       -> tokA KSemiColon       : lexMore 1 w'+        '_'  : w'       -> tokA KUnderscore      : lexMore 1 w'+        '='  : w'       -> tokA KEquals          : lexMore 1 w'+        '&'  : w'       -> tokA KAmpersand       : lexMore 1 w'+        '-'  : w'       -> tokA KDash            : lexMore 1 w'+        +        -- Bottoms+        '!' : '0' : w'  -> tokA KBotEffect       : lexMore 2 w'+        '$' : '0' : w'  -> tokA KBotClosure      : lexMore 2 w'++        -- Sort Constructors+        '*' : '*' : w'  -> tokA KSortComp        : lexMore 2 w'+        '@' : '@' : w'  -> tokA KSortProp        : lexMore 2 w'        ++        -- Kind Constructors+        '*' : w'        -> tokA KKindValue       : lexMore 1 w'+        '%' : w'        -> tokA KKindRegion      : lexMore 1 w'+        '!' : w'        -> tokA KKindEffect      : lexMore 1 w'+        '$' : w'        -> tokA KKindClosure     : lexMore 1 w'+        '@' : w'        -> tokA KKindWitness     : lexMore 1 w'+        ++        -- Named Constructors+        c : cs+         | isConStart c+         , (body,  rest)        <- span isConBody cs+         , (body', rest')       <- case rest of+                                        '#' : rest'     -> (body ++ "#", rest')+                                        _               -> (body, rest)+         -> let readNamedCon s+                 | Just twcon   <- readTwConBuiltin s+                 = tokA (KTwConBuiltin twcon)    : lexMore (length s) rest'+                 +                 | Just tccon   <- readTcConBuiltin s+                 = tokA (KTcConBuiltin tccon)    : lexMore (length s) rest'+                 +                 | Just con     <- readCon s+                 = tokN (KCon con)               : lexMore (length s) rest'+               +                 | otherwise    +                 = [tok (KJunk [c])]+                 +            in  readNamedCon (c : body')++        -- Keywords, Named Variables and Witness constructors+        c : cs+         | isVarStart c+         , (body,  rest)        <- span isVarBody cs+         , (body', rest')       <- case rest of+                                        '#' : rest'     -> (body ++ "#", rest')+                                        _               -> (body, rest)+         -> let readNamedVar s+                 | Just t <- lookup s keywords+                 = tok t                   : lexMore (length s) rest'++                 | Just wc      <- readWbConBuiltin s+                 = tokA (KWbConBuiltin wc) : lexMore (length s) rest'+         +                 | Just v       <- readVar s+                 = tokN (KVar v)           : lexMore (length s) rest'++                 | otherwise+                 = [tok (KJunk [c])]++            in  readNamedVar (c : body')++        -- Some unrecognised character.+        -- We still need to keep lexing as this may be in a comment.+        c : cs   -> (tok $ KJunk [c]) : lexMore 1 cs+
+ DDC/Core/Lexer/Comments.hs view
@@ -0,0 +1,64 @@++module DDC.Core.Lexer.Comments+        ( dropComments+        , dropNewLines)+where+import DDC.Core.Lexer.Tokens+import DDC.Data.Token+import DDC.Data.SourcePos+++-- | Drop all the comments and newline tokens in this stream.+dropComments +        :: Eq n => [Token (Tok n)] -> [Token (Tok n)]++dropComments []      = []+dropComments (t@(Token tok sourcePos) : xs)+ = case tok of+        KM KCommentLineStart +         -> dropComments $ dropWhile (\t' -> not $ isToken t' (KM KNewLine)) xs++        KM KCommentBlockStart +         -> dropComments $ dropCommentBlock sourcePos xs t++        _ -> t : dropComments xs+++-- | Drop block comments form a token stream.+dropCommentBlock +        :: Eq n+        => SourcePos            -- ^ Position of outer-most block comment start.+        -> [Token (Tok n)] +        -> Token (Tok n) +        -> [Token (Tok n)]++dropCommentBlock spStart [] _terr+        = [Token (KM KCommentUnterminated) spStart]++dropCommentBlock spStart (t@(Token tok _) : xs) terr+ = case tok of+        -- enter into nested block comments.+        KM KCommentBlockStart+         -> dropCommentBlock spStart (dropCommentBlock spStart xs t) terr++        -- outer-most block comment has ended.+        KM KCommentBlockEnd+         -> xs++        _ -> dropCommentBlock spStart xs terr+++-- | Drop newline tokens from this list.+dropNewLines :: Eq n => [Token (Tok n)] -> [Token (Tok n)]+dropNewLines [] = []+dropNewLines (t:ts)+        | isToken t (KM KNewLine)+        = dropNewLines ts++        | otherwise+        = t : dropNewLines ts+++isToken :: Eq n => Token (Tok n) -> Tok n -> Bool+isToken (Token tok _) tok2 = tok == tok2+
+ DDC/Core/Lexer/Names.hs view
@@ -0,0 +1,226 @@++module DDC.Core.Lexer.Names+        ( -- * Keywords+          keywords++          -- * Builtin constructors+        , readTwConBuiltin+        , readTcConBuiltin+        , readWbConBuiltin++          -- * Variable names+        , isVarName+        , isVarStart+        , isVarBody+        , readVar++          -- * Constructor names+        , isConName+        , isConStart+        , isConBody+        , readCon++          -- * Literal names+        , isLitName+        , isLitStart+        , isLitBody)+where+import DDC.Core.Exp+import DDC.Core.Lexer.Tokens+import DDC.Data.ListUtils+import Data.Char+import Data.List+++-- | Textual keywords in the core language.+keywords :: [(String, Tok n)]+keywords+ =      [ ("module",     KA KModule)+        , ("imports",    KA KImports)+        , ("exports",    KA KExports)+        , ("in",         KA KIn)+        , ("of",         KA KOf) +        , ("letrec",     KA KLetRec)+        , ("letregions", KA KLetRegions)+        , ("letregion",  KA KLetRegion)+        , ("withregion", KA KWithRegion)+        , ("let",        KA KLet)+        , ("lazy",       KA KLazy)+        , ("case",       KA KCase)+        , ("purify",     KA KPurify)+        , ("forget",     KA KForget)+        , ("type",       KA KType)+        , ("weakeff",    KA KWeakEff)+        , ("weakclo",    KA KWeakClo)+        , ("with",       KA KWith)+        , ("where",      KA KWhere) +        , ("do",         KA KDo)+        , ("match",      KA KMatch)+        , ("else",       KA KElse) ]+++-- | Read a named `TwCon`. +readTwConBuiltin :: String -> Maybe TwCon+readTwConBuiltin ss+ = case ss of+        "Global"        -> Just TwConGlobal+        "DeepGlobal"    -> Just TwConDeepGlobal+        "Const"         -> Just TwConConst+        "DeepConst"     -> Just TwConDeepConst+        "Mutable"       -> Just TwConMutable+        "DeepMutable"   -> Just TwConDeepMutable+        "Lazy"          -> Just TwConLazy+        "HeadLazy"      -> Just TwConHeadLazy+        "Manifest"      -> Just TwConManifest+        "Pure"          -> Just TwConPure+        "Empty"         -> Just TwConEmpty+        "Disjoint"      -> Just TwConDisjoint+        "Distinct"      -> Just (TwConDistinct 2)+        _               -> readTwConWithArity ss+++readTwConWithArity :: String -> Maybe TwCon+readTwConWithArity ss+ | Just n <- stripPrefix "Distinct" ss + , all isDigit n+ = Just (TwConDistinct $ read n)+ | otherwise = Nothing+ + +-- | Read a builtin `TcCon` with a non-symbolic name, +--   ie not '->'.+readTcConBuiltin :: String -> Maybe TcCon+readTcConBuiltin ss+ = case ss of+        "Unit"          -> Just TcConUnit+        "Read"          -> Just TcConRead+        "HeadRead"      -> Just TcConHeadRead+        "DeepRead"      -> Just TcConDeepRead+        "Write"         -> Just TcConWrite+        "DeepWrite"     -> Just TcConDeepWrite+        "Alloc"         -> Just TcConAlloc+        "DeepAlloc"     -> Just TcConDeepAlloc+        "Use"           -> Just TcConUse+        "DeepUse"       -> Just TcConDeepUse+        _               -> Nothing+++-- | Read a `WbCon`.+readWbConBuiltin :: String -> Maybe WbCon+readWbConBuiltin ss+ = case ss of+        "pure"          -> Just WbConPure+        "empty"         -> Just WbConEmpty+        "use"           -> Just WbConUse+        "read"          -> Just WbConRead+        "alloc"         -> Just WbConAlloc+        _               -> Nothing+++-- Variable names -------------------------------------------------------------+-- | String is a variable name+isVarName :: String -> Bool+isVarName str+ = case str of+     []          -> False+     c : cs +        | isVarStart c +        , and (map isVarBody cs)+        -> True+        +        | _ : _         <- cs+        , Just initCs   <- takeInit cs+        , isVarStart c+        , and (map isVarBody initCs)+        , last cs == '#'+        -> True++        | otherwise+        -> False+++-- | Charater can start a variable name.+isVarStart :: Char -> Bool+isVarStart = isLower+        ++-- | Character can be part of a variable body.+isVarBody  :: Char -> Bool+isVarBody c+        = isUpper c || isLower c || isDigit c || c == '_' || c == '\''+++-- | Read a named, user defined variable.+readVar :: String -> Maybe String+readVar ss+        | isVarName ss  = Just ss+        | otherwise     = Nothing+++-- Constructor names ----------------------------------------------------------+-- | String is a constructor name.+isConName :: String -> Bool+isConName str+ = case str of+     []          -> False+     c : cs +        | isConStart c +        , and (map isConBody cs)+        -> True+        +        | _ : _         <- cs+        , Just initCs   <- takeInit cs+        , isConStart c+        , and (map isConBody initCs)+        , last cs == '#'+        -> True++        | otherwise+        -> False++-- | Character can start a constructor name.+isConStart :: Char -> Bool+isConStart = isUpper+++-- | Charater can be part of a constructor body.+isConBody  :: Char -> Bool+isConBody c           = isUpper c || isLower c || isDigit c || c == '_'+        +++-- | Read a named, user defined `TcCon`.+readCon :: String -> Maybe String+readCon ss+        | isConName ss  = Just ss+        | otherwise     = Nothing+++-- Literal names --------------------------------------------------------------+-- | String is the name of a literal.+isLitName :: String -> Bool+isLitName str+ = case str of+        []      -> False+        c : cs+         | isLitStart c+         , and (map isLitBody cs)+         -> True++         | otherwise+         -> False++-- | Character can start a literal.+isLitStart :: Char -> Bool+isLitStart c+        =   isDigit c+        ||  c == '-'++-- | Character can be part of a literal body.+isLitBody :: Char -> Bool+isLitBody c+        =  isDigit c+        || c == 'b' || c == 'o' || c == 'x'+        || c == 'w' || c == 'i' +        || c == '#'+
+ DDC/Core/Lexer/Offside.hs view
@@ -0,0 +1,265 @@++-- | Apply the offside rule to a token stream to add braces.+module DDC.Core.Lexer.Offside+        ( Lexeme        (..)+        , applyOffside+        , addStarts)+where+import DDC.Core.Lexer.Tokens+import DDC.Data.SourcePos+import DDC.Data.Token+++-- | Holds a real token or start symbol which is used to apply the offside rule.+data Lexeme n+        = LexemeToken           (Token (Tok n))+        | LexemeStartLine       Int++        -- | Signal that we're starting a block in this column.+        | LexemeStartBlock      Int+        deriving (Eq, Show)++type Context+        = Int++-- | Apply the offside rule to this token stream.+--   It should have been processed with addStarts first to add the+--   LexemeStartLine/LexemeStartLine tokens.+--+applyOffside +        :: (Eq n, Show n) +        => [Context] +        -> [Lexeme n] +        -> [Token (Tok n)]++-- Wait for the module header before we start applying the real offside rule. +-- This allows us to write 'module Name with letrec' all on the same line.+applyOffside [] (LexemeToken t : ts) +        |   isToken t (KA KModule)+         || isKNToken t+        = t : applyOffside [] ts++-- When we see the top-level letrec then enter into the outer-most context.+applyOffside [] (LexemeToken t1 : (LexemeStartBlock n) : ls)+        |   isToken t1 (KA KLetRec)+         || isToken t1 (KA KExports)+         || isToken t1 (KA KImports)+        = t1 : newCBra ls : applyOffside [n] ls ++-- At top level without a context.+-- Skip over everything until we get the 'with' in 'module Name with ...''+applyOffside [] (LexemeStartLine _  : ts)+        = applyOffside [] ts ++applyOffside [] (LexemeStartBlock _ : ts)+        = applyOffside [] ts+++-- line start+applyOffside mm@(m : ms) (t@(LexemeStartLine n) : ts)+        -- add semicolon to get to the next statement in this block+        | m == n+        = newSemiColon ts : applyOffside mm ts++        -- end a block+        -- we keep the StartLine token in the recursion in case we're ending+        -- multiple blocks difference from Haskell98: add a semicolon as well+        | n < m +        = newSemiColon ts : newCKet ts : applyOffside ms (t : ts)++        -- indented continuation of this statement+        | otherwise+        = applyOffside mm ts+++-- block start+applyOffside mm@(m : ms) (LexemeStartBlock n : ts)+        -- enter into a nested context+        | n > m+        = newCBra ts : applyOffside (n : m : ms) ts ++        -- new context starts less than the current one.+        --   This should never happen, +        --     provided addStarts works.+        | tNext : _    <- dropNewLinesLexeme ts+        = error $ "DDC.Core.Lexer.Tokens.Offside: layout error on " ++ show tNext ++ "."++        -- new context cannot be less indented than outer one+        --   This should never happen,+        --      as there is no lexeme to start a new context at the end of the file+        | []            <- dropNewLinesLexeme ts+        = error "DDC.Core.Lexer.Tokens.Offside: tried to start new context at end of file."++        -- an empty block+        | otherwise+        = newCBra ts : newCKet ts : applyOffside mm (LexemeStartLine n : ts)+++-- pop contexts from explicit close braces+applyOffside mm (LexemeToken t@Token { tokenTok = KA KBraceKet } : ts) ++        -- make sure that explict open braces match explicit close braces+        | 0 : ms        <- mm+        = t : applyOffside ms ts++        -- nup+        | _tNext : _     <- dropNewLinesLexeme ts+        = [newOffsideClosingBrace ts]+++-- push contexts for explicit open braces+applyOffside ms (LexemeToken t@Token { tokenTok = KA KBraceBra } : ts)+        = t : applyOffside (0 : ms) ts++applyOffside ms (LexemeToken t : ts) +        = t : applyOffside ms ts++applyOffside [] []          = []++-- close off remaining contexts once we've reached the end of the stream.+applyOffside (_ : ms) []    = newCKet [] : applyOffside ms []+++-- addStarts ------------------------------------------------------------------+-- | Add block and line start tokens to this stream.+--      This is lifted straight from the Haskell98 report.+addStarts :: Eq n => [Token (Tok n)] -> [Lexeme n]+addStarts ts+ = case dropNewLines ts of++        -- If the first lexeme of a module is not '{' then start a new block.+        (t1 : tsRest)+          |  not $ or $ map (isToken t1) [KA KBraceBra]+          -> LexemeStartBlock (tokenColumn t1) : addStarts' (t1 : tsRest)++          | otherwise+          -> addStarts' (t1 : tsRest)++        -- empty file+        []      -> []+++addStarts'  :: Eq n => [Token (Tok n)] -> [Lexeme n]+addStarts' []           = []+addStarts' (t1 : ts) ++        -- We're starting a block+        | isBlockStart t1+        , []            <- dropNewLines ts+        = LexemeToken t1    : [LexemeStartBlock 0]++        | isBlockStart t1+        , t2 : tsRest   <- dropNewLines ts+        , not $ isToken t2 (KA KBraceBra)+        = LexemeToken t1    : LexemeStartBlock (tokenColumn t2)+                            : addStarts' (t2 : tsRest)++        -- check for start of list+        | isToken t1 (KA KBraceBra)+        = LexemeToken t1    : addStarts' ts++        -- check for end of list+        | isToken t1 (KA KBraceKet)+        = LexemeToken t1    : addStarts' ts++        -- check for start of new line+        | isToken t1 (KM KNewLine)+        , t2 : tsRest   <- dropNewLines ts+        , not $ isToken t2 (KA KBraceBra)+        = LexemeStartLine (tokenColumn t2) +                : addStarts' (t2 : tsRest)++        -- eat up trailine newlines+        | isToken t1 (KM KNewLine)+        = addStarts' ts++        -- a regular token+        | otherwise+        = LexemeToken t1    : addStarts' ts+++-- | Drop newline tokens at the front fo this stream.+dropNewLines :: Eq n => [Token (Tok n)] -> [Token (Tok n)]+dropNewLines []              = []+dropNewLines (t1:ts)+        | isToken t1 (KM KNewLine)+        = dropNewLines ts++        | otherwise+        = t1 : ts+++-- | Drop newline tokens at the front fo this stream.+dropNewLinesLexeme :: Eq n => [Lexeme n] -> [Lexeme n]+dropNewLinesLexeme ll+ = case ll of+        []                      -> []+        LexemeToken t1 : ts+         |  isToken t1 (KM KNewLine)+         -> dropNewLinesLexeme ts++        l : ls+         -> l : dropNewLinesLexeme ls+++-- | Check if a token is one that starts a block of statements.+isBlockStart :: Token (Tok n) -> Bool+isBlockStart Token { tokenTok = tok }+ = case tok of+        KA KDo          -> True+        KA KOf          -> True+        KA KLetRec      -> True+        KA KWhere       -> True+        KA KExports     -> True+        KA KImports     -> True+        _               -> False+++-- Utils ----------------------------------------------------------------------+-- | Test whether this wrapper token matches.+isToken :: Eq n => Token (Tok n) -> Tok n -> Bool+isToken (Token tok _) tok2 = tok == tok2+++-- | Test whether this wrapper token matches.+isKNToken :: Eq n => Token (Tok n) -> Bool+isKNToken (Token (KN _) _)      = True+isKNToken _                     = False+++-- | When generating new source tokens, take the position from the first+--   non-newline token in this list+newCBra :: [Lexeme n] -> Token (Tok n)+newCBra ts+        = (takeTok ts) { tokenTok = KA KBraceBra }+++newCKet :: [Lexeme n] -> Token (Tok n)+newCKet ts+        = (takeTok ts) { tokenTok = KA KBraceKet }+++newSemiColon :: [Lexeme n] -> Token (Tok n)+newSemiColon ts +        = (takeTok ts) { tokenTok = KA KSemiColon }+++-- | This is injected by `applyOffside` when it finds an explit close+--   brace in a position where it would close a synthetic one.+newOffsideClosingBrace :: [Lexeme n] -> Token (Tok n)+newOffsideClosingBrace ts+        = (takeTok ts) { tokenTok = KM KOffsideClosingBrace }+++takeTok :: [Lexeme n] -> Token (Tok n)+takeTok []      + = Token (KJunk "") (SourcePos "" 0 0)++takeTok (l : ls)+ = case l of+        LexemeToken (Token { tokenTok = KM KNewLine })+         -> takeTok ls++        LexemeToken t           -> t+        LexemeStartLine  _      -> takeTok ls+        LexemeStartBlock _      -> takeTok ls
+ DDC/Core/Lexer/Tokens.hs view
@@ -0,0 +1,347 @@++module DDC.Core.Lexer.Tokens+        ( -- * Tokens+          Tok      (..)+        , renameTok+        , describeTok++          -- * Meta Tokens+        , TokMeta  (..)+        , describeTokMeta++          -- * Atomic Tokens+        , TokAtom  (..)+        , describeTokAtom++          -- * Named Tokens+        , TokNamed (..)+        , describeTokNamed)+where+import DDC.Core.Pretty+import DDC.Core.Exp+import Control.Monad+++-- TokenFamily ----------------------------------------------------------------+-- | The family of a token.+--   This is used to help generate parser error messages,+--   so we can say ''the constructor Cons''+--             and ''the keyword case'' etc.+data TokenFamily+        = Symbol+        | Keyword+        | Constructor+        | Index+        | Variable+++-- | Describe a token family, for parser error messages.+describeTokenFamily :: TokenFamily -> String+describeTokenFamily tf+ = case tf of+        Symbol          -> "symbol"+        Keyword         -> "keyword"+        Constructor     -> "constructor"+        Index           -> "index"+        Variable        -> "variable"+++-- Tok ------------------------------------------------------------------------+-- | Tokens accepted by the core language parser.+data Tok n+        -- | Some junk symbol that isn't part of the language.+        = KJunk String++        -- | Meta tokens contain out-of-band information that is eliminated+        --   before parsing proper.+        | KM    !TokMeta++        -- | Atomic tokens are keywords, punctuation and baked-in +        --   constructor names.+        | KA    !TokAtom ++        -- | A named token that is specific to the language fragment +        --   (maybe it's a primop), or a user defined name.+        | KN    !(TokNamed n)+        deriving (Eq, Show)+++-- | Apply a function to all the names in a `Tok`.+renameTok+        :: Ord n2+        => (n1 -> Maybe n2) +        -> Tok n1 +        -> Maybe (Tok n2)++renameTok f kk+ = case kk of+        KJunk s -> Just $ KJunk s+        KM t    -> Just $ KM t+        KA t    -> Just $ KA t+        KN t    -> liftM KN $ renameTokNamed f t+++-- | Describe a token for parser error messages.+describeTok :: Pretty n => Tok n -> String+describeTok kk+ = case kk of+        KJunk c         -> "character " ++ show c+        KM tm           -> describeTokMeta  tm+        KA ta           -> describeTokAtom  ta+        KN tn           -> describeTokNamed tn+++-- TokMeta --------------------------------------------------------------------+-- | Meta tokens contain out-of-band information that is +--   eliminated before parsing proper.+data TokMeta+        = KNewLine+        | KCommentLineStart+        | KCommentBlockStart+        | KCommentBlockEnd++        -- | This is injected by `dropCommentBlock` when it finds+        --   an unterminated block comment.+        | KCommentUnterminated++        -- | This is injected by `applyOffside` when it finds an explit close+        --   brace in a position where it would close a synthetic one.+        | KOffsideClosingBrace+        deriving (Eq, Show)+++-- | Describe a TokMeta, for lexer error messages.+describeTokMeta :: TokMeta -> String+describeTokMeta tm+ = case tm of+        KNewLine                -> "new line"+        KCommentLineStart       -> "comment start"+        KCommentBlockStart      -> "block comment start"+        KCommentBlockEnd        -> "block comment end"+        KCommentUnterminated    -> "unterminated block comment"+        KOffsideClosingBrace    -> "closing brace"+++-- TokAtom --------------------------------------------------------------------+-- | Atomic tokens are keywords, punctuation and baked-in constructor names.+--   They don't contain user-defined names or primops specific to the +--   language fragment.+data TokAtom+        -- parens+        = KRoundBra+        | KRoundKet+        | KSquareBra+        | KSquareKet+        | KBraceBra+        | KBraceKet+        | KAngleBra+        | KAngleKet++        -- compound parens+        | KSquareColonBra+        | KSquareColonKet+        | KAngleColonBra+        | KAngleColonKet++        -- punctuation+        | KDot+        | KBar+        | KHat+        | KPlus+        | KColon+        | KComma+        | KBackSlash+        | KSemiColon+        | KUnderscore+        | KEquals+        | KAmpersand+        | KDash+        | KColonColon+        | KBigLambda++        -- symbolic constructors+        | KSortComp+        | KSortProp+        | KKindValue+        | KKindRegion+        | KKindEffect+        | KKindClosure+        | KKindWitness+        | KArrowTilde+        | KArrowDash+        | KArrowDashLeft+        | KArrowEquals++        -- bottoms+        | KBotEffect+        | KBotClosure++        -- core keywords+        | KModule+        | KImports+        | KExports+        | KWith+        | KWhere+        | KIn+        | KLet+        | KLazy+        | KLetRec+        | KLetRegions+        | KLetRegion+        | KWithRegion+        | KCase+        | KOf+        | KType+        | KWeakEff+        | KWeakClo+        | KPurify+        | KForget++        -- sugar keywords+        | KDo+        | KMatch+        | KElse++        -- debruijn indices+        | KIndex Int++        -- builtin names ------------+        --   the unit data constructor.+        | KDaConUnit++        --   witness type constructors.+        | KTwConBuiltin TwCon++        --   witness constructors.+        | KWbConBuiltin WbCon++        --   other builtin spec constructors.+        | KTcConBuiltin TcCon+        deriving (Eq, Show)+++-- | Describe a `TokAtom`, for parser error messages.+describeTokAtom  :: TokAtom -> String+describeTokAtom ta+ = let  (family, str)           = describeTokAtom' ta+   in   describeTokenFamily family ++ " " ++ show str++describeTokAtom' :: TokAtom -> (TokenFamily, String)+describeTokAtom' ta+ = case ta of+        -- parens+        KRoundBra               -> (Symbol, "(")+        KRoundKet               -> (Symbol, ")")+        KSquareBra              -> (Symbol, "[")+        KSquareKet              -> (Symbol, "]")+        KBraceBra               -> (Symbol, "{")+        KBraceKet               -> (Symbol, "}")+        KAngleBra               -> (Symbol, "<")+        KAngleKet               -> (Symbol, ">")++        -- compound parens+        KSquareColonBra         -> (Symbol, "[:")+        KSquareColonKet         -> (Symbol, ":]")+        KAngleColonBra          -> (Symbol, "<:")+        KAngleColonKet          -> (Symbol, ":>")++        -- punctuation+        KDot                    -> (Symbol, ".")+        KBar                    -> (Symbol, "|")+        KHat                    -> (Symbol, "^")+        KPlus                   -> (Symbol, "+")+        KColon                  -> (Symbol, ":")+        KComma                  -> (Symbol, ",")+        KBackSlash              -> (Symbol, "\\")+        KSemiColon              -> (Symbol, ";")+        KUnderscore             -> (Symbol, "_")+        KEquals                 -> (Symbol, "=")+        KAmpersand              -> (Symbol, "&")+        KDash                   -> (Symbol, "-")+        KColonColon             -> (Symbol, "::")+        KBigLambda              -> (Symbol, "/\\")++        -- symbolic constructors+        KSortComp               -> (Constructor, "**")+        KSortProp               -> (Constructor, "@@")+        KKindValue              -> (Constructor, "*")+        KKindRegion             -> (Constructor, "%")+        KKindEffect             -> (Constructor, "!")+        KKindClosure            -> (Constructor, "$")+        KKindWitness            -> (Constructor, "@")+        KArrowTilde             -> (Constructor, "~>")+        KArrowDash              -> (Constructor, "->")+        KArrowDashLeft          -> (Constructor, "<-")+        KArrowEquals            -> (Constructor, "=>")++        -- bottoms+        KBotEffect              -> (Constructor, "!0")+        KBotClosure             -> (Constructor, "!$")++        -- expression keywords+        KModule                 -> (Keyword, "module")+        KImports                -> (Keyword, "imports")+        KExports                -> (Keyword, "exports")+        KWith                   -> (Keyword, "with")+        KWhere                  -> (Keyword, "where")+        KIn                     -> (Keyword, "in")+        KLet                    -> (Keyword, "let")+        KLazy                   -> (Keyword, "lazy")+        KLetRec                 -> (Keyword, "letrec")+        KLetRegions             -> (Keyword, "letregions")+        KLetRegion              -> (Keyword, "letregion")+        KWithRegion             -> (Keyword, "withregion")+        KCase                   -> (Keyword, "case")+        KOf                     -> (Keyword, "of")+        KType                   -> (Keyword, "type")+        KWeakEff                -> (Keyword, "weakeff")+        KWeakClo                -> (Keyword, "weakclo")+        KPurify                 -> (Keyword, "purify")+        KForget                 -> (Keyword, "forget")++        -- sugar keywords+        KDo                     -> (Keyword, "do")+        KMatch                  -> (Keyword, "match")+        KElse                   -> (Keyword, "else")++        -- debruijn indices+        KIndex i                -> (Index,   "^" ++ show i)++        -- builtin names+        KDaConUnit              -> (Constructor, "()")+        KTwConBuiltin tw        -> (Constructor, renderPlain $ ppr tw)+        KWbConBuiltin wi        -> (Constructor, renderPlain $ ppr wi)+        KTcConBuiltin tc        -> (Constructor, renderPlain $ ppr tc)+++-- TokNamed -------------------------------------------------------------------+-- | A token with a user-defined name.+data TokNamed n+        = KCon n+        | KVar n+        | KLit n+        deriving (Eq, Show)+++-- | Describe a `TokNamed`, for parser error messages.+describeTokNamed :: Pretty n => TokNamed n -> String+describeTokNamed tn+ = case tn of+        KCon n  -> renderPlain $ text "constructor" <+> (dquotes $ ppr n)+        KVar n  -> renderPlain $ text "variable"    <+> (dquotes $ ppr n)+        KLit n  -> renderPlain $ text "literal"     <+> (dquotes $ ppr n)+++-- | Apply a function to all the names in a `TokNamed`.+renameTokNamed +        :: Ord n2+        => (n1 -> Maybe n2) +        -> TokNamed n1 +        -> Maybe (TokNamed n2)++renameTokNamed f kk+  = case kk of+        KCon c           -> liftM KCon $ f c+        KVar c           -> liftM KVar $ f c+        KLit c           -> liftM KLit $ f c+
+ DDC/Core/Load.hs view
@@ -0,0 +1,240 @@++-- | \"Loading\" refers to the combination of parsing and type checking.+--   This is the easiest way to turn source tokens into a type-checked +--   abstract syntax tree.+module DDC.Core.Load+        ( C.AnTEC (..)+        , Error (..)+        , loadModuleFromFile+        , loadModuleFromString+        , loadModuleFromTokens+        , loadExp+        , loadType+        , loadWitness)+where+import DDC.Core.Transform.SpreadX+import DDC.Core.Fragment.Profile+import DDC.Core.Lexer.Tokens+import DDC.Core.Exp+import DDC.Type.Transform.SpreadT+import DDC.Core.Module+import DDC.Base.Pretty+import DDC.Data.Token+import qualified DDC.Core.Fragment              as I+import qualified DDC.Core.Parser                as C+import qualified DDC.Core.Check                 as C+import qualified DDC.Type.Check                 as T+import qualified DDC.Base.Parser                as BP+import Data.Map.Strict                          (Map)+import System.Directory+++-- | Things that can go wrong when loading a core thing.+data Error n+        = ErrorRead       !String+        | ErrorParser     !BP.ParseError+        | ErrorCheckType  !(T.Error n)      +        | ErrorCheckExp   !(C.Error () n)+        | ErrorCompliance !(I.Error n)+        deriving Show+++instance (Eq n, Show n, Pretty n) => Pretty (Error n) where+ ppr err+  = case err of+        ErrorRead str+         -> vcat [ text "While reading."+                 , indent 2 $ text str ]++        ErrorParser     err'    +         -> vcat [ text "While parsing."+                 , indent 2 $ ppr err' ]++        ErrorCheckType  err'+         -> vcat [ text "When checking type."+                 , indent 2 $ ppr err' ]+++        ErrorCheckExp   err'    +         -> vcat [ text "When checking expression."+                 , indent 2 $ ppr err' ]++        ErrorCompliance err'    +         -> vcat [ text "During fragment compliance check."+                 , indent 2 $ ppr err' ]+++-- Module ---------------------------------------------------------------------+-- | Parse and type check a core module from a file.+loadModuleFromFile +        :: (Eq n, Ord n, Show n, Pretty n)+        => Profile n                    -- ^ Language fragment profile.+        -> (String -> [Token (Tok n)])  -- ^ Function to lex the source file.+        -> FilePath                     -- ^ File containing source code.+        -> IO (Either (Error n)+                      (Module (C.AnTEC () n) n))++loadModuleFromFile profile lexSource filePath+ = do   +        -- Check whether the file exists.+        exists  <- doesFileExist filePath+        if not exists +         then return $ Left $ ErrorRead "Cannot read file."+         else do+                -- Read the source file.+                src     <- readFile filePath++                -- Lex the source.+                let toks = lexSource src++                return $ loadModuleFromTokens profile filePath toks++-- | Parse and type check a core module from a string.+loadModuleFromString+        :: (Eq n, Ord n, Show n, Pretty n)+        => Profile n                    -- ^ Language fragment profile.+        -> (String -> [Token (Tok n)])  -- ^ Function to lex the source file.+        -> FilePath                     -- ^ Path to source file for error messages.+        -> String                       -- ^ Program text.+        -> Either (Error n) (Module (C.AnTEC () n) n)++loadModuleFromString profile lexSource filePath src+        = loadModuleFromTokens profile filePath (lexSource src)+++-- | Parse and type check a core module.+loadModuleFromTokens+        :: (Eq n, Ord n, Show n, Pretty n)+        => Profile n                    -- ^ Language fragment profile.+        -> FilePath                     -- ^ Path to source file for error messages.+        -> [Token (Tok n)]              -- ^ Source tokens.+        -> Either (Error n) (Module (C.AnTEC () n) n)++loadModuleFromTokens profile sourceName toks'+ = goParse toks'+ where  +        -- Type checker config kind and type environments.+        config  = C.configOfProfile  profile+        kenv    = profilePrimKinds profile+        tenv    = profilePrimTypes profile++        -- Parse the tokens.+        goParse toks                +         = case BP.runTokenParser describeTok sourceName C.pModule toks of+                Left err  -> Left (ErrorParser err)+                Right mm  -> goCheckType (spreadX kenv tenv mm)++        -- Check that the module is type sound.+        goCheckType mm+         = case C.checkModule config mm of+                Left err  -> Left (ErrorCheckExp err)+                Right mm' -> goCheckCompliance mm'++        -- Check that the module compiles with the language fragment.+        goCheckCompliance mm+         = case I.complies profile mm of+                Just err  -> Left (ErrorCompliance err)+                Nothing   -> Right mm+++-- Exp ------------------------------------------------------------------------+-- | Parse and check an expression+--   returning it along with its spec, effect and closure+loadExp+        :: (Eq n, Ord n, Show n, Pretty n)+        => Profile n            -- ^ Language fragment profile.+        -> Map ModuleName (Module (C.AnTEC () n) n)+                                -- ^ Other modules currently in scope.+                                --   We add their exports to the environment.+        -> FilePath             -- ^ Path to source file for error messages.+        -> [Token (Tok n)]      -- ^ Source tokens.+        -> Either (Error n) +                  (Exp (C.AnTEC () n) n)++loadExp profile modules sourceName toks'+ = goParse toks'+ where  +        -- Type checker profile, kind and type environments.+        config  = C.configOfProfile  profile+        kenv    = modulesExportKinds modules $ profilePrimKinds profile+        tenv    = modulesExportTypes modules $ profilePrimTypes profile++        -- Parse the tokens.+        goParse toks                +         = case BP.runTokenParser describeTok sourceName C.pExp toks of+                Left err  -> Left (ErrorParser err)+                Right t   -> goCheckType (spreadX kenv tenv t)++        -- Check the kind of the type.+        goCheckType x+         = case C.checkExp config kenv tenv x of+                Left err            -> Left  (ErrorCheckExp err)+                Right (x', _, _, _) -> goCheckCompliance x'++        -- Check that the module compiles with the language fragment.+        goCheckCompliance x +         = case I.compliesWithEnvs profile kenv tenv x of+                Just err  -> Left (ErrorCompliance err)+                Nothing   -> Right x+++-- Type -----------------------------------------------------------------------+-- | Parse and check a type,+--   returning it along with its kind.+loadType+        :: (Eq n, Ord n, Show n, Pretty n)+        => Profile n            -- ^ Language fragment profile.+        -> FilePath             -- ^ Path to source file for error messages.+        -> [Token (Tok n)]      -- ^ Source tokens.+        -> Either (Error n) +                  (Type n, Kind n)++loadType profile sourceName toks'+ = goParse toks'+ where  defs    = profilePrimDataDefs profile+        kenv    = profilePrimKinds    profile++        -- Parse the tokens.+        goParse toks                +         = case BP.runTokenParser describeTok sourceName C.pType toks of+                Left err  -> Left (ErrorParser err)+                Right t   -> goCheckType (spreadT kenv t)++        -- Check the kind of the type.+        goCheckType t+         = case T.checkType defs kenv t of+                Left err  -> Left (ErrorCheckType err)+                Right k   -> Right (t, k)+        +++-- Witness --------------------------------------------------------------------+-- | Parse and check a witness,+--   returning it along with its type.+loadWitness+        :: (Eq n, Ord n, Show n, Pretty n)+        => Profile n            -- ^ Language fragment profile.+        -> FilePath             -- ^ Path to source file for error messages.+        -> [Token (Tok n)]      -- ^ Source tokens.+        -> Either (Error n) +                  (Witness n, Type n)++loadWitness profile sourceName toks'+ = goParse toks'+ where  -- Type checker config, kind and type environments.+        config  = C.configOfProfile  profile+        kenv    = profilePrimKinds profile+        tenv    = profilePrimTypes profile++        -- Parse the tokens.+        goParse toks                +         = case BP.runTokenParser describeTok sourceName C.pWitness toks of+                Left err  -> Left (ErrorParser err)+                Right t   -> goCheckType (spreadX kenv tenv t)++        -- Check the kind of the type.+        goCheckType w+         = case C.checkWitness config kenv tenv w of+                Left err  -> Left (ErrorCheckExp err)+                Right k   -> Right (w, k)+
+ DDC/Core/Module.hs view
@@ -0,0 +1,147 @@++module DDC.Core.Module+        ( -- * Modules+          Module        (..)+        , isMainModule+	, moduleKindEnv+        , moduleTypeEnv+        , modulesGetBinds++	  -- * Module maps+	, ModuleMap+	, modulesExportKinds+	, modulesExportTypes++         -- * Module Names.+        , QualName      (..)+        , ModuleName    (..)+        , isMainModuleName)+where+import DDC.Core.Exp+import Data.Typeable+import Data.Map.Strict                  (Map)+import DDC.Type.Env                     as Env+import qualified Data.Map.Strict        as Map+import Control.DeepSeq+++-- Module ---------------------------------------------------------------------+-- | A module can be mutually recursive with other modules.+data Module a n+        = ModuleCore+        { -- | Name of this module.+          moduleName            :: !ModuleName++          -- Exports ------------------+          -- | Kinds of exported types.+        , moduleExportKinds     :: !(Map n (Kind n))++          -- | Types of exported values.+        , moduleExportTypes     :: !(Map n (Type n))++          -- Imports ------------------+          -- | Kinds of imported types,+          --   along with the name of the module they are from.+        , moduleImportKinds     :: !(Map n (QualName n, Kind n))++          -- | Types of imported values,+          --   along with the name of the module they are from.+        , moduleImportTypes     :: !(Map n (QualName n, Type n))++          -- Local --------------------+          -- | The module body consists of some let-bindings+          --   wrapping a unit data constructor.+          -- +          --  We're only interested in the bindings, +          --  with the unit being just a place-holder.+        , moduleBody            :: !(Exp a n)+        }+        deriving (Show, Typeable)+++instance (NFData a, NFData n) => NFData (Module a n) where+ rnf !mm+        =     rnf (moduleName mm)+        `seq` rnf (moduleExportKinds mm)+        `seq` rnf (moduleExportTypes mm)+        `seq` rnf (moduleImportKinds mm)+        `seq` rnf (moduleImportTypes mm)+        `seq` rnf (moduleBody mm)+++-- | Check if this is the `Main` module.+isMainModule :: Module a n -> Bool+isMainModule mm+        = isMainModuleName +        $ moduleName mm+++-- | Get the top-level kind environment of a module,+--   from its imported types.+moduleKindEnv :: Ord n => Module a n -> KindEnv n+moduleKindEnv mm+        = Env.fromList +        $ [BName n k | (n, (_, k)) <- Map.toList $ moduleImportKinds mm]+++-- | Get the top-level type environment of a module,+--   from its imported values.+moduleTypeEnv :: Ord n => Module a n -> TypeEnv n+moduleTypeEnv mm+        = Env.fromList +        $ [BName n k | (n, (_, k)) <- Map.toList $ moduleImportTypes mm]+++-- ModuleMap ------------------------------------------------------------------+-- | Map of module names to modules.+type ModuleMap a n +        = Map ModuleName (Module a n)++modulesGetBinds m +        = Env.fromList $ map (uncurry BName) (Map.assocs m)+++-- | Add the kind environment exported by all these modules to the given one.+modulesExportKinds :: Ord n => ModuleMap a n -> KindEnv n -> KindEnv n+modulesExportKinds mods base+        = foldl Env.union base +        $ map (modulesGetBinds.moduleExportKinds) (Map.elems mods)+++-- | Add the type environment exported by all these modules to the given one.+modulesExportTypes :: Ord n => ModuleMap a n -> TypeEnv n -> TypeEnv n++modulesExportTypes mods base+        = foldl Env.union base +        $ map (modulesGetBinds.moduleExportTypes) (Map.elems mods)+++-- ModuleName -----------------------------------------------------------------+-- | A hierarchical module name.+data ModuleName+        = ModuleName [String]+        deriving (Show, Eq, Ord, Typeable)++instance NFData ModuleName where+ rnf (ModuleName ss)+        = rnf ss+ ++-- | A fully qualified name, +--   including the name of the module it is from.+data QualName n+        = QualName ModuleName n+        deriving Show++instance NFData n => NFData (QualName n) where+ rnf (QualName mn n)+        = rnf mn `seq` rnf n+++-- | Check whether this is the name of the \"Main\" module.+isMainModuleName :: ModuleName -> Bool+isMainModuleName mn+ = case mn of+        ModuleName ["Main"]     -> True+        _                       -> False+
DDC/Core/Parser.hs view
@@ -1,631 +1,44 @@ -- | Core language parser. module DDC.Core.Parser-        ( module DDC.Base.Parser-        , Parser-        , pExp-        , pWitness)-        -where-import DDC.Core.Exp-import DDC.Core.Parser.Tokens-import DDC.Base.Parser                  ((<?>))-import DDC.Type.Parser                  (pTok)-import qualified DDC.Base.Parser        as P-import qualified DDC.Type.Compounds     as T-import qualified DDC.Type.Parser        as T-import Control.Monad.Error----- | A parser of core language tokens.-type Parser n a-        = P.Parser (Tok n) a----- Expressions ------------------------------------------------------------------- | Parse a core language expression.-pExp    :: Ord n => Parser n (Exp () n)-pExp - = P.choice-        -- Level-0 lambda abstractions-        -- \(x1 x2 ... : TYPE) (y1 y2 ... : TYPE) ... . EXP- [ do   pTok KBackSlash--        bs      <- liftM concat-                $  P.many1 -                $  do   pTok KRoundBra-                        bs'     <- P.many1 T.pBinder-                        pTok KColon-                        t       <- T.pType-                        pTok KRoundKet-                        return (map (\b -> T.makeBindFromBinder b t) bs')--        pTok KDot-        xBody   <- pExp-        return  $ foldr (XLam ()) xBody bs--        -- Level-1 lambda abstractions.-        -- /\(x1 x2 ... : TYPE) (y1 y2 ... : TYPE) ... . EXP- , do   pTok KBigLambda--        bs      <- liftM concat-                $  P.many1 -                $  do   pTok KRoundBra-                        bs'     <- P.many1 T.pBinder-                        pTok KColon-                        t       <- T.pType-                        pTok KRoundKet-                        return (map (\b -> T.makeBindFromBinder b t) bs')--        pTok KDot-        xBody   <- pExp-        return  $ foldr (XLAM ()) xBody bs---        -- let expression- , do   pTok KLet-        (mode1, b1, x1)  <- pLetBinding-        pTok KIn-        x2              <- pExp-        return  $ XLet () (LLet mode1 b1 x1) x2---        -- letrec expression- , do   pTok KLetRec--        P.choice-         -- Multiple bindings in braces-         [ do   pTok KBraceBra-                lets    <- P.sepEndBy1 pLetRecBinding (pTok KSemiColon)-                pTok KBraceKet-                pTok KIn-                x       <- pExp-                return  $ XLet () (LRec lets) x--         -- A single binding without braces.-         , do   ll      <- pLetRecBinding-                pTok KIn-                x       <- pExp-                return  $ XLet () (LRec [ll]) x-         ]      ---        -- Local region binding.-        --   letregion BINDER with { BINDER : TYPE ... } in EXP-        --   letregion BINDER in EXP- , do   pTok KLetRegion-        br      <- T.pBinder-        let b   = T.makeBindFromBinder br T.kRegion--        P.choice -         [ do   pTok KWith-                pTok KBraceBra-                wits    <- P.sepBy-                           (do  w       <- pVar-                                pTok KColon-                                t       <- T.pTypeApp-                                return  (BName w t))-                           (pTok KSemiColon)-                pTok KBraceKet-                pTok KIn-                x       <- pExp -                return  $ XLet () (LLetRegion b wits) x --         , do   pTok KIn-                x       <- pExp-                return $ XLet ()  (LLetRegion b []) x ]---        -- withregion CON in EXP- , do   pTok KWithRegion-        n       <- pVar-        pTok KIn-        x       <- pExp-        let u   = UName n (T.tBot T.kRegion)-        return  $ XLet () (LWithRegion u) x---        -- case EXP of { ALTS }- , do   pTok KCase-        x       <- pExp-        pTok KOf -        pTok KBraceBra-        alts    <- P.sepEndBy1 pAlt (pTok KSemiColon)-        pTok KBraceKet-        return  $ XCase () x alts---        -- weakeff [TYPE] in EXP- , do   pTok KWeakEff-        pTok KSquareBra-        t       <- T.pType-        pTok KSquareKet-        pTok KIn-        x       <- pExp-        return  $ XCast () (CastWeakenEffect t) x---        -- weakclo [TYPE] in EXP- , do   pTok KWeakClo-        pTok KSquareBra-        t       <- T.pType-        pTok KSquareKet-        pTok KIn-        x       <- pExp-        return  $ XCast () (CastWeakenClosure t) x---        -- purify <WITNESS> in EXP- , do   pTok KPurify-        pTok KAngleBra-        w       <- pWitness-        pTok KAngleKet-        pTok KIn-        x       <- pExp-        return  $ XCast () (CastPurify w) x---        -- forget <WITNESS> in EXP- , do   pTok KForget-        pTok KAngleBra-        w       <- pWitness-        pTok KAngleKet-        pTok KIn-        x       <- pExp-        return  $ XCast () (CastForget w) x--        -- APP- , do   pExpApp- ]-- <?> "an expression"----- Applications.-pExpApp :: Ord n => Parser n (Exp () n)-pExpApp -  = do  x1      <- pExp0-        -        P.choice-         [ do   xs  <- liftM concat $ P.many1 pArgs-                return  $ foldl (XApp ()) x1 xs--         ,      return x1]-- <?> "an expression or application"----- Comp, Witness or Spec arguments.-pArgs   :: Ord n => Parser n [Exp () n]-pArgs - = P.choice-        -- [TYPE]- [ do   pTok KSquareBra-        t       <- T.pType -        pTok KSquareKet-        return  [XType t]--        -- [: TYPE0 TYPE0 ... :]- , do   pTok KSquareColonBra-        ts      <- P.many1 T.pTypeAtom-        pTok KSquareColonKet-        return  $ map XType ts-        -        -- <WITNESS>- , do   pTok KAngleBra-        w       <- pWitness-        pTok KAngleKet-        return  [XWitness w]-                -        -- <: WITNESS0 WITNESS0 ... :>- , do   pTok KAngleColonBra-        ws      <- P.many1 pWitnessAtom-        pTok KAngleColonKet-        return  $ map XWitness ws-                -        -- EXP0- , do   x       <- pExp0-        return  [x]- ]- <?> "a type, witness or expression argument"----- Atomics-pExp0   :: Ord n => Parser n (Exp () n)-pExp0 - = P.choice-        -- (EXP2)- [ do   pTok KRoundBra-        t       <- pExp-        pTok KRoundKet-        return  $ t-        -        -- Named constructors- , do   con     <- pCon-        return  $ XCon () (UName con (T.tBot T.kData)) --        -- Literals- , do   lit     <- pLit-        return  $ XCon () (UName lit (T.tBot T.kData))--        -- Debruijn indices- , do   i       <- T.pIndex-        return  $ XVar () (UIx   i   (T.tBot T.kData))--        -- Variables- , do   var     <- pVar-        return  $ XVar () (UName var (T.tBot T.kData)) - ]-- <?> "a variable, constructor, or parenthesised type"----- Case alternatives.-pAlt    :: Ord n => Parser n (Alt () n)-pAlt- = do   p       <- pPat-        pTok KArrowDash-        x       <- pExp-        return  $ AAlt p x----- Patterns.-pPat    :: Ord n => Parser n (Pat n)-pPat- = P.choice- [      -- Wildcard-   do   pTok KUnderscore-        return  $ PDefault--        -- LIT- , do   nLit    <- pLit-        return  $ PData (UName nLit (T.tBot T.kData)) []--        -- CON BIND BIND ...- , do   nCon    <- pCon -        bs      <- P.many pBindPat-        return  $ PData (UName nCon (T.tBot T.kData)) bs]----- Binds in patterns can have no type annotation,--- or can have an annotation if the whole thing is in parens.-pBindPat :: Ord n => Parser n (Bind n)-pBindPat - = P.choice-        -- Plain binder.- [ do   b       <- T.pBinder-        return  $ T.makeBindFromBinder b (T.tBot T.kData)--        -- Binder with type, wrapped in parens.- , do   pTok KRoundBra-        b       <- T.pBinder-        pTok KColon-        t       <- T.pType-        pTok KRoundKet-        return  $ T.makeBindFromBinder b t- ]----- Bindings ---------------------------------------------------------------------- | A binding for let expression.-pLetBinding :: Ord n => Parser n (LetMode n, Bind n, Exp () n)-pLetBinding - = do   b       <- T.pBinder--        P.choice-         [ do   -- Binding with full type signature.-                --  BINDER : TYPE = EXP-                pTok KColon-                t       <- T.pType-                mode    <- pLetMode-                pTok KEquals-                xBody   <- pExp--                return  $ (mode, T.makeBindFromBinder b t, xBody) ---         , do   -- Non-function binding with no type signature.-                -- This form can't be used with letrec as we can't use it-                -- to build the full type sig for the let-bound variable.-                --  BINDER = EXP-                mode    <- pLetMode-                pTok KEquals-                xBody   <- pExp-                let t   = T.tBot T.kData-                return  $ (mode, T.makeBindFromBinder b t, xBody)---         , do   -- Binding using function syntax.-                ps      <- liftM concat -                        $  P.many pBindParamSpec -        -                P.choice-                 [ do   -- Function syntax with a return type.-                        -- We can make the full type sig for the let-bound variable.-                        --   BINDER PARAM1 PARAM2 .. PARAMN : TYPE = EXP-                        pTok KColon-                        tBody   <- T.pType-                        mode    <- pLetMode-                        pTok KEquals-                        xBody   <- pExp--                        let x   = expOfParams () ps xBody-                        let t   = funTypeOfParams ps tBody-                        return  (mode, T.makeBindFromBinder b t, x)--                        -- Function syntax with no return type.-                        -- We can't make the type sig for the let-bound variable,-                        -- but we can create lambda abstractions with the given -                        -- parameter types.-                        --  BINDER PARAM1 PARAM2 .. PARAMN = EXP-                 , do   mode    <- pLetMode-                        pTok KEquals-                        xBody   <- pExp--                        let x   = expOfParams () ps xBody-                        let t   = T.tBot T.kData-                        return  (mode, T.makeBindFromBinder b t, x) ]-         ]---- | Parse a let mode specifier.---   Only allow the lazy specifier with non-recursive bindings.---   We don't support value recursion, so the right of all recursive---   bindings must be explicit lambda abstractions anyway, so there's ---   no point suspending them.-pLetMode :: Ord n => Parser n (LetMode n)-pLetMode- = do   P.choice-                -- lazy <WITNESS>-         [ do   pTok KLazy--                P.choice-                 [ do   pTok KAngleBra-                        w       <- pWitness-                        pTok KAngleKet-                        return  $ LetLazy (Just w)-                 -                 , do   return  $ LetLazy Nothing ]--         , do   return  $ LetStrict ]----- | Letrec bindings must have a full type signature, ---   or use function syntax with a return type so that we can make one.-pLetRecBinding :: Ord n => Parser n (Bind n, Exp () n)-pLetRecBinding - = do   b       <- T.pBinder--        P.choice-         [ do   -- Binding with full type signature.-                --  BINDER : TYPE = EXP-                pTok KColon-                t       <- T.pType-                pTok KEquals-                xBody   <- pExp--                return  $ (T.makeBindFromBinder b t, xBody) ---         , do   -- Binding using function syntax.-                --  BINDER PARAM1 PARAM2 .. PARAMN : TYPE = EXP-                ps      <- liftM concat -                        $  P.many pBindParamSpec -        -                pTok KColon-                tBody   <- T.pType-                let t   = funTypeOfParams ps tBody--                pTok KEquals-                xBody   <- pExp-                let x   = expOfParams () ps xBody--                return  (T.makeBindFromBinder b t, x) ]----- | Parse a parameter specification.------       [BIND1 BIND2 .. BINDN : TYPE]---   or  (BIND : TYPE)---   or  (BIND : TYPE) { EFFECT | CLOSURE }----pBindParamSpec :: Ord n => Parser n [ParamSpec n]-pBindParamSpec- = P.choice-        -- Type parameter-        -- [BIND1 BIND2 .. BINDN : TYPE]- [ do   pTok KSquareBra-        bs      <- P.many1 T.pBinder-        pTok KColon-        t       <- T.pType-        pTok KSquareKet-        return  [ ParamType b -                | b <- zipWith T.makeBindFromBinder bs (repeat t)]---        -- Witness parameter-        -- <BIND : TYPE>- , do   pTok KAngleBra-        b       <- T.pBinder-        pTok KColon-        t       <- T.pType-        pTok KAngleKet-        return  [ ParamWitness $ T.makeBindFromBinder b t]--        -- Value parameter-        -- (BIND : TYPE) -        -- (BIND : TYPE) { TYPE | TYPE }- , do   pTok KRoundBra-        b       <- T.pBinder-        pTok KColon-        t       <- T.pType-        pTok KRoundKet--        (eff, clo) -         <- P.choice-                [ do    pTok KBraceBra-                        eff'    <- T.pType-                        pTok KBar-                        clo'    <- T.pType-                        pTok KBraceKet-                        return  (eff', clo')-                -                , do    return  (T.tBot T.kEffect, T.tBot T.kClosure) ]-                --        return  $ [ParamValue (T.makeBindFromBinder b t) eff clo]- ]----- | Specification of a function parameter.---   We can determine the contribution to the type of the function, ---   as well as its expression based on the parameter.-data ParamSpec n-        = ParamType    (Bind n)-        | ParamWitness (Bind n)-        | ParamValue   (Bind n) (Type n) (Type n)----- | Build the type of a function from specifications of its parameters,---   and the type of the body.-funTypeOfParams -        :: [ParamSpec n]        -- ^ Spec of parameters.-        -> Type n               -- ^ Type of body.-        -> Type n               -- ^ Type of whole function.--funTypeOfParams [] tBody        = tBody-funTypeOfParams (p:ps) tBody- = case p of-        ParamType  b    -         -> TForall b -                $ funTypeOfParams ps tBody--        ParamWitness b-         -> T.tImpl (T.typeOfBind b)-                $ funTypeOfParams ps tBody--        ParamValue b eff clo-         -> T.tFun (T.typeOfBind b) eff clo -                $ funTypeOfParams ps tBody----- | Build the expression of a function from specifications of its parameters,---   and the expression for the body.-expOfParams -        :: a-        -> [ParamSpec n]        -- ^ Spec of parameters.-        -> Exp a n              -- ^ Body of function.-        -> Exp a n              -- ^ Expression of whole function.--expOfParams _ [] xBody            = xBody-expOfParams a (p:ps) xBody- = case p of-        ParamType b     -         -> XLAM a b $ expOfParams a ps xBody-        -        ParamWitness b-         -> XLam a b $ expOfParams a ps xBody--        ParamValue b _ _-         -> XLam a b $ expOfParams a ps xBody------ Witnesses --------------------------------------------------------------------- | Parse a witness expression.-pWitness :: Ord n  => Parser n (Witness n)-pWitness = pWitnessJoin----- Witness Joining-pWitnessJoin :: Ord n => Parser n (Witness n)-pWitnessJoin -   -- WITNESS  or  WITNESS & WITNESS- = do   w1      <- pWitnessApp-        P.choice -         [ do   pTok KAmpersand-                w2      <- pWitnessJoin-                return  (WJoin w1 w2)--         , do   return w1 ]----- Applications-pWitnessApp :: Ord n => Parser n (Witness n)-pWitnessApp -  = do  (x:xs)  <- P.many1 pWitnessArg-        return  $ foldl WApp x xs-- <?> "a witness expression or application"----- Function argument-pWitnessArg :: Ord n => Parser n (Witness n)-pWitnessArg - = P.choice- [ -- [TYPE]-   do   pTok KSquareBra-        t       <- T.pType-        pTok KSquareKet-        return  $ WType t--   -- WITNESS- , do   pWitnessAtom ]----- Atomics-pWitnessAtom :: Ord n => Parser n (Witness n)-pWitnessAtom - = P.choice-   -- (WITNESS)- [ do    pTok KRoundBra-         w       <- pWitness-         pTok KRoundKet-         return  $ w--   -- Named constructors- , do   con     <- pCon-        return  $ WCon (WiConBound $ UName con (T.tBot T.kWitness)) --   -- Baked-in witness constructors.- , do    wb     <- pWbCon-         return $ WCon (WiConBuiltin wb)--                -   -- Debruijn indices- , do    i       <- T.pIndex-         return  $ WVar (UIx   i   (T.tBot T.kWitness))--   -- Variables- , do    var     <- pVar-         return  $ WVar (UName var (T.tBot T.kWitness)) ]+        ( Parser - <?> "a witness"+        -- * Modules+        , pModule +          -- * Expressions+        , pExp+        , pExpApp+        , pExpAtom ----------------------------------------------------------------------------------- | Parse a builtin named `WiCon`-pWbCon :: Parser n WbCon-pWbCon  = P.pTokMaybe f- where  f (KA (KWbConBuiltin wb)) = Just wb-        f _                       = Nothing+          -- * Types+        , pType+        , pTypeApp+        , pTypeAtom +          -- * Witnesses+        , pWitness+        , pWitnessApp+        , pWitnessAtom --- | Parse a variable name-pVar :: Parser n n-pVar    = P.pTokMaybe f- where  f (KN (KVar n)) = Just n-        f _             = Nothing+          -- * Constructors+        , pCon+        , pLit +          -- * Variables+        , pBinder+        , pIndex+        , pVar+        , pName --- | Parse a constructor name-pCon :: Parser n n-pCon    = P.pTokMaybe f- where  f (KN (KCon n)) = Just n-        f _             = Nothing+          -- * Raw Tokens+        , pTok+        , pTokAs) +where+import DDC.Core.Parser.Base+import DDC.Core.Parser.Witness+import DDC.Core.Parser.Type+import DDC.Core.Parser.Exp+import DDC.Core.Parser.Module --- | Parse a literal-pLit :: Parser n n-pLit    = P.pTokMaybe f- where  f (KN (KLit n)) = Just n-        f _             = Nothing 
+ DDC/Core/Parser/Base.hs view
@@ -0,0 +1,98 @@++module DDC.Core.Parser.Base+        ( Parser+        , pWbCon+        , pModuleName+        , pQualName+        , pName+        , pCon+        , pLit+        , pIndex+        , pVar+        , pTok+        , pTokAs)+where+import DDC.Base.Pretty+import DDC.Core.Module+import DDC.Core.Exp+import DDC.Core.Lexer.Tokens+import DDC.Base.Parser                  ((<?>))+import qualified DDC.Base.Parser        as P+++-- | A parser of core language tokens.+type Parser n a+        = P.Parser (Tok n) a+++-- | Parse a builtin named `WiCon`+pWbCon :: Parser n WbCon+pWbCon  = P.pTokMaybe f+ where  f (KA (KWbConBuiltin wb)) = Just wb+        f _                       = Nothing+++-- | Parse a module name.                               +--   +---  ISSUE #273: Handle hierarchical module names.+--      Accept hierachical names, and reject hashes at the end of a name.+--      Hashes can be at the end of constructor name, but not module names.+pModuleName :: Pretty n => Parser n ModuleName+pModuleName = P.pTokMaybe f+ where  f (KN (KCon n)) = Just $ ModuleName [renderPlain $ ppr n]+        f _             = Nothing+++-- | Parse a qualified variable or constructor name.+pQualName :: Pretty n => Parser n (QualName n)+pQualName+ = do   mn      <- pModuleName+        pTok KDot+        n       <- pName+        return  $ QualName mn n+++-- | Parse a constructor or variable name.+pName :: Parser n n+pName   = P.choice [pCon, pVar]+++-- | Parse a constructor name.+pCon  :: Parser n n+pCon    = P.pTokMaybe f+ where  f (KN (KCon n)) = Just n+        f _             = Nothing+++-- | Parse a literal+pLit :: Parser n n+pLit    = P.pTokMaybe f+ where  f (KN (KLit n)) = Just n+        f _             = Nothing+++-- | Parse a variable.+pVar :: Parser n n+pVar    =   P.pTokMaybe f+        <?> "a variable"+ where  f (KN (KVar n))         = Just n+        f _                     = Nothing+++-- | Parse a deBruijn index+pIndex :: Parser n Int+pIndex  =   P.pTokMaybe f+        <?> "an index"+ where  f (KA (KIndex i))       = Just i+        f _                     = Nothing+++-- | Parse an atomic token.+pTok :: TokAtom -> Parser n ()+pTok k     = P.pTok (KA k)+++-- | Parse an atomic token and return some value.+pTokAs :: TokAtom -> a -> Parser n a+pTokAs k x = P.pTokAs (KA k) x+
+ DDC/Core/Parser/Exp.hs view
@@ -0,0 +1,547 @@++-- | Core language parser.+module DDC.Core.Parser.Exp+        ( pExp+        , pExpApp+        , pExpAtom+        , pLets+        , pType+        , pTypeApp+        , pTypeAtom)+where+import DDC.Core.Exp+import DDC.Core.Parser.Witness+import DDC.Core.Parser.Param+import DDC.Core.Parser.Type+import DDC.Core.Parser.Base+import DDC.Core.Lexer.Tokens+import DDC.Core.Compounds+import DDC.Base.Parser                  ((<?>))+import qualified DDC.Base.Parser        as P+import qualified DDC.Type.Compounds     as T+import Control.Monad.Error+++-- Expressions ----------------------------------------------------------------+-- | Parse a core language expression.+pExp    :: Ord n => Parser n (Exp () n)+pExp + = P.choice+        -- Level-0 lambda abstractions+        -- \(x1 x2 ... : TYPE) (y1 y2 ... : TYPE) ... . EXP+ [ do   pTok KBackSlash++        bs      <- liftM concat+                $  P.many1 +                $  do   pTok KRoundBra+                        bs'     <- P.many1 pBinder+                        pTok KColon+                        t       <- pType+                        pTok KRoundKet+                        return (map (\b -> T.makeBindFromBinder b t) bs')++        pTok KDot+        xBody   <- pExp+        return  $ foldr (XLam ()) xBody bs++        -- Level-1 lambda abstractions.+        -- /\(x1 x2 ... : TYPE) (y1 y2 ... : TYPE) ... . EXP+ , do   pTok KBigLambda++        bs      <- liftM concat+                $  P.many1 +                $  do   pTok KRoundBra+                        bs'     <- P.many1 pBinder+                        pTok KColon+                        t       <- pType+                        pTok KRoundKet+                        return (map (\b -> T.makeBindFromBinder b t) bs')++        pTok KDot+        xBody   <- pExp+        return  $ foldr (XLAM ()) xBody bs+++        -- let expression+ , do   lts     <- pLets+        pTok    KIn+        x2      <- pExp+        return  $ XLet () lts x2+++        -- do { STMTS }+        --   Sugar for a let-expression.+ , do   pTok    KDo+        pTok    KBraceBra+        xx      <- pStmts+        pTok    KBraceKet+        return  $ xx+++        -- withregion CON in EXP+ , do   pTok KWithRegion+        u       <- P.choice +                [  do   n    <- pVar+                        return $ UName n++                ,  do   n    <- pCon+                        return $ UPrim n kRegion]+        pTok KIn+        x       <- pExp+        return  $ XLet () (LWithRegion u) x+++        -- case EXP of { ALTS }+ , do   pTok KCase+        x       <- pExp+        pTok KOf +        pTok KBraceBra+        alts    <- P.sepEndBy1 pAlt (pTok KSemiColon)+        pTok KBraceKet+        return  $ XCase () x alts+++        -- match PAT <- EXP else EXP in EXP+        --  Sugar for a case-expression.+ , do   pTok KMatch+        p       <- pPat+        pTok KArrowDashLeft+        x1      <- pExp +        pTok KElse+        x2      <- pExp +        pTok KIn+        x3      <- pExp+        return  $ XCase () x1 [AAlt p x3, AAlt PDefault x2]+++        -- weakeff [TYPE] in EXP+ , do   pTok KWeakEff+        pTok KSquareBra+        t       <- pType+        pTok KSquareKet+        pTok KIn+        x       <- pExp+        return  $ XCast () (CastWeakenEffect t) x+++        -- weakclo {EXP;+} in EXP+ , do   pTok KWeakClo+        pTok KBraceBra+        xs       <- liftM concat $ P.sepEndBy1 pArgs (pTok KSemiColon)+        pTok KBraceKet+        pTok KIn+        x       <- pExp+        return  $ XCast () (CastWeakenClosure xs) x+++        -- purify <WITNESS> in EXP+ , do   pTok KPurify+        pTok KAngleBra+        w       <- pWitness+        pTok KAngleKet+        pTok KIn+        x       <- pExp+        return  $ XCast () (CastPurify w) x+++        -- forget <WITNESS> in EXP+ , do   pTok KForget+        pTok KAngleBra+        w       <- pWitness+        pTok KAngleKet+        pTok KIn+        x       <- pExp+        return  $ XCast () (CastForget w) x++        -- APP+ , do   pExpApp+ ]++ <?> "an expression"+++-- Applications.+pExpApp :: Ord n => Parser n (Exp () n)+pExpApp +  = do  x1      <- pExpAtom+        +        P.choice+         [ do   xs  <- liftM concat $ P.many1 pArgs+                return  $ foldl (XApp ()) x1 xs++         ,      return x1]++ <?> "an expression or application"+++-- Comp, Witness or Spec arguments.+pArgs   :: Ord n => Parser n [Exp () n]+pArgs + = P.choice+        -- [TYPE]+ [ do   pTok KSquareBra+        t       <- pType +        pTok KSquareKet+        return  [XType t]++        -- [: TYPE0 TYPE0 ... :]+ , do   pTok KSquareColonBra+        ts      <- P.many1 pTypeAtom+        pTok KSquareColonKet+        return  $ map XType ts+        +        -- <WITNESS>+ , do   pTok KAngleBra+        w       <- pWitness+        pTok KAngleKet+        return  [XWitness w]+                +        -- <: WITNESS0 WITNESS0 ... :>+ , do   pTok KAngleColonBra+        ws      <- P.many1 pWitnessAtom+        pTok KAngleColonKet+        return  $ map XWitness ws+                +        -- EXP0+ , do   x       <- pExpAtom+        return  [x]+ ]+ <?> "a type, witness or expression argument"+++-- | Parse a variable, constructor or parenthesised expression.+pExpAtom   :: Ord n => Parser n (Exp () n)+pExpAtom + = P.choice+        -- (EXP2)+ [ do   pTok KRoundBra+        t       <- pExp+        pTok KRoundKet+        return  $ t+ +        -- The unit data constructor.       + , do   pTok KDaConUnit+        return  $ XCon () dcUnit++        -- Named algebraic constructors.+        --  We just fill-in the type with tBot for now, and leave it to +        --  the spreader to attach the real type.+ , do   con     <- pCon+        return  $ XCon () (mkDaConAlg con (T.tBot T.kData))++        -- Literals.+        --  We just fill-in the type with tBot for now, and leave it to+        --  the spreader to attach the real type.+        --  We also set the literal as being algebraic, which may not be+        --  true (as for Floats). The spreader also needs to fix this.+ , do   lit     <- pLit+        return  $ XCon () (mkDaConAlg lit (T.tBot T.kData))++        -- Debruijn indices+ , do   i       <- pIndex+        return  $ XVar () (UIx   i)++        -- Variables+ , do   var     <- pVar+        return  $ XVar () (UName var) + ]++ <?> "a variable, constructor, or parenthesised type"+++-- Alternatives ---------------------------------------------------------------+-- Case alternatives.+pAlt    :: Ord n => Parser n (Alt () n)+pAlt+ = do   p       <- pPat+        pTok KArrowDash+        x       <- pExp+        return  $ AAlt p x+++-- Patterns.+pPat    :: Ord n => Parser n (Pat n)+pPat+ = P.choice+ [      -- Wildcard+   do   pTok KUnderscore+        return  $ PDefault++        -- LIT+ , do   nLit    <- pLit+        return  $ PData (mkDaConAlg nLit (T.tBot T.kData)) []++        -- Unit+ , do   pTok KDaConUnit+        return  $ PData  dcUnit []++        -- CON BIND BIND ...+ , do   nCon    <- pCon +        bs      <- P.many pBindPat+        return  $ PData (mkDaConAlg nCon (T.tBot T.kData)) bs]+++-- Binds in patterns can have no type annotation,+-- or can have an annotation if the whole thing is in parens.+pBindPat :: Ord n => Parser n (Bind n)+pBindPat + = P.choice+        -- Plain binder.+ [ do   b       <- pBinder+        return  $ T.makeBindFromBinder b (T.tBot T.kData)++        -- Binder with type, wrapped in parens.+ , do   pTok KRoundBra+        b       <- pBinder+        pTok KColon+        t       <- pType+        pTok KRoundKet+        return  $ T.makeBindFromBinder b t+ ]+++-- Bindings -------------------------------------------------------------------+pLets :: Ord n => Parser n (Lets () n)+pLets+ = P.choice+    [ -- non-recursive let.+      do pTok KLet+         (mode1, b1, x1) <- pLetBinding+         return  $ LLet mode1 b1 x1++      -- recursive let.+    , do pTok KLetRec+         P.choice+          -- Multiple bindings in braces+          [ do   pTok KBraceBra+                 lets    <- P.sepEndBy1 pLetRecBinding (pTok KSemiColon)+                 pTok KBraceKet+                 return $ LRec lets++          -- A single binding without braces.+          , do   ll      <- pLetRecBinding+                 return  $ LRec [ll]+          ]      ++      -- Local region binding.+      --   letregions [BINDER] with { BINDER : TYPE ... } in EXP+      --   letregions [BINDER] in EXP+    , do pTok KLetRegions+         brs    <- P.manyTill pBinder (P.try $ P.lookAhead $ P.choice [pTok KIn, pTok KWith])+         let bs =  map (flip T.makeBindFromBinder T.kRegion) brs+         pLetWits bs+          +    , do pTok KLetRegion+         br    <- pBinder+         let b =  T.makeBindFromBinder br T.kRegion+         pLetWits [b]+         +    ]+    +    +pLetWits :: Ord n => [Bind n] -> Parser n (Lets () n)+pLetWits bs+ = P.choice +    [ do   pTok KWith+           pTok KBraceBra+           wits    <- P.sepBy+                      (do  b    <- pBinder+                           pTok KColon+                           t    <- pTypeApp+                           return  $ T.makeBindFromBinder b t)+                      (pTok KSemiColon)+           pTok KBraceKet+           return (LLetRegions bs wits)+    +    , do   return (LLetRegions bs [])+    ]+++-- | A binding for let expression.+pLetBinding :: Ord n => Parser n (LetMode n, Bind n, Exp () n)+pLetBinding + = do   b       <- pBinder++        P.choice+         [ do   -- Binding with full type signature.+                --  BINDER : TYPE = EXP+                pTok KColon+                t       <- pType+                mode    <- pLetMode+                pTok KEquals+                xBody   <- pExp++                return  $ (mode, T.makeBindFromBinder b t, xBody) +++         , do   -- Non-function binding with no type signature.+                -- This form can't be used with letrec as we can't use it+                -- to build the full type sig for the let-bound variable.+                --  BINDER = EXP+                mode    <- pLetMode+                pTok KEquals+                xBody   <- pExp+                let t   = T.tBot T.kData+                return  $ (mode, T.makeBindFromBinder b t, xBody)+++         , do   -- Binding using function syntax.+                ps      <- liftM concat +                        $  P.many pBindParamSpec +        +                P.choice+                 [ do   -- Function syntax with a return type.+                        -- We can make the full type sig for the let-bound variable.+                        --   BINDER PARAM1 PARAM2 .. PARAMN : TYPE = EXP+                        pTok KColon+                        tBody   <- pType+                        mode    <- pLetMode+                        pTok KEquals+                        xBody   <- pExp++                        let x   = expOfParams () ps xBody+                        let t   = funTypeOfParams ps tBody+                        return  (mode, T.makeBindFromBinder b t, x)++                        -- Function syntax with no return type.+                        -- We can't make the type sig for the let-bound variable,+                        -- but we can create lambda abstractions with the given +                        -- parameter types.+                        --  BINDER PARAM1 PARAM2 .. PARAMN = EXP+                 , do   mode    <- pLetMode+                        pTok KEquals+                        xBody   <- pExp++                        let x   = expOfParams () ps xBody+                        let t   = T.tBot T.kData+                        return  (mode, T.makeBindFromBinder b t, x) ]+         ]++-- | Parse a let mode specifier.+--   Only allow the lazy specifier with non-recursive bindings.+--   We don't support value recursion, so the right of all recursive+--   bindings must be explicit lambda abstractions anyway, so there's +--   no point suspending them.+pLetMode :: Ord n => Parser n (LetMode n)+pLetMode+ = do   P.choice+                -- lazy <WITNESS>+         [ do   pTok KLazy++                P.choice+                 [ do   pTok KAngleBra+                        w       <- pWitness+                        pTok KAngleKet+                        return  $ LetLazy (Just w)+                 +                 , do   return  $ LetLazy Nothing ]++         , do   return  $ LetStrict ]+++-- | Letrec bindings must have a full type signature, +--   or use function syntax with a return type so that we can make one.+pLetRecBinding :: Ord n => Parser n (Bind n, Exp () n)+pLetRecBinding + = do   b       <- pBinder++        P.choice+         [ do   -- Binding with full type signature.+                --  BINDER : TYPE = EXP+                pTok KColon+                t       <- pType+                pTok KEquals+                xBody   <- pExp++                return  $ (T.makeBindFromBinder b t, xBody) +++         , do   -- Binding using function syntax.+                --  BINDER PARAM1 PARAM2 .. PARAMN : TYPE = EXP+                ps      <- liftM concat +                        $  P.many pBindParamSpec +        +                pTok KColon+                tBody   <- pType+                let t   = funTypeOfParams ps tBody++                pTok KEquals+                xBody   <- pExp+                let x   = expOfParams () ps xBody++                return  (T.makeBindFromBinder b t, x) ]+++-- Statements -----------------------------------------------------------------+data Stmt n+        = StmtBind  (Bind n) (Exp () n)+        | StmtMatch (Pat n)  (Exp () n) (Exp () n)+        | StmtNone  (Exp () n)+++-- | Parse a single statement.+pStmt :: Ord n => Parser n (Stmt n)+pStmt + = P.choice+ [ -- BINDER = EXP ;+   -- We need the 'try' because a VARIABLE binders can also be parsed+   --   as a function name in a non-binding statement.+   --  +   P.try $ +    do  br      <- pBinder+        pTok    KEquals+        x1      <- pExp+        let t   = T.tBot T.kData+        let b   = T.makeBindFromBinder br t+        return  $ StmtBind b x1++   -- PAT <- EXP else EXP;+   -- Sugar for a case-expression.+   -- We need the 'try' because the PAT can also be parsed+   --  as a function name in a non-binding statement.+ , P.try $+    do  p       <- pPat+        pTok KArrowDashLeft+        x1      <- pExp +        pTok KElse+        x2      <- pExp +        return  $ StmtMatch p x1 x2++        -- EXP+ , do   x       <- pExp+        return  $ StmtNone x+ ]+++-- | Parse some statements.+pStmts :: Ord n => Parser n (Exp () n)+pStmts+ = do   stmts   <- P.sepEndBy1 pStmt (pTok KSemiColon)+        case makeStmts stmts of+         Nothing -> P.unexpected "do-block must end with a statement"+         Just x  -> return x+++-- | Make an expression from some statements.+makeStmts :: [Stmt n] -> Maybe (Exp () n)+makeStmts ss+ = case ss of+        [StmtNone x]    +         -> Just x++        StmtNone x1 : rest+         | Just x2      <- makeStmts rest+         -> Just $ XLet () (LLet LetStrict (BNone (T.tBot T.kData)) x1) x2++        StmtBind b x1 : rest+         | Just x2      <- makeStmts rest+         -> Just $ XLet () (LLet LetStrict b x1) x2++        StmtMatch p x1 x2 : rest+         | Just x3      <- makeStmts rest+         -> Just $ XCase () x1 +                 [ AAlt p x3+                 , AAlt PDefault x2]++        _ -> Nothing+
− DDC/Core/Parser/Lexer.hs
@@ -1,293 +0,0 @@---- | Reference lexer for core langauge parser. Slow but Simple.-module DDC.Core.Parser.Lexer-        ( -- * Constructors-          isConName, isConStart, isConBody-        , readTwConBuiltin-        , readTcConBuiltin-        , readWbConBuiltin-        , readCon-        -          -- * Variables-        , isVarName, isVarStart, isVarBody-        , readVar--          -- * Lexer-        , lexExp)-where-import DDC.Base.Lexer-import DDC.Core.Exp-import DDC.Core.Parser.Tokens-import Data.Char----- WbCon names ------------------------------------------------------------------- | Read a `WbCon`.-readWbConBuiltin :: String -> Maybe WbCon-readWbConBuiltin ss- = case ss of-        "pure"          -> Just WbConPure-        "empty"         -> Just WbConEmpty-        "use"           -> Just WbConUse-        "read"          -> Just WbConRead-        "alloc"         -> Just WbConAlloc-        _               -> Nothing----- | Textual keywords in the core language.-keywords :: [(String, Tok n)]-keywords- =      [ ("in",         KA KIn)-        , ("of",         KA KOf) -        , ("letrec",     KA KLetRec)-        , ("letregion",  KA KLetRegion)-        , ("withregion", KA KWithRegion)-        , ("let",        KA KLet)-        , ("lazy",       KA KLazy)-        , ("case",       KA KCase)-        , ("purify",     KA KPurify)-        , ("forget",     KA KForget)-        , ("weakeff",    KA KWeakEff)-        , ("weakclo",    KA KWeakClo)-        , ("with",       KA KWith)-        , ("where",      KA KWhere) ]------------------------------------------------------------------------------------- | Lex a string into tokens.----lexExp :: Int -> String -> [Token (Tok String)]-lexExp lineStart str- = lexWord lineStart 1 str- where --  lexWord :: Int -> Int -> String -> [Token (Tok String)]-  lexWord line column w-   = let  tok t = Token t (SourcePos Nothing line column)-          tokA  = tok . KA-          tokN  = tok . KN--          lexMore n rest-           = lexWord line (column + n) rest--     in case w of-        []               -> []        --        ' '  : w'        -> lexMore 1 w'-        '\t' : w'        -> lexMore 8 w'-        '\n' : w'        -> lexWord (line + 1) 1 w'---        -- The unit data constructor-        '(' : ')' : w'   -> tokN (KCon "()")     : lexMore 2 w'--        -- Compound Parens-        '['  : ':' : w'  -> tokA KSquareColonBra : lexMore 2 w'-        ':'  : ']' : w'  -> tokA KSquareColonKet : lexMore 2 w'-        '<'  : ':' : w'  -> tokA KAngleColonBra  : lexMore 2 w'-        ':'  : '>' : w'  -> tokA KAngleColonKet  : lexMore 2 w'--        -- Function Constructors-        '~'  : '>'  : w' -> tokA KArrowTilde     : lexMore 2 w'-        '-'  : '>'  : w' -> tokA KArrowDash      : lexMore 2 w'-        '='  : '>'  : w' -> tokA KArrowEquals    : lexMore 2 w'--        -- Compound symbols-        ':'  : ':'  : w' -> tokA KColonColon     : lexMore 2 w'-        '/'  : '\\' : w' -> tokA KBigLambda      : lexMore 2 w'--        -- Debruijn indices-        '^'  : cs-         |  (ds, rest)   <- span isDigit cs-         ,  length ds >= 1-         -> tokA (KIndex (read ds))              : lexMore (1 + length ds) rest         --        -- Parens-        '('  : w'       -> tokA KRoundBra        : lexMore 1 w'-        ')'  : w'       -> tokA KRoundKet        : lexMore 1 w'-        '['  : w'       -> tokA KSquareBra       : lexMore 1 w'-        ']'  : w'       -> tokA KSquareKet       : lexMore 1 w'-        '{'  : w'       -> tokA KBraceBra        : lexMore 1 w'-        '}'  : w'       -> tokA KBraceKet        : lexMore 1 w'-        '<'  : w'       -> tokA KAngleBra        : lexMore 1 w'-        '>'  : w'       -> tokA KAngleKet        : lexMore 1 w'            --        -- Punctuation-        '.'  : w'       -> tokA KDot             : lexMore 1 w'-        '|'  : w'       -> tokA KBar             : lexMore 1 w'-        '^'  : w'       -> tokA KHat             : lexMore 1 w'-        '+'  : w'       -> tokA KPlus            : lexMore 1 w'-        ':'  : w'       -> tokA KColon           : lexMore 1 w'-        ','  : w'       -> tokA KComma           : lexMore 1 w'-        '\\' : w'       -> tokA KBackSlash       : lexMore 1 w'-        ';'  : w'       -> tokA KSemiColon       : lexMore 1 w'-        '_'  : w'       -> tokA KUnderscore      : lexMore 1 w'-        '='  : w'       -> tokA KEquals          : lexMore 1 w'-        '&'  : w'       -> tokA KAmpersand       : lexMore 1 w'-        '-'  : w'       -> tokA KDash            : lexMore 1 w'-        -        -- Bottoms-        '!' : '0' : w'  -> tokA KBotEffect       : lexMore 2 w'-        '$' : '0' : w'  -> tokA KBotClosure      : lexMore 2 w'--        -- Sort Constructors-        '*' : '*' : w'  -> tokA KSortComp        : lexMore 2 w'-        '@' : '@' : w'  -> tokA KSortProp        : lexMore 2 w'        --        -- Kind Constructors-        '*' : w'        -> tokA KKindValue       : lexMore 1 w'-        '%' : w'        -> tokA KKindRegion      : lexMore 1 w'-        '!' : w'        -> tokA KKindEffect      : lexMore 1 w'-        '$' : w'        -> tokA KKindClosure     : lexMore 1 w'-        '@' : w'        -> tokA KKindWitness     : lexMore 1 w'-        -        -- Literal values-        c : cs-         | isDigit c-         , (body, rest)         <- span isDigit cs-         -> tokN (KLit (c:body))                 : lexMore (length (c:body)) rest-        -        -- Named Constructors-        c : cs-         | isConStart c-         , (body,  rest)        <- span isConBody cs-         , (body', rest')       <- case rest of-                                        '#' : rest'     -> (body ++ "#", rest')-                                        _               -> (body, rest)-         -> let readNamedCon s-                 | Just twcon   <- readTwConBuiltin s-                 = tokA (KTwConBuiltin twcon)    : lexMore (length s) rest'-                 -                 | Just tccon   <- readTcConBuiltin s-                 = tokA (KTcConBuiltin tccon)    : lexMore (length s) rest'-                 -                 | Just con     <- readCon s-                 = tokN (KCon con)               : lexMore (length s) rest'-               -                 | otherwise    -                 = [tok (KJunk c)]-                 -            in  readNamedCon (c : body')--        -- Keywords, Named Variables and Witness constructors-        c : cs-         | isVarStart c-         , (body,  rest)        <- span isVarBody cs-         -> let readNamedVar s-                 | Just t <- lookup s keywords-                 = tok t                   : lexMore (length s) rest--                 | Just wc      <- readWbConBuiltin s-                 = tokA (KWbConBuiltin wc) : lexMore (length s) rest-         -                 | Just v       <- readVar s-                 = tokN (KVar v)           : lexMore (length s) rest--                 | otherwise-                 = [tok (KJunk c)]--            in  readNamedVar (c : body)--        -- Error-        c : _   -> [tok $ KJunk c]-        ---- TyCon names ------------------------------------------------------------------- | String is a constructor name.-isConName :: String -> Bool-isConName str- = case str of-     []          -> False-     (c:cs)      -        | isConStart c -        , and (map isConBody cs)-        -> True-        -        | _ : _         <- cs-        , isConStart c-        , and (map isConBody (init cs))-        , last cs == '#'-        -> True--        | otherwise-        -> False---- | Character can start a constructor name.-isConStart :: Char -> Bool-isConStart = isUpper----- | Charater can be part of a constructor body.-isConBody  :: Char -> Bool-isConBody c           = isUpper c || isLower c || isDigit c || c == '_'-        ---- | Read a named `TwCon`. -readTwConBuiltin :: String -> Maybe TwCon-readTwConBuiltin ss- = case ss of-        "Global"        -> Just TwConGlobal-        "DeepGlobal"    -> Just TwConDeepGlobal-        "Const"         -> Just TwConConst-        "DeepConst"     -> Just TwConDeepConst-        "Mutable"       -> Just TwConMutable-        "DeepMutable"   -> Just TwConDeepMutable-        "Lazy"          -> Just TwConLazy-        "HeadLazy"      -> Just TwConHeadLazy-        "Manifest"      -> Just TwConManifest-        "Pure"          -> Just TwConPure-        "Empty"         -> Just TwConEmpty-        _               -> Nothing----- | Read a builtin `TcCon` with a non-symbolic name, ---   ie not '->'.-readTcConBuiltin :: String -> Maybe TcCon-readTcConBuiltin ss- = case ss of-        "Read"          -> Just TcConRead-        "HeadRead"      -> Just TcConHeadRead-        "DeepRead"      -> Just TcConDeepRead-        "Write"         -> Just TcConWrite-        "DeepWrite"     -> Just TcConDeepWrite-        "Alloc"         -> Just TcConAlloc-        "DeepAlloc"     -> Just TcConDeepAlloc-        "Use"           -> Just TcConUse-        "DeepUse"       -> Just TcConDeepUse-        _               -> Nothing----- | Read a named, user defined `TcCon`.------   We won't know its kind, so fill this in with the Bottom element for ---   computatation kinds (**0).-readCon :: String -> Maybe String-readCon ss-        | isConName ss  = Just ss-        | otherwise     = Nothing----- TyVar names ------------------------------------------------------------------- | String is a variable name.-isVarName :: String -> Bool-isVarName []     = False-isVarName (c:cs) = isVarStart c && (and $ map isVarBody cs)----- | Charater can start a variable name.-isVarStart :: Char -> Bool-isVarStart = isLower-        ---- | Character can be part of a variable body.-isVarBody  :: Char -> Bool-isVarBody c-        = isUpper c || isLower c || isDigit c || c == '_' || c == '\''----- | Read a named, user defined variable.-readVar :: String -> Maybe String-readVar ss-        | isVarName ss  = Just ss-        | otherwise     = Nothing-
+ DDC/Core/Parser/Module.hs view
@@ -0,0 +1,125 @@++module DDC.Core.Parser.Module+        (pModule)+where+import DDC.Core.Module+import DDC.Core.Exp+import DDC.Core.Parser.Type+import DDC.Core.Parser.Exp+import DDC.Core.Parser.Base+import DDC.Core.Lexer.Tokens+import DDC.Core.Compounds+import DDC.Base.Pretty+import qualified DDC.Base.Parser        as P+import qualified Data.Map               as Map+++-- Module ---------------------------------------------------------------------+-- | Parse a core module.+pModule :: (Ord n, Pretty n) +        => Parser n (Module () n)+pModule + = do   pTok KModule+        name    <- pModuleName++        -- exports { SIG;+ }+        tExports +         <- P.choice+            [do pTok KExports+                pTok KBraceBra+                sigs    <- P.sepEndBy1 pTypeSig (pTok KSemiColon)+                pTok KBraceKet+                return sigs++            ,   return []]++        -- imports { SIG;+ }+        tImportKindsTypes+         <- P.choice+            [do pTok KImports+                pTok KBraceBra+                importKinds     <- P.sepEndBy pImportKindSpec (pTok KSemiColon)+                importTypes     <- P.sepEndBy pImportTypeSpec (pTok KSemiColon)+                pTok KBraceKet+                return (importKinds, importTypes)++            ,   return ([], [])]++        let (tImportKinds, tImportTypes)+                = tImportKindsTypes++        pTok KWith++        -- LET;++        lts     <- P.sepBy1 pLets (pTok KIn)++        -- The body of the module consists of the top-level bindings wrapped+        -- around a unit constructor place-holder.+        let body = xLets () lts (xUnit ())++        -- ISSUE #295: Check for duplicate exported names in module parser.+        --  The names are added to a unique map, so later ones with the same+        --  name will replace earlier ones.+        return  $ ModuleCore+                { moduleName            = name+                , moduleExportKinds     = Map.empty+                , moduleExportTypes     = Map.fromList tExports+                , moduleImportKinds     = Map.fromList tImportKinds+                , moduleImportTypes     = Map.fromList tImportTypes+                , moduleBody            = body }+++-- | Parse a type signature.+pTypeSig :: Ord n => Parser n (n, Type n)        +pTypeSig+ = do   var     <- pVar+        pTok KColonColon+        t       <- pType+        return  (var, t)+++-- | Parse the type signature of an imported variable.+pImportKindSpec +        :: (Ord n, Pretty n) +        => Parser n (n, (QualName n, Kind n))++pImportKindSpec + =   pTok KType+ >>  P.choice+ [      -- Import with an explicit external name.+        -- Module.varExternal with varLocal+   do   qn      <- pQualName+        pTok KWith+        n       <- pName+        pTok KColonColon+        k       <- pType+        return  (n, (qn, k))++ , do   n       <- pName+        pTok KColonColon+        k       <- pType+        return  (n, (QualName (ModuleName []) n, k))+ ]        +++-- | Parse the type signature of an imported variable.+pImportTypeSpec +        :: (Ord n, Pretty n) +        => Parser n (n, (QualName n, Type n))++pImportTypeSpec + = P.choice+ [      -- Import with an explicit external name.+        -- Module.varExternal with varLocal+   do   qn      <- pQualName+        pTok KWith+        n       <- pName+        pTok KColonColon+        t       <- pType+        return  (n, (qn, t))++ , do   n       <- pName+        pTok KColonColon+        t       <- pType+        return  (n, (QualName (ModuleName []) n, t))+ ]        
+ DDC/Core/Parser/Param.hs view
@@ -0,0 +1,122 @@++module DDC.Core.Parser.Param+        ( ParamSpec     (..)+        , funTypeOfParams+        , expOfParams+        , pBindParamSpec)+where+import DDC.Core.Exp+import DDC.Core.Parser.Type+import DDC.Core.Parser.Base             (Parser)+import DDC.Core.Lexer.Tokens+import qualified DDC.Base.Parser        as P+import qualified DDC.Type.Compounds     as T+++-- | Specification of a function parameter.+--   We can determine the contribution to the type of the function, +--   as well as its expression based on the parameter.+data ParamSpec n+        = ParamType    (Bind n)+        | ParamWitness (Bind n)+        | ParamValue   (Bind n) (Type n) (Type n)+++-- | Build the type of a function from specifications of its parameters,+--   and the type of the body.+funTypeOfParams +        :: [ParamSpec n]        -- ^ Spec of parameters.+        -> Type n               -- ^ Type of body.+        -> Type n               -- ^ Type of whole function.++funTypeOfParams [] tBody        = tBody+funTypeOfParams (p:ps) tBody+ = case p of+        ParamType  b    +         -> TForall b +                $ funTypeOfParams ps tBody++        ParamWitness b+         -> T.tImpl (T.typeOfBind b)+                $ funTypeOfParams ps tBody++        ParamValue b eff clo+         -> T.tFun (T.typeOfBind b) eff clo +                $ funTypeOfParams ps tBody+++-- | Build the expression of a function from specifications of its parameters,+--   and the expression for the body.+expOfParams +        :: a+        -> [ParamSpec n]        -- ^ Spec of parameters.+        -> Exp a n              -- ^ Body of function.+        -> Exp a n              -- ^ Expression of whole function.++expOfParams _ [] xBody            = xBody+expOfParams a (p:ps) xBody+ = case p of+        ParamType b     +         -> XLAM a b $ expOfParams a ps xBody+        +        ParamWitness b+         -> XLam a b $ expOfParams a ps xBody++        ParamValue b _ _+         -> XLam a b $ expOfParams a ps xBody+++-- | Parse a parameter specification.+--+--       [BIND1 BIND2 .. BINDN : TYPE]+--   or  (BIND : TYPE)+--   or  (BIND : TYPE) { EFFECT | CLOSURE }+--+pBindParamSpec :: Ord n => Parser n [ParamSpec n]+pBindParamSpec+ = P.choice+        -- Type parameter+        -- [BIND1 BIND2 .. BINDN : TYPE]+ [ do   pTok KSquareBra+        bs      <- P.many1 pBinder+        pTok KColon+        t       <- pType+        pTok KSquareKet+        return  [ ParamType b +                | b <- zipWith T.makeBindFromBinder bs (repeat t)]+++        -- Witness parameter+        -- <BIND : TYPE>+ , do   pTok KAngleBra+        b       <- pBinder+        pTok KColon+        t       <- pType+        pTok KAngleKet+        return  [ ParamWitness $ T.makeBindFromBinder b t]++        -- Value parameter+        -- (BIND : TYPE) +        -- (BIND : TYPE) { TYPE | TYPE }+ , do   pTok KRoundBra+        b       <- pBinder+        pTok KColon+        t       <- pType+        pTok KRoundKet++        (eff, clo) +         <- P.choice+                [ do    pTok KBraceBra+                        eff'    <- pType+                        pTok KBar+                        clo'    <- pType+                        pTok KBraceKet+                        return  (eff', clo')+                +                , do    return  (T.tBot T.kEffect, T.tBot T.kClosure) ]+                ++        return  $ [ParamValue (T.makeBindFromBinder b t) eff clo]+ ]++
− DDC/Core/Parser/Tokens.hs
@@ -1,263 +0,0 @@--module DDC.Core.Parser.Tokens-        ( Tok      (..)-        , describeTok-        , renameTok--        , TokAtom  (..)-        , describeTokAtom--        , TokNamed (..)-        , describeTokNamed)-where-import DDC.Core.Pretty-import DDC.Core.Exp----- TokenFamily ------------------------------------------------------------------- | The family of a token.---   This is used to help generate parser error messages,---   so we can say ''the constructor Cons''---             and ''the keyword case'' etc.-data TokenFamily-        = Symbol-        | Keyword-        | Constructor-        | Index-        | Variable----- | Describe a token family, for parser error messages.-describeTokenFamily :: TokenFamily -> String-describeTokenFamily tf- = case tf of-        Symbol          -> "symbol"-        Keyword         -> "keyword"-        Constructor     -> "constructor"-        Index           -> "index"-        Variable        -> "variable"----- Tok --------------------------------------------------------------------------- | Tokens accepted by the core language parser.-data Tok n-        -- Some junk symbol that isn't part of the language.-        = KJunk Char--        -- An atomic token.-        | KA    !TokAtom --        -- A named token.-        | KN    !(TokNamed n)-        deriving (Eq, Show)----- | Describe a token for parser error messages.-describeTok :: Pretty n => Tok n -> String-describeTok kk- = case kk of-        KJunk c         -> "character " ++ show c-        KA ta           -> describeTokAtom  ta-        KN tn           -> describeTokNamed tn----- | Apply a function to all the names in a `Tok`.-renameTok-        :: Ord n2-        => (n1 -> n2) -> Tok n1 -> Tok n2--renameTok f kk- = case kk of-        KJunk s -> KJunk s-        KA t    -> KA t-        KN t    -> KN $ renameTokNamed f t----- TokAtom ----------------------------------------------------------------------- | Atomic tokens, that don't contain user-defined names.-data TokAtom-        -- parens-        = KRoundBra-        | KRoundKet-        | KSquareBra-        | KSquareKet-        | KBraceBra-        | KBraceKet-        | KAngleBra-        | KAngleKet--        -- compound parens-        | KSquareColonBra-        | KSquareColonKet-        | KAngleColonBra-        | KAngleColonKet--        -- punctuation-        | KDot-        | KBar-        | KHat-        | KPlus-        | KColon-        | KComma-        | KBackSlash-        | KSemiColon-        | KUnderscore-        | KEquals-        | KAmpersand-        | KDash-        | KColonColon-        | KBigLambda--        -- symbolic constructors-        | KSortComp-        | KSortProp-        | KKindValue-        | KKindRegion-        | KKindEffect-        | KKindClosure-        | KKindWitness-        | KArrowTilde-        | KArrowDash-        | KArrowEquals--        -- bottoms-        | KBotEffect-        | KBotClosure--        -- expression keywords-        | KWith-        | KWhere-        | KIn-        | KLet-        | KLazy-        | KLetRec-        | KLetRegion-        | KWithRegion-        | KCase-        | KOf-        | KWeakEff-        | KWeakClo-        | KPurify-        | KForget--        -- debruijn indices-        | KIndex Int--        -- builtin names-        | KTwConBuiltin TwCon-        | KWbConBuiltin WbCon-        | KTcConBuiltin TcCon-        deriving (Eq, Show)----- | Describe a `TokAtom`, for parser error messages.-describeTokAtom  :: TokAtom -> String-describeTokAtom ta- = let  (family, str)           = describeTokAtom' ta-   in   describeTokenFamily family ++ " " ++ show str--describeTokAtom' :: TokAtom -> (TokenFamily, String)-describeTokAtom' ta- = case ta of-        -- parens-        KRoundBra               -> (Symbol, "(")-        KRoundKet               -> (Symbol, ")")-        KSquareBra              -> (Symbol, "[")-        KSquareKet              -> (Symbol, "]")-        KBraceBra               -> (Symbol, "{")-        KBraceKet               -> (Symbol, "}")-        KAngleBra               -> (Symbol, "<")-        KAngleKet               -> (Symbol, ">")--        -- compound parens-        KSquareColonBra         -> (Symbol, "[:")-        KSquareColonKet         -> (Symbol, ":]")-        KAngleColonBra          -> (Symbol, "<:")-        KAngleColonKet          -> (Symbol, ":>")--        -- punctuation-        KDot                    -> (Symbol, ".")-        KBar                    -> (Symbol, "|")-        KHat                    -> (Symbol, "^")-        KPlus                   -> (Symbol, "+")-        KColon                  -> (Symbol, ":")-        KComma                  -> (Symbol, ",")-        KBackSlash              -> (Symbol, "\\")-        KSemiColon              -> (Symbol, ";")-        KUnderscore             -> (Symbol, "_")-        KEquals                 -> (Symbol, "=")-        KAmpersand              -> (Symbol, "&")-        KDash                   -> (Symbol, "-")-        KColonColon             -> (Symbol, "::")-        KBigLambda              -> (Symbol, "/\\")--        -- symbolic constructors-        KSortComp               -> (Constructor, "**")-        KSortProp               -> (Constructor, "@@")-        KKindValue              -> (Constructor, "*")-        KKindRegion             -> (Constructor, "%")-        KKindEffect             -> (Constructor, "!")-        KKindClosure            -> (Constructor, "$")-        KKindWitness            -> (Constructor, "@")-        KArrowTilde             -> (Constructor, "~>")-        KArrowDash              -> (Constructor, "->")-        KArrowEquals            -> (Constructor, "=>")--        -- bottoms-        KBotEffect              -> (Constructor, "!0")-        KBotClosure             -> (Constructor, "!$")--        -- expression keywords-        KWith                   -> (Keyword, "with")-        KWhere                  -> (Keyword, "where")-        KIn                     -> (Keyword, "in")-        KLet                    -> (Keyword, "let")-        KLazy                   -> (Keyword, "lazy")-        KLetRec                 -> (Keyword, "letrec")-        KLetRegion              -> (Keyword, "letregion")-        KWithRegion             -> (Keyword, "withregion")-        KCase                   -> (Keyword, "case")-        KOf                     -> (Keyword, "of")-        KWeakEff                -> (Keyword, "weakeff")-        KWeakClo                -> (Keyword, "weakclo")-        KPurify                 -> (Keyword, "purify")-        KForget                 -> (Keyword, "forget")-        -        -- debruijn indices-        KIndex i                -> (Index,   "^" ++ show i)--        -- builtin names-        KTwConBuiltin tw        -> (Constructor, renderPlain $ ppr tw)-        KWbConBuiltin wi        -> (Constructor, renderPlain $ ppr wi)-        KTcConBuiltin tc        -> (Constructor, renderPlain $ ppr tc)----- TokNamed ---------------------------------------------------------------------- | A token witn a user-defined name.-data TokNamed n-        = KCon n-        | KVar n-        | KLit n-        deriving (Eq, Show)----- | Describe a `TokNamed`, for parser error messages.-describeTokNamed :: Pretty n => TokNamed n -> String-describeTokNamed tn- = case tn of-        KCon n  -> renderPlain $ text "constructor" <+> (dquotes $ ppr n)-        KVar n  -> renderPlain $ text "variable"    <+> (dquotes $ ppr n)-        KLit n  -> renderPlain $ text "literal"     <+> (dquotes $ ppr n)----- | Apply a function to all the names in a `TokNamed`.-renameTokNamed -        :: Ord n2-        => (n1 -> n2) -> TokNamed n1 -> TokNamed n2--renameTokNamed f kk-  = case kk of-        KCon c           -> KCon $ f c-        KVar c           -> KVar $ f c-        KLit c           -> KLit $ f c-
+ DDC/Core/Parser/Type.hs view
@@ -0,0 +1,209 @@++-- | Parser for type expressions.+module DDC.Core.Parser.Type+        ( pType+        , pTypeAtom+        , pTypeApp+        , pBinder+        , pIndex+        , pTok+        , pTokAs)+where+import DDC.Core.Parser.Base+import DDC.Core.Lexer.Tokens   +import DDC.Type.Exp+import DDC.Type.Compounds+import DDC.Base.Parser                  ((<?>))+import qualified DDC.Base.Parser        as P+import qualified DDC.Type.Sum           as TS+++-- | Parse a type.+pType   :: Ord n => Parser n (Type n)+pType   = pTypeSum+ <?> "a type"+++--  | Parse a type sum.+pTypeSum :: Ord n => Parser n (Type n)+pTypeSum + = do   t1      <- pTypeForall+        P.choice +         [ -- Type sums.+           -- T2 + T3+           do   pTok KPlus+                t2      <- pTypeSum+                return  $ TSum $ TS.fromList (tBot sComp) [t1, t2]+                +         , do   return t1 ]+ <?> "a type"+++-- | Parse a binder.+pBinder :: Ord n => Parser n (Binder n)+pBinder+ = P.choice+        -- Named binders.+        [ do    v       <- pVar+                return  $ RName v+                +        -- Anonymous binders.+        , do    pTok KHat+                return  $ RAnon +        +        -- Vacant binders.+        , do    pTok KUnderscore+                return  $ RNone ]+ <?> "a binder"+   +-- | Parse a quantified type.+pTypeForall :: Ord n => Parser n (Type n)+pTypeForall+ = P.choice+         [ -- Universal quantification.+           -- [v1 v1 ... vn : T1]. T2+           do   pTok KSquareBra+                bs      <- P.many1 pBinder+                pTok KColon+                k       <- pTypeSum+                pTok KSquareKet+                pTok KDot++                body    <- pTypeForall++                return  $ foldr TForall body +                        $ map (\b -> makeBindFromBinder b k) bs++           -- Body type+         , do   pTypeFun]+ <?> "a type"+++-- | Parse a function type.+pTypeFun :: Ord n => Parser n (Type n)+pTypeFun+ = do   t1      <- pTypeApp+        P.choice +         [ -- T1 ~> T2+           do   pTok KArrowTilde+                t2      <- pTypeFun+                return  $ TApp (TApp (TCon (TyConKind KiConFun)) t1) t2++           -- T1 => T2+         , do   pTok KArrowEquals+                t2      <- pTypeFun+                return  $ TApp (TApp (TCon (TyConWitness TwConImpl)) t1) t2++           -- T1 -> T2+         , do   pTok KArrowDash+                t2      <- pTypeFun+                return  $ t1 `tFunPE` t2++           -- T1 -(TSUM | TSUM)> t2+         , do   pTok KDash+                pTok KRoundBra+                eff     <- pTypeSum+                pTok KBar+                clo     <- pTypeSum+                pTok KRoundKet+                pTok KAngleKet+                t2      <- pTypeFun+                return  $ tFun t1 eff clo t2+++           -- Body type+         , do   return t1 ]+ <?> "an atomic type or type application"+++-- | Parse a type application.+pTypeApp :: Ord n => Parser n (Type n)+pTypeApp  + = do   (t:ts)  <- P.many1 pTypeAtom+        return  $  foldl TApp t ts+ <?> "an atomic type or type application"+++-- | Parse a variable, constructor or parenthesised type.+pTypeAtom :: Ord n => Parser n (Type n)+pTypeAtom  + = P.choice+        -- (~>) and (=>) and (->) and (TYPE2)+        [ do    pTok KRoundBra+                P.choice+                 [ do   pTok KArrowTilde+                        pTok KRoundKet+                        return (TCon $ TyConKind KiConFun)++                 , do   pTok KArrowEquals+                        pTok KRoundKet+                        return (TCon $ TyConWitness TwConImpl)++                 , do   pTok KArrowDash+                        pTok KRoundKet+                        return (TCon $ TyConSpec TcConFun)++                 , do   t       <- pTypeSum+                        pTok KRoundKet+                        return t +                 ]++        -- Named type constructors+        , do    tc      <- pTcCon+                return  $ TCon (TyConSpec tc)++        , do    tc      <- pTwCon+                return  $ TCon (TyConWitness tc)++        , do    tc      <- pTyConNamed+                return  $ TCon tc++        -- Symbolic constructors.+        , do    pTokAs KSortComp    (TCon $ TyConSort SoConComp)+        , do    pTokAs KSortProp    (TCon $ TyConSort SoConProp) +        , do    pTokAs KKindValue   (TCon $ TyConKind KiConData)+        , do    pTokAs KKindRegion  (TCon $ TyConKind KiConRegion) +        , do    pTokAs KKindEffect  (TCon $ TyConKind KiConEffect) +        , do    pTokAs KKindClosure (TCon $ TyConKind KiConClosure) +        , do    pTokAs KKindWitness (TCon $ TyConKind KiConWitness) +            +        -- Bottoms.+        , do    pTokAs KBotEffect  (tBot kEffect)+        , do    pTokAs KBotClosure (tBot kClosure)+      +        -- Bound occurrence of a variable.+        --  We don't know the kind of this variable yet, so fill in the+        --  field with the bottom element of computation kinds. This isn't+        --  really part of the language, but makes sense implentation-wise.+        , do    v       <- pVar+                return  $  TVar (UName v)++        , do    i       <- pIndex+                return  $  TVar (UIx (fromIntegral i))+        ]+ <?> "an atomic type"+++-------------------------------------------------------------------------------+-- | Parse a builtin `TcCon`+pTcCon :: Parser n TcCon+pTcCon  =   P.pTokMaybe f+        <?> "a type constructor"+ where f (KA (KTcConBuiltin c)) = Just c+       f _                      = Nothing ++-- | Parse a builtin `TwCon`+pTwCon :: Parser n TwCon+pTwCon  =   P.pTokMaybe f+        <?> "a witness constructor"+ where f (KA (KTwConBuiltin c)) = Just c+       f _                      = Nothing++-- | Parse a user `TcCon`+pTyConNamed :: Parser n (TyCon n)+pTyConNamed  +        =   P.pTokMaybe f+        <?> "a type constructor"+ where  f (KN (KCon n))          = Just (TyConBound (UName n) (tBot kData))+        f _                      = Nothing+
+ DDC/Core/Parser/Witness.hs view
@@ -0,0 +1,84 @@++module DDC.Core.Parser.Witness+        ( pWitness+        , pWitnessApp+        , pWitnessAtom) +where+import DDC.Core.Parser.Type+import DDC.Core.Parser.Base+import DDC.Core.Lexer.Tokens+import DDC.Core.Exp+import DDC.Base.Parser                  ((<?>))+import qualified DDC.Base.Parser        as P+import qualified DDC.Type.Compounds     as T+ ++-- | Parse a witness expression.+pWitness :: Ord n  => Parser n (Witness n)+pWitness = pWitnessJoin+++-- | Parse a witness join.+pWitnessJoin :: Ord n => Parser n (Witness n)+pWitnessJoin +   -- WITNESS  or  WITNESS & WITNESS+ = do   w1      <- pWitnessApp+        P.choice +         [ do   pTok KAmpersand+                w2      <- pWitnessJoin+                return  (WJoin w1 w2)++         , do   return w1 ]+++-- | Parse a witness application.+pWitnessApp :: Ord n => Parser n (Witness n)+pWitnessApp +  = do  (x:xs)  <- P.many1 pWitnessArg+        return  $ foldl WApp x xs++ <?> "a witness expression or application"+++-- | Parse a witness argument.+pWitnessArg :: Ord n => Parser n (Witness n)+pWitnessArg + = P.choice+ [ -- [TYPE]+   do   pTok KSquareBra+        t       <- pType+        pTok KSquareKet+        return  $ WType t++   -- WITNESS+ , do   pWitnessAtom ]+++-- | Parse a variable, constructor or parenthesised witness.+pWitnessAtom :: Ord n => Parser n (Witness n)+pWitnessAtom + = P.choice+   -- (WITNESS)+ [ do    pTok KRoundBra+         w       <- pWitness+         pTok KRoundKet+         return  $ w++   -- Named constructors+ , do   con     <- pCon+        return  $ WCon (WiConBound (UName con) (T.tBot T.kWitness))++   -- Baked-in witness constructors.+ , do    wb     <- pWbCon+         return $ WCon (WiConBuiltin wb)++                +   -- Debruijn indices+ , do    i       <- pIndex+         return  $ WVar (UIx   i)++   -- Variables+ , do    var     <- pVar+         return  $ WVar (UName var) ]++ <?> "a witness"
DDC/Core/Predicates.hs view
@@ -1,10 +1,12 @@  -- | Simple predicates on core expressions. module DDC.Core.Predicates-        ( -- * Atoms-          isXVar,  isXCon-        , isAtomW, isAtomX+        ( module DDC.Type.Predicates +          -- * Atoms+        , isXVar,  isXCon+        , isAtomX, isAtomW+           -- * Lambdas         , isXLAM, isXLam         , isLambdaX@@ -12,6 +14,10 @@           -- * Applications         , isXApp +          -- * Types and Witnesses+        , isXType+        , isXWitness+           -- * Patterns         , isPDefault) where@@ -36,15 +42,6 @@         _       -> False  --- | Check whether a witness is a `WVar` or `WCon`.-isAtomW :: Witness n -> Bool-isAtomW ww- = case ww of-        WVar{}          -> True-        WCon{}          -> True-        _               -> False-- -- | Check whether an expression is a `XVar` or an `XCon`,  --   or some type or witness atom. isAtomX :: Exp a n -> Bool@@ -57,6 +54,15 @@         _               -> False  +-- | Check whether a witness is a `WVar` or `WCon`.+isAtomW :: Witness n -> Bool+isAtomW ww+ = case ww of+        WVar{}          -> True+        WCon{}          -> True+        _               -> False++ -- Lambdas -------------------------------------------------------------------- -- | Check whether an expression is a spec abstraction (level-1). isXLAM :: Exp a n -> Bool@@ -87,6 +93,23 @@  = case xx of         XApp{}  -> True         _       -> False+++-- Type and Witness -----------------------------------------------------------+-- | Check whether an expression is an `XType`+isXType :: Exp a n -> Bool+isXType xx+ = case xx of+        XType{}         -> True+        _               -> False+++-- | Check whether an expression is an `XWitness`+isXWitness :: Exp a n -> Bool+isXWitness xx+ = case xx of+        XWitness{}      -> True+        _               -> False   -- Patterns -------------------------------------------------------------------
DDC/Core/Pretty.hs view
@@ -1,43 +1,94 @@--- | Pretty printing for core expressions.++-- | Provides pretty printing for core modules and expressions. module DDC.Core.Pretty          ( module DDC.Type.Pretty         , module DDC.Base.Pretty) where-import DDC.Core.Exp import DDC.Core.Compounds import DDC.Core.Predicates+import DDC.Core.Module+import DDC.Core.Exp import DDC.Type.Pretty-import DDC.Type.Compounds-import DDC.Type.Predicates import DDC.Base.Pretty+import Data.List+import qualified Data.Map.Strict        as Map  --- Binder ------------------------------------------------------------------------ | Pretty print a binder, adding spaces after names.---   The RAnon and None binders don't need spaces, as they're single symbols.-pprBinderSep   :: Pretty n => Binder n -> Doc-pprBinderSep bb- = case bb of-        RName v         -> ppr v-        RAnon           -> text "^"-        RNone           -> text "_"+-- ModuleName -----------------------------------------------------------------+instance Pretty ModuleName where+ ppr (ModuleName parts)+        = text $ intercalate "." parts  --- | Print a group of binders with the same type.-pprBinderGroup -        :: (Pretty n, Eq n) -        => Doc -> ([Binder n], Type n) -> Doc+-- Module ---------------------------------------------------------------------+instance (Pretty n, Eq n) => Pretty (Module a n) where+ ppr ModuleCore +        { moduleName            = name+        , moduleExportKinds     = exportKinds+        , moduleExportTypes     = exportTypes+        , moduleImportKinds     = importKinds+        , moduleImportTypes     = importTypes+        , moduleBody            = body }+  = {-# SCC "ppr[Module]" #-}+    let +        (lts, _)         = splitXLets body -pprBinderGroup lam (rs, t)-        = lam <> parens ((cat $ map pprBinderSep rs) <+> text ":" <+> ppr t) <> dot+        docsExportKinds+         | Map.null exportKinds        = empty+         | otherwise  +         = nest 8 $ line +         <> vcat  [ text "type" <+> ppr n <+> text "::" <+> ppr t <> semi+                  | (n, t)      <- Map.toList exportKinds ] +        docsExportTypes  +         | Map.null exportTypes        = empty+         | otherwise+         = nest 8 $ line+         <> vcat  [ ppr n                 <+> text "::" <+> ppr t <> semi+                  | (n, t)      <- Map.toList exportTypes ] +        docsImportKinds+         | Map.null importKinds        = empty+         | otherwise  +         = nest 8 $ line +         <> vcat  [ text "type" <+> ppr n <+> text "::" <+> ppr t <> semi+                  | (n, (_, t)) <- Map.toList importKinds ]++        docsImportTypes  +         | Map.null importTypes        = empty+         | otherwise+         = nest 8 $ line+         <> vcat  [ ppr n                 <+> text "::" <+> ppr t <> semi+                  | (n, (_, t)) <- Map.toList importTypes ]++    in  text "module" <+> ppr name +         <+> (if Map.null exportKinds && Map.null exportTypes+                then empty+                else line+                        <> text "exports" <+> lbrace+                        <> docsExportKinds+                        <> docsExportTypes+                        <> line +                        <> rbrace <> space)++         <>  (if Map.null importKinds && Map.null importTypes+                then empty+                else line +                        <> text "imports" <+> lbrace +                        <> docsImportKinds+                        <> docsImportTypes+                        <> line +                        <> rbrace <> space)+         <>  text "with" <$$> (vcat $ map ppr lts)++ -- Exp ------------------------------------------------------------------------ instance (Pretty n, Eq n) => Pretty (Exp a n) where  pprPrec d xx-  = case xx of+  = {-# SCC "ppr[Exp]" #-}+    case xx of         XVar  _ u       -> ppr u-        XCon  _ tc      -> ppr tc+        XCon  _ dc      -> ppr dc                  XLAM{}          -> let Just (bs, xBody) = takeXLAMs xx@@ -107,15 +158,25 @@   = ppr p <+> nest 1 (line <> nest 3 (text "->" <+> ppr x))  +-- DaCon ----------------------------------------------------------------------+instance (Pretty n, Eq n) => Pretty (DaCon n) where+ ppr dc+  = case daConName dc of+        DaConUnit               -> text "()"+        DaConNamed n            -> ppr n++ -- Cast ------------------------------------------------------------------------instance (Pretty n, Eq n) => Pretty (Cast n) where+instance (Pretty n, Eq n) => Pretty (Cast a n) where  ppr cc   = case cc of         CastWeakenEffect  eff             -> text "weakeff" <+> brackets (ppr eff) -        CastWeakenClosure clo-         -> text "weakclo" <+> brackets (ppr clo)+        CastWeakenClosure xs+         -> text "weakclo" +         <+> braces (hcat $ punctuate (semi <> space) +                          $ map ppr xs)          CastPurify w          -> text "purify"  <+> angles   (ppr w)@@ -152,17 +213,27 @@                                $ map pprLetRecBind bxs)))                 <$> rbrace --        LLetRegion b []+        +        LLetRegions [b] []          -> text "letregion"                 <+> ppr (binderOfBind b)--        LLetRegion b bs+        +        LLetRegions [b] bs          -> text "letregion"                 <+> ppr (binderOfBind b)                 <+> text "with"                 <+> braces (cat $ punctuate (text "; ") $ map ppr bs) +        LLetRegions b []+         -> text "letregions"+                <+> (hcat $ punctuate space (map (ppr . binderOfBind) b))++        LLetRegions b bs+         -> text "letregions"+                <+> (hcat $ punctuate space (map (ppr . binderOfBind) b))+                <+> text "with"+                <+> braces (cat $ punctuate (text "; ") $ map ppr bs)+         LWithRegion b          -> text "withregion"                 <+> ppr b@@ -195,8 +266,8 @@ instance (Pretty n, Eq n) => Pretty (WiCon n) where  ppr wc   = case wc of-        WiConBuiltin wb -> ppr wb-        WiConBound   u  -> ppr u+        WiConBuiltin wb   -> ppr wb+        WiConBound   u  _ -> ppr u   instance Pretty WbCon where@@ -207,6 +278,24 @@         WbConUse        -> text "use"         WbConRead       -> text "read"         WbConAlloc      -> text "alloc"+++-- Binder ---------------------------------------------------------------------+pprBinder   :: Pretty n => Binder n -> Doc+pprBinder bb+ = case bb of+        RName v         -> ppr v+        RAnon           -> text "^"+        RNone           -> text "_"+++-- | Print a group of binders with the same type.+pprBinderGroup +        :: (Pretty n, Eq n) +        => Doc -> ([Binder n], Type n) -> Doc++pprBinderGroup lam (rs, t)+        = lam <> parens ((hsep $ map pprBinder rs) <+> text ":" <+> ppr t) <> dot   -- Utils ----------------------------------------------------------------------
+ DDC/Core/Transform/LiftT.hs view
@@ -0,0 +1,107 @@++module DDC.Core.Transform.LiftT+        ( liftT,         liftAtDepthT+        , MapBoundT(..))+where+import DDC.Core.Exp+import DDC.Type.Transform.LiftT+++instance Ord n => MapBoundT (Exp a) n where+ mapBoundAtDepthT f d xx+  = let down = mapBoundAtDepthT f d+    in case xx of+        XVar a u        -> XVar a   u+        XCon{}          -> xx+        XApp a x1 x2    -> XApp a   (down x1) (down x2)+        XLAM a b x      -> XLAM a b (mapBoundAtDepthT f (d + countBAnons [b]) x)+        XLam a b x      -> XLam a   (down b) (down x)+         +        XLet a lets x   +         -> let (lets', levels) = mapBoundAtDepthTLets f d lets +            in  XLet a lets' (mapBoundAtDepthT f (d + levels) x)++        XCase a x alts  -> XCase a  (down x)  (map down alts)+        XCast a cc x    -> XCast a  (down cc) (down x)+        XType    t      -> XType    (down t)+        XWitness w      -> XWitness (down w)+++instance Ord n => MapBoundT LetMode n where+ mapBoundAtDepthT f d m+  = case m of+        LetStrict        -> m+        LetLazy Nothing  -> m+        LetLazy (Just w) -> LetLazy (Just $ mapBoundAtDepthT f d w)++         +instance Ord n => MapBoundT Witness n where+ mapBoundAtDepthT f d ww+  = let down = mapBoundAtDepthT f d+    in case ww of+        WVar u         -> WVar  (down u)+        WCon _         -> ww+        WApp  w1 w2    -> WApp  (down w1) (down w2)+        WJoin w1 w2    -> WJoin (down w1) (down w2)+        WType t        -> WType (down t)+++instance Ord n => MapBoundT (Cast a) n where+ mapBoundAtDepthT f d cc+  = let down = mapBoundAtDepthT f d+    in case cc of+        CastWeakenEffect t +         -> CastWeakenEffect  (down t)++        CastWeakenClosure xs    +         -> CastWeakenClosure (map down xs)++        CastPurify w+         -> CastPurify (down w)++        CastForget w+         -> CastForget (down w)+++instance Ord n => MapBoundT (Alt a) n where+ mapBoundAtDepthT f d (AAlt p x)+  = let down = mapBoundAtDepthT f d+    in case p of+        PDefault +         -> AAlt PDefault (down x)++        PData dc bs+         -> AAlt (PData dc (map down bs)) (down x) +        ++mapBoundAtDepthTLets+        :: Ord n+        => (Int -> Bound n -> Bound n)  -- ^ Number of levels to lift.+        -> Int                          -- ^ Current binding depth.+        -> Lets a n                     -- ^ Lift exp indices in this thing.+        -> (Lets a n, Int)              -- ^ Lifted, and how much to increase depth by++mapBoundAtDepthTLets f d lts+ = let down = mapBoundAtDepthT f d+   in case lts of+        LLet m b x+         ->     ( LLet (down m) (down b) (down x)+                , 0)++        LRec bs+         -> let bs' = [ (b, mapBoundAtDepthT f d x) | (b, x) <- bs ]+            in  (LRec bs', 0)++        LLetRegions bsT bsX+         -> let inc  = countBAnons bsT+                bsX' = map (mapBoundAtDepthT f (d + inc)) bsX+            in  ( LLetRegions bsT bsX'+                , inc)++        LWithRegion _+         -> (lts, 0)+++countBAnons = length . filter isAnon+ where  isAnon (BAnon _) = True+        isAnon _         = False
− DDC/Core/Transform/LiftW.hs
@@ -1,116 +0,0 @@---- | Lift deBruijn indices in witnesses.-module DDC.Core.Transform.LiftW-        (LiftW(..))-where-import DDC.Core.Exp---class LiftW (c :: * -> *) where- -- | Lift indices that are at least a the given depth by some number- --   of levels- liftAtDepthW-        :: forall n. Ord n-        => Int          -- ^ Number of levels to lift.-        -> Int          -- ^ Current binding depth.-        -> c n          -- ^ Lift witness variable indices in this thing.-        -> c n- - -- | Wrapper for `liftAtDepthX` that starts at depth 0.       - liftW  :: forall n. Ord n-        => Int          -- ^ Number of levels to lift.-        -> c n          -- ^ Lift witness variable indices in this thing.-        -> c n-        - liftW n xx  = liftAtDepthW n 0 xx-  --instance LiftW Bound where- liftAtDepthW n d uu-  = case uu of-        UName{}         -> uu-        UPrim{}         -> uu-        UIx i t -         | d <= i       -> UIx (i + n) t-         | otherwise    -> uu---instance LiftW (Exp a) where- liftAtDepthW n d xx-  = let down = liftAtDepthW n d-    in case xx of-        XVar{}          -> xx-        XCon{}          -> xx-        XApp a x1 x2    -> XApp a (down x1) (down x2)-        XLAM a b x      -> XLAM a b (down x)-        XLam a b x      -> XLam a b (liftAtDepthW n (d + 1) x)-         -        XLet a lets x   -         -> let (lets', levels) = liftAtDepthXLets n d lets -            in  XLet a lets' (liftAtDepthW n (d + levels) x)--        XCase a x alts  -> XCase a (down x) (map down alts)-        XCast a cc x    -> XCast a cc (down x)-        XType{}         -> xx-        XWitness w      -> XWitness (down w)-         --instance LiftW LetMode where- liftAtDepthW n d m-  = case m of-        LetStrict        -> m-        LetLazy Nothing  -> m-        LetLazy (Just w) -> LetLazy (Just $ liftAtDepthW n d w)---instance LiftW (Alt a) where- liftAtDepthW n d (AAlt p x)-  = case p of-	PDefault -         -> AAlt PDefault (liftAtDepthW n d x)--	PData _ bs -         -> let d' = d + countBAnons bs-	    in  AAlt p (liftAtDepthW n d' x)---instance LiftW Witness where- liftAtDepthW n d ww-  = let down = liftAtDepthW n d-    in case ww of-        WVar  u         -> WVar (down u)-        WCon{}          -> ww-        WApp  w1 w2     -> WApp  (down w1) (down w2)-        WJoin w1 w2     -> WJoin (down w1) (down w2)-        WType{}         -> ww-        --liftAtDepthXLets-        :: forall a n. Ord n-        => Int             -- ^ Number of levels to lift.-        -> Int             -- ^ Current binding depth.-        -> Lets a n        -- ^ Lift exp indices in this thing.-        -> (Lets a n, Int) -- ^ Lifted, and how much to increase depth by--liftAtDepthXLets n d lts- = case lts of-        LLet m b x-         -> let m'  = liftAtDepthW n d m-                inc = countBAnons [b]-                x'  = liftAtDepthW n (d+inc) x-            in  (LLet m' b x', inc)--        LRec bs-         -> let inc = countBAnons (map fst bs)-                bs' = map (\(b,e) -> (b, liftAtDepthW n (d+inc) e)) bs-            in  (LRec bs', inc)--        LLetRegion _b bs -> (lts, countBAnons bs)-        LWithRegion _    -> (lts, 0)---countBAnons = length . filter isAnon- where	isAnon (BAnon _) = True-	isAnon _	 = False--
DDC/Core/Transform/LiftX.hs view
@@ -1,92 +1,176 @@ --- | Lift deBruijn indices in expressions.+-- | Lifting and lowering level-0 deBruijn indices in core things.+-- +--   Level-0 indices are used for both value and witness variables. module DDC.Core.Transform.LiftX-        (LiftX(..))+        ( liftX,        liftAtDepthX+        , lowerX,       lowerAtDepthX+        , MapBoundX(..)) where import DDC.Core.Exp  -class LiftX (c :: * -> *) where- -- | Lift indices that are at least the given depth by some number- --   of levels.- liftAtDepthX-        :: forall n. Ord n+-- Lift -----------------------------------------------------------------------+-- | Lift debruijn indices less than or equal to the given depth.+liftAtDepthX   +        :: MapBoundX c n         => Int          -- ^ Number of levels to lift.         -> Int          -- ^ Current binding depth.         -> c n          -- ^ Lift expression indices in this thing.         -> c n- - -- | Wrapper for `liftAtDepthX` that starts at depth 0.       - liftX  :: forall n. Ord n-        => Int          -- ^ Number of levels to lift.-        -> c n          -- ^ Lift expression indices in this thing.++liftAtDepthX n d+ = {-# SCC liftAtDepthX #-} +   mapBoundAtDepthX liftU d+ where  +        liftU d' u+         = case u of+                UName{}         -> u+                UPrim{}         -> u+                UIx i+                 | d' <= i      -> UIx (i + n)+                 | otherwise    -> u+++-- | Wrapper for `liftAtDepthX` that starts at depth 0.       +liftX   :: MapBoundX c n => Int -> c n -> c n+liftX n xx  = liftAtDepthX n 0 xx+++-- Lower ----------------------------------------------------------------------+-- | Lower debruijn indices less than or equal to the given depth.+lowerAtDepthX   +        :: MapBoundX c n+        => Int          -- ^ Number of levels to lower.+        -> Int          -- ^ Current binding depth.+        -> c n          -- ^ Lower expression indices in this thing.         -> c n-        - liftX n xx  = liftAtDepthX n 0 xx-   -instance LiftX Bound where- liftAtDepthX n d uu-  = case uu of-        UName{}         -> uu-        UPrim{}         -> uu-        UIx i t -         | d <= i       -> UIx (i + n) t-         | otherwise    -> uu+lowerAtDepthX n d+ = {-# SCC lowerAtDepthX #-}+   mapBoundAtDepthX liftU d+ where  +        liftU d' u+         = case u of+                UName{}         -> u+                UPrim{}         -> u+                UIx i+                 | d' <= i      -> UIx (i - n)+                 | otherwise    -> u  -instance LiftX (Exp a) where- liftAtDepthX n d xx-  = let down = liftAtDepthX n d+-- | Wrapper for `lowerAtDepthX` that starts at depth 0.       +lowerX   :: MapBoundX c n => Int -> c n -> c n+lowerX n xx  = lowerAtDepthX n 0 xx+++-- MapBoundX ------------------------------------------------------------------+class MapBoundX (c :: * -> *) n where+ -- | Apply a function to all bound variables in the program.+ --   The function is passed the current binding depth.+ --   This is used to defined both `liftX` and `lowerX`.+ mapBoundAtDepthX+        :: (Int -> Bound n -> Bound n)  -- ^ Function to apply to the bound occ.+                                        --   It is passed the current binding depth.+        -> Int                          -- ^ Current binding depth.+        -> c n                          -- ^ Lift expression indices in this thing.+        -> c n+++instance MapBoundX Bound n where+ mapBoundAtDepthX f d u+        = f d u+++instance MapBoundX (Exp a) n where+ mapBoundAtDepthX f d xx+  = let down = mapBoundAtDepthX f d     in case xx of-        XVar a u        -> XVar a (down u)+        XVar a u        -> XVar a (f d u)         XCon{}          -> xx         XApp a x1 x2    -> XApp a (down x1) (down x2)         XLAM a b x      -> XLAM a b (down x)-        XLam a b x      -> XLam a b (liftAtDepthX n (d + 1) x)+        XLam a b x      -> XLam a b (mapBoundAtDepthX f (d + countBAnons [b]) x)                   XLet a lets x   -         -> let (lets', levels) = liftAtDepthXLets n d lets -            in  XLet a lets' (liftAtDepthX n (d + levels) x)+         -> let (lets', levels) = mapBoundAtDepthXLets f d lets +            in  XLet a lets' (mapBoundAtDepthX f (d + levels) x) -        XCase a x alts  -> XCase a (down x) (map down alts)-        XCast a cc x    -> XCast a cc (down x)+        XCase a x alts  -> XCase a (down x)  (map down alts)+        XCast a cc x    -> XCast a (down cc) (down x)         XType{}         -> xx-        XWitness{}      -> xx+        XWitness w	-> XWitness (down w)+++instance MapBoundX LetMode n where+ mapBoundAtDepthX f d m+  = case m of+        LetStrict        -> m+        LetLazy Nothing  -> m+        LetLazy (Just w) -> LetLazy (Just $ mapBoundAtDepthX f d w)+          +instance MapBoundX Witness n where+ mapBoundAtDepthX f d ww+  = let down = mapBoundAtDepthX f d+    in case ww of+        WVar u         -> WVar  (down u)+	WCon _         -> ww+	WApp  w1 w2    -> WApp  (down w1) (down w2)+	WJoin w1 w2    -> WJoin (down w1) (down w2)+	WType _        -> ww -instance LiftX (Alt a) where- liftAtDepthX n d (AAlt p x)++instance MapBoundX (Cast a) n where+ mapBoundAtDepthX f d cc+  = case cc of+        CastWeakenEffect{}+         -> cc++        CastWeakenClosure xs    +         -> CastWeakenClosure (map (mapBoundAtDepthX f d) xs)++        CastPurify w+         -> CastPurify w++        CastForget w+         -> CastForget w+++instance MapBoundX (Alt a) n where+ mapBoundAtDepthX f d (AAlt p x)   = case p of 	PDefault -         -> AAlt PDefault (liftAtDepthX n d x)+         -> AAlt PDefault (mapBoundAtDepthX f d x)  	PData _ bs           -> let d' = d + countBAnons bs-	    in  AAlt p (liftAtDepthX n d' x)+	    in  AAlt p (mapBoundAtDepthX f d' x)          -liftAtDepthXLets-        :: forall a n. Ord n-        => Int             -- ^ Number of levels to lift.-        -> Int             -- ^ Current binding depth.-        -> Lets a n        -- ^ Lift exp indices in this thing.-        -> (Lets a n, Int) -- ^ Lifted, and how much to increase depth by+mapBoundAtDepthXLets+        :: (Int -> Bound n -> Bound n)  -- ^ Number of levels to lift.+        -> Int                          -- ^ Current binding depth.+        -> Lets a n                     -- ^ Lift exp indices in this thing.+        -> (Lets a n, Int)              -- ^ Lifted, and how much to increase depth by -liftAtDepthXLets n d lts+mapBoundAtDepthXLets f d lts  = case lts of         LLet m b x          -> let inc = countBAnons [b]-                x'  = liftAtDepthX n (d+inc) x-            in  (LLet m b x', inc)+                m'  = mapBoundAtDepthX f d m +		-- non-recursive binding: do not increase x's depth+                x'  = mapBoundAtDepthX f d x+            in  (LLet m' b x', inc)+         LRec bs          -> let inc = countBAnons (map fst bs)-                bs' = map (\(b,e) -> (b, liftAtDepthX n (d+inc) e)) bs+                bs' = map (\(b,e) -> (b, mapBoundAtDepthX f (d+inc) e)) bs             in  (LRec bs', inc) -        LLetRegion _b bs -> (lts, countBAnons bs)-        LWithRegion _    -> (lts, 0)+        LLetRegions _b bs -> (lts, countBAnons bs)+        LWithRegion _     -> (lts, 0)   countBAnons = length . filter isAnon
+ DDC/Core/Transform/Reannotate.hs view
@@ -0,0 +1,68 @@++module DDC.Core.Transform.Reannotate+        (Reannotate (..))+where+import DDC.Core.Module+import DDC.Core.Exp+++-- | Apply the given function to every annotation in a core thing.+class Reannotate c where+ reannotate :: (a -> b) -> c a n -> c b n+++instance Reannotate Module where+ reannotate f+     (ModuleCore name +                 exportKinds exportTypes +                 importKinds importTypes+                 body)+  =   ModuleCore name+                 exportKinds exportTypes+                 importKinds importTypes+                 (reannotate f body)+++instance Reannotate Exp where+ reannotate f xx+  = {-# SCC reannotate #-}+    let down x   = reannotate f x+    in case xx of+        XVar  a u       -> XVar  (f a) u+        XCon  a u       -> XCon  (f a) u+        XLAM  a b x     -> XLAM  (f a) b (down x)+        XLam  a b x     -> XLam  (f a) b (down x)+        XApp  a x1 x2   -> XApp  (f a) (down x1)  (down x2)+        XLet  a lts x   -> XLet  (f a) (down lts) (down x)+        XCase a x alts  -> XCase (f a) (down x)   (map down alts)+        XCast a c x     -> XCast (f a) (down c)   (down x)+        XType t         -> XType t+        XWitness w      -> XWitness w+++instance Reannotate Lets where+ reannotate f xx+  = let down x  = reannotate f x+    in case xx of+        LLet m b x       -> LLet m b (down x)+        LRec bxs         -> LRec [(b, down x) | (b, x) <- bxs]+        LLetRegions b bs -> LLetRegions b bs+        LWithRegion b    -> LWithRegion b+++instance Reannotate Alt where+ reannotate f aa+  = case aa of+        AAlt w x        -> AAlt w (reannotate f x)+++instance Reannotate Cast where+ reannotate f cc+  = let down x  = reannotate f x+    in case cc of+        CastWeakenEffect  eff   -> CastWeakenEffect eff+        CastWeakenClosure xs    -> CastWeakenClosure (map down xs)+        CastPurify w            -> CastPurify w+        CastForget w            -> CastForget w++
+ DDC/Core/Transform/Rename.hs view
@@ -0,0 +1,41 @@++module DDC.Core.Transform.Rename+        ( Rename(..)++        -- * Substitution states+        , Sub(..)++        -- * Binding stacks+        , BindStack(..)+        , pushBind+        , pushBinds+        , substBound++        -- * Rewriting binding occurences+        , bind1, bind1s, bind0, bind0s++        -- * Rewriting bound occurences+        , use1,  use0)+where+import DDC.Core.Exp+import DDC.Type.Transform.Rename+++instance Rename LetMode where+ renameWith sub lm+  = case lm of+        LetStrict        -> lm+        LetLazy (Just t) -> LetLazy (Just $ renameWith sub t) +        LetLazy Nothing  -> LetLazy Nothing+++instance Rename Witness where+ renameWith sub ww+  = let down x   = renameWith x+    in case ww of+        WVar u          -> WVar  (use0 sub u)+        WCon{}          -> ww+        WApp  w1 w2     -> WApp  (down sub w1) (down sub w2)+        WJoin w1 w2     -> WJoin (down sub w1) (down sub w2)+        WType t         -> WType (down sub t)+
DDC/Core/Transform/SpreadX.hs view
@@ -1,15 +1,14 @@ --- | Spread type annotations from binders and the environment into bound---   occurrences of variables and constructors. module DDC.Core.Transform.SpreadX         (SpreadX(..)) where+import DDC.Core.Module import DDC.Core.Exp import DDC.Core.Compounds import DDC.Type.Transform.SpreadT import DDC.Type.Env                     (Env) import qualified DDC.Type.Env           as Env-+import qualified Data.Map               as Map  class SpreadX (c :: * -> *) where @@ -22,9 +21,24 @@          => Env n -> Env n -> c n -> c n  +-- Module ---------------------------------------------------------------------+instance SpreadX (Module a) where+ spreadX kenv tenv mm@ModuleCore{}+        = mm+        { moduleExportKinds = Map.map (spreadT kenv)  (moduleExportKinds mm)+        , moduleExportTypes = Map.map (spreadT kenv)  (moduleExportTypes mm)+        , moduleImportKinds = Map.map (liftSnd (spreadT kenv))  (moduleImportKinds mm)+        , moduleImportTypes = Map.map (liftSnd (spreadT kenv))  (moduleImportTypes mm)+        , moduleBody        = spreadX kenv tenv (moduleBody mm) }++        where liftSnd f (x, y) = (x, f y)+        ++------------------------------------------------------------------------------- instance SpreadX (Exp a) where  spreadX kenv tenv xx -  = let down = spreadX kenv tenv +  = {-# SCC spreadX #-}+    let down x = spreadX kenv tenv x     in case xx of         XVar a u        -> XVar a (down u)         XCon a u        -> XCon a (down u)@@ -50,19 +64,37 @@         XWitness w      -> XWitness (down w)  -instance SpreadX Cast where+instance SpreadX DaCon where+ spreadX _kenv tenv dc+  = case daConName dc of+        DaConUnit       -> dc++        DaConNamed n+         -> let u | Env.isPrim tenv n   = UPrim n (daConType dc)+                  | otherwise           = UName n++            in  case Env.lookup u tenv of+                 Just t' -> dc { daConType = t' }++                 -- Primitive constructors won't be in the type environment.+                 --  But we leave it to checkExp to worry about whether a constructor+                 --  is primitive or simply undefined.+                 Nothing -> dc+++instance SpreadX (Cast a) where  spreadX kenv tenv cc-  = let down = spreadX kenv tenv +  = let down x = spreadX kenv tenv x     in case cc of-        CastWeakenEffect eff  -> CastWeakenEffect  (spreadT kenv eff)-        CastWeakenClosure clo -> CastWeakenClosure (spreadT kenv clo)-        CastPurify w          -> CastPurify        (down w)-        CastForget w          -> CastForget        (down w)+        CastWeakenEffect eff    -> CastWeakenEffect  (spreadT kenv eff)+        CastWeakenClosure xs    -> CastWeakenClosure (map down xs)+        CastPurify w            -> CastPurify        (down w)+        CastForget w            -> CastForget        (down w)   instance SpreadX Pat where  spreadX kenv tenv pat-  = let down    = spreadX kenv tenv+  = let down x   = spreadX kenv tenv x     in case pat of         PDefault        -> PDefault         PData u bs      -> PData (down u) (map down bs)@@ -79,7 +111,7 @@  instance SpreadX (Lets a) where  spreadX kenv tenv lts-  = let down = spreadX kenv tenv+  = let down x = spreadX kenv tenv x     in case lts of         LLet m b x       -> LLet (down m) (down b) (down x)         @@ -90,11 +122,11 @@                 xs'      = map (spreadX kenv tenv') xs              in LRec (zip bs' xs') -        LLetRegion b bs-         -> let b'       = spreadT kenv b-                kenv'    = Env.extend b' kenv+        LLetRegions b bs+         -> let b'       = map (spreadT kenv) b+                kenv'    = Env.extends b' kenv                 bs'      = map (spreadX kenv' tenv) bs-            in  LLetRegion b' bs'+            in  LLetRegions b' bs'          LWithRegion b          -> LWithRegion (spreadX kenv tenv b)@@ -121,12 +153,17 @@  instance SpreadX WiCon where  spreadX kenv tenv wc-  = let down = spreadX kenv tenv-    in case wc of-        WiConBound u     -> WiConBound (down u)-        WiConBuiltin{}   -> wc+  = case wc of+        WiConBound (UName n) _+         -> case Env.envPrimFun tenv n of+                Nothing -> wc+                Just t  +                 -> let t'      = spreadT kenv t+                    in  WiConBound (UPrim n t') t' +        _                -> wc + instance SpreadX Bind where  spreadX kenv _tenv bb   = case bb of@@ -139,13 +176,14 @@  spreadX kenv tenv uu   | Just t'     <- Env.lookup uu tenv   = case uu of-        UIx ix _         -> UIx ix t'-        UPrim n _        -> UPrim n t'+        UIx ix          -> UIx   ix -        UName n _+        UName n          -> if Env.isPrim tenv n                   then UPrim n (spreadT kenv t')-                 else UName n (spreadT kenv t')+                 else UName n++        UPrim n _       -> UPrim n t'    | otherwise   = uu         
DDC/Core/Transform/SubstituteTX.hs view
@@ -3,17 +3,18 @@ -- --   If a binder would capture a variable then it is anonymized --   to deBruijn form.+-- module DDC.Core.Transform.SubstituteTX-        ( substituteTX+        ( SubstituteTX(..)+        , substituteTX         , substituteTXs-        , substituteBoundTX-        , SubstituteTX(..))+        , substituteBoundTX) where import DDC.Core.Collect import DDC.Core.Exp import DDC.Type.Compounds import DDC.Type.Transform.SubstituteT-import DDC.Type.Rewrite+import DDC.Type.Transform.Rename import Data.Maybe import qualified Data.Set               as Set import qualified DDC.Type.Env           as Env@@ -64,9 +65,10 @@  instance SubstituteTX (Exp a) where   substituteWithTX tArg sub xx-  = let down    = substituteWithTX tArg+  = {-# SCC substituteWithTX #-}+    let down x   = substituteWithTX tArg x     in case xx of-        XVar a u        -> XVar a (down sub u)+        XVar a u        -> XVar a u         XCon{}          -> xx         XApp a x1 x2    -> XApp a (down sub x1) (down sub x2) @@ -94,11 +96,11 @@                 x2'             = down sub1 x2             in  XLet a (LRec (zip bs' xs')) x2' -        XLet a (LLetRegion b bs) x2-         -> let (sub1, b')      = bind1  sub  b+        XLet a (LLetRegions b bs) x2+         -> let (sub1, b')      = bind1s sub  b                 (sub2, bs')     = bind0s sub1 (map (down sub1) bs)                 x2'             = down   sub2 x2-            in  XLet a (LLetRegion b' bs') x2'+            in  XLet a (LLetRegions b' bs') x2'          XLet a (LWithRegion uR) x2          -> XLet a (LWithRegion uR) (down sub x2)@@ -111,7 +113,7 @@  instance SubstituteTX LetMode where  substituteWithTX tArg sub lm-  = let down    = substituteWithTX tArg+  = let down x   = substituteWithTX tArg x     in case lm of         LetStrict         -> lm         LetLazy Nothing   -> lm@@ -120,7 +122,7 @@  instance SubstituteTX (Alt a) where  substituteWithTX tArg sub aa-  = let down = substituteWithTX tArg+  = let down x = substituteWithTX tArg x     in case aa of         AAlt PDefault xBody          -> AAlt PDefault $ down sub xBody@@ -131,21 +133,21 @@             in  AAlt (PData uCon bs') x'  -instance SubstituteTX Cast where+instance SubstituteTX (Cast a) where  substituteWithTX tArg sub cc-  = let down    = substituteWithTX tArg+  = let down x   = substituteWithTX tArg x     in case cc of         CastWeakenEffect eff    -> CastWeakenEffect  (down sub eff)-        CastWeakenClosure clo   -> CastWeakenClosure (down sub clo)+        CastWeakenClosure clo   -> CastWeakenClosure (map (down sub) clo)         CastPurify w            -> CastPurify        (down sub w)         CastForget w            -> CastForget        (down sub w)   instance SubstituteTX Witness where  substituteWithTX tArg sub ww-  = let down    = substituteWithTX tArg+  = let down x   = substituteWithTX tArg x     in case ww of-        WVar u                  -> WVar  (down sub u)+        WVar u                  -> WVar u         WCon{}                  -> ww         WApp  w1 w2             -> WApp  (down sub w1) (down sub w2)         WJoin w1 w2             -> WJoin (down sub w1) (down sub w2)@@ -155,11 +157,6 @@ instance SubstituteTX Bind where  substituteWithTX tArg sub bb   = replaceTypeOfBind (substituteWithTX tArg sub (typeOfBind bb))  bb---instance SubstituteTX Bound where- substituteWithTX tArg sub uu-  = replaceTypeOfBound (substituteWithTX tArg sub (typeOfBound uu)) uu   instance SubstituteTX Type where
DDC/Core/Transform/SubstituteWX.hs view
@@ -3,6 +3,7 @@ -- --   If a binder would capture a variable then it is anonymized --   to deBruijn form.+-- module DDC.Core.Transform.SubstituteWX         ( SubstituteWX(..)         , substituteWX@@ -10,15 +11,15 @@ where import DDC.Core.Exp import DDC.Core.Collect-import DDC.Core.Transform.LiftW+import DDC.Core.Transform.Rename+import DDC.Core.Transform.LiftX import DDC.Type.Compounds-import DDC.Type.Rewrite import Data.Maybe import qualified DDC.Type.Env   as Env import qualified Data.Set       as Set  --- | Wrapper for `substituteWithW` that determines the set of free names in the+-- | Wrapper for `substituteWithWX` that determines the set of free names in the --   type being substituted, and starts with an empty binder stack. substituteWX          :: (Ord n, SubstituteWX c) @@ -52,7 +53,7 @@  | otherwise    = xx   --- | Wrapper for `substituteW` to substitute multiple things.+-- | Wrapper for `substituteWithWX` to substitute multiple things. substituteWXs          :: (Ord n, SubstituteWX c)          => [(Bind n, Witness n)] -> c n -> c n@@ -60,12 +61,8 @@         = foldr (uncurry substituteWX) x bts  +------------------------------------------------------------------------------- class SubstituteWX (c :: * -> *) where-- -- | Substitute a witness into some thing.- --   In the target, if we find a named binder that would capture a free variable- --   in the type to substitute, then we rewrite that binder to anonymous form,- --   avoiding the capture.  substituteWithWX         :: forall n. Ord n         => Witness n -> Sub n -> c n -> c n@@ -73,10 +70,11 @@  instance SubstituteWX (Exp a) where   substituteWithWX wArg sub xx-  = let down    = substituteWithWX wArg-        into    = rewriteWith+  = {-# SCC substituteWithWX #-}+    let down s x   = substituteWithWX wArg s x+        into s x   = renameWith s x     in case xx of-        XVar a u        -> XVar a (into sub u)+        XVar a u        -> XVar a u         XCon{}          -> xx         XApp a x1 x2    -> XApp a (down sub x1) (down sub x2) @@ -104,11 +102,11 @@                 x2'             = down sub1 x2             in  XLet a (LRec (zip bs' xs')) x2' -        XLet a (LLetRegion b bs) x2-         -> let (sub1, b')      = bind1  sub  b+        XLet a (LLetRegions b bs) x2+         -> let (sub1, b')      = bind1s sub b                 (sub2, bs')     = bind0s sub1 bs                 x2'             = down   sub2 x2-            in  XLet a (LLetRegion b' bs') x2'+            in  XLet a (LLetRegions b' bs') x2'          XLet a (LWithRegion uR) x2          -> XLet a (LWithRegion uR) (down sub x2)@@ -122,7 +120,7 @@  instance SubstituteWX LetMode where  substituteWithWX wArg sub lm-  = let down = substituteWithWX wArg+  = let down s x = substituteWithWX wArg s x     in case lm of         LetStrict        -> lm         LetLazy Nothing  -> LetLazy Nothing@@ -131,7 +129,7 @@  instance SubstituteWX (Alt a) where  substituteWithWX wArg sub aa-  = let down = substituteWithWX wArg+  = let down s x = substituteWithWX wArg s x     in case aa of         AAlt PDefault xBody          -> AAlt PDefault $ down sub xBody@@ -142,25 +140,25 @@             in  AAlt (PData uCon bs') x'  -instance SubstituteWX Cast where+instance SubstituteWX (Cast a) where  substituteWithWX wArg sub cc-  = let down    = substituteWithWX wArg-        into    = rewriteWith+  = let down s x = substituteWithWX wArg s x+        into s x = renameWith s x     in case cc of         CastWeakenEffect eff    -> CastWeakenEffect  (into sub eff)-        CastWeakenClosure clo   -> CastWeakenClosure (into sub clo)+        CastWeakenClosure xs    -> CastWeakenClosure (map (down sub) xs)         CastPurify w            -> CastPurify        (down sub w)         CastForget w            -> CastForget        (down sub w)   instance SubstituteWX Witness where  substituteWithWX wArg sub ww-  = let down    = substituteWithWX wArg-        into    = rewriteWith+  = let down s x = substituteWithWX wArg s x+        into s x = renameWith s x     in case ww of         WVar u          -> case substW wArg sub u of-                Left u'  -> WVar (into sub u')+                Left u'  -> WVar u'                 Right w  -> w          WCon{}                  -> ww@@ -175,8 +173,8 @@  substW wArg sub u   = case substBound (subStack0 sub) (subBound sub) u of-        Left  u'                -> Left (rewriteWith sub u')+        Left  u'                -> Left u'         Right n  -         | not $ subShadow0 sub -> Right (liftW n wArg)-         | otherwise            -> Left (rewriteWith sub u)+         | not $ subShadow0 sub -> Right (liftX n wArg)+         | otherwise            -> Left  u 
DDC/Core/Transform/SubstituteXX.hs view
@@ -3,6 +3,7 @@ -- --   If a binder would capture a variable then it is anonymized --   to deBruijn form.+-- module DDC.Core.Transform.SubstituteXX         ( SubstituteXX(..)         , substituteXX@@ -17,7 +18,7 @@ import DDC.Core.Transform.SubstituteWX import DDC.Core.Transform.SubstituteTX import DDC.Type.Transform.SubstituteT-import DDC.Type.Rewrite+import DDC.Type.Transform.Rename import Data.Maybe import qualified DDC.Type.Env   as Env import qualified Data.Set       as Set@@ -41,7 +42,7 @@         , subConflict1                   = Set.fromList                 $  (mapMaybe takeNameOfBound $ Set.toList $ freeT Env.empty xArg) -                ++ (mapMaybe takeNameOfBind  $ collectSpecBinds xArg)+                ++ (mapMaybe takeNameOfBind  $ fst $ collectBinds xArg)            -- Rewrite level-0 binders that have the same name as any           -- of the free variables in the expression to substitute.@@ -99,12 +100,13 @@  instance SubstituteXX Exp where   substituteWithXX xArg sub xx-  = let down    = substituteWithXX xArg-        into    = rewriteWith+  = {-# SCC substituteWithXX #-}+    let down s x   = substituteWithXX xArg s x+        into s x   = renameWith s x     in case xx of         XVar a u          -> case substX xArg sub u of-                Left  u' -> XVar a (into sub u')+                Left  u' -> XVar a u'                 Right x  -> x          XCon{}           -> xx@@ -134,24 +136,24 @@                 x2'             = down sub1 x2             in  XLet a (LRec (zip bs' xs')) x2' -        XLet a (LLetRegion b bs) x2-         -> let (sub1, b')      = bind1  sub  b+        XLet a (LLetRegions b bs) x2+         -> let (sub1, b')      = bind1s sub  b                 (sub2, bs')     = bind0s sub1 bs                 x2'             = down   sub2 x2-            in  XLet a (LLetRegion b' bs') x2'+            in  XLet a (LLetRegions b' bs') x2'          XLet a (LWithRegion uR) x2          -> XLet a (LWithRegion uR) (down sub x2)          XCase a x1 alts -> XCase a  (down sub x1) (map (down sub) alts)-        XCast a cc x1   -> XCast a  (into sub cc) (down sub x1)+        XCast a cc x1   -> XCast a  (down sub cc) (down sub x1)         XType t         -> XType    (into sub t)         XWitness w      -> XWitness (into sub w)    instance SubstituteXX Alt where  substituteWithXX xArg sub aa-  = let down = substituteWithXX xArg+  = let down s x = substituteWithXX xArg s x     in case aa of         AAlt PDefault xBody          -> AAlt PDefault $ down sub xBody@@ -162,15 +164,26 @@             in  AAlt (PData uCon bs') x'  +instance SubstituteXX Cast where+ substituteWithXX xArg sub cc+  = let down s x = substituteWithXX xArg s x+        into s x = renameWith s x+    in case cc of+        CastWeakenEffect eff    -> CastWeakenEffect  (into sub eff)+        CastWeakenClosure xs    -> CastWeakenClosure (map (down sub) xs)+        CastPurify w            -> CastPurify (into sub w)+        CastForget w            -> CastForget (into sub w)++ -- | Rewrite or substitute into an expression variable. substX  :: Ord n => Exp a n -> Sub n -> Bound n          -> Either (Bound n) (Exp a n)  substX xArg sub u   = case substBound (subStack0 sub) (subBound sub) u of-        Left  u'                -> Left (rewriteWith sub u')+        Left  u'                -> Left u'         Right n            | not $ subShadow0 sub -> Right (liftX n xArg)-         | otherwise            -> Left (rewriteWith sub u)+         | otherwise            -> Left  u  
+ DDC/Core/Transform/Trim.hs view
@@ -0,0 +1,112 @@++-- | Trim the expressions passed to @weakclo@ casts to just those terms+--   that can affect the closure of the body. +--+module DDC.Core.Transform.Trim+        ( trimX, trimClosures )+where+import DDC.Core.Collect()+import DDC.Type.Collect+import DDC.Core.Exp+import DDC.Type.Env+import DDC.Core.Transform.Reannotate+import Data.List                (nubBy)+++-- | Trim the expressions of a weaken closure @(XCast CastWeakenClosure)@+--   into only the free variables.+--+--   For example,+--    @trimClosures [build (\k z. something k), else]+--       = [build, something, else]+--    @+trimClosures+        :: (Ord n)+        => a+        -> [Exp a n]+        -> [Exp a n]++trimClosures a xs+ = {-# SCC trimClosures #-}+   nub' $ concatMap (freeExp a empty empty) xs+ where  nub' = nubBy (\x y -> reannotate (const ()) x == reannotate (const ()) y)+++-- | Trim an expression if it is a @weakclo@ cast. +--+--   Non-recursive version. If you want to recursively trim closures,+--   use @transformUpX' (const trimX)@.+trimX   :: (Ord n)+        => Exp a n+        -> Exp a n+trimX (XCast a (CastWeakenClosure ws) in_)+ = XCast a (CastWeakenClosure $ trimClosures a ws) in_++trimX x+ = x+++-- freeExp --------------------------------------------------------------------+-- | Collect all the free variables, but return them all as expressions:+--   eg+--   @+--     freeExp +--       (let i = 5 [R0#] () in+--        updateInt [:R0# R1#:] <w> i ...)+--+--     will return something like+--       [ XType (TCon R0#)+--       , XVar updateInt+--       , XType (TCon R0#)+--       , XType (TCon R1#)+--       , XWitness w ]+--   @+freeExp :: (BindStruct c, Ord n) +        => a+        -> Env n+        -> Env n+        -> c n+        -> [Exp a n]+freeExp a kenv tenv xx + = concatMap (freeOfTreeExp a kenv tenv) $ slurpBindTree xx++freeOfTreeExp+        :: Ord n+        => a+        -> Env n+        -> Env n+        -> BindTree n+        -> [Exp a n]+freeOfTreeExp a kenv tenv tt+ = case tt of+        BindDef way bs ts+         |  isBoundExpWit $ boundLevelOfBindWay way+         ,  tenv'        <- extends bs tenv+         -> concatMap (freeOfTreeExp a kenv tenv') ts++        BindDef way bs ts+         |  BoundSpec    <- boundLevelOfBindWay way+         ,  kenv'        <- extends bs kenv+         -> concatMap (freeOfTreeExp a kenv' tenv) ts++        BindDef _ _ ts+         -> concatMap (freeOfTreeExp a kenv tenv) ts++        BindUse BoundExp u+         | member u tenv     -> []+         | otherwise         -> [XVar a u]++        BindUse BoundWit u+         | member u tenv     -> []+         | otherwise         -> [XWitness (WVar u)]++        BindUse BoundSpec u+         | member u kenv     -> []+         | otherwise         -> [XType (TVar u)]++        BindCon BoundSpec u (Just k)+         | member u kenv     -> []+         | otherwise         -> [XType (TCon (TyConBound u k))]++        _                    -> []+
+ DDC/Type/Bind.hs view
@@ -0,0 +1,31 @@++module DDC.Type.Bind+        (getBindType)+where+import DDC.Type.Exp+++-- | Lookup the type of a bound thing from the binder stack.+--   The binder stack contains the binders of all the `TForall`s we've+--   entered under so far.+getBindType :: Eq n => [Bind n] -> Bound n -> Maybe (Int, Type n)+getBindType bs' u'+ = go 0 u' bs'+ where  go n u (BName n1 t : bs)+         | UName n2     <- u+         , n1 == n2     = Just (n, t)++         | otherwise    = go (n + 1) u bs++        go n (UIx i)    (BAnon t   : bs)+         | i < 0        = Nothing+         | i == 0       = Just (n, t)+         | otherwise    = go (n + 1) (UIx (i - 1)) bs++        go n u          (BAnon _   : bs)+         | otherwise    = go (n + 1) u bs++        go n u (BNone _   : bs)+         = go (n + 1) u bs++        go _ _ []       = Nothing
DDC/Type/Check.hs view
@@ -12,23 +12,23 @@           -- * Errors         , Error(..)) where-import DDC.Type.Check.CheckError+import DDC.Type.DataDef+import DDC.Type.Check.Error+import DDC.Type.Check.ErrorMessage      () import DDC.Type.Check.CheckCon import DDC.Type.Compounds import DDC.Type.Predicates-import DDC.Type.Transform.LiftT-import DDC.Core.DataDef import DDC.Type.Exp import DDC.Base.Pretty import Data.List import Control.Monad-import DDC.Type.Check.Monad             (throw, result)-import DDC.Type.Pretty                  ()-import DDC.Type.Env                     (Env)-import qualified DDC.Type.Sum           as TS-import qualified DDC.Type.Env           as Env-import qualified DDC.Type.Check.Monad   as G-import qualified Data.Map               as Map+import DDC.Type.Pretty                   ()+import DDC.Type.Env                      (KindEnv)+import DDC.Control.Monad.Check           (throw, result)+import qualified DDC.Control.Monad.Check as G+import qualified DDC.Type.Sum            as TS+import qualified DDC.Type.Env            as Env+import qualified Data.Map                as Map   -- | The type checker monad.@@ -37,9 +37,9 @@  -- Wrappers ------------------------------------------------------------------- -- | Check a type in the given environment, returning an error or its kind.-checkType  :: (Ord n, Pretty n) +checkType  :: (Ord n, Show n, Pretty n)             => DataDefs n -           -> Env n +           -> KindEnv n             -> Type n             -> Either (Error n) (Kind n) @@ -48,7 +48,7 @@   -- | Check a type in an empty environment, returning an error or its kind.-kindOfType :: (Ord n, Pretty n) +kindOfType :: (Ord n, Show n, Pretty n)             => DataDefs n            -> Type n             -> Either (Error n) (Kind n)@@ -65,55 +65,22 @@ --   that need to be compared up to alpha-equivalence, nor do they contain --   crushable components terms. checkTypeM -        :: (Ord n, Pretty n) +        :: (Ord n, Show n, Pretty n)          => DataDefs n-        -> Env n+        -> KindEnv n         -> Type n          -> CheckM n (Kind n)  checkTypeM defs env tt         = -- trace (pretty $ text "checkTypeM:" <+> ppr tt) $+          {-# SCC checkTypeM #-}           checkTypeM' defs env tt  -- Variables ------------------ checkTypeM' _defs env (TVar u)- = do   let tBound      = typeOfBound u-        let mtEnv       = Env.lookup u env--        let mkResult-                -- If the annot is Bot then just use the type-                -- from the environment.-                | Just tEnv     <- mtEnv-                , isBot tBound-                = return tEnv--                -- The bound has an explicit type annotation,-                --  which matches the one from the environment.-                -- -                --  When the bound is a deBruijn index we need to lift the-                --  annotation on the original binder through any lambdas-                --  between the binding occurrence and the use.-                | Just tEnv    <- mtEnv-                , UIx i _      <- u-                , tBound == liftT (i + 1) tEnv-                = return tBound--                -- The bound has an explicit type annotation,-                --   that matches the one from the environment.-                | Just tEnv     <- mtEnv-                , tBound == tEnv-                = return tBound--                -- The bound has an explicit type annotation,-                --  that does not match the one from the environment. -                | Just tEnv     <- mtEnv-                = throw $ ErrorVarAnnotMismatch u tEnv--                -- Type variables must be in the environment.-                | _             <- mtEnv-                = throw $ ErrorUndefined u--        mkResult+ = case Env.lookup u env of+        Just t  -> return t+        Nothing -> throw $ ErrorUndefined u  -- Constructors --------------- checkTypeM' defs _env tt@(TCon tc)@@ -132,17 +99,17 @@         TyConSpec    tcc -> return $ kindOfTcCon tcc          -- User defined type constructors need to be in the set of data defs.-        TyConBound    u  +        TyConBound   u k          -> case u of-                UName n _+                UName n                  | Just _ <- Map.lookup n (dataDefsTypes defs)-                 -> return $ typeOfBound u+                 -> return k                   | otherwise                  -> throw $ ErrorUndefinedCtor u -                UPrim{} -> return $ typeOfBound u-                UIx{}   -> error "sorry"+                UPrim{} -> return k+                UIx{}   -> throw $ ErrorUndefinedCtor u   -- Quantifiers ----------------
DDC/Type/Check/CheckCon.hs view
@@ -14,18 +14,18 @@ takeKindOfTyCon tt  = case tt of                 -- Sorts don't have a higher classification.-        TyConSort    _  -> Nothing+        TyConSort    _   -> Nothing  -        TyConKind    kc -> takeSortOfKiCon kc-        TyConWitness tc -> Just $ kindOfTwCon tc-        TyConSpec    tc -> Just $ kindOfTcCon tc-        TyConBound   u  -> Just $ typeOfBound u+        TyConKind    kc  -> takeSortOfKiCon kc+        TyConWitness tc  -> Just $ kindOfTwCon tc+        TyConSpec    tc  -> Just $ kindOfTcCon tc+        TyConBound  _u k -> Just k   -- | Take the superkind of an atomic kind constructor. -----   * Yields `Nothing` for the kind function (~>) as it doesn't have a sort---     without being fully applied.+--   Yields `Nothing` for the kind function (~>) as it doesn't have a sort+--   without being fully applied. takeSortOfKiCon :: KiCon -> Maybe (Sort n) takeSortOfKiCon kc  = case kc of@@ -41,24 +41,27 @@ kindOfTwCon :: TwCon -> Kind n kindOfTwCon tc  = case tc of-        TwConImpl       -> kWitness `kFun` (kWitness `kFun` kWitness)-        TwConPure       -> kEffect  `kFun` kWitness-        TwConEmpty      -> kClosure `kFun` kWitness-        TwConGlobal     -> kRegion  `kFun` kWitness-        TwConDeepGlobal -> kData    `kFun` kWitness-        TwConConst      -> kRegion  `kFun` kWitness-        TwConDeepConst  -> kData    `kFun` kWitness-        TwConMutable    -> kRegion  `kFun` kWitness-        TwConDeepMutable-> kData    `kFun` kWitness-        TwConLazy       -> kRegion  `kFun` kWitness-        TwConHeadLazy   -> kData    `kFun` kWitness-        TwConManifest   -> kRegion  `kFun` kWitness+        TwConImpl       -> kWitness  `kFun`  kWitness `kFun` kWitness+        TwConPure       -> kEffect   `kFun`  kWitness+        TwConEmpty      -> kClosure  `kFun`  kWitness+        TwConGlobal     -> kRegion   `kFun`  kWitness+        TwConDeepGlobal -> kData     `kFun`  kWitness+        TwConConst      -> kRegion   `kFun`  kWitness+        TwConDeepConst  -> kData     `kFun`  kWitness+        TwConMutable    -> kRegion   `kFun`  kWitness+        TwConDeepMutable-> kData     `kFun`  kWitness+        TwConLazy       -> kRegion   `kFun`  kWitness+        TwConHeadLazy   -> kData     `kFun`  kWitness+        TwConManifest   -> kRegion   `kFun`  kWitness+        TwConDisjoint	  -> kEffect   `kFun`  kEffect  `kFun`  kWitness+        TwConDistinct n -> (replicate n kRegion)      `kFuns` kWitness           -- | Take the kind of a computation type constructor. kindOfTcCon :: TcCon -> Kind n kindOfTcCon tc  = case tc of+        TcConUnit       -> kData         TcConFun        -> [kData, kEffect, kClosure, kData] `kFuns` kData         TcConRead       -> kRegion  `kFun` kEffect         TcConHeadRead   -> kData    `kFun` kEffect
− DDC/Type/Check/CheckError.hs
@@ -1,141 +0,0 @@-{-# OPTIONS_HADDOCK hide #-}--- | Errors produced when checking types.-module DDC.Type.Check.CheckError-        (Error(..))-where-import DDC.Type.Exp-import DDC.Type.Compounds-import DDC.Type.Pretty----- Error --------------------------------------------------------------------------------------------- | Type errors.-data Error n--        -- | An undefined type variable.-        = ErrorUndefined        -        { errorBound            :: Bound n }--        -- | An undefined type constructor.-        | ErrorUndefinedCtor-        { errorBound            :: Bound n }--        -- | The kind annotation on the variables does not match the one in the environment.-        | ErrorVarAnnotMismatch-        { errorBound            :: Bound n-        , errorTypeEnv          :: Type n }--        -- | Found a naked sort constructor.-        | ErrorNakedSort-        { errorSort             :: Sort n }--        -- | Found an unapplied kind function constructor.-        | ErrorUnappliedKindFun --        -- | A type application where the parameter and argument kinds don't match.-        | ErrorAppArgMismatch   -        { errorChecking         :: Type n-        , errorParamKind        :: Kind n-        , errorArgKind          :: Kind n }--        -- | A type application where the thing being applied is not a function.-        | ErrorAppNotFun-        { errorChecking         :: Type n-        , errorFunType          :: Type n-        , errorFunTypeKind      :: Kind n-        , errorArgType          :: Type n-        , errorArgTypeKind      :: Kind n }--        -- | A type sum where the components have differing kinds.-        | ErrorSumKindMismatch-        { errorKindExpected     :: Kind n-        , errorTypeSum          :: TypeSum n-        , errorKinds            :: [Kind n] }-        -        -- | A type sum that does not have effect or closure kind.-        | ErrorSumKindInvalid-        { errorCheckingSum      :: TypeSum n-        , errorKind             :: Kind n }--        -- | A forall where the body does not have data or witness kind.-        | ErrorForallKindInvalid-        { errorChecking         :: Type n-        , errorBody             :: Type n-        , errorKind             :: Kind n }--        -- | A witness implication where the premise or conclusion has an invalid kind.-        | ErrorWitnessImplInvalid-        { errorChecking         :: Type n-        , errorLeftType         :: Type n-        , errorLeftKind         :: Kind n-        , errorRightType        :: Type n-        , errorRightKind        :: Kind n }-        deriving Show---instance (Eq n, Pretty n) => Pretty (Error n) where- ppr err-  = case err of-        ErrorUndefined u-         -> text "Undefined type variable:  " <> ppr u--        ErrorUndefinedCtor u-         -> text "Undefined type constructor:  " <> ppr u--        ErrorUnappliedKindFun -         -> text "Can't take sort of unapplied kind function constructor."-        -        ErrorNakedSort s-         -> text "Can't check a naked sort: " <> ppr s-        -        ErrorVarAnnotMismatch u t-         -> vcat [ text "Type mismatch in annotation."-                 , text "             Variable: "       <> ppr u-                 , text "       has annotation: "       <> (ppr $ typeOfBound u)-                 , text " which conflicts with: "       <> ppr t-                 , text "     from environment." ]- -        ErrorAppArgMismatch tt t1 t2-         -> vcat [ text "Core type mismatch in application."-                 , text "             type: " <> ppr t1-                 , text "   does not match: " <> ppr t2-                 , text "   in application: " <> ppr tt ]-         -        ErrorAppNotFun tt t1 k1 t2 k2-         -> vcat [ text "Core type mismatch in application."-                 , text "     cannot apply type: " <> ppr t2-                 , text "               of kind: " <> ppr k2-                 , text "  to non-function type: " <> ppr t1-                 , text "               of kind: " <> ppr k1-                 , text "         in appliction: " <> ppr tt]-                -        ErrorSumKindMismatch k ts ks-         -> vcat -              $  [ text "Core type mismatch in sum."-                 , text " found multiple types: " <> ppr ts-                 , text " with differing kinds: " <> ppr ks ]-                 ++ (if k /= tBot sComp-                        then [text "        expected kind: " <> ppr k ]-                        else [])-                -        ErrorSumKindInvalid ts k-         -> vcat [ text "Invalid kind for type sum."-                 , text "         the type sum: " <> ppr ts-                 , text "             has kind: " <> ppr k-                 , text "  but it must be ! or $" ]--        ErrorForallKindInvalid tt t k-         -> vcat [ text "Invalid kind for body of quantified type."-                 , text "        the body type: " <> ppr t-                 , text "             has kind: " <> ppr k-                 , text "  but it must be * or @" -                 , text "        when checking: " <> ppr tt ]-        -        ErrorWitnessImplInvalid tt t1 k1 t2 k2-         -> vcat [ text "Invalid args for witness implication."-                 , text "            left type: " <> ppr t1-                 , text "             has kind: " <> ppr k1-                 , text "           right type: " <> ppr t2-                 , text "             has kind: " <> ppr k2 -                 , text "        when checking: " <> ppr tt ]-                
+ DDC/Type/Check/Error.hs view
@@ -0,0 +1,71 @@++-- | Errors produced when checking types.+module DDC.Type.Check.Error+        (Error(..))+where+import DDC.Type.Exp+++-- | Things that can go wrong when checking the kind of at type.+data Error n++        -- | An undefined type variable.+        = ErrorUndefined        +        { errorBound            :: Bound n }++        -- | An undefined type constructor.+        | ErrorUndefinedCtor+        { errorBound            :: Bound n }++        -- | The kind annotation on the variables does not match the one in the environment.+        | ErrorVarAnnotMismatch+        { errorBound            :: Bound n+        , errorTypeEnv          :: Type n }++        -- | Found a naked sort constructor.+        | ErrorNakedSort+        { errorSort             :: Sort n }++        -- | Found an unapplied kind function constructor.+        | ErrorUnappliedKindFun ++        -- | A type application where the parameter and argument kinds don't match.+        | ErrorAppArgMismatch   +        { errorChecking         :: Type n+        , errorParamKind        :: Kind n+        , errorArgKind          :: Kind n }++        -- | A type application where the thing being applied is not a function.+        | ErrorAppNotFun+        { errorChecking         :: Type n+        , errorFunType          :: Type n+        , errorFunTypeKind      :: Kind n+        , errorArgType          :: Type n+        , errorArgTypeKind      :: Kind n }++        -- | A type sum where the components have differing kinds.+        | ErrorSumKindMismatch+        { errorKindExpected     :: Kind n+        , errorTypeSum          :: TypeSum n+        , errorKinds            :: [Kind n] }+        +        -- | A type sum that does not have effect or closure kind.+        | ErrorSumKindInvalid+        { errorCheckingSum      :: TypeSum n+        , errorKind             :: Kind n }++        -- | A forall where the body does not have data or witness kind.+        | ErrorForallKindInvalid+        { errorChecking         :: Type n+        , errorBody             :: Type n+        , errorKind             :: Kind n }++        -- | A witness implication where the premise or conclusion has an invalid kind.+        | ErrorWitnessImplInvalid+        { errorChecking         :: Type n+        , errorLeftType         :: Type n+        , errorLeftKind         :: Kind n+        , errorRightType        :: Type n+        , errorRightKind        :: Kind n }+        deriving Show+
+ DDC/Type/Check/ErrorMessage.hs view
@@ -0,0 +1,75 @@++-- | Errors produced when checking types.+module DDC.Type.Check.ErrorMessage+where+import DDC.Type.Check.Error+import DDC.Type.Compounds+import DDC.Type.Pretty+++instance (Eq n, Show n, Pretty n) => Pretty (Error n) where+ ppr err+  = case err of+        ErrorUndefined u+         -> text "Undefined type variable:  " <> ppr u++        ErrorUndefinedCtor u+         -> text "Undefined type constructor:  " <> ppr u++        ErrorUnappliedKindFun +         -> text "Can't take sort of unapplied kind function constructor."+        +        ErrorNakedSort s+         -> text "Can't check a naked sort: " <> ppr s+        +        ErrorVarAnnotMismatch u t+         -> vcat [ text "Type mismatch in annotation."+                 , text "             Variable: "       <> ppr u+                 , text "       has annotation: "       <> ppr u+                 , text " which conflicts with: "       <> ppr t+                 , text "     from environment." ]+ +        ErrorAppArgMismatch tt t1 t2+         -> vcat [ text "Core type mismatch in application."+                 , text "             type: " <> ppr t1+                 , text "   does not match: " <> ppr t2+                 , text "   in application: " <> ppr tt ]+         +        ErrorAppNotFun tt t1 k1 t2 k2+         -> vcat [ text "Core type mismatch in application."+                 , text "     cannot apply type: " <> ppr t2+                 , text "               of kind: " <> ppr k2+                 , text "  to non-function type: " <> ppr t1+                 , text "               of kind: " <> ppr k1+                 , text "         in appliction: " <> ppr tt]+                +        ErrorSumKindMismatch k ts ks+         -> vcat +              $  [ text "Core type mismatch in sum."+                 , text " found multiple types: " <> ppr ts+                 , text " with differing kinds: " <> ppr ks ]+                 ++ (if k /= tBot sComp+                        then [text "        expected kind: " <> ppr k ]+                        else [])+                +        ErrorSumKindInvalid ts k+         -> vcat [ text "Invalid kind for type sum."+                 , text "         the type sum: " <> ppr ts+                 , text "             has kind: " <> ppr k+                 , text "  but it must be ! or $" ]++        ErrorForallKindInvalid tt t k+         -> vcat [ text "Invalid kind for body of quantified type."+                 , text "        the body type: " <> ppr t+                 , text "             has kind: " <> ppr k+                 , text "  but it must be * or @" +                 , text "        when checking: " <> ppr tt ]+        +        ErrorWitnessImplInvalid tt t1 k1 t2 k2+         -> vcat [ text "Invalid args for witness implication."+                 , text "            left type: " <> ppr t1+                 , text "             has kind: " <> ppr k1+                 , text "           right type: " <> ppr t2+                 , text "             has kind: " <> ppr k2 +                 , text "        when checking: " <> ppr tt ]+                
− DDC/Type/Check/Monad.hs
@@ -1,28 +0,0 @@--module DDC.Type.Check.Monad-        ( CheckM (..)-        , throw-        , result)-where---- | Type checking monad.-data CheckM err a-        = CheckM (Either err a)--instance Monad (CheckM err) where- return x   = CheckM (Right x)- (>>=) m f  -  = case m of-          CheckM (Left err)     -> CheckM (Left err)-          CheckM (Right x)      -> f x--          --- | Throw a type error in the monad.-throw :: err -> CheckM err a-throw e       = CheckM $ Left e----- | Take the result from a check monad.-result :: CheckM err a -> Either err a-result (CheckM r)       = r-
+ DDC/Type/Collect.hs view
@@ -0,0 +1,185 @@++-- | Collecting sets of variables and constructors.+module DDC.Type.Collect+        ( freeT+        , collectBound+        , collectBinds+        , BindTree   (..)+        , BindWay    (..)+        , BindStruct (..)++        , BoundLevel (..)+        , isBoundExpWit+        , boundLevelOfBindWay+        , bindDefT)+where+import DDC.Type.Exp+import DDC.Type.Env                     (Env)+import qualified DDC.Type.Env           as Env+import qualified DDC.Type.Sum           as Sum+import qualified Data.Set               as Set+import Data.Set                         (Set)+++-- freeT ----------------------------------------------------------------------+-- | Collect the free Spec variables in a thing (level-1).+freeT   :: (BindStruct c, Ord n) +        => Env n -> c n -> Set (Bound n)+freeT tenv xx = Set.unions $ map (freeOfTreeT tenv) $ slurpBindTree xx++freeOfTreeT :: Ord n => Env n -> BindTree n -> Set (Bound n)+freeOfTreeT kenv tt+ = case tt of+        BindDef way bs ts+         |  BoundSpec   <- boundLevelOfBindWay way+         ,  kenv'       <- Env.extends bs kenv+         -> Set.unions $ map (freeOfTreeT kenv') ts++        BindDef _ _ ts+         -> Set.unions $ map (freeOfTreeT kenv) ts++        BindUse BoundSpec u+         | Env.member u kenv -> Set.empty+         | otherwise         -> Set.singleton u+        _                    -> Set.empty+++-- collectBound ---------------------------------------------------------------+-- | Collect all the bound variables in a thing, +--   independent of whether they are free or not.+collectBound :: (BindStruct c, Ord n) => c n -> Set (Bound n)+collectBound +        = Set.unions . map collectBoundOfTree . slurpBindTree ++collectBoundOfTree :: Ord n => BindTree n -> Set (Bound n)+collectBoundOfTree tt+ = case tt of+        BindDef _ _ ts  -> Set.unions $ map collectBoundOfTree ts+        BindUse _ u     -> Set.singleton u+        BindCon _ u _   -> Set.singleton u+++-- collectSpecBinds -----------------------------------------------------------+-- | Collect all the spec and exp binders in a thing.+collectBinds +        :: (BindStruct c, Ord n) +        => c n +        -> ([Bind n], [Bind n])++collectBinds thing+ = let  tree    = slurpBindTree thing+   in   ( concatMap collectSpecBindsOfTree tree+        , concatMap collectExpBindsOfTree  tree)+        ++collectSpecBindsOfTree :: Ord n => BindTree n -> [Bind n]+collectSpecBindsOfTree tt+ = case tt of+        BindDef way bs ts+         |   BoundSpec <- boundLevelOfBindWay way+         ->  concat ( bs+                    : map collectSpecBindsOfTree ts)++         | otherwise+         ->  concatMap collectSpecBindsOfTree ts++        _ -> []+++collectExpBindsOfTree :: Ord n => BindTree n -> [Bind n]+collectExpBindsOfTree tt+ = case tt of+        BindDef way bs ts+         |   BoundExp <- boundLevelOfBindWay way+         ->  concat ( bs+                    : map collectExpBindsOfTree ts)++         | otherwise+         ->  concatMap collectExpBindsOfTree ts++        _ -> []+++-------------------------------------------------------------------------------+-- | A description of the binding structure of some type or expression.+data BindTree n+        -- | An abstract binding expression.+        = BindDef BindWay    [Bind n] [BindTree n]++        -- | Use of a variable.+        | BindUse BoundLevel (Bound n)++        -- | Use of a constructor.+        | BindCon BoundLevel (Bound n) (Maybe (Kind n))+        deriving (Eq, Show)+++-- | Describes how a variable was bound.+data BindWay+        = BindForall+        | BindLAM+        | BindLam+        | BindLet+        | BindLetRec+        | BindLetRegions+        | BindLetRegionWith+        | BindCasePat+        deriving (Eq, Show)+++-- | What level this binder is at.+data BoundLevel+        = BoundSpec+        | BoundExp+        | BoundWit+        deriving (Eq, Show)+++-- | Check if a boundlevel is expression or witness+isBoundExpWit :: BoundLevel -> Bool+isBoundExpWit BoundExp = True+isBoundExpWit BoundWit = True+isBoundExpWit _        = False+++-- | Get the `BoundLevel` corresponding to a `BindWay`.+boundLevelOfBindWay :: BindWay -> BoundLevel+boundLevelOfBindWay way+ = case way of+        BindForall              -> BoundSpec+        BindLAM                 -> BoundSpec+        BindLam                 -> BoundExp+        BindLet                 -> BoundExp+        BindLetRec              -> BoundExp+        BindLetRegions          -> BoundSpec+        BindLetRegionWith       -> BoundExp+        BindCasePat             -> BoundExp+++-- BindStruct -----------------------------------------------------------------+class BindStruct (c :: * -> *) where+ slurpBindTree :: c n -> [BindTree n]+++instance BindStruct Type where+ slurpBindTree tt+  = case tt of+        TVar u          -> [BindUse BoundSpec u]+        TCon tc         -> slurpBindTree tc+        TForall b t     -> [bindDefT BindForall [b] [t]]+        TApp t1 t2      -> slurpBindTree t1 ++ slurpBindTree t2+        TSum ts         -> concatMap slurpBindTree $ Sum.toList ts+++instance BindStruct TyCon where+ slurpBindTree tc+  = case tc of+        TyConBound u k  -> [BindCon BoundSpec u (Just k)]+        _               -> []+++-- | Helper for constructing the `BindTree` for a type binder.+bindDefT :: BindStruct c+         => BindWay -> [Bind n] -> [c n] -> BindTree n+bindDefT way bs xs+        = BindDef way bs $ concatMap slurpBindTree xs
+ DDC/Type/Collect/FreeT.hs view
@@ -0,0 +1,47 @@++module DDC.Type.Collect.FreeT+        (FreeVarConT(..))+where+import DDC.Type.Exp+import Data.Set                 (Set)+import DDC.Type.Env             (KindEnv)+import qualified DDC.Type.Env   as Env+import qualified DDC.Type.Sum   as Sum+import qualified Data.Set       as Set+++class FreeVarConT (c :: * -> *) where+  -- | Collect the free type variables and constructors used in a thing.+  freeVarConT +        :: Ord n +        => KindEnv n -> c n +        -> (Set (Bound n), Set (Bound n))+++instance FreeVarConT Type where+ freeVarConT kenv tt+  = case tt of+        TVar u  +         -> if Env.member u kenv+                then (Set.empty, Set.empty)+                else (Set.singleton u, Set.empty)++        TCon tc+         | TyConBound u _ <- tc -> (Set.empty, Set.singleton u)+         | otherwise            -> (Set.empty, Set.empty)++        TForall b t+         -> freeVarConT (Env.extend b kenv) t++        TApp t1 t2+         -> let (vs1, cs1)      = freeVarConT kenv t1+                (vs2, cs2)      = freeVarConT kenv t2+            in  ( Set.union vs1 vs2+                , Set.union cs1 cs2)++        TSum ts+         -> let (vss, css)      = unzip $ map (freeVarConT kenv) +                                $ Sum.toList ts+            in  (Set.unions vss, Set.unions css)++
DDC/Type/Compounds.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS -fno-warn-missing-signatures #-} module DDC.Type.Compounds-        ( -- * Binds+        (  -- * Binds           takeNameOfBind         , typeOfBind         , replaceTypeOfBind@@ -11,31 +11,53 @@         , partitionBindsByType                    -- * Bounds-        , typeOfBound         , takeNameOfBound-        , replaceTypeOfBound         , boundMatchesBind         , namedBoundMatchesBind         , takeSubstBoundOfBind+        , takeSubstBoundsOfBinds -          -- * Type structure-        , tIx-        , tApp,          ($:)-        , tApps,         takeTApps-        , takeTyConApps, takeDataTyConApps+          -- * Kinds+        , kFun+        , kFuns+        , takeKFun+        , takeKFuns+        , takeKFuns'+        , takeResultKind++         -- * Quantifiers         , tForall-        , tForalls,      takeTForalls+        , tForalls,      takeTForalls,  eraseTForalls++          -- * Sums         , tBot         , tSum -          -- * Function type construction-        , kFun-        , kFuns,        takeKFun-        , takeKFuns,    takeKFuns',     takeResultKind-        , tFun,         takeTFun,       takeTFunArgResult+          -- * Applications+        , tApp,          ($:)+        , tApps,         takeTApps+        , takeTyConApps+        , takePrimTyConApps+        , takeDataTyConApps+        , takePrimeRegion++          -- * Functions+        , tFun         , tFunPE+        , takeTFun+        , takeTFunArgResult+        , takeTFunWitArgResult+        , arityOfType++          -- * Implications         , tImpl +          -- * Units+        , tUnit++          -- * Variables+        , tIx+           -- * Sort construction         , sComp, sProp @@ -47,15 +69,16 @@         , tWrite,       tDeepWrite         , tAlloc,       tDeepAlloc -          -- * Closure type constructors.+          -- * Closure type constructors         , tUse,         tDeepUse -          -- * Witness type constructors.+          -- * Witness type constructors         , tPure         , tEmpty         , tGlobal,      tDeepGlobal         , tConst,       tDeepConst         , tMutable,     tDeepMutable+        , tDistinct         , tLazy,        tHeadLazy         , tManifest         , tConData0,    tConData1)@@ -123,32 +146,14 @@   -- Bounds ------------------------------------------------------------------------ | Take the type of a bound variable.-typeOfBound :: Bound n -> Type n-typeOfBound uu- = case uu of-        UName _ t       -> t-        UPrim _ t       -> t-        UIx   _ t       -> t-- -- | Take the name of bound variable. --   If this is a deBruijn index then there won't be a name. takeNameOfBound :: Bound n -> Maybe n takeNameOfBound uu  = case uu of-        UName n _       -> Just n+        UName n         -> Just n         UPrim n _       -> Just n-        UIx _ _         -> Nothing----- | Replace the type of a bound with a new one.-replaceTypeOfBound :: Type n -> Bound n -> Bound n-replaceTypeOfBound t uu- = case uu of-        UName n _       -> UName n t-        UPrim n _       -> UPrim n t-        UIx   i _       -> UIx   i t+        UIx{}           -> Nothing   -- | Check whether a bound maches a bind.@@ -158,9 +163,9 @@ boundMatchesBind :: Eq n => Bound n -> Bind n -> Bool boundMatchesBind u b  = case (u, b) of-        (UName n1 _, BName n2 _) -> n1 == n2-        (UIx 0 _,    BAnon _   ) -> True-        _                        -> False+        (UName n1, BName n2 _)  -> n1 == n2+        (UIx 0,    BAnon _)     -> True+        _                       -> False   -- | Check whether a named bound matches a named bind. @@ -168,27 +173,36 @@ namedBoundMatchesBind :: Eq n => Bound n -> Bind n -> Bool namedBoundMatchesBind u b  = case (u, b) of-        (UName n1 _, BName n2 _) -> n1 == n2-        _                        -> False-+        (UName n1, BName n2 _)  -> n1 == n2+        _                       -> False  --- | Convert a `Bound` to a `Bind`, ready for substitution.+-- | Convert a `Bind` to a `Bound`, ready for substitution. --    --   Returns `UName` for `BName`, @UIx 0@ for `BAnon`  --   and `Nothing` for `BNone`, because there's nothing to substitute. takeSubstBoundOfBind :: Bind n -> Maybe (Bound n) takeSubstBoundOfBind bb  = case bb of-        BName n t       -> Just $ UName n t-        BAnon t         -> Just $ UIx 0 t+        BName n _       -> Just $ UName n +        BAnon _         -> Just $ UIx 0          BNone _         -> Nothing  +-- | Convert some `Bind`s to `Bounds`+takeSubstBoundsOfBinds :: [Bind n] -> [Bound n]+takeSubstBoundsOfBinds bs+ = go 0 bs+ where  go _level []               = []+        go level (BName n _ : bs') = UName n   : go level bs'+        go level (BAnon _   : bs') = UIx level : go (level + 1) bs'+        go level (BNone _   : bs') =             go level bs'++             -- Variables ------------------------------------------------------------------ -- | Construct a deBruijn index. tIx :: Kind n -> Int -> Type n-tIx k i         = TVar (UIx i k)+tIx _ i         = TVar (UIx i)   -- Applications ---------------------------------------------------------------@@ -226,35 +240,58 @@   -- | Flatten a sequence of type applications, returning the type constructor+--   and arguments, if there is one. Only accept primitive type constructors.+takePrimTyConApps :: Type n -> Maybe (n, [Type n])+takePrimTyConApps tt+ = case takeTApps tt of+        TCon tc : args  +         | TyConBound (UPrim n _) _     <- tc+         -> Just (n, args)++        _ -> Nothing+++-- | Flatten a sequence of type applications, returning the type constructor --   and arguments, if there is one. Only accept data type constructors. takeDataTyConApps :: Type n -> Maybe (TyCon n, [Type n]) takeDataTyConApps tt  = case takeTApps tt of         TCon tc : args  -         | TyConBound (UName _ t)       <- tc-         , TCon (TyConKind KiConData)   <- takeResultKind t+         | TyConBound (UName _) k       <- tc+         , TCon (TyConKind KiConData)   <- takeResultKind k          -> Just (tc, args) -         | TyConBound (UPrim _ t)       <- tc-         , TCon (TyConKind KiConData)   <- takeResultKind t+         | TyConBound  UPrim{}  k       <- tc+         , TCon (TyConKind KiConData)   <- takeResultKind k          -> Just (tc, args)          _ -> Nothing  +-- | Take the prime region variable of a data type.+--   This corresponds to the region the outermost constructor is allocated into.+takePrimeRegion :: Type n -> Maybe (Type n)+takePrimeRegion tt+ = case takeTApps tt of+        TCon _ : tR@(TVar _) : _+          -> Just tR++        _ -> Nothing++ -- Foralls -------------------------------------------------------------------- -- | Build an anonymous type abstraction, with a single parameter. tForall :: Kind n -> (Type n -> Type n) -> Type n tForall k f-        = TForall (BAnon k) (f (TVar (UIx 0 k)))+        = TForall (BAnon k) (f (TVar (UIx 0)))   -- | Build an anonymous type abstraction, with several parameters. tForalls  :: [Kind n] -> ([Type n] -> Type n) -> Type n tForalls ks f  = let  bs      = [BAnon k | k <- ks]-        us      = reverse [TVar (UIx n  k) | k <- ks | n <- [0..]]-   in   foldr TForall (f us) bs+        us      = map (\i -> TVar (UIx i)) [0.. (length ks - 1)]+   in   foldr TForall (f $ reverse us) bs   -- | Split nested foralls from the front of a type, @@ -268,17 +305,33 @@          (bs, body)     -> Just (bs, body)  +-- | Erase all `TForall` quantifiers from a type.+eraseTForalls :: Ord n => Type n -> Type n+eraseTForalls tt+ = case tt of+        TVar{}          -> tt+        TCon{}          -> tt+        TForall _ t     -> eraseTForalls t+        TApp t1 t2      -> TApp (eraseTForalls t1) (eraseTForalls t2)+        TSum ts         -> TSum $ Sum.fromList (Sum.kindOfSum ts) +                                $ map eraseTForalls $ Sum.toList ts++ -- Sums ----------------------------------------------------------------------- tSum :: Ord n => Kind n -> [Type n] -> Type n tSum k ts         = TSum (Sum.fromList k ts)  +-- Unit -----------------------------------------------------------------------+tUnit :: Type n+tUnit           = TCon (TyConSpec TcConUnit)++ -- Function Constructors ------------------------------------------------------ -- | Construct a kind function. kFun :: Kind n -> Kind n -> Kind n kFun k1 k2      = ((TCon $ TyConKind KiConFun)`TApp` k1) `TApp` k2- infixr `kFun`  @@ -330,7 +383,6 @@ tFun    :: Type n -> Effect n -> Closure n -> Type n -> Type n tFun t1 eff clo t2         = (TCon $ TyConSpec TcConFun) `tApps` [t1, eff, clo, t2]- infixr `tFun`  @@ -343,8 +395,8 @@         _ -> Nothing  --- | Destruct the type of a value function, returning just the argument---   and result types.+-- | Destruct the type of a function,+--   returning just the argument and result types. takeTFunArgResult :: Type n -> ([Type n], Type n) takeTFunArgResult tt  = case tt of@@ -354,17 +406,40 @@          _ -> ([], tt) +-- | Destruct the type of a function,+--   returning the witness argument, value argument and result types.+--   The function type must have the witness implications before +--   the value arguments, eg  @T1 => T2 -> T3 -> T4 -> T5@.+takeTFunWitArgResult :: Type n -> ([Type n], [Type n], Type n)+takeTFunWitArgResult tt+ = case tt of+        TApp (TApp (TCon (TyConWitness TwConImpl)) t1) t2+         ->  let (twsMore, tvsMore, tResult) = takeTFunWitArgResult t2+             in  (t1 : twsMore, tvsMore, tResult) +        _ -> let (tvsMore, tResult)          = takeTFunArgResult tt+             in  ([], tvsMore, tResult)+++-- | Determine the arity of an expression by looking at its type.+--   Count all the function arrows, and foralls.+arityOfType :: Type n -> Int+arityOfType tt+ = case tt of+        TForall _ t     -> 1 + arityOfType t+        t               -> length $ fst $ takeTFunArgResult t++ -- | Construct a pure and empty value type function. tFunPE  :: Type n -> Type n -> Type n tFunPE t1 t2    = tFun t1 (tBot kEffect) (tBot kClosure) t2+infixr `tFunPE`   -- | Construct a witness implication type. tImpl :: Type n -> Type n -> Type n tImpl t1 t2               = ((TCon $ TyConWitness TwConImpl) `tApp` t1) `tApp` t2- infixr `tImpl`  @@ -405,6 +480,7 @@ tDeepConst      = twCon1 TwConDeepConst tMutable        = twCon1 TwConMutable tDeepMutable    = twCon1 TwConDeepMutable+tDistinct n     = twCon2 (TwConDistinct n) tLazy           = twCon1 TwConLazy tHeadLazy       = twCon1 TwConHeadLazy tManifest       = twCon1 TwConManifest@@ -412,14 +488,16 @@ tcCon1 tc t  = (TCon $ TyConSpec    tc) `tApp` t twCon1 tc t  = (TCon $ TyConWitness tc) `tApp` t +twCon2 tc ts = tApps (TCon $ TyConWitness tc) ts + -- | Build a nullary type constructor of the given kind. tConData0 :: n -> Kind n -> Type n-tConData0 n k    = TCon (TyConBound (UName n k))+tConData0 n k   = TCon (TyConBound (UName n) k)   -- | Build a type constructor application of one argumnet. tConData1 :: n -> Kind n -> Type n -> Type n-tConData1 n k t1 = TApp (TCon (TyConBound (UName n k))) t1+tConData1 n k t1 = TApp (TCon (TyConBound (UName n) k)) t1  
+ DDC/Type/DataDef.hs view
@@ -0,0 +1,142 @@++-- | Algebraic data type definitions.+module DDC.Type.DataDef+        ( DataDef    (..)++        -- * Data type definition table+        , DataDefs   (..)+        , DataMode   (..)+        , DataType   (..)+        , DataCtor   (..)++        , emptyDataDefs+        , insertDataDef+        , fromListDataDefs+        , lookupModeOfDataType)+where+import DDC.Type.Exp+import Data.Map                         (Map)+import qualified Data.Map.Strict        as Map+import Data.Maybe+import Control.Monad+++-- | The definition of a single data type.+data DataDef n+        = DataDef+        { -- | Name of the data type.+          dataDefTypeName       :: !n++          -- | Kinds of type parameters.+        , dataDefParamKinds     :: ![Kind n]++          -- | Constructors of the data type, or Nothing if there are+          --   too many to list (like with `Int`).+        , dataDefCtors          :: !(Maybe [(n, [Type n])]) }+        deriving Show+++-- DataDefs -------------------------------------------------------------------+-- | A table of data type definitions,+--   unpacked into type and data constructors so we can find them easily.+data DataDefs n+        = DataDefs+        { dataDefsTypes :: !(Map n (DataType n))+        , dataDefsCtors :: !(Map n (DataCtor n)) }+        deriving Show+++-- | The mode of a data type records how many data constructors there are.+--   This can be set to 'Large' for large primitive types like Int and Float.+--   In this case we don't ever expect them all to be enumerated+--   as case alternatives.+data DataMode n+        = DataModeSmall ![n]+        | DataModeLarge+        deriving Show+++-- | Describes a data type constructor, used in the `DataDefs` table.+data DataType n+        = DataType +        { -- | Name of data type constructor.+          dataTypeName       :: !n++          -- | Kinds of type parameters to constructor.+        , dataTypeParamKinds :: ![Kind n]++          -- | Names of data constructors of this data type,+          --   or `Nothing` if it has infinitely many constructors.+        , dataTypeMode       :: !(DataMode n) }+        deriving Show+++-- | Describes a data constructor, used in the `DataDefs` table.+data DataCtor n+        = DataCtor+        { -- | Name of data constructor.+          dataCtorName       :: !n++          -- | Tag of constructor (order in data type declaration)+        , dataCtorTag        :: !Integer++          -- | Field types of constructor.+        , dataCtorFieldTypes :: ![Type n]++          -- | Name of result type of constructor.+        , dataCtorTypeName   :: !n }+        deriving Show+++-- | An empty table of data type definitions.+emptyDataDefs :: DataDefs n+emptyDataDefs+        = DataDefs+        { dataDefsTypes = Map.empty+        , dataDefsCtors = Map.empty }+++-- | Insert a data type definition into some DataDefs.+insertDataDef  :: Ord n => DataDef  n -> DataDefs n -> DataDefs n+insertDataDef (DataDef nType ks mCtors) dataDefs+ = let  defType = DataType+                { dataTypeName       = nType+                , dataTypeParamKinds = ks+                , dataTypeMode       = defMode }++        defMode = case mCtors of+                   Nothing    -> DataModeLarge+                   Just ctors -> DataModeSmall (map fst ctors)++        makeDefCtor tag (nCtor, tsFields)+                = DataCtor+                { dataCtorName       = nCtor+                , dataCtorTag        = tag+                , dataCtorFieldTypes = tsFields+                , dataCtorTypeName   = nType }++        defCtors = case mCtors of+                    Nothing  -> Nothing+                    Just cs  -> Just $ zipWith makeDefCtor [0..] cs++   in   dataDefs+         { dataDefsTypes = Map.insert nType defType (dataDefsTypes dataDefs)+         , dataDefsCtors = Map.union (dataDefsCtors dataDefs)+                         $ Map.fromList [(n, def) +                                | def@(DataCtor n _ _ _) <- concat $ maybeToList defCtors ]}+++-- | Build a `DataDefs` table from a list of `DataDef`+fromListDataDefs :: Ord n => [DataDef n] -> DataDefs n+fromListDataDefs defs+        = foldr insertDataDef emptyDataDefs defs++++-- | Yield the list of data constructor names for some data type, +--   or `Nothing` for large types with too many constructors to list.+lookupModeOfDataType :: Ord n => n -> DataDefs n -> Maybe (DataMode n)+lookupModeOfDataType n defs+        = liftM dataTypeMode $ Map.lookup n (dataDefsTypes defs)++
DDC/Type/Env.hs view
@@ -8,24 +8,43 @@ -- module DDC.Type.Env         ( Env(..)+        , KindEnv+        , TypeEnv++        -- * Construction         , empty-        , extend,       extends-        , setPrimFun,   isPrim-        , fromList+        , extend+        , extends         , union-        , member,       memberBind-        , lookup,       lookupName++        -- * Conversion+        , fromList+        , fromTypeMap++        -- * Projetions          , depth-        , lift-        , wrapTForalls)+        , member+        , memberBind+        , lookup+        , lookupName++        -- * Primitives+        , setPrimFun+        , isPrim++        -- * Lifting+        , wrapTForalls++        -- * Wrapping+        , lift) where import DDC.Type.Exp import DDC.Type.Transform.LiftT import Data.Maybe-import Data.Map                 (Map)-import Prelude                  hiding (lookup)-import qualified Data.Map       as Map-import qualified Prelude        as P+import Data.Map                         (Map)+import Prelude                          hiding (lookup)+import qualified Data.Map.Strict        as Map+import qualified Prelude                as P import Control.Monad  @@ -33,18 +52,26 @@ data Env n         = Env         { -- | Types of named binders.-          envMap         :: Map n (Type n)+          envMap         :: !(Map n (Type n))            -- | Types of anonymous deBruijn binders.-        , envStack       :: [Type n] +        , envStack       :: ![Type n]                     -- | The length of the above stack.-        , envStackLength :: Int+        , envStackLength :: !Int            -- | Types of baked in, primitive names.-        , envPrimFun     :: n -> Maybe (Type n) }+        , envPrimFun     :: !(n -> Maybe (Type n)) }  +-- | Type synonym to improve readability.+type KindEnv n  = Env n+++-- | Type synonym to improve readability.+type TypeEnv n  = Env n++ -- | An empty environment. empty :: Env n empty   = Env@@ -90,6 +117,12 @@         = foldr extend empty bs  +-- | Convert a map of names to types to a environment.+fromTypeMap :: Map n (Type n) -> Env n+fromTypeMap m+        = empty { envMap = m}++ -- | Combine two environments. --   If both environments have a binding with the same name, --   then the one in the second environment takes preference.@@ -121,15 +154,12 @@ lookup :: Ord n => Bound n -> Env n -> Maybe (Type n) lookup uu env  = case uu of-        UName n _+        UName n           ->      Map.lookup n (envMap env)           `mplus` envPrimFun env n -        UIx i _ -         -> P.lookup i (zip [0..] (envStack env))--        UPrim n _-         -> envPrimFun env n+        UIx i           -> P.lookup i (zip [0..] (envStack env))+        UPrim n _       -> envPrimFun env n   -- | Lookup a bound name from an environment.@@ -144,8 +174,13 @@   -- | Lift all free deBruijn indices in the environment by the given number of steps.---   TODO: Delay this, only lift when we extract the final type.---         will also need to update the 'member' function.+---+--  ISSUE #276: Delay lifting of indices in type environments.+--      The 'lift' function on type environments applies to every member of+--      the environment. We'd get better complexity by recording how many+--      levels all types should be lifted by, and only applying the real lift+--      function when the type is finally extracted.+-- lift  :: Ord n => Int -> Env n -> Env n lift n env         = Env
DDC/Type/Equiv.hs view
@@ -1,13 +1,12 @@  module DDC.Type.Equiv-        (equivT)+        ( equivT+        , equivWithBindsT) where-import DDC.Type.Exp-import DDC.Type.Compounds import DDC.Type.Transform.Crush-import DDC.Type.Transform.Trim-import DDC.Base.Pretty-import Data.Maybe+import DDC.Type.Compounds+import DDC.Type.Bind+import DDC.Type.Exp import qualified DDC.Type.Sum   as Sum  @@ -22,33 +21,42 @@ --     bound variables match the binders. If this is not the case then you get --     an indeterminate result. ---equivT  :: (Ord n, Pretty n) => Type n -> Type n -> Bool+equivT  :: Ord n => Type n -> Type n -> Bool equivT t1 t2-        = equivT' [] 0 [] 0 t1 t2-+        = equivWithBindsT [] [] t1 t2 -equivT' :: (Ord n, Pretty n)-        => [Bind n] -> Int-        -> [Bind n] -> Int-        -> Type n   -> Type n+-- | Like `equivT` but take the initial stacks of type binders.+equivWithBindsT+        :: Ord n+        => [Bind n]+        -> [Bind n]+        -> Type n+        -> Type n         -> Bool -equivT' stack1 depth1 stack2 depth2 t1 t2+equivWithBindsT stack1 stack2 t1 t2  = let  t1'     = unpackSumT $ crushSomeT t1         t2'     = unpackSumT $ crushSomeT t2    in case (t1', t2') of         (TVar u1,         TVar u2)-         -- Bound variables are name-equivalent.-         | u1 == u2     -> True+         -- Free variables are name-equivalent, bound variables aren't:+	 -- (forall a. a) != (forall b. a)+         | Nothing      <- getBindType stack1 u1+         , Nothing      <- getBindType stack2 u2+         , u1 == u2     -> checkBounds u1 u2 True -         -- Variables aren't name equivalent, -         -- but would be equivalent if we renamed them.-         | depth1 == depth2-         , Just (ix1, t1a)   <- getBindType stack1 u1+	 -- Both variables are bound in foralls, so check the stack+         -- to see if they would be equivalent if we named them.+         | Just (ix1, t1a)   <- getBindType stack1 u1          , Just (ix2, t2a)   <- getBindType stack2 u2          , ix1 == ix2-         -> equivT' stack1 depth1 stack2 depth2 t1a t2a+         -> checkBounds u1 u2 +         $  equivWithBindsT stack1 stack2 t1a t2a +         | otherwise+         -> checkBounds u1 u2+         $  False+         -- Constructor names must be equal.         (TCon tc1,        TCon tc2)          -> tc1 == tc2@@ -56,31 +64,34 @@         -- Push binders on the stack as we enter foralls.         (TForall b11 t12, TForall b21 t22)          |  equivT  (typeOfBind b11) (typeOfBind b21)-         -> equivT' (b11 : stack1) (depth1 + 1) -                    (b21 : stack2) (depth2 + 1) -                    t12 t22+         -> equivWithBindsT+                (b11 : stack1)+                (b21 : stack2)+                t12 t22          -- Decend into applications.         (TApp t11 t12,    TApp t21 t22)-         -> equivT' stack1 depth1 stack2 depth2 t11 t21-         && equivT' stack1 depth1 stack2 depth2 t12 t22+         -> equivWithBindsT stack1 stack2 t11 t21+         && equivWithBindsT stack1 stack2 t12 t22                  -- Sums are equivalent if all of their components are.         (TSum ts1,        TSum ts2)          -> let ts1'      = Sum.toList ts1                 ts2'      = Sum.toList ts2-                equiv     = equivT' stack1 depth1 stack2 depth2                  -- If all the components of the sum were in the element                 -- arrays then they come out of Sum.toList sorted                 -- and we can compare corresponding pairs.-                checkFast = and $ zipWith equiv ts1' ts2'+                checkFast = and $ zipWith (equivWithBindsT stack1 stack2) ts1' ts2'                  -- If any of the components use a higher kinded type variable                 -- like (c : % ~> !) then they won't nessesarally be sorted,                 -- so we need to do this slower O(n^2) check.-                checkSlow = and [ or (map (equiv t1c) ts2') | t1c <- ts1' ]-                         && and [ or (map (equiv t2c) ts1') | t2c <- ts2' ]+                -- Make sure to get the bind stacks the right way around here.+                checkSlow = and [ or (map (equivWithBindsT stack1 stack2 t1c) ts2') +                                | t1c <- ts1' ]+                         && and [ or (map (equivWithBindsT stack2 stack1 t2c) ts1') +                                | t2c <- ts2' ]              in  (length ts1' == length ts2')             &&  (checkFast || checkSlow)@@ -88,62 +99,30 @@         (_, _)  -> False  --- | Unpack single element sums into plain types.-unpackSumT :: Type n -> Type n-unpackSumT (TSum ts)-        | [t]   <- Sum.toList ts = t-unpackSumT tt                     = tt----- | Crush compound effects and closure terms.---   We check for a crushable term before calling crushT because that function---   will recursively crush the components. ---   As equivT is already recursive, we don't want a doubly-recursive function---   that tries to re-crush the same non-crushable type over and over.----crushSomeT :: (Ord n, Pretty n) => Type n -> Type n-crushSomeT tt- = case tt of-        (TApp (TCon tc) _)-         -> case tc of-                TyConSpec    TcConDeepRead   -> crushEffect tt-                TyConSpec    TcConDeepWrite  -> crushEffect tt-                TyConSpec    TcConDeepAlloc  -> crushEffect tt--                -- If a closure is miskinded then 'trimClosure' -                -- can return Nothing, so we just leave the term untrimmed.-                TyConSpec    TcConDeepUse    -> fromMaybe tt (trimClosure tt)--                TyConWitness TwConDeepGlobal -> crushEffect tt-                _                            -> tt--        _ -> tt----- | Lookup the type of a bound thing from the binder stack.---   The binder stack contains the binders of all the `TForall`s we've---   entered under so far.-getBindType :: Eq n => [Bind n] -> Bound n -> Maybe (Int, Type n)-getBindType bs' u- = go 0 bs'- where  go n (BName n1 t : bs)-         | UName n2 _   <- u-         , n1 == n2     = Just (n, t)-         | otherwise    = go (n + 1) bs---        go n (BAnon t   : bs)-         | UIx i _      <- u-         , i == 0       = Just (n, t)+-- | If we have a UName and UPrim with the same name then these won't match+--   even though they pretty print the same. This will only happen due to +--   a compiler bugs, but is very confusing when it does, so we check for+--   this case explicitly.+checkBounds :: Eq n => Bound n -> Bound n -> a -> a+checkBounds u1 u2 x+ = case (u1, u2) of+        (UName n2, UPrim n1 _)+         | n1 == n2     -> die -         | UIx i _      <- u-         , i < 0        = Nothing+        (UPrim n1 _, UName n2)+         | n1 == n2     -> die -         | otherwise    = go (n + 1) bs+        _               -> x+ where+  die   = error $ unlines+        [ "DDC.Type.Equiv"+        , "  Found a primitive and non-primitive bound variable with the same name."]  -        go n (BNone _   : bs)-         = go (n + 1) bs+-- | Unpack single element sums into plain types.+unpackSumT :: Type n -> Type n+unpackSumT (TSum ts)+	| [t]   <- Sum.toList ts = t+unpackSumT tt			 = tt -        go _ []         = Nothing 
DDC/Type/Exp.hs view
@@ -1,10 +1,7 @@  module DDC.Type.Exp         ( -- * Types, Kinds, and Sorts-          Binder   (..)-        , Bind     (..)-        , Bound    (..)-        , Type     (..)+          Type     (..)         , Kind,    Sort         , Region,  Effect, Closure         , TypeSum  (..),   TyConHash(..), TypeSumVarCon(..)@@ -12,260 +9,11 @@         , SoCon    (..)         , KiCon    (..)         , TwCon    (..)-        , TcCon    (..))+        , TcCon    (..)+        , Binder   (..)+        , Bind     (..)+        , Bound    (..)) where-import Data.Array-import Data.Map         (Map)-import Data.Set         (Set)----- Bind -------------------------------------------------------------------------- | A variable binder.-data Binder n-        = RNone-        | RAnon-        | RName n-        deriving Show----- | A variable binder with its type.-data Bind n-        -- | A variable with no uses in the body doesn't need a name.-        = BNone     (Type n)--        -- | Nameless variable on the deBruijn stack.-        | BAnon     (Type n)--        -- | Named variable in the environment.-        | BName n   (Type n)-        deriving Show------ | A bound occurrence of a variable, with its type.------   If variable hasn't been annotated with its real type then this ---   can be `tBot` (an empty sum).--data Bound n-        -- | Nameless variable that should be on the deBruijn stack.-        = UIx   Int (Type n)    --        -- | Named variable that should be in the environment.-        | UName n   (Type n)--        -- | Named primitive that is not bound in the environment.-        --   Prims aren't every counted as being free.-        | UPrim n   (Type n)    -        deriving Show----- Types ------------------------------------------------------------------------- | A value type, kind, or sort.------   We use the same data type to represent all three universes, as they have---  a similar algebraic structure.----data Type n-        -- | Variable.-        = TVar    (Bound n)--        -- | Constructor.-        | TCon    (TyCon n)--        -- | Abstraction.-        | TForall (Bind  n) (Type  n)-        -        -- | Application.-        | TApp    (Type  n) (Type  n)--        -- | Least upper bound.-        | TSum    (TypeSum n)-        deriving Show---type Sort    n = Type n-type Kind    n = Type n-type Region  n = Type n-type Effect  n = Type n-type Closure n = Type n----- Type Sums --------------------------------------------------------------------- | A least upper bound of several types.--- ---   We keep type sums in this normalised format instead of joining them---   together with a binary operator (like @(+)@). This makes sums easier to work---   with, as a given sum type often only has a single physical representation.-data TypeSum n-        = TypeSum-        { -- | The kind of the elements in this sum.-          typeSumKind           :: Kind n--          -- | Where we can see the outer constructor of a type, its argument-          --   is inserted into this array. This handles common cases like-          --   Read, Write, Alloc effects.-        , typeSumElems          :: Array TyConHash (Set (TypeSumVarCon n))--          -- | A map for named type variables.-        , typeSumBoundNamed     :: Map n   (Kind n)--          -- | A map for anonymous type variables.-        , typeSumBoundAnon      :: Map Int (Kind n)--          -- | Types that can't be placed in the other fields go here.-          -- -          --   INVARIANT: this list doesn't contain more `TSum`s.-        , typeSumSpill          :: [Type n] }-        deriving (Show)-        ---- | Hash value used to insert types into the `typeSumElems` array of a `TypeSum`.-data TyConHash -        = TyConHash !Int-        deriving (Eq, Show, Ord, Ix)----- | Wraps a variable or constructor that can be added the `typeSumElems` array.-data TypeSumVarCon n-        = TypeSumVar (Bound n)-        | TypeSumCon (Bound n)-        deriving Show----- TyCon ------------------------------------------------------------------------- | Kind, type and witness constructors.------   These are grouped to make it easy to determine the universe that they---   belong to.--- -data TyCon n-        -- | (level 3) Builtin Sort constructors.-        = TyConSort     SoCon--        -- | (level 2) Builtin Kind constructors.-        | TyConKind     KiCon--        -- | (level 1) Builtin Spec constructors for the types of witnesses.-        | TyConWitness  TwCon--        -- | (level 1) Builtin Spec constructors for types of other kinds.-        | TyConSpec     TcCon--        -- | User defined and primitive constructors.-        | TyConBound   (Bound n)-        deriving Show----- | Sort constructor.-data SoCon-        -- | Sort of witness kinds.-        = SoConProp                -- '@@'--        -- | Sort of computation kinds.-        | SoConComp                -- '**'-        deriving (Eq, Show)----- | Kind constructor.-data KiCon-        -- | Function kind constructor.-        --   This is only well formed when it is fully applied.-        = KiConFun              -- (~>)--        -- Witness kinds -------------------------        -- | Kind of witnesses.-        | KiConWitness          -- '@ :: @@'--        -- Computation kinds ----------------------        -- | Kind of data values.-        | KiConData             -- '* :: **'--        -- | Kind of regions.-        | KiConRegion           -- '% :: **'--        -- | Kind of effects.-        | KiConEffect           -- '! :: **'--        -- | Kind of closures.-        | KiConClosure          -- '$ :: **'-        deriving (Eq, Show)----- | Witness type constructors.-data TwCon-        -- Witness implication.-        = TwConImpl             -- :: '(=>) :: * ~> *'--        -- | Purity of some effect.-        | TwConPure             -- :: ! ~> @--        -- | Emptiness of some closure.-        | TwConEmpty            -- :: $ ~> @--        -- | Globalness of some region.-        | TwConGlobal           -- :: % ~> @--        -- | Globalness of material regions in some type.-        | TwConDeepGlobal       -- :: * ~> @-        -        -- | Constancy of some region.-        | TwConConst            -- :: % ~> @--        -- | Constancy of material regions in some type-        | TwConDeepConst        -- :: * ~> @--        -- | Mutability of some region.-        | TwConMutable          -- :: % ~> @--        -- | Mutability of material regions in some type.-        | TwConDeepMutable      -- :: * ~> @--        -- | Laziness of some region.-        | TwConLazy             -- :: % ~> @--        -- | Laziness of the primary region in some type.-        | TwConHeadLazy         -- :: * ~> @--        -- | Manifestness of some region (not lazy).-        | TwConManifest         -- :: % ~> @-        deriving (Eq, Show)----- | Other constructors at the spec level.-data TcCon-        -- Data type constructors ----------------        -- | The function type constructor is baked in so we -        --   represent it separately.-        = TcConFun              -- '(->) :: * ~> * ~> ! ~> $ ~> *'--        -- Effect type constructors --------------        -- | Read of some region.-        | TcConRead             -- :: '% ~> !'--        -- | Read the head region in a data type.-        | TcConHeadRead         -- :: '* ~> !'--        -- | Read of all material regions in a data type.-        | TcConDeepRead         -- :: '* ~> !'-        -        -- | Write of some region.-        | TcConWrite            -- :: '% ~> !'--        -- | Write to all material regions in some data type.-        | TcConDeepWrite        -- :: '* ~> !'-        -        -- | Allocation into some region.-        | TcConAlloc            -- :: '% ~> !'--        -- | Allocation into all material regions in some data type.-        | TcConDeepAlloc        -- :: '* ~> !'-        -        -- Closure type constructors -------------        -- | Region is captured in a closure.-        | TcConUse              -- :: '% ~> $'-        -        -- | All material regions in a data type are captured in a closure.-        | TcConDeepUse          -- :: '* ~> $'-        deriving (Eq, Show)+import DDC.Type.Exp.Base+import DDC.Type.Exp.NFData      () 
+ DDC/Type/Exp/Base.hs view
@@ -0,0 +1,267 @@++module DDC.Type.Exp.Base where+import Data.Array+import Data.Map.Strict  (Map)+import Data.Set         (Set)+++-- Bind -----------------------------------------------------------------------+-- | A variable binder.+data Binder n+        = RNone+        | RAnon+        | RName !n+        deriving Show+++-- | A variable binder with its type.+data Bind n+        -- | A variable with no uses in the body doesn't need a name.+        = BNone     !(Type n)++        -- | Nameless variable on the deBruijn stack.+        | BAnon     !(Type n)++        -- | Named variable in the environment.+        | BName n   !(Type n)+        deriving Show++++-- | A bound occurrence of a variable, with its type.+--+--   If variable hasn't been annotated with its real type then this +--   can be `tBot` (an empty sum).++data Bound n+        -- | Nameless variable that should be on the deBruijn stack.+        = UIx   !Int   ++        -- | Named variable that should be in the environment.+        | UName !n++        -- | Named primitive that has its type attached to it.+        --   The types of primitives must be closed.+        | UPrim !n !(Type n)+        deriving Show+++-- Types ----------------------------------------------------------------------+-- | A value type, kind, or sort.+--+--   We use the same data type to represent all three universes, as they have+--  a similar algebraic structure.+--+data Type n+        -- | Variable.+        = TVar    !(Bound n)++        -- | Constructor.+        | TCon    !(TyCon n)++        -- | Abstraction.+        | TForall !(Bind  n) !(Type  n)+        +        -- | Application.+        | TApp    !(Type  n) !(Type  n)++        -- | Least upper bound.+        | TSum    !(TypeSum n)+        deriving Show+++type Sort    n = Type n+type Kind    n = Type n+type Region  n = Type n+type Effect  n = Type n+type Closure n = Type n+++-- Type Sums ------------------------------------------------------------------+-- | A least upper bound of several types.+-- +--   We keep type sums in this normalised format instead of joining them+--   together with a binary operator (like @(+)@). This makes sums easier to work+--   with, as a given sum type often only has a single physical representation.+data TypeSum n+        = TypeSumBot+        { typeSumKind           :: !(Kind n) }++        | TypeSumSet+        { -- | The kind of the elements in this sum.+          typeSumKind           :: !(Kind n)++          -- | Where we can see the outer constructor of a type, its argument+          --   is inserted into this array. This handles common cases like+          --   Read, Write, Alloc effects.+        , typeSumElems          :: !(Array TyConHash (Set (TypeSumVarCon n)))++          -- | A map for named type variables.+        , typeSumBoundNamed     :: !(Map n   (Kind n))++          -- | A map for anonymous type variables.+        , typeSumBoundAnon      :: !(Map Int (Kind n))++          -- | Types that can't be placed in the other fields go here.+          -- +          --   INVARIANT: this list doesn't contain more `TSum`s.+        , typeSumSpill          :: ![Type n] }+        deriving (Show)+        ++-- | Hash value used to insert types into the `typeSumElems` array of a `TypeSum`.+data TyConHash +        = TyConHash !Int+        deriving (Eq, Show, Ord, Ix)+++-- | Wraps a variable or constructor that can be added the `typeSumElems` array.+data TypeSumVarCon n+        = TypeSumVar !(Bound n)+        | TypeSumCon !(Bound n) !(Type n)+        deriving Show+++-- TyCon ----------------------------------------------------------------------+-- | Kind, type and witness constructors.+--+--   These are grouped to make it easy to determine the universe that they+--   belong to.+-- +data TyCon n+        -- | (level 3) Builtin Sort constructors.+        = TyConSort     !SoCon++        -- | (level 2) Builtin Kind constructors.+        | TyConKind     !KiCon++        -- | (level 1) Builtin Spec constructors for the types of witnesses.+        | TyConWitness  !TwCon++        -- | (level 1) Builtin Spec constructors for types of other kinds.+        | TyConSpec     !TcCon++        -- | User defined and primitive constructors.+        | TyConBound   !(Bound n) !(Kind n)+        deriving Show+++-- | Sort constructor.+data SoCon+        -- | Sort of witness kinds.+        = SoConProp                -- '@@'++        -- | Sort of computation kinds.+        | SoConComp                -- '**'+        deriving (Eq, Show)+++-- | Kind constructor.+data KiCon+        -- | Function kind constructor.+        --   This is only well formed when it is fully applied.+        = KiConFun              -- (~>)++        -- Witness kinds ------------------------+        -- | Kind of witnesses.+        | KiConWitness          -- '@ :: @@'++        -- Computation kinds ---------------------+        -- | Kind of data values.+        | KiConData             -- '* :: **'++        -- | Kind of regions.+        | KiConRegion           -- '% :: **'++        -- | Kind of effects.+        | KiConEffect           -- '! :: **'++        -- | Kind of closures.+        | KiConClosure          -- '$ :: **'+        deriving (Eq, Show)+++-- | Witness type constructors.+data TwCon+        -- Witness implication.+        = TwConImpl             -- :: '(=>) :: @ ~> *'++        -- | Purity of some effect.+        | TwConPure             -- :: ! ~> @++        -- | Emptiness of some closure.+        | TwConEmpty            -- :: $ ~> @++        -- | Globalness of some region.+        | TwConGlobal           -- :: % ~> @++        -- | Globalness of material regions in some type.+        | TwConDeepGlobal       -- :: * ~> @+        +        -- | Constancy of some region.+        | TwConConst            -- :: % ~> @++        -- | Constancy of material regions in some type+        | TwConDeepConst        -- :: * ~> @++        -- | Mutability of some region.+        | TwConMutable          -- :: % ~> @++        -- | Mutability of material regions in some type.+        | TwConDeepMutable      -- :: * ~> @++        -- | Distinctness of some n regions+        | TwConDistinct Int     -- :: * ~> [%] ~> @+        +        -- | Laziness of some region.+        | TwConLazy             -- :: % ~> @++        -- | Laziness of the primary region in some type.+        | TwConHeadLazy         -- :: * ~> @++        -- | Manifestness of some region (not lazy).+        | TwConManifest         -- :: % ~> @++        -- | Non-interfering effects are disjoint. Used for rewrite rules.+        | TwConDisjoint               -- :: ! ~> ! ~> @+        deriving (Eq, Show)+++-- | Other constructors at the spec level.+data TcCon+        -- Data type constructors ---------------+        -- | The unit data type constructor is baked in.+        = TcConUnit             -- 'Unit :: *'++        -- | The function type constructor is baked in.+        | TcConFun              -- '(->) :: * ~> * ~> ! ~> $ ~> *'++        -- Effect type constructors -------------+        -- | Read of some region.+        | TcConRead             -- :: '% ~> !'++        -- | Read the head region in a data type.+        | TcConHeadRead         -- :: '* ~> !'++        -- | Read of all material regions in a data type.+        | TcConDeepRead         -- :: '* ~> !'+        +        -- | Write of some region.+        | TcConWrite            -- :: '% ~> !'++        -- | Write to all material regions in some data type.+        | TcConDeepWrite        -- :: '* ~> !'+        +        -- | Allocation into some region.+        | TcConAlloc            -- :: '% ~> !'++        -- | Allocation into all material regions in some data type.+        | TcConDeepAlloc        -- :: '* ~> !'+        +        -- Closure type constructors ------------+        -- | Region is captured in a closure.+        | TcConUse              -- :: '% ~> $'+        +        -- | All material regions in a data type are captured in a closure.+        | TcConDeepUse          -- :: '* ~> $'+        deriving (Eq, Show)
+ DDC/Type/Exp/NFData.hs view
@@ -0,0 +1,81 @@++module DDC.Type.Exp.NFData where+import DDC.Type.Exp.Base+import Control.DeepSeq+++instance NFData n => NFData (Binder n) where+ rnf bb+  = case bb of+        RNone   -> ()+        RAnon   -> ()+        RName n -> rnf n+++instance NFData n => NFData (Bind n) where+ rnf bb+  = case bb of+        BNone t         -> rnf t+        BAnon t         -> rnf t+        BName n t       -> rnf n `seq` rnf t+++instance NFData n => NFData (Bound n) where+ rnf uu+  = case uu of+        UIx   i         -> rnf i+        UName n         -> rnf n+        UPrim u t       -> rnf u `seq` rnf t+++instance NFData n => NFData (Type n) where+ rnf tt+  = case tt of+        TVar u          -> rnf u+        TCon tc         -> rnf tc+        TForall b t     -> rnf b  `seq` rnf t+        TApp    t1 t2   -> rnf t1 `seq` rnf t2+        TSum    ts      -> rnf ts+++instance NFData n => NFData (TypeSum n) where+ rnf !ts+  = case ts of+        TypeSumBot{}+         -> rnf (typeSumKind ts)++        TypeSumSet{}    +         ->    rnf (typeSumKind       ts)+         `seq` rnf (typeSumElems      ts)+         `seq` rnf (typeSumBoundNamed ts)+         `seq` rnf (typeSumBoundAnon  ts)+         `seq` rnf (typeSumSpill      ts)+++instance NFData TyConHash where+ rnf (TyConHash i)+  = rnf i+++instance NFData n => NFData (TypeSumVarCon n) where+ rnf ts+  = case ts of+        TypeSumVar u    -> rnf u+        TypeSumCon u t  -> rnf u `seq` rnf t+++instance NFData n => NFData (TyCon n) where+ rnf tc+  = case tc of+        TyConSort    con        -> rnf con+        TyConKind    con        -> rnf con+        TyConWitness con        -> rnf con+        TyConSpec    con        -> rnf con+        TyConBound   con k      -> rnf con `seq` rnf k+++instance NFData SoCon+instance NFData KiCon+instance NFData TwCon+instance NFData TcCon+
− DDC/Type/Parser.hs
@@ -1,236 +0,0 @@---- | Parser for type expressions.-module DDC.Type.Parser-        ( module DDC.Base.Parser-        , Parser-        , pType, pTypeAtom, pTypeApp-        , pBinder-        , pIndex-        , pTok, pTokAs)-where-import DDC.Core.Parser.Tokens   -import DDC.Type.Exp-import DDC.Type.Compounds-import DDC.Base.Parser                  ((<?>))-import qualified DDC.Base.Parser        as P-import qualified DDC.Type.Sum           as TS----- | Parser of type tokens.-type Parser n a-        = P.Parser (Tok n) a----- | Top level parser for types.-pType   :: Ord n => Parser n (Type n)-pType   = pTypeSum- <?> "a type"-----  | Parse a type sum.-pTypeSum :: Ord n => Parser n (Type n)-pTypeSum - = do   t1      <- pTypeForall-        P.choice -         [ -- Type sums.-           -- T2 + T3-           do   pTok KPlus-                t2      <- pTypeSum-                return  $ TSum $ TS.fromList (tBot sComp) [t1, t2]-                -         , do   return t1 ]- <?> "a type"----- | Parse a binder.-pBinder :: Ord n => Parser n (Binder n)-pBinder- = P.choice-        -- Named binders.-        [ do    v       <- pVar-                return  $ RName v-                -        -- Anonymous binders.-        , do    pTok KHat-                return  $ RAnon -        -        -- Vacant binders.-        , do    pTok KUnderscore-                return  $ RNone ]- <?> "a binder"----- | Parse a quantified type.-pTypeForall :: Ord n => Parser n (Type n)-pTypeForall- = P.choice-         [ -- Universal quantification.-           -- [v1 v1 ... vn : T1]. T2-           do   pTok KSquareBra-                bs      <- P.many1 pBinder-                pTok KColon-                k       <- pTypeSum-                pTok KSquareKet-                pTok KDot--                body    <- pTypeForall--                return  $ foldr TForall body -                        $ map (\b -> makeBindFromBinder b k) bs--           -- Body type-         , do   pTypeFun]- <?> "a type"----- | Parse a function type.-pTypeFun :: Ord n => Parser n (Type n)-pTypeFun- = do   t1      <- pTypeApp-        P.choice -         [ -- T1 ~> T2-           do   pTok KArrowTilde-                t2      <- pTypeFun-                return  $ TApp (TApp (TCon (TyConKind KiConFun)) t1) t2--           -- T1 => T2-         , do   pTok KArrowEquals-                t2      <- pTypeFun-                return  $ TApp (TApp (TCon (TyConWitness TwConImpl)) t1) t2--           -- T1 -> T2-         , do   pTok KArrowDash-                t2      <- pTypeFun-                return  $ t1 `tFunPE` t2--           -- T1 -(TSUM | TSUM)> t2-         , do   pTok KDash-                pTok KRoundBra-                eff     <- pTypeSum-                pTok KBar-                clo     <- pTypeSum-                pTok KRoundKet-                pTok KAngleKet-                t2      <- pTypeFun-                return  $ tFun t1 eff clo t2---           -- Body type-         , do   return t1 ]- <?> "an atomic type or type application"----- | Parse a type application.-pTypeApp :: Ord n => Parser n (Type n)-pTypeApp  - = do   (t:ts)  <- P.many1 pTypeAtom-        return  $  foldl TApp t ts- <?> "an atomic type or type application"----- | Parse a variable, constructor or parenthesised type.-pTypeAtom :: Ord n => Parser n (Type n)-pTypeAtom  - = P.choice-        -- (~>) and (=>) and (->) and (TYPE2)-        [ do    pTok KRoundBra-                P.choice-                 [ do   pTok KArrowTilde-                        pTok KRoundKet-                        return (TCon $ TyConKind KiConFun)--                 , do   pTok KArrowEquals-                        pTok KRoundKet-                        return (TCon $ TyConWitness TwConImpl)--                 , do   pTok KArrowDash-                        pTok KRoundKet-                        return (TCon $ TyConSpec TcConFun)--                 , do   t       <- pTypeSum-                        pTok KRoundKet-                        return t -                 ]--        -- Named type constructors-        , do    tc      <- pTcCon-                return  $ TCon (TyConSpec tc)--        , do    tc      <- pTwCon-                return  $ TCon (TyConWitness tc)--        , do    tc      <- pTyConNamed-                return  $ TCon tc--        -- Symbolic constructors.-        , do    pTokAs KSortComp    (TCon $ TyConSort SoConComp)-        , do    pTokAs KSortProp    (TCon $ TyConSort SoConProp) -        , do    pTokAs KKindValue   (TCon $ TyConKind KiConData)-        , do    pTokAs KKindRegion  (TCon $ TyConKind KiConRegion) -        , do    pTokAs KKindEffect  (TCon $ TyConKind KiConEffect) -        , do    pTokAs KKindClosure (TCon $ TyConKind KiConClosure) -        , do    pTokAs KKindWitness (TCon $ TyConKind KiConWitness) -            -        -- Bottoms.-        , do    pTokAs KBotEffect  (tBot kEffect)-        , do    pTokAs KBotClosure (tBot kClosure)-      -        -- Bound occurrence of a variable.-        --  We don't know the kind of this variable yet, so fill in the-        --  field with the bottom element of computation kinds. This isn't-        --  really part of the language, but makes sense implentation-wise.-        , do    v       <- pVar-                return  $  TVar (UName v (tBot sComp))--        , do    i       <- pIndex-                return  $  TVar (UIx (fromIntegral i) (tBot sComp))-        ]- <?> "an atomic type"------------------------------------------------------------------------------------- | Parse a builtin `TcCon`-pTcCon :: Parser n TcCon-pTcCon  =   P.pTokMaybe f-        <?> "a type constructor"- where f (KA (KTcConBuiltin c)) = Just c-       f _                      = Nothing ---- | Parse a builtin `TwCon`-pTwCon :: Parser n TwCon-pTwCon  =   P.pTokMaybe f-        <?> "a witness constructor"- where f (KA (KTwConBuiltin c)) = Just c-       f _                      = Nothing---- | Parse a user `TcCon`-pTyConNamed :: Parser n (TyCon n)-pTyConNamed  -        =   P.pTokMaybe f-        <?> "a type constructor"- where  f (KN (KCon n))          = Just (TyConBound (UName n (tBot kData)))-        f _                      = Nothing---- | Parse a variable.-pVar :: Parser n n-pVar    =   P.pTokMaybe f-        <?> "a variable"- where  f (KN (KVar n))         = Just n-        f _                     = Nothing---- | Parse a deBruijn index-pIndex :: Parser n Int-pIndex  =   P.pTokMaybe f-        <?> "an index"- where  f (KA (KIndex i))       = Just i-        f _                     = Nothing---- | Parse an atomic token.-pTok :: TokAtom -> Parser n ()-pTok k     = P.pTok (KA k)----- | Parse an atomic token and return some value.-pTokAs :: TokAtom -> a -> Parser n a-pTokAs k x = P.pTokAs (KA k) x-
DDC/Type/Predicates.hs view
@@ -1,21 +1,71 @@  -- | Predicates on type expressions. module DDC.Type.Predicates-        ( isBot+        ( -- * Binders+          isBNone+        , isBAnon+        , isBName++          -- * Atoms+        , isTVar+        , isBot         , isAtomT++          -- * Kinds         , isDataKind         , isRegionKind         , isEffectKind         , isClosureKind         , isWitnessKind-        , isAlgDataType)++          -- * Data Types+        , isAlgDataType+        , isWitnessType+        , isConstWitType+        , isMutableWitType+        , isDistinctWitType++          -- * Effect Types+        , isReadEffect+        , isWriteEffect+        , isAllocEffect+        , isSomeReadEffect+        , isSomeWriteEffect+        , isSomeAllocEffect) where import DDC.Type.Exp import DDC.Type.Compounds import qualified DDC.Type.Sum   as T  +-- Binders --------------------------------------------------------------------+isBNone :: Bind n -> Bool+isBNone bb+ = case bb of+        BNone{} -> True+        _       -> False++isBAnon :: Bind n -> Bool+isBAnon bb+ = case bb of+        BAnon{} -> True+        _       -> False++isBName :: Bind n -> Bool+isBName bb+ = case bb of+        BName{} -> True+        _       -> False++ -- Atoms ----------------------------------------------------------------------+-- | Check whether a type is a `TVar`+isTVar :: Type n -> Bool+isTVar tt+ = case tt of+        TVar{}          -> True+        _               -> False+ -- | Test if some type is an empty TSum isBot :: Type n -> Bool isBot tt@@ -82,17 +132,114 @@ --   It needs to have an explicit data constructor out the front, --   and not a type variable. The constructor must not be the function --   constructor, and must return a value of kind '*'.---- Algebraic data types are all built from constructors--- that have '*' as their result kind.--- The function constructor (->) also has this result kind,--- but it is in `TyConComp`, so is easy to ignore.+---+--   The function constructor (->) also has this result kind,+--   but it is in `TyConComp`, so is easy to ignore. isAlgDataType :: Eq n => Type n -> Bool isAlgDataType tt-        | Just (tc, _)  <- takeTyConApps tt-        , TyConBound u  <- tc-        = takeResultKind (typeOfBound u) == kData+        | Just (tc, _)   <- takeTyConApps tt+        , TyConBound _ k <- tc+        = takeResultKind k == kData          | otherwise         = False++-- | Check whether type is a witness constructor+isWitnessType :: Eq n => Type n -> Bool+isWitnessType tt+ = case takeTyConApps tt of+	Just (TyConWitness _, _) -> True+	_			 -> False+	++-- | Check whether this is the type of a @Const@ witness.+isConstWitType :: Eq n => Type n -> Bool+isConstWitType tt+ = case takeTyConApps tt of+        Just (TyConWitness TwConConst, _) -> True+        _                                 -> False+++-- | Check whether this is the type of a @Mutable@ witness.+isMutableWitType :: Eq n => Type n -> Bool+isMutableWitType tt+ = case takeTyConApps tt of+        Just (TyConWitness TwConMutable, _) -> True+        _                                   -> False+++-- | Check whether this is the type of a @Distinct@ witness.+isDistinctWitType :: Eq n => Type n -> Bool+isDistinctWitType tt+ = case takeTyConApps tt of+        Just (TyConWitness (TwConDistinct _), _) -> True+        _                                        -> False+	++-- Effects --------------------------------------------------------------------+-- | Check whether this is an atomic read effect.+isReadEffect :: Effect n -> Bool+isReadEffect eff+ = case eff of+        TApp (TCon (TyConSpec TcConRead)) _     -> True+        _                                       -> False+++-- | Check whether this is an atomic write effect.+isWriteEffect :: Effect n -> Bool+isWriteEffect eff+ = case eff of+        TApp (TCon (TyConSpec TcConWrite)) _    -> True+        _                                       -> False+++-- | Check whether this is an atomic alloc effect.+isAllocEffect :: Effect n -> Bool+isAllocEffect eff+ = case eff of+        TApp (TCon (TyConSpec TcConAlloc)) _    -> True+        _                                       -> False+++-- | Check whether an effect is some sort of read effect.+--   Matches @Read@ @HeadRead@ and @DeepRead@.+isSomeReadEffect :: Effect n -> Bool+isSomeReadEffect tt+ = case tt of+        TApp (TCon (TyConSpec con)) _+         -> case con of+                TcConRead       -> True+                TcConHeadRead   -> True+                TcConDeepRead   -> True+                _               -> False++        _                       -> False+++-- | Check whether an effect is some sort of allocation effect.+--   Matches @Alloc@ and @DeepAlloc@+isSomeWriteEffect :: Effect n -> Bool+isSomeWriteEffect tt+ = case tt of+        TApp (TCon (TyConSpec con)) _+         -> case con of+                TcConWrite      -> True+                TcConDeepWrite  -> True+                _               -> False++        _                       -> False+++-- | Check whether an effect is some sort of allocation effect.+--   Matches @Alloc@ and @DeepAlloc@+isSomeAllocEffect :: Effect n -> Bool+isSomeAllocEffect tt+ = case tt of+        TApp (TCon (TyConSpec con)) _+         -> case con of+                TcConAlloc      -> True+                TcConDeepAlloc  -> True+                _               -> False++        _                       -> False 
DDC/Type/Pretty.hs view
@@ -49,13 +49,9 @@ instance (Pretty n, Eq n) => Pretty (Bound n) where  ppr nn   = case nn of---        UName n t       -> parens (ppr n <> text ":" <> ppr t)-        UName n _       -> ppr n---        UPrim n _       -> ppr n---        UIx i t         -> parens (text "^" <> ppr i <> text ":" <> ppr t)-        UIx i _         -> text "^" <> ppr i+        UName n        -> ppr n+        UPrim n _      -> ppr n+        UIx i          -> text "^" <> ppr i   -- Type -----------------------------------------------------------------------@@ -127,7 +123,7 @@         TyConKind kc    -> ppr kc         TyConWitness tc -> ppr tc         TyConSpec tc    -> ppr tc-        TyConBound u    -> ppr u+        TyConBound u _  -> ppr u   instance Pretty SoCon where@@ -160,14 +156,17 @@         TwConDeepConst  -> text "DeepConst"         TwConMutable    -> text "Mutable"         TwConDeepMutable-> text "DeepMutable"+        TwConDistinct n -> text "Distinct" <> ppr n         TwConLazy       -> text "Lazy"         TwConHeadLazy   -> text "HeadLazy"         TwConManifest   -> text "Manifest"+        TwConDisjoint   -> text "Disjoint"           instance Pretty TcCon where  ppr tc    = case tc of+        TcConUnit       -> text "Unit"         TcConFun        -> text "(->)"         TcConRead       -> text "Read"         TcConHeadRead   -> text "HeadRead"
− DDC/Type/Rewrite.hs
@@ -1,264 +0,0 @@---- | Rewriting of variable binders to anonymous form to avoid capture.-module DDC.Type.Rewrite-        ( Rewrite(..)-        , Sub(..)-        , BindStack(..)-        , pushBind-        , pushBinds-        , substBound--        , bind1, bind0, bind0s-        , use1,  use0)-where-import DDC.Core.Exp-import DDC.Type.Compounds-import Data.List-import Data.Set                         (Set)-import qualified DDC.Type.Sum           as Sum-import qualified Data.Set               as Set----- | Substitution state.---   Keeps track of the binders in the environment that have been rewrittten---   to avoid variable capture or spec binder shadowing.-data Sub n-        = Sub-        { -- | Bound variable that we're substituting for.-          subBound      :: Bound n--          -- | We've decended past a binder that shadows the one that we're-          --   substituting for. We're no longer substituting, but still may-          --   need to anonymise variables in types. -          --   This can only happen for level-0 named binders.-        , subShadow0    :: Bool --          -- | Level-1 names that need to be rewritten to avoid capture.-        , subConflict1  :: Set n--          -- | Level-0 names that need to be rewritten to avoid capture.-        , subConflict0  :: Set n --          -- | Rewriting stack for level-1 names.-        , subStack1     :: BindStack n--          -- | Rewriting stack for level-0 names.-        , subStack0     :: BindStack n  }----- | Stack of anonymous binders that we've entered under during substitution. -data BindStack n-        = BindStack-        { -- | Holds anonymous binders that were already in the program,-          --   as well as named binders that are being rewritten to anonymous ones.-          --   In the resulting expression all these binders will be anonymous.-          stackBinds    :: [Bind n]--          -- | Holds all binders, independent of whether they are being rewritten or not.-        , stackAll      :: [Bind n] --          -- | Number of `BAnon` in `stackBinds`.-        , stackAnons    :: Int--          -- | Number of `BName` in `stackBinds`.-        , stackNamed    :: Int }----- | Push several binds onto the bind stack,---   anonymyzing them if need be to avoid variable capture.-pushBinds :: Ord n => Set n -> BindStack n -> [Bind n]  -> (BindStack n, [Bind n])-pushBinds fns stack bs-        = mapAccumL (pushBind fns) stack bs----- | Push a bind onto a bind stack, ---   anonymizing it if need be to avoid variable capture.-pushBind-        :: Ord n-        => Set n                  -- ^ Names that need to be rewritten.-        -> BindStack n            -- ^ Current bind stack.-        -> Bind n                 -- ^ Bind to push.-        -> (BindStack n, Bind n)  -- ^ New stack and possibly anonymised bind.--pushBind fns bs@(BindStack stack env dAnon dName) bb- = case bb of-        -- Push already anonymous bind on stack.-        BAnon t                 -         -> ( BindStack (BAnon t   : stack) (BAnon t : env) (dAnon + 1) dName-            , BAnon t)-            -        -- If the binder needs to be rewritten then push the original name on the-        -- 'stackBinds' to remember this.-        BName n t-         | Set.member n fns     -         -> ( BindStack (BName n t : stack) (BAnon t : env)  dAnon       (dName + 1)-            , BAnon t)--         | otherwise-         -> ( BindStack stack               (BName n t : env) dAnon dName-            , bb)--        -- Binder was a wildcard.-        _ -> (bs, bb)------ | Compare a `Bound` against the one we're substituting for.-substBound-        :: Ord n-        => BindStack n      -- ^ Current Bind stack during substitution.-        -> Bound n          -- ^ Bound we're substituting for.-        -> Bound n          -- ^ Bound we're looking at now.-        -> Either -                (Bound n)   --   Bound doesn't match, but replace with this one.-                Int         --   Bound matches, drop the thing being substituted and -                            --   and lift indices this many steps.--substBound (BindStack binds _ dAnon dName) u u'-        -- Bound name matches the one that we're substituting for.-        | UName n1 _   <- u-        , UName n2 _   <- u'-        , n1 == n2-        = Right (dAnon + dName)--        -- Bound index matches the one that we're substituting for.-        | UIx  i1 _     <- u-        , UIx  i2 _     <- u'-        , i1 + dAnon == i2 -        = Right (dAnon + dName)--        -- The Bind for this name was rewritten to avoid variable capture,-        -- so we also have to update the bound occurrence.-        | UName _ t     <- u'-        , Just ix       <- findIndex (boundMatchesBind u') binds-        = Left $ UIx ix t--        -- Bound index doesn't match, but lower this index by one to account-        -- for the removal of the outer binder.-        | UIx  i2 t     <- u'-        , i2 > dAnon-        , cutOffset     <- case u of-                                UIx{}   -> 1-                                _       -> 0-        = Left $ UIx (i2 + dName - cutOffset) t--        -- Some name that didn't match.-        | otherwise-        = Left u'------------------------------------------------------------------------------------- | Push a level-1 binder on the rewrite stack.-bind1 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)-bind1 sub b - = let  (stackT', b')     = pushBind (subConflict1 sub) (subStack1 sub) b-   in   (sub { subStack1  = stackT' }, b')----- | Push a level-0 binder on the rewrite stack.-bind0 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)-bind0 sub b - = let  b1                  = rewriteWith sub b-        (stackX', b2)       = pushBind (subConflict0 sub) (subStack0 sub) b1-   in   ( sub { subStack0   = stackX'-              , subShadow0  =  subShadow0 sub -                            || namedBoundMatchesBind (subBound sub) b2 }-        , b2)----- | Push some level-0 binders on the rewrite stack.-bind0s :: Ord n => Sub n -> [Bind n] -> (Sub n, [Bind n])-bind0s = mapAccumL bind0----- | Rewrite a use of a level-1 binder if need be.-use1 :: Ord n => Sub n -> Bound n -> Bound n-use1 sub u-        | UName _ t             <- u-        , BindStack binds _ _ _ <- subStack1 sub-        , Just ix               <- findIndex (boundMatchesBind u) binds-        = UIx ix t--        | otherwise-        = u----- | Rewrite the use of a level-0 binder if need be.-use0 :: Ord n => Sub n -> Bound n -> Bound n-use0 sub u-        | UName _ t             <- u-        , BindStack binds _ _ _ <- subStack0 sub-        , Just ix               <- findIndex (boundMatchesBind u) binds-        = UIx ix (rewriteWith sub t)--        | otherwise-        = rewriteWith sub u-----------------------------------------------------------------------------------class Rewrite (c :: * -> *) where- -- | Rewrite names in some thing to anonymous form if they conflict with---    any names in the `Sub` state.- rewriteWith :: Ord n => Sub n -> c n -> c n ---instance Rewrite Bind where- rewriteWith sub bb-  = replaceTypeOfBind  (rewriteWith sub (typeOfBind bb))  bb---instance Rewrite Bound where- rewriteWith sub uu-  = replaceTypeOfBound (rewriteWith sub (typeOfBound uu)) uu---instance Rewrite LetMode where- rewriteWith sub lm-  = case lm of-        LetStrict        -> lm-        LetLazy (Just t) -> LetLazy (Just $ rewriteWith sub t) -        LetLazy Nothing  -> LetLazy Nothing---instance Rewrite Cast where- rewriteWith sub cc-  = let down    = rewriteWith sub -    in case cc of-        CastWeakenEffect  eff   -> CastWeakenEffect  (down eff)-        CastWeakenClosure clo   -> CastWeakenClosure (down clo)-        CastPurify w            -> CastPurify (down w)-        CastForget w            -> CastForget (down w)---instance Rewrite Type where- rewriteWith sub tt -  = let down    = rewriteWith -    in case tt of-        TVar u          -> TVar (use1 sub u)-        TCon{}          -> tt--        TForall b t-         -> let (sub1, b')      = bind1 sub b-                t'              = down  sub1 t-            in  TForall b' t'--        TApp t1 t2      -> TApp (down sub t1) (down sub t2)-        TSum ts         -> TSum (down sub ts)---instance Rewrite TypeSum where- rewriteWith sub ts-        = Sum.fromList (Sum.kindOfSum ts)-        $ map (rewriteWith sub)-        $ Sum.toList ts---instance Rewrite Witness where- rewriteWith sub ww-  = let down    = rewriteWith -    in case ww of-        WVar u          -> WVar  (use0 sub u)-        WCon{}          -> ww-        WApp  w1 w2     -> WApp  (down sub w1) (down sub w2)-        WJoin w1 w2     -> WJoin (down sub w1) (down sub w2)-        WType t         -> WType (down sub t)
DDC/Type/Sum.hs view
@@ -2,32 +2,48 @@ -- | Utilities for working with `TypeSum`s. -- module DDC.Type.Sum -        ( empty+        ( -- * Constructors+          empty         , singleton-        , elem-        , insert-        , delete         , union         , unions-        , difference+        , insert++          -- * Conversion+        , toList+        , fromList++          -- * Projection         , kindOfSum-        , toList, fromList-        , hashTyCon, hashTyConRange-        , unhashTyCon-        , takeSumArrayElem-        , makeSumArrayElem)+        , elem++          -- * Deletion+        , delete+        , difference++          -- * Hashing+        , hashTyCon+        , hashTyConRange+        , unhashTyCon) where import DDC.Type.Exp import Data.Array-import qualified Data.List      as L-import qualified Data.Map       as Map-import qualified Data.Set       as Set-import Prelude                  hiding (elem)+import qualified Data.List              as L+import qualified Data.Map.Strict        as Map+import qualified Data.Set               as Set+import Prelude                          hiding (elem)   -- | Construct an empty type sum of the given kind. empty :: Kind n -> TypeSum n-empty k = TypeSum+empty k = TypeSumBot k+++-- | Construct an empty type sum of the given kind, but in `TypeSumSet` form.+--   This isn't exported.+emptySet :: Kind n -> TypeSum n+emptySet k +        = TypeSumSet         { typeSumKind           = k         , typeSumElems          = listArray hashTyConRange (repeat Set.empty)         , typeSumBoundNamed     = Map.empty@@ -50,11 +66,12 @@ --   * May return False if the first argument is miskinded but still --     alpha-equivalent to some component of the sum. elem :: (Eq n, Ord n) => Type n -> TypeSum n -> Bool-elem t ts +elem _ TypeSumBot{}      =  False+elem t ts@TypeSumSet{}  = case t of-        TVar (UName n _) -> Map.member n (typeSumBoundNamed ts)+        TVar (UName n)   -> Map.member n (typeSumBoundNamed ts)+        TVar (UIx   i)   -> Map.member i (typeSumBoundAnon  ts)         TVar (UPrim n _) -> Map.member n (typeSumBoundNamed ts)-        TVar (UIx   i _) -> Map.member i (typeSumBoundAnon  ts)         TCon{}           -> L.elem t (typeSumSpill ts)          -- Foralls can't be a part of well-kinded sums.@@ -86,17 +103,19 @@  -- | Insert a new element into a sum. insert :: Ord n => Type n -> TypeSum n -> TypeSum n-insert t ts- = case t of-        TVar (UName n k) -> ts { typeSumBoundNamed = Map.insert n k (typeSumBoundNamed ts) }-        TVar (UPrim n k) -> ts { typeSumBoundNamed = Map.insert n k (typeSumBoundNamed ts) }-        TVar (UIx   i k) -> ts { typeSumBoundAnon  = Map.insert i k (typeSumBoundAnon  ts) }-        TCon{}           -> ts { typeSumSpill      = t : typeSumSpill ts }+insert t (TypeSumBot k)   = insert t (emptySet k)+insert t ts@TypeSumSet{}+ = let k        = typeSumKind ts+   in case t of+        TVar (UName n)  -> ts { typeSumBoundNamed = Map.insert n k (typeSumBoundNamed ts) }+        TVar (UIx   i)  -> ts { typeSumBoundAnon  = Map.insert i k (typeSumBoundAnon  ts) }+        TVar (UPrim n _)-> ts { typeSumBoundNamed = Map.insert n k (typeSumBoundNamed ts) }+        TCon{}          -> ts { typeSumSpill      = L.nub $ t : typeSumSpill ts }          -- Foralls can't be part of well-kinded sums.         --  Just add them to the splill lists so that we can still         --  pretty print such mis-kinded types.-        TForall{}        -> ts { typeSumSpill      = t : typeSumSpill ts }+        TForall{}        -> ts { typeSumSpill      = L.nub $ t : typeSumSpill ts }          TApp (TCon _) _          |  Just (h, vc)  <- takeSumArrayElem t@@ -105,20 +124,21 @@                 then ts                 else ts { typeSumElems = (typeSumElems ts) // [(h, Set.insert vc tsThere)] }         -        TApp{}           -> ts { typeSumSpill      = t : typeSumSpill ts }+        TApp{}           -> ts { typeSumSpill      = L.nub $ t : typeSumSpill ts }                  TSum ts'         -> foldr insert ts (toList ts')   -- | Delete an element from a sum. delete :: Ord n => Type n -> TypeSum n -> TypeSum n-delete t ts+delete _ ts@TypeSumBot{} = ts+delete t ts@TypeSumSet{}  = case t of-        TVar (UName n _) -> ts { typeSumBoundNamed = Map.delete n (typeSumBoundNamed ts) }-        TVar (UPrim n _) -> ts { typeSumBoundNamed = Map.delete n (typeSumBoundNamed ts) }-        TVar (UIx   i _) -> ts { typeSumBoundAnon  = Map.delete i (typeSumBoundAnon  ts) }-        TCon{}           -> ts { typeSumSpill      = L.delete t (typeSumSpill ts) }-        TForall{}        -> ts { typeSumSpill      = L.delete t (typeSumSpill ts) }+        TVar (UName n)  -> ts { typeSumBoundNamed = Map.delete n (typeSumBoundNamed ts) }+        TVar (UIx   i)  -> ts { typeSumBoundAnon  = Map.delete i (typeSumBoundAnon  ts) }+        TVar (UPrim n _)-> ts { typeSumBoundNamed = Map.delete n (typeSumBoundNamed ts) }+        TCon{}          -> ts { typeSumSpill      = L.delete t (typeSumSpill ts) }+        TForall{}       -> ts { typeSumSpill      = L.delete t (typeSumSpill ts) }                  TApp (TCon _) _          | Just (h, vc) <- takeSumArrayElem t@@ -157,7 +177,10 @@  -- | Flatten out a sum, yielding a list of individual terms. toList :: TypeSum n -> [Type n]-toList TypeSum+toList TypeSumBot{}       + = []++toList TypeSumSet         { typeSumKind           = _kind         , typeSumElems          = sumElems         , typeSumBoundNamed     = named@@ -166,8 +189,8 @@   =      [ makeSumArrayElem h vc                 | (h, ts) <- assocs sumElems, vc <- Set.toList ts] -        ++ [TVar $ UName n k | (n, k) <- Map.toList named]-        ++ [TVar $ UIx   i k | (i, k) <- Map.toList anon]+        ++ [TVar $ UName n | (n, _) <- Map.toList named]+        ++ [TVar $ UIx   i | (i, _) <- Map.toList anon]         ++ spill                  @@ -231,7 +254,7 @@         | Just h        <- hashTyCon tc         = case t2 of                 TVar u                  -> Just (h, TypeSumVar u)-                TCon (TyConBound u)     -> Just (h, TypeSumCon u)+                TCon (TyConBound u k)   -> Just (h, TypeSumCon u k)                 _                       -> Nothing          takeSumArrayElem _ = Nothing@@ -243,7 +266,7 @@  = let  tc       = unhashTyCon h    in   case vc of          TypeSumVar u   -> TApp (TCon tc) (TVar u)-         TypeSumCon u   -> TApp (TCon tc) (TCon (TyConBound u))+         TypeSumCon u k -> TApp (TCon tc) (TCon (TyConBound u k))   -- Type Equality --------------------------------------------------------------@@ -268,6 +291,7 @@         -- Unwrap single element sums into plain types.   where normalise (TSum ts)          | [t'] <- toList ts    = t'+         | []   <- toList ts    = TSum $ empty (typeSumKind ts)          normalise t'            = t' @@ -280,25 +304,47 @@         , []    <- toList ts2         = typeSumKind ts1 == typeSumKind ts2 -        -- If the sum has elements, then compare them directly and ignore the+        | TypeSumBot{}  <- normalise ts1+        , TypeSumBot{}  <- normalise ts2+        = typeSumKind ts1 == typeSumKind ts2++        -- If both sums have elements, then compare them directly and ignore the         -- kind. This allows us to use (tBot sComp) as the typeSumKind field         -- when we want to compute the real kind based on the elements. -        | otherwise+        | TypeSumSet{} <- ts1+	, TypeSumSet{} <- ts2         =  typeSumElems ts1      == typeSumElems ts2         && typeSumBoundNamed ts1 == typeSumBoundNamed ts2         && typeSumBoundAnon  ts1 == typeSumBoundAnon ts2         && typeSumSpill      ts1 == typeSumSpill ts2 +	-- One is a set and one is bottom, so they are not equal.+	| otherwise+	= False +  where normalise ts+         | []   <- toList ts    = empty (typeSumKind ts)+        normalise ts            = ts++ instance Ord n => Ord (Bound n) where- compare (UName n1 _) (UName n2 _)      = compare n1 n2- compare (UIx   i1 _) (UIx   i2 _)      = compare i1 i2- compare (UPrim n1 _) (UPrim n2 _)      = compare n1 n2- compare (UIx   _  _) _                 = LT- compare (UName _  _) (UIx   _ _)       = GT- compare (UName _  _) (UPrim _ _)       = LT- compare (UPrim _  _) _                 = GT+ compare (UName n1)     (UName n2)      = compare n1 n2+ compare (UIx   i1)     (UIx   i2)      = compare i1 i2+ compare (UPrim n1 _)   (UPrim n2 _)    = compare n1 n2+ compare UIx{}          _               = LT+ compare UName{}        UIx{}           = GT+ compare UName{}        UPrim{}         = LT+ compare UPrim{}        _               = GT -deriving instance Eq n  => Eq  (TypeSumVarCon n)-deriving instance Ord n => Ord (TypeSumVarCon n)++instance Eq n => Eq (TypeSumVarCon n) where+ (==) (TypeSumVar u1)   (TypeSumVar u2)     = u1 == u2+ (==) (TypeSumCon u1 _) (TypeSumCon u2 _)   = u1 == u2+ (==) _ _                                   = False++instance Ord n => Ord (TypeSumVarCon n) where+ compare (TypeSumVar u1)   (TypeSumVar u2)    = compare u1 u2+ compare (TypeSumCon u1 _) (TypeSumCon u2 _)  = compare u1 u2+ compare (TypeSumVar _)    _                  = LT+ compare (TypeSumCon _ _)  _                  = GT 
DDC/Type/Transform/Crush.hs view
@@ -1,12 +1,41 @@ module DDC.Type.Transform.Crush-        (crushEffect)+        ( crushSomeT+        , crushEffect ) where import DDC.Type.Predicates import DDC.Type.Compounds+import DDC.Type.Transform.Trim import DDC.Type.Exp import qualified DDC.Type.Sum   as Sum+import Data.Maybe  +-- | Crush compound effects and closure terms.+--   We check for a crushable term before calling crushT because that function+--   will recursively crush the components. +--   As equivT is already recursive, we don't want a doubly-recursive function+--   that tries to re-crush the same non-crushable type over and over.+--+crushSomeT :: Ord n => Type n -> Type n+crushSomeT tt+ = {-# SCC crushSomeT #-}+   case tt of+        (TApp (TCon tc) _)+         -> case tc of+                TyConSpec    TcConDeepRead   -> crushEffect tt+                TyConSpec    TcConDeepWrite  -> crushEffect tt+                TyConSpec    TcConDeepAlloc  -> crushEffect tt++                -- If a closure is miskinded then 'trimClosure' +                -- can return Nothing, so we just leave the term untrimmed.+                TyConSpec    TcConDeepUse    -> fromMaybe tt (trimClosure tt)++                TyConWitness TwConDeepGlobal -> crushEffect tt+                _                            -> tt++        _ -> tt++ -- | Crush compound effect terms into their components. -- --   This is like `trimClosure` but for effects instead of closures.@@ -15,7 +44,8 @@ -- crushEffect :: Ord n => Effect n -> Effect n crushEffect tt- = case tt of+ = {-# SCC crushEffect #-}+   case tt of         TVar{}          -> tt         TCon{}          -> tt         TForall b t@@ -33,14 +63,15 @@          -> case takeTyConApps t of               -- Type has a head region.-             Just (TyConBound u, (tR : _)) -              |  (k1 : _, _) <- takeKFuns (typeOfBound u)+             Just (TyConBound _ k, (tR : _)) +              |  (k1 : _, _) <- takeKFuns k               ,  isRegionKind k1               -> tRead tR               -- Type has no head region.              -- This happens with  case () of { ... }-             Just (TyConBound _, [])        -> tBot kEffect+             Just (TyConSpec  TcConUnit, [])    -> tBot kEffect+             Just (TyConBound _ _,       [])    -> tBot kEffect               _ -> tt @@ -48,8 +79,8 @@          -- See Note: Crushing with higher kinded type vars.          | Just (TyConSpec TcConDeepRead, [t]) <- takeTyConApps tt          -> case takeTyConApps t of-             Just (TyConBound u, ts)-              | (ks, _)  <- takeKFuns (typeOfBound u)+             Just (TyConBound _ k, ts)+              | (ks, _)  <- takeKFuns k               , length ks == length ts               , Just effs       <- sequence $ zipWith makeDeepRead ks ts               -> crushEffect $ TSum $ Sum.fromList kEffect effs@@ -60,8 +91,8 @@          -- See Note: Crushing with higher kinded type vars.          | Just (TyConSpec TcConDeepWrite, [t]) <- takeTyConApps tt          -> case takeTyConApps t of-             Just (TyConBound u, ts)-              | (ks, _)  <- takeKFuns (typeOfBound u)+             Just (TyConBound _ k, ts)+              | (ks, _)  <- takeKFuns k               , length ks == length ts               , Just effs       <- sequence $ zipWith makeDeepWrite ks ts               -> crushEffect $ TSum $ Sum.fromList kEffect effs@@ -72,22 +103,24 @@          -- See Note: Crushing with higher kinded type vars.          | Just (TyConSpec TcConDeepAlloc, [t]) <- takeTyConApps tt          -> case takeTyConApps t of-             Just (TyConBound u, ts)-              | (ks, _)  <- takeKFuns (typeOfBound u)+             Just (TyConBound _ k, ts)+              | (ks, _)  <- takeKFuns k               , length ks == length ts               , Just effs       <- sequence $ zipWith makeDeepAlloc ks ts               -> crushEffect $ TSum $ Sum.fromList kEffect effs               _ -> tt -         -- TODO: we're hijacking crushEffect to work on witnesses as well.-         --       we should split this into another function.          -- Deep Global          -- See Note: Crushing with higher kinded type vars.+         --+         -- NOTE: We're hijacking crushEffect to work on witnesses as well.+         --       It would be better to split this into another function.+         --          | Just (TyConWitness TwConDeepGlobal, [t]) <- takeTyConApps tt          -> case takeTyConApps t of-             Just (TyConBound u, ts)-              | (ks, _)  <- takeKFuns (typeOfBound u)+             Just (TyConBound _ k, ts)+              | (ks, _)  <- takeKFuns k               , length ks == length ts               , Just props       <- sequence $ zipWith makeDeepGlobal ks ts               -> crushEffect $ TSum $ Sum.fromList kWitness props
DDC/Type/Transform/Instantiate.hs view
@@ -10,7 +10,12 @@  -- | Instantiate a type with an argument. --   The type to be instantiated must have an outer forall, else `Nothing`.-instantiateT :: (Ord n, Pretty n) => Type n -> Type n -> Maybe (Type n)+instantiateT +        :: (Ord n, Pretty n) +        => Type n               -- ^ Type to instantiate.+        -> Type n               -- ^ Argument type.+        -> Maybe (Type n)+ instantiateT (TForall b tBody) t2 = Just $ substituteT b t2 tBody instantiateT _ _                  = Nothing @@ -18,7 +23,12 @@ -- | Instantiate a type with several arguments. --   The type to be instantiated must have at least as many outer foralls  --   as provided type arguments, else `Nothing`.-instantiateTs :: (Ord n, Pretty n) => Type n -> [Type n] -> Maybe (Type n)+instantiateTs +        :: (Ord n, Pretty n) +        => Type n               -- ^ Type to instantiate.+        -> [Type n]             -- ^ Argument types.+        -> Maybe (Type n)+ instantiateTs t []              = Just t instantiateTs t (tArg:tsArgs)  = case instantiateT t tArg of
DDC/Type/Transform/LiftT.hs view
@@ -1,63 +1,109 @@  -- | Lifting of deBruijn indices in a type.-------   TODO: merge this code with LowerT module DDC.Type.Transform.LiftT-        (LiftT(..))+        ( liftT,        liftAtDepthT+        , lowerT,       lowerAtDepthT+        , MapBoundT(..)) where import DDC.Type.Exp import DDC.Type.Compounds import qualified DDC.Type.Sum   as Sum  -class LiftT (c :: * -> *) where-- -- | Lift type indices that are at least a certain depth by the given number of levels.- liftAtDepthT   -        :: forall n. Ord n+-- Lift -----------------------------------------------------------------------+-- | Lift debruijn indices less than or equal to the given depth.+liftAtDepthT+        :: MapBoundT c n         => Int          -- ^ Number of levels to lift.         -> Int          -- ^ Current binding depth.-        -> c n          -- ^ Lift type indices in this thing.+        -> c n          -- ^ Lift expression indices in this thing.         -> c n- - -- | Wrapper for `liftAtDepthT` that starts at depth 0.       - liftT  :: forall n. Ord n-        => Int          -- ^ Number of levels to lift-        -> c n          -- ^ Lift type indices in this thing.++liftAtDepthT n d+ = mapBoundAtDepthT liftU d+ where  +        liftU d' u+         = case u of+                UName{}         -> u+                UPrim{}         -> u+                UIx i+                 | d' <= i      -> UIx (i + n)+                 | otherwise    -> u+++-- | Wrapper for `liftAtDepthX` that starts at depth 0.       +liftT   :: MapBoundT c n => Int -> c n -> c n+liftT n xx  = liftAtDepthT n 0 xx+++-- Lower ----------------------------------------------------------------------+-- | Lower debruijn indices less than or equal to the given depth.+lowerAtDepthT+        :: MapBoundT c n+        => Int          -- ^ Number of levels to lower.+        -> Int          -- ^ Current binding depth.+        -> c n          -- ^ Lower expression indices in this thing.         -> c n-        - liftT n xx  = liftAtDepthT n 0 xx-  -instance LiftT Bind where- liftAtDepthT n d bb-  = replaceTypeOfBind (liftAtDepthT n d $ typeOfBind bb) bb-  +lowerAtDepthT n d+ = mapBoundAtDepthT lowerU d+ where  +        lowerU d' u+         = case u of+                UName{}         -> u+                UPrim{}         -> u+                UIx i+                 | d' <= i      -> UIx (i - n)+                 | otherwise    -> u -instance LiftT Bound where- liftAtDepthT n d uu-  = case uu of-        UName{}         -> uu-        UPrim{}         -> uu-        UIx i t -         | d <= i       -> UIx (i + n) t-         | otherwise    -> uu-          -instance LiftT Type where- liftAtDepthT n d tt-  = let down = liftAtDepthT n+-- | Wrapper for `lowerAtDepthX` that starts at depth 0.       +lowerT   :: MapBoundT c n => Int -> c n -> c n+lowerT n xx  = lowerAtDepthT n 0 xx+++-- MapBoundT ------------------------------------------------------------------+class MapBoundT (c :: * -> *) n where+ -- | Apply a function to all bound variables in the program.+ --   The function is passed the current binding depth.+ --   This is used to defined both `liftT` and `lowerT`.+ mapBoundAtDepthT+        :: (Int -> Bound n -> Bound n)  +                        -- ^ Function to apply to the bound occ.+                        --   It is passed the current binding depth.+        -> Int          -- ^ Current binding depth.+        -> c n          -- ^ Lift expression indices in this thing.+        -> c n+++instance Ord n => MapBoundT Bind n where+ mapBoundAtDepthT f d bb+  = replaceTypeOfBind (mapBoundAtDepthT f d $ typeOfBind bb) bb+++instance MapBoundT Bound n where+ mapBoundAtDepthT f d u+        = f d u+++instance Ord n => MapBoundT Type n where+ mapBoundAtDepthT f d tt+  = let down = mapBoundAtDepthT f d     in case tt of-        TVar u          -> TVar    (down d u)+        TVar u          -> TVar    (f d u)         TCon{}          -> tt-        TForall b t     -> TForall (down d b)  (down (d + 1) t)-        TApp t1 t2      -> TApp    (down d t1) (down d t2)-        TSum ss         -> TSum    (down d ss)+        TForall b t     -> TForall b (mapBoundAtDepthT f (d + countBAnons [b]) t)+        TApp t1 t2      -> TApp    (down t1) (down t2)+        TSum ss         -> TSum    (down ss)  -instance LiftT TypeSum where- liftAtDepthT n d ss-  = Sum.fromList (liftAtDepthT n d $ Sum.kindOfSum ss)-        $ map (liftAtDepthT n d)+instance Ord n => MapBoundT TypeSum n where+ mapBoundAtDepthT f d ss+  = Sum.fromList (Sum.kindOfSum ss)+        $ map (mapBoundAtDepthT f d)         $ Sum.toList ss++countBAnons = length . filter isAnon+ where	isAnon (BAnon _) = True+	isAnon _	 = False 
− DDC/Type/Transform/LowerT.hs
@@ -1,63 +0,0 @@---- | Lowering of deBruijn indices in a type.-------   TODO: merge this code with LiftT.-module DDC.Type.Transform.LowerT-        (LowerT(..))-where-import DDC.Type.Exp-import DDC.Type.Compounds-import qualified DDC.Type.Sum   as Sum---class LowerT (c :: * -> *) where-- -- | Lower type indices that are at least a certain depth by the given number of levels.- lowerAtDepthT   -        :: forall n. Ord n-        => Int          -- ^ Number of levels to lower.-        -> Int          -- ^ Current binding depth.-        -> c n          -- ^ Lower type indices in this thing.-        -> c n- - -- | Wrapper for `lowerAtDepthT` that starts at depth 0.       - lowerT :: forall n. Ord n-        => Int          -- ^ Number of levels to lower.-        -> c n          -- ^ Lower type indices in this thing.-        -> c n-        - lowerT n xx  = lowerAtDepthT n 0 xx- --instance LowerT Bind where- lowerAtDepthT n d bb-  = replaceTypeOfBind (lowerAtDepthT n d $ typeOfBind bb) bb-  --instance LowerT Bound where- lowerAtDepthT n d uu-  = case uu of-        UName{}         -> uu-        UPrim{}         -> uu-        UIx i t -         | d <= i       -> UIx (i - n) t-         | otherwise    -> uu-         --instance LowerT Type where- lowerAtDepthT n d tt-  = let down = lowerAtDepthT n -    in case tt of-        TVar uu         -> TVar    (down d uu)-        TCon{}          -> tt-        TForall b t     -> TForall (down d b)  (down (d + 1) t)-        TApp t1 t2      -> TApp    (down d t1) (down d t2)-        TSum ss         -> TSum    (down d ss)---instance LowerT TypeSum where- lowerAtDepthT n d ss-  = Sum.fromList (lowerAtDepthT n d $ Sum.kindOfSum ss)-        $ map (lowerAtDepthT n d)-        $ Sum.toList ss-
+ DDC/Type/Transform/Rename.hs view
@@ -0,0 +1,246 @@++-- | Renaming of variable binders to anonymous form to avoid capture.+module DDC.Type.Transform.Rename+        ( Rename(..)++        -- * Substitution states+        , Sub(..)++        -- * Binding stacks+        , BindStack(..)+        , pushBind+        , pushBinds+        , substBound++        -- * Rewriting binding occurences+        , bind1, bind1s, bind0, bind0s++        -- * Rewriting bound occurences+        , use1,  use0)+where+import DDC.Type.Compounds+import DDC.Type.Exp+import Data.List+import Data.Set                         (Set)+import qualified DDC.Type.Sum           as Sum+import qualified Data.Set               as Set+++-------------------------------------------------------------------------------+class Rename (c :: * -> *) where+ -- | Rewrite names in some thing to anonymous form if they conflict with+--    any names in the `Sub` state. We use this to avoid variable capture+--    during substitution.+ renameWith :: Ord n => Sub n -> c n -> c n +++instance Rename Type where+ renameWith sub tt +  = {-# SCC renameWith #-}+    let down    = renameWith +    in case tt of+        TVar u          -> TVar (use1 sub u)+        TCon{}          -> tt++        TForall b t+         -> let (sub1, b')      = bind1 sub b+                t'              = down  sub1 t+            in  TForall b' t'++        TApp t1 t2      -> TApp (down sub t1) (down sub t2)+        TSum ts         -> TSum (down sub ts)+++instance Rename TypeSum where+ renameWith sub ts+        = Sum.fromList (Sum.kindOfSum ts)+        $ map (renameWith sub)+        $ Sum.toList ts+++instance Rename Bind where+ renameWith sub bb+  = replaceTypeOfBind  (renameWith sub (typeOfBind bb))  bb+++-------------------------------------------------------------------------------+-- | Substitution state.+--   Keeps track of the binders in the environment that have been rewrittten+--   to avoid variable capture or spec binder shadowing.+data Sub n+        = Sub+        { -- | Bound variable that we're substituting for.+          subBound      :: !(Bound n)++          -- | We've decended past a binder that shadows the one that we're+          --   substituting for. We're no longer substituting, but still may+          --   need to anonymise variables in types. +          --   This can only happen for level-0 named binders.+        , subShadow0    :: !Bool ++          -- | Level-1 names that need to be rewritten to avoid capture.+        , subConflict1  :: !(Set n)++          -- | Level-0 names that need to be rewritten to avoid capture.+        , subConflict0  :: !(Set n)++          -- | Rewriting stack for level-1 names.+        , subStack1     :: !(BindStack n)++          -- | Rewriting stack for level-0 names.+        , subStack0     :: !(BindStack n)  }+++-- | Stack of anonymous binders that we've entered under during substitution. +data BindStack n+        = BindStack+        { -- | Holds anonymous binders that were already in the program,+          --   as well as named binders that are being rewritten to anonymous ones.+          --   In the resulting expression all these binders will be anonymous.+          stackBinds    :: ![Bind n]++          -- | Holds all binders, independent of whether they are being rewritten or not.+        , stackAll      :: ![Bind n] ++          -- | Number of `BAnon` in `stackBinds`.+        , stackAnons    :: !Int++          -- | Number of `BName` in `stackBinds`.+        , stackNamed    :: !Int }+++-- | Push several binds onto the bind stack,+--   anonymyzing them if need be to avoid variable capture.+pushBinds :: Ord n => Set n -> BindStack n -> [Bind n]  -> (BindStack n, [Bind n])+pushBinds fns stack bs+        = mapAccumL (pushBind fns) stack bs+++-- | Push a bind onto a bind stack, +--   anonymizing it if need be to avoid variable capture.+pushBind+        :: Ord n+        => Set n                  -- ^ Names that need to be rewritten.+        -> BindStack n            -- ^ Current bind stack.+        -> Bind n                 -- ^ Bind to push.+        -> (BindStack n, Bind n)  -- ^ New stack and possibly anonymised bind.++pushBind fns bs@(BindStack stack env dAnon dName) bb+ = case bb of+        -- Push already anonymous bind on stack.+        BAnon t                 +         -> ( BindStack (BAnon t   : stack) (BAnon t : env) (dAnon + 1) dName+            , BAnon t)+            +        -- If the binder needs to be rewritten then push the original name on the+        -- 'stackBinds' to remember this.+        BName n t+         | Set.member n fns     +         -> ( BindStack (BName n t : stack) (BAnon t : env)  dAnon       (dName + 1)+            , BAnon t)++         | otherwise+         -> ( BindStack stack               (BName n t : env) dAnon dName+            , bb)++        -- Binder was a wildcard.+        _ -> (bs, bb)++++-- | Compare a `Bound` against the one we're substituting for.+substBound+        :: Ord n+        => BindStack n      -- ^ Current Bind stack during substitution.+        -> Bound n          -- ^ Bound we're substituting for.+        -> Bound n          -- ^ Bound we're looking at now.+        -> Either +                (Bound n)   --   Bound doesn't match, but replace with this one.+                Int         --   Bound matches, drop the thing being substituted and +                            --   and lift indices this many steps.++substBound (BindStack binds _ dAnon dName) u u'+        -- Bound name matches the one that we're substituting for.+        | UName n1      <- u+        , UName n2      <- u'+        , n1 == n2+        = Right (dAnon + dName)++        -- Bound index matches the one that we're substituting for.+        | UIx  i1       <- u+        , UIx  i2       <- u'+        , i1 + dAnon == i2 +        = Right (dAnon + dName)++        -- The Bind for this name was rewritten to avoid variable capture,+        -- so we also have to update the bound occurrence.+        | UName _       <- u'+        , Just ix       <- findIndex (boundMatchesBind u') binds+        = Left $ UIx ix++        -- Bound index doesn't match, but lower this index by one to account+        -- for the removal of the outer binder.+        | UIx  i2       <- u'+        , i2 > dAnon+        , cutOffset     <- case u of+                                UIx{}   -> 1+                                _       -> 0+        = Left $ UIx (i2 + dName - cutOffset)++        -- Some name that didn't match.+        | otherwise+        = Left u'+++-------------------------------------------------------------------------------+-- | Push a level-1 binder on the rewrite stack.+bind1 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)+bind1 sub b + = let  (stackT', b')     = pushBind (subConflict1 sub) (subStack1 sub) b+   in   (sub { subStack1  = stackT' }, b')+++-- | Push some level-1 binders on the rewrite stack.+bind1s :: Ord n => Sub n -> [Bind n] -> (Sub n, [Bind n])+bind1s = mapAccumL bind1+++-- | Push a level-0 binder on the rewrite stack.+bind0 :: Ord n => Sub n -> Bind n -> (Sub n, Bind n)+bind0 sub b + = let  b1                  = renameWith sub b+        (stackX', b2)       = pushBind (subConflict0 sub) (subStack0 sub) b1+   in   ( sub { subStack0   = stackX'+              , subShadow0  =  subShadow0 sub +                            || namedBoundMatchesBind (subBound sub) b2 }+        , b2)+++-- | Push some level-0 binders on the rewrite stack.+bind0s :: Ord n => Sub n -> [Bind n] -> (Sub n, [Bind n])+bind0s = mapAccumL bind0+++-- | Rewrite the use of a level-1 binder if need be.+use1 :: Ord n => Sub n -> Bound n -> Bound n+use1 sub u+        | UName _               <- u+        , BindStack binds _ _ _ <- subStack1 sub+        , Just ix               <- findIndex (boundMatchesBind u) binds+        = UIx ix++        | otherwise+        = u+++-- | Rewrite the use of a level-0 binder if need be.+use0 :: Ord n => Sub n -> Bound n -> Bound n+use0 sub u+        | UName _               <- u+        , BindStack binds _ _ _ <- subStack0 sub+        , Just ix               <- findIndex (boundMatchesBind u) binds+        = UIx ix++        | otherwise+        = u+
DDC/Type/Transform/SpreadT.hs view
@@ -3,17 +3,19 @@         (SpreadT(..)) where import DDC.Type.Exp-import DDC.Type.Env                     (Env)+import DDC.Type.Env                     (TypeEnv) import qualified DDC.Type.Env           as Env import qualified DDC.Type.Sum           as T   class SpreadT (c :: * -> *) where - -- | Spread type annotations from variable binders in to the bound- --   occurrences.+ -- | Rewrite `UName` bounds to `UPrim` bounds and attach their types.+ --   Primitives have their types attached because they are so common in the+ --   language, their types are closed, and we don't want to keep having to+ --   look them up from the environment.  spreadT :: forall n. Ord n -         => Env n -> c n -> c n+         => TypeEnv n -> c n -> c n           instance SpreadT Type where@@ -47,21 +49,23 @@  instance SpreadT Bound where  spreadT kenv uu-  | Just t'     <- Env.lookup uu kenv   = case uu of-        UIx ix _        -> UIx ix t'-        UPrim n _       -> UPrim n t'-        UName n _-         -> if Env.isPrim kenv n -                 then UPrim n t'-                 else UName n t'-                 -  | otherwise           = uu+        UIx{}           -> uu+        UPrim{}         -> uu +        UName n+         -> case Env.envPrimFun kenv n of+                Nothing -> UName n+                Just t  -> UPrim n t+                   instance SpreadT TyCon where  spreadT kenv tc   = case tc of-        TyConBound u    -> TyConBound (spreadT kenv u)+        TyConBound (UName n) _+         -> case Env.envPrimFun kenv n of+                Nothing -> tc+                Just t  -> TyConBound (UPrim n t) t+         _               -> tc 
DDC/Type/Transform/SubstituteT.hs view
@@ -1,23 +1,23 @@  -- | Capture avoiding substitution of types in types. module DDC.Type.Transform.SubstituteT-        ( SubstituteT(..)-        , substituteT+        ( substituteT         , substituteTs         , substituteBoundT+        , SubstituteT(..)          , BindStack(..)         , pushBind         , pushBinds         , substBound) where-import DDC.Type.Exp+import DDC.Type.Collect import DDC.Type.Compounds-import DDC.Core.Collect import DDC.Type.Transform.LiftT import DDC.Type.Transform.Crush import DDC.Type.Transform.Trim-import DDC.Type.Rewrite+import DDC.Type.Transform.Rename+import DDC.Type.Exp import Data.Maybe import qualified DDC.Type.Sum   as Sum import qualified DDC.Type.Env   as Env
DDC/Type/Transform/Trim.hs view
@@ -2,7 +2,7 @@ module DDC.Type.Transform.Trim          (trimClosure) where-import DDC.Core.Collect+import DDC.Type.Collect import DDC.Type.Check.CheckCon import DDC.Type.Exp import DDC.Type.Compounds@@ -18,19 +18,22 @@ -- --   This is like `crushEffect`, but for closures instead of effects. -----   For example, trimming @Int r2 -(Read r1 | Use r1)> Int r2@ yields just @Use r1@. +--   For example, trimming @DeepUse (Int r2 -(Read r1 | Use r1)> Int r2)@ yields+--   just @Use r1@.  --   Only @r1@ might contain an actual store object that is reachable from a function --   closure with such a type. -- --   This function assumes the closure is well-kinded, and may return `Nothing` if --   this is not the case.+-- trimClosure          :: Ord n         => Closure n          -> Maybe (Closure n)  trimClosure cc-        = liftM TSum $ trimToSumC cc+        = {-# SCC trimClosure #-}+          liftM TSum $ trimToSumC cc   -- | Trim a closure down to a closure sum.
DDC/Type/Universe.hs view
@@ -1,5 +1,4 @@ --- | Universes of the Disciple Core language. module DDC.Type.Universe         ( Universe(..)         , universeFromType3@@ -8,7 +7,8 @@         , universeOfType) where import DDC.Type.Exp-import DDC.Type.Compounds+import DDC.Base.Pretty+import DDC.Type.Env             as Env import qualified DDC.Type.Sum   as T  @@ -45,6 +45,16 @@         deriving (Show, Eq)   +instance Pretty Universe where+ ppr u+  = case u of+        UniverseSort    -> text "Sort"+        UniverseKind    -> text "Kind"+        UniverseSpec    -> text "Spec"+        UniverseWitness -> text "Witness"+        UniverseData    -> text "Data"++ -- | Given the type of the type of the type of some thing (up three levels), --   yield the universe of the original thing, or `Nothing` it was badly formed. universeFromType3 :: Type n -> Maybe Universe@@ -69,9 +79,9 @@                 KiConData       -> Just UniverseData                 _               -> Nothing -        TCon (TyConWitness _)   -> Nothing-        TCon (TyConSpec  _)     -> Nothing-        TCon (TyConBound _)     -> Nothing+        TCon TyConWitness{}     -> Nothing+        TCon TyConSpec{}        -> Nothing+        TCon TyConBound{}       -> Nothing         TForall _ _             -> Nothing         TApp _ t2               -> universeFromType2 t2         TSum _                  -> Nothing@@ -79,38 +89,47 @@  -- | Given the type of some thing (up one level), --   yield the universe of the original thing, or `Nothing` if it was badly formed.-universeFromType1 :: Type n -> Maybe Universe-universeFromType1 tt+universeFromType1 :: Ord n => Env n -> Type n -> Maybe Universe+universeFromType1 kenv tt  = case tt of-        TVar u                    -> universeFromType2 (typeOfBound u)-        TCon (TyConSort _)        -> Just UniverseKind-        TCon (TyConKind _)        -> Just UniverseSpec-        TCon (TyConWitness _)     -> Just UniverseWitness-        TCon (TyConSpec TcConFun) -> Just UniverseData-        TCon (TyConSpec _)        -> Nothing-        TCon (TyConBound u)       -> universeFromType2 (typeOfBound u)-        TForall _ t2              -> universeFromType1 t2-        TApp _ t2                 -> universeFromType1 t2-        TSum _                    -> Nothing+        TVar n+         -> case Env.lookup n kenv of+                Nothing            -> Nothing+                Just k             -> universeFromType2 k +        TCon (TyConSort _)         -> Just UniverseKind+        TCon (TyConKind _)         -> Just UniverseSpec+        TCon (TyConWitness _)      -> Just UniverseWitness+        TCon (TyConSpec TcConFun)  -> Just UniverseData+        TCon (TyConSpec TcConUnit) -> Just UniverseData+        TCon (TyConSpec _)         -> Nothing+        TCon (TyConBound _ k)      -> universeFromType2 k+        TForall b t2               -> universeFromType1 (Env.extend b kenv) t2+        TApp t1 _                  -> universeFromType1 kenv t1+        TSum _                     -> Nothing + -- | Yield the universe of some type. -- -- @  universeOfType (tBot kEffect) = UniverseSpec --  universeOfType kRegion        = UniverseKind -- @ ---universeOfType :: Type n -> Maybe Universe-universeOfType tt+universeOfType :: Ord n => Env n -> Type n -> Maybe Universe+universeOfType kenv tt  = case tt of-        TVar u                  -> universeFromType1 (typeOfBound u)+        TVar n+         -> case Env.lookup n kenv of+                Nothing         -> Nothing+                Just k          -> universeFromType1 kenv k+         TCon (TyConSort _)      -> Just UniverseSort         TCon (TyConKind _)      -> Just UniverseKind         TCon (TyConWitness _)   -> Just UniverseSpec         TCon (TyConSpec _)      -> Just UniverseSpec-        TCon (TyConBound u)     -> universeFromType1 (typeOfBound u)-        TForall _ t2            -> universeOfType t2-        TApp _ t2               -> universeOfType t2-        TSum ss                 -> universeFromType1 (T.kindOfSum ss)+        TCon (TyConBound _ k)   -> universeFromType1 kenv k+        TForall b t2            -> universeOfType (Env.extend b kenv) t2+        TApp _ t2               -> universeOfType kenv t2+        TSum ss                 -> universeFromType1 kenv (T.kindOfSum ss)  
ddc-core.cabal view
@@ -1,5 +1,5 @@ Name:           ddc-core-Version:        0.2.1.2+Version:        0.3.1.1 License:        MIT License-file:   LICENSE Author:         The Disciplined Disciple Compiler Strike Force@@ -10,73 +10,116 @@ Category:       Compilers/Interpreters Homepage:       http://disciple.ouroborus.net Bug-reports:    disciple@ouroborus.net-Synopsis:       Disciple Core language and type checker.+Synopsis:       Disciplined Disciple Compiler core language and type checker. Description:             Disciple Core is an explicitly typed language based on System-F2, intended-        as an intermediate representation for a compiler. In addition to the features of +        as an intermediate representation for a compiler. In addition to the polymorphism of          System-F2 it supports region, effect and closure typing. Evaluation order is          left-to-right call-by-value by default, but explicit lazy evaluation is also supported.-        There is also a capability system to track whether objects are mutable or constant,+        There is a capability system to track whether objects are mutable or constant,         and to ensure that computations that perform visible side effects are not suspended with         lazy evaluation. -        See the @ddci-core@ package for a user-facing interpreter.+        See the @ddc-tools@ package for a user-facing interpreter and compiler.  Library   Build-Depends:          base            == 4.6.*,+        deepseq         == 1.3.*,         containers      == 0.5.*,         array           == 0.4.*,+        directory       == 1.2.*,         transformers    == 0.3.*,         mtl             == 2.1.*,-        ddc-base        == 0.2.1.*+        ddc-base        == 0.3.1.*    Exposed-modules:-        DDC.Core.Check.CheckExp-        DDC.Core.Check.CheckWitness-        DDC.Core.Check.Error-        DDC.Core.Check.TaggedClosure-        DDC.Core.Parser.Lexer-        DDC.Core.Parser.Tokens-        DDC.Core.Transform.LiftW+        DDC.Core.Lexer.Names+        DDC.Core.Lexer.Tokens++        DDC.Core.Transform.LiftT         DDC.Core.Transform.LiftX+        DDC.Core.Transform.Reannotate+        DDC.Core.Transform.Rename         DDC.Core.Transform.SpreadX         DDC.Core.Transform.SubstituteTX         DDC.Core.Transform.SubstituteWX         DDC.Core.Transform.SubstituteXX+        DDC.Core.Transform.Trim+         DDC.Core.Check         DDC.Core.Collect         DDC.Core.Compounds-        DDC.Core.DataDef+        DDC.Core.DaCon         DDC.Core.Exp-        DDC.Core.Pretty-        DDC.Core.Predicates+        DDC.Core.Fragment+        DDC.Core.Lexer+        DDC.Core.Load+        DDC.Core.Module         DDC.Core.Parser-        DDC.Type.Check.Monad+        DDC.Core.Predicates+        DDC.Core.Pretty+         DDC.Type.Transform.Crush         DDC.Type.Transform.Instantiate         DDC.Type.Transform.LiftT-        DDC.Type.Transform.LowerT+        DDC.Type.Transform.Rename         DDC.Type.Transform.SpreadT         DDC.Type.Transform.SubstituteT         DDC.Type.Transform.Trim+        DDC.Type.Bind         DDC.Type.Check+        DDC.Type.Collect         DDC.Type.Compounds+        DDC.Type.DataDef         DDC.Type.Env         DDC.Type.Equiv         DDC.Type.Exp-        DDC.Type.Parser         DDC.Type.Predicates-        DDC.Type.Rewrite+        DDC.Type.Pretty         DDC.Type.Subsumes         DDC.Type.Sum         DDC.Type.Universe    Other-modules:+        DDC.Core.Check.CheckDaCon+        DDC.Core.Check.CheckExp+        DDC.Core.Check.CheckModule+        DDC.Core.Check.CheckWitness         DDC.Core.Check.ErrorMessage+        DDC.Core.Check.Error+        DDC.Core.Check.TaggedClosure++        DDC.Core.Collect.Support+        DDC.Core.Collect.Free++        DDC.Core.Exp.Base+        DDC.Core.Exp.NFData++        DDC.Core.Fragment.Compliance+        DDC.Core.Fragment.Error+        DDC.Core.Fragment.Feature+        DDC.Core.Fragment.Profile++        DDC.Core.Lexer.Comments+        DDC.Core.Lexer.Offside++        DDC.Core.Parser.Base+        DDC.Core.Parser.Exp+        DDC.Core.Parser.Module+        DDC.Core.Parser.Param+        DDC.Core.Parser.Type+        DDC.Core.Parser.Witness+         DDC.Type.Check.CheckCon-        DDC.Type.Check.CheckError-        DDC.Type.Pretty+        DDC.Type.Check.Error+        DDC.Type.Check.ErrorMessage++        DDC.Type.Collect.FreeT++        DDC.Type.Exp.Base+        DDC.Type.Exp.NFData+                      GHC-options:         -Wall@@ -85,6 +128,7 @@         -fno-warn-unused-do-bind    Extensions:+        BangPatterns         ParallelListComp         PatternGuards         RankNTypes@@ -97,4 +141,6 @@         ScopedTypeVariables         StandaloneDeriving         DoAndIfThenElse-        +        DeriveDataTypeable+        ViewPatterns+