{-# Language ImplicitParams #-} module Cryptol.IR.TraverseNames where import Data.Set(Set) import qualified Data.Set as Set import Data.Functor.Identity import Cryptol.ModuleSystem.Name(nameUnique) import Cryptol.Utils.RecordMap(traverseRecordMap) import Cryptol.Parser.Position(Located(..)) import Cryptol.TypeCheck.AST import Cryptol.TypeCheck.FFI.FFIType traverseNames :: (TraverseNames t, Applicative f) => (Name -> f Name) -> (t -> f t) traverseNames f = let ?name = f in traverseNamesIP mapNames :: (TraverseNames t) => (Name -> Name) -> t -> t mapNames f x = result where Identity result = let ?name = pure . f in traverseNamesIP x class TraverseNames t where traverseNamesIP :: (Applicative f, ?name :: Name -> f Name) => t -> f t instance TraverseNames a => TraverseNames [a] where traverseNamesIP = traverse traverseNamesIP instance TraverseNames a => TraverseNames (Maybe a) where traverseNamesIP = traverse traverseNamesIP instance (Ord a, TraverseNames a) => TraverseNames (Set a) where traverseNamesIP = fmap Set.fromList . traverseNamesIP . Set.toList instance TraverseNames a => TraverseNames (Located a) where traverseNamesIP (Located r a) = Located r <$> traverseNamesIP a instance TraverseNames Name where traverseNamesIP = ?name instance (Ord a, TraverseNames a) => TraverseNames (ExportSpec a) where traverseNamesIP (ExportSpec mp) = ExportSpec <$> traverse traverseNamesIP mp instance TraverseNames Expr where traverseNamesIP expr = case expr of EList es t -> EList <$> traverseNamesIP es <*> traverseNamesIP t ETuple es -> ETuple <$> traverseNamesIP es ERec mp -> ERec <$> traverseRecordMap (\_ -> traverseNamesIP) mp ESel e l -> (`ESel` l) <$> traverseNamesIP e ESet t e1 l e2 -> ESet <$> traverseNamesIP t <*> traverseNamesIP e1 <*> pure l <*> traverseNamesIP e2 EIf e1 e2 e3 -> EIf <$> traverseNamesIP e1 <*> traverseNamesIP e2 <*> traverseNamesIP e3 EComp t1 t2 e mss -> EComp <$> traverseNamesIP t1 <*> traverseNamesIP t2 <*> traverseNamesIP e <*> traverseNamesIP mss EVar x -> EVar <$> traverseNamesIP x ETAbs tp e -> ETAbs <$> traverseNamesIP tp <*> traverseNamesIP e ETApp e t -> ETApp <$> traverseNamesIP e <*> traverseNamesIP t EApp e1 e2 -> EApp <$> traverseNamesIP e1 <*> traverseNamesIP e2 EAbs x t e -> EAbs <$> traverseNamesIP x <*> traverseNamesIP t <*> traverseNamesIP e ELocated r e -> ELocated r <$> traverseNamesIP e EProofAbs p e -> EProofAbs <$> traverseNamesIP p <*> traverseNamesIP e EProofApp e -> EProofApp <$> traverseNamesIP e EWhere e ds -> EWhere <$> traverseNamesIP e <*> traverseNamesIP ds EPropGuards gs t -> EPropGuards <$> traverse doG gs <*> traverseNamesIP t where doG (xs, e) = (,) <$> traverseNamesIP xs <*> traverseNamesIP e instance TraverseNames Match where traverseNamesIP mat = case mat of From x t1 t2 e -> From <$> traverseNamesIP x <*> traverseNamesIP t1 <*> traverseNamesIP t2 <*> traverseNamesIP e Let d -> Let <$> traverseNamesIP d instance TraverseNames DeclGroup where traverseNamesIP dg = case dg of NonRecursive d -> NonRecursive <$> traverseNamesIP d Recursive ds -> Recursive <$> traverseNamesIP ds instance TraverseNames Decl where traverseNamesIP decl = mk <$> traverseNamesIP (dName decl) <*> traverseNamesIP (dSignature decl) <*> traverseNamesIP (dDefinition decl) where mk nm sig def = decl { dName = nm , dSignature = sig , dDefinition = def } instance TraverseNames DeclDef where traverseNamesIP d = case d of DPrim -> pure d DForeign t -> DForeign <$> traverseNamesIP t DExpr e -> DExpr <$> traverseNamesIP e instance TraverseNames Schema where traverseNamesIP (Forall as ps t) = Forall <$> traverseNamesIP as <*> traverseNamesIP ps <*> traverseNamesIP t instance TraverseNames TParam where traverseNamesIP tp = mk <$> traverseNamesIP (tpFlav tp) <*> traverseNamesIP (tpInfo tp) -- XXX: module parameters should probably be represented directly -- as (abstract) user-defined types, rather than type variables. where mk f i = case f of TPModParam x -> tp { tpUnique = nameUnique x, tpFlav = f, tpInfo = i } _ -> tp { tpFlav = f, tpInfo = i } instance TraverseNames TPFlavor where traverseNamesIP tpf = case tpf of TPModParam x -> TPModParam <$> traverseNamesIP x TPUnifyVar -> pure tpf TPSchemaParam x -> TPSchemaParam <$> traverseNamesIP x TPTySynParam x -> TPTySynParam <$> traverseNamesIP x TPPropSynParam x -> TPPropSynParam <$> traverseNamesIP x TPNewtypeParam x -> TPNewtypeParam <$> traverseNamesIP x TPPrimParam x -> TPPrimParam <$> traverseNamesIP x instance TraverseNames TVarInfo where traverseNamesIP (TVarInfo r s) = TVarInfo r <$> traverseNamesIP s instance TraverseNames TypeSource where traverseNamesIP src = case src of TVFromModParam x -> TVFromModParam <$> traverseNamesIP x TVFromSignature x -> TVFromSignature <$> traverseNamesIP x TypeWildCard -> pure src TypeOfRecordField {} -> pure src TypeOfTupleField {} -> pure src TypeOfSeqElement -> pure src LenOfSeq -> pure src TypeParamInstNamed x i -> TypeParamInstNamed <$> traverseNamesIP x <*> pure i TypeParamInstPos x i -> TypeParamInstPos <$> traverseNamesIP x <*> pure i DefinitionOf x -> DefinitionOf <$> traverseNamesIP x LenOfCompGen -> pure src TypeOfArg arg -> TypeOfArg <$> traverseNamesIP arg TypeOfRes -> pure src FunApp -> pure src TypeOfIfCondExpr -> pure src TypeFromUserAnnotation -> pure src GeneratorOfListComp -> pure src TypeErrorPlaceHolder -> pure src instance TraverseNames ArgDescr where traverseNamesIP arg = mk <$> traverseNamesIP (argDescrFun arg) where mk n = arg { argDescrFun = n } instance TraverseNames Type where traverseNamesIP ty = case ty of TCon tc ts -> TCon <$> traverseNamesIP tc <*> traverseNamesIP ts TVar x -> TVar <$> traverseNamesIP x TUser x ts t -> TUser <$> traverseNamesIP x <*> traverseNamesIP ts <*> traverseNamesIP t TRec rm -> TRec <$> traverseRecordMap (\_ -> traverseNamesIP) rm TNewtype nt ts -> TNewtype <$> traverseNamesIP nt <*> traverseNamesIP ts instance TraverseNames TCon where traverseNamesIP tcon = case tcon of TC tc -> TC <$> traverseNamesIP tc _ -> pure tcon instance TraverseNames TC where traverseNamesIP tc = case tc of TCAbstract ut -> TCAbstract <$> traverseNamesIP ut _ -> pure tc instance TraverseNames UserTC where traverseNamesIP (UserTC x k) = UserTC <$> traverseNamesIP x <*> pure k instance TraverseNames TVar where traverseNamesIP tvar = case tvar of TVFree x k ys i -> TVFree x k <$> traverseNamesIP ys <*> traverseNamesIP i TVBound x -> TVBound <$> traverseNamesIP x instance TraverseNames Newtype where traverseNamesIP nt = mk <$> traverseNamesIP (ntName nt) <*> traverseNamesIP (ntParams nt) <*> traverseNamesIP (ntConstraints nt) <*> traverseNamesIP (ntConName nt) <*> traverseRecordMap (\_ -> traverseNamesIP) (ntFields nt) where mk a b c d e = nt { ntName = a , ntParams = b , ntConstraints = c , ntConName = d , ntFields = e } instance TraverseNames ModTParam where traverseNamesIP nt = mk <$> traverseNamesIP (mtpName nt) where mk x = nt { mtpName = x } instance TraverseNames ModVParam where traverseNamesIP nt = mk <$> traverseNamesIP (mvpName nt) <*> traverseNamesIP (mvpType nt) where mk x t = nt { mvpName = x, mvpType = t } instance TraverseNames FFIFunType where traverseNamesIP fi = mk <$> traverseNamesIP (ffiArgTypes fi) <*> traverseNamesIP (ffiRetType fi) where mk as b = FFIFunType { ffiTParams = ffiTParams fi , ffiArgTypes = as , ffiRetType = b } instance TraverseNames FFIType where traverseNamesIP ft = case ft of FFIBool -> pure ft FFIBasic _ -> pure ft -- assumes no names here FFIArray sz t -> (`FFIArray` t) <$> traverseNamesIP sz FFITuple ts -> FFITuple <$> traverseNamesIP ts FFIRecord mp -> FFIRecord <$> traverseRecordMap (\_ -> traverseNamesIP) mp instance TraverseNames TySyn where traverseNamesIP ts = mk <$> traverseNamesIP (tsName ts) <*> traverseNamesIP (tsParams ts) <*> traverseNamesIP (tsConstraints ts) <*> traverseNamesIP (tsDef ts) where mk n ps cs t = TySyn { tsName = n , tsParams = ps , tsConstraints = cs , tsDef = t , tsDoc = tsDoc ts }