packages feed

cryptol 2.11.0 → 2.12.0

raw patch · 79 files changed

+6573/−4328 lines, 79 filesdep +prettyprinterdep −prettydep −randomdep ~sbvdep ~simple-smtdep ~what4PVP ok

version bump matches the API change (PVP)

Dependencies added: prettyprinter

Dependencies removed: pretty, random

Dependency ranges changed: sbv, simple-smt, what4

API changes (from Hackage documentation)

- Cryptol.Backend.Monad: type CallStack = Seq (Name, Range)
- Cryptol.Eval.Generic: barrelShifter :: Backend sym => sym -> (SeqMap sym -> Integer -> SEval sym (SeqMap sym)) -> SeqMap sym -> [SBit sym] -> SEval sym (SeqMap sym)
- Cryptol.Eval.Generic: bitsValueLessThan :: Backend sym => sym -> Integer -> [SBit sym] -> Integer -> SEval sym (SBit sym)
- Cryptol.Eval.Generic: ecSplitV :: Backend sym => sym -> Prim sym
- Cryptol.Eval.Generic: enumerateIntBits :: Backend sym => sym -> Nat' -> TValue -> SInteger sym -> SEval sym [SBit sym]
- Cryptol.Eval.Generic: enumerateIntBits' :: Backend sym => sym -> Integer -> SInteger sym -> SEval sym [SBit sym]
- Cryptol.Eval.Generic: extractWordVal :: Backend sym => sym -> Integer -> Integer -> WordValue sym -> SEval sym (WordValue sym)
- Cryptol.Eval.Generic: iteValue :: Backend sym => sym -> SBit sym -> SEval sym (GenValue sym) -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: joinWordVal :: Backend sym => sym -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)
- Cryptol.Eval.Generic: joinWords :: forall sym. Backend sym => sym -> Integer -> Integer -> SeqMap sym -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: mergeSeqMap :: Backend sym => sym -> SBit sym -> SeqMap sym -> SeqMap sym -> SeqMap sym
- Cryptol.Eval.Generic: mergeValue :: Backend sym => sym -> SBit sym -> GenValue sym -> GenValue sym -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: mergeValue' :: Backend sym => sym -> SBit sym -> SEval sym (GenValue sym) -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: mergeWord :: Backend sym => sym -> SBit sym -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)
- Cryptol.Eval.Generic: mergeWord' :: Backend sym => sym -> SBit sym -> SEval sym (WordValue sym) -> SEval sym (WordValue sym) -> SEval sym (WordValue sym)
- Cryptol.Eval.Generic: splitAtV :: Backend sym => sym -> Nat' -> Nat' -> TValue -> GenValue sym -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: splitWordVal :: Backend sym => sym -> Integer -> Integer -> WordValue sym -> SEval sym (WordValue sym, WordValue sym)
- Cryptol.Eval.Generic: wordValLogicOp :: Backend sym => sym -> (SBit sym -> SBit sym -> SEval sym (SBit sym)) -> (SWord sym -> SWord sym -> SEval sym (SWord sym)) -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)
- Cryptol.Eval.Generic: wordValUnaryOp :: Backend sym => sym -> (SBit sym -> SEval sym (SBit sym)) -> (SWord sym -> SEval sym (SWord sym)) -> WordValue sym -> SEval sym (WordValue sym)
- Cryptol.Eval.Value: IndexSeqMap :: !Integer -> SEval sym (GenValue sym) -> SeqMap sym
- Cryptol.Eval.Value: LargeBitsVal :: !Integer -> !SeqMap sym -> WordValue sym
- Cryptol.Eval.Value: UpdateSeqMap :: !Map Integer (SEval sym (GenValue sym)) -> !Integer -> SEval sym (GenValue sym) -> SeqMap sym
- Cryptol.Eval.Value: WordVal :: !SWord sym -> WordValue sym
- Cryptol.Eval.Value: asBitsMap :: Backend sym => sym -> WordValue sym -> SeqMap sym
- Cryptol.Eval.Value: asWordVal :: Backend sym => sym -> WordValue sym -> SEval sym (SWord sym)
- Cryptol.Eval.Value: concatSeqMap :: Integer -> SeqMap sym -> SeqMap sym -> SeqMap sym
- Cryptol.Eval.Value: data SeqMap sym
- Cryptol.Eval.Value: data WordValue sym
- Cryptol.Eval.Value: dropSeqMap :: Integer -> SeqMap sym -> SeqMap sym
- Cryptol.Eval.Value: enumerateSeqMap :: Integral n => n -> SeqMap sym -> [SEval sym (GenValue sym)]
- Cryptol.Eval.Value: enumerateWordValue :: Backend sym => sym -> WordValue sym -> SEval sym [SBit sym]
- Cryptol.Eval.Value: enumerateWordValueRev :: Backend sym => sym -> WordValue sym -> SEval sym [SBit sym]
- Cryptol.Eval.Value: finiteSeqMap :: [SEval sym (GenValue sym)] -> SeqMap sym
- Cryptol.Eval.Value: forceWordValue :: Backend sym => WordValue sym -> SEval sym ()
- Cryptol.Eval.Value: indexWordValue :: Backend sym => sym -> WordValue sym -> Integer -> SEval sym (SBit sym)
- Cryptol.Eval.Value: infiniteSeqMap :: Backend sym => sym -> [SEval sym (GenValue sym)] -> SEval sym (SeqMap sym)
- Cryptol.Eval.Value: instance Cryptol.Backend.Backend sym => GHC.Show.Show (Cryptol.Eval.Value.GenValue sym)
- Cryptol.Eval.Value: instance GHC.Generics.Generic (Cryptol.Eval.Value.WordValue sym)
- Cryptol.Eval.Value: largeBitSize :: Integer
- Cryptol.Eval.Value: lookupSeqMap :: SeqMap sym -> Integer -> SEval sym (GenValue sym)
- Cryptol.Eval.Value: mapSeqMap :: Backend sym => sym -> (GenValue sym -> SEval sym (GenValue sym)) -> SeqMap sym -> SEval sym (SeqMap sym)
- Cryptol.Eval.Value: memoMap :: Backend sym => sym -> SeqMap sym -> SEval sym (SeqMap sym)
- Cryptol.Eval.Value: reverseSeqMap :: Integer -> SeqMap sym -> SeqMap sym
- Cryptol.Eval.Value: splitSeqMap :: Integer -> SeqMap sym -> (SeqMap sym, SeqMap sym)
- Cryptol.Eval.Value: streamSeqMap :: SeqMap sym -> [SEval sym (GenValue sym)]
- Cryptol.Eval.Value: toFinSeq :: Backend sym => sym -> Integer -> TValue -> [GenValue sym] -> GenValue sym
- Cryptol.Eval.Value: toSeq :: Backend sym => sym -> Nat' -> TValue -> [GenValue sym] -> SEval sym (GenValue sym)
- Cryptol.Eval.Value: toStream :: Backend sym => sym -> [GenValue sym] -> SEval sym (GenValue sym)
- Cryptol.Eval.Value: updateSeqMap :: SeqMap sym -> Integer -> SEval sym (GenValue sym) -> SeqMap sym
- Cryptol.Eval.Value: updateWordValue :: Backend sym => sym -> WordValue sym -> Integer -> SEval sym (SBit sym) -> SEval sym (WordValue sym)
- Cryptol.Eval.Value: wordValueSize :: Backend sym => sym -> WordValue sym -> Integer
- Cryptol.Eval.Value: zipSeqMap :: Backend sym => sym -> (GenValue sym -> GenValue sym -> SEval sym (GenValue sym)) -> SeqMap sym -> SeqMap sym -> SEval sym (SeqMap sym)
- Cryptol.ModuleSystem: [meSolverConfig] :: ModuleEnv -> SolverConfig
- Cryptol.ModuleSystem: data Iface
- Cryptol.ModuleSystem.Base: importIface :: Import -> ModuleM (IfaceDecls, NamingEnv)
- Cryptol.ModuleSystem.Base: importIfaces :: [Import] -> ModuleM (IfaceDecls, NamingEnv)
- Cryptol.ModuleSystem.Env: NameIsDynamicDecl :: DeclProvenance
- Cryptol.ModuleSystem.Env: NameIsImportedFrom :: ModName -> DeclProvenance
- Cryptol.ModuleSystem.Env: NameIsLocalPrivate :: DeclProvenance
- Cryptol.ModuleSystem.Env: NameIsLocalPublic :: DeclProvenance
- Cryptol.ModuleSystem.Env: NameIsParameter :: DeclProvenance
- Cryptol.ModuleSystem.Env: [mctxTypeProvenace] :: ModContext -> Map Name DeclProvenance
- Cryptol.ModuleSystem.Env: [mctxValueProvenance] :: ModContext -> Map Name DeclProvenance
- Cryptol.ModuleSystem.Env: [meSolverConfig] :: ModuleEnv -> SolverConfig
- Cryptol.ModuleSystem.Env: data DeclProvenance
- Cryptol.ModuleSystem.Env: instance GHC.Classes.Eq Cryptol.ModuleSystem.Env.DeclProvenance
- Cryptol.ModuleSystem.Env: instance GHC.Classes.Ord Cryptol.ModuleSystem.Env.DeclProvenance
- Cryptol.ModuleSystem.Exports: [eBinds] :: ExportSpec name -> Set name
- Cryptol.ModuleSystem.Exports: [eTypes] :: ExportSpec name -> Set name
- Cryptol.ModuleSystem.Exports: data ExportSpec name
- Cryptol.ModuleSystem.Interface: data Iface
- Cryptol.ModuleSystem.Interface: genIface :: Module -> Iface
- Cryptol.ModuleSystem.Interface: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Interface.Iface
- Cryptol.ModuleSystem.Interface: instance GHC.Generics.Generic Cryptol.ModuleSystem.Interface.Iface
- Cryptol.ModuleSystem.Interface: instance GHC.Show.Show Cryptol.ModuleSystem.Interface.Iface
- Cryptol.ModuleSystem.Interface: mkIfaceDecl :: Decl -> IfaceDecl
- Cryptol.ModuleSystem.Monad: getSolverConfig :: ModuleM SolverConfig
- Cryptol.ModuleSystem.Monad: setSolver :: SolverConfig -> ModuleM ()
- Cryptol.ModuleSystem.Name: cmpNameLexical :: Name -> Name -> Ordering
- Cryptol.ModuleSystem.NamingEnv: [neExprs] :: NamingEnv -> !Map PName [Name]
- Cryptol.ModuleSystem.NamingEnv: [neTypes] :: NamingEnv -> !Map PName [Name]
- Cryptol.ModuleSystem.NamingEnv: data NamingEnv
- Cryptol.ModuleSystem.NamingEnv: interpImport :: Import -> IfaceDecls -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: namingEnv' :: BindsNames a => a -> Supply -> (NamingEnv, Supply)
- Cryptol.ModuleSystem.Renamer: ExpectedType :: Located PName -> NameDisp -> RenamerError
- Cryptol.ModuleSystem.Renamer: ExpectedValue :: Located PName -> NameDisp -> RenamerError
- Cryptol.ModuleSystem.Renamer: UnboundExpr :: Located PName -> NameDisp -> RenamerError
- Cryptol.ModuleSystem.Renamer: UnboundType :: Located PName -> NameDisp -> RenamerError
- Cryptol.ModuleSystem.Renamer: checkNamingEnv :: NamingEnv -> ([RenamerError], [RenamerWarning])
- Cryptol.ModuleSystem.Renamer: instance (GHC.Base.Semigroup a, GHC.Base.Monoid a) => GHC.Base.Monoid (Cryptol.ModuleSystem.Renamer.RenameM a)
- Cryptol.ModuleSystem.Renamer: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Renamer.RenamerError
- Cryptol.ModuleSystem.Renamer: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Renamer.RenamerWarning
- Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Name.FreshM Cryptol.ModuleSystem.Renamer.RenameM
- Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.TopDecl
- Cryptol.ModuleSystem.Renamer: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.Renamer.RenamerError
- Cryptol.ModuleSystem.Renamer: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.Renamer.RenamerWarning
- Cryptol.ModuleSystem.Renamer: instance GHC.Base.Applicative Cryptol.ModuleSystem.Renamer.RenameM
- Cryptol.ModuleSystem.Renamer: instance GHC.Base.Functor Cryptol.ModuleSystem.Renamer.RenameM
- Cryptol.ModuleSystem.Renamer: instance GHC.Base.Monad Cryptol.ModuleSystem.Renamer.RenameM
- Cryptol.ModuleSystem.Renamer: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Cryptol.ModuleSystem.Renamer.RenameM a)
- Cryptol.ModuleSystem.Renamer: instance GHC.Classes.Eq Cryptol.ModuleSystem.Renamer.EnvCheck
- Cryptol.ModuleSystem.Renamer: instance GHC.Generics.Generic Cryptol.ModuleSystem.Renamer.RenamerError
- Cryptol.ModuleSystem.Renamer: instance GHC.Generics.Generic Cryptol.ModuleSystem.Renamer.RenamerWarning
- Cryptol.ModuleSystem.Renamer: instance GHC.Show.Show Cryptol.ModuleSystem.Renamer.EnvCheck
- Cryptol.ModuleSystem.Renamer: instance GHC.Show.Show Cryptol.ModuleSystem.Renamer.RenamerError
- Cryptol.ModuleSystem.Renamer: instance GHC.Show.Show Cryptol.ModuleSystem.Renamer.RenamerWarning
- Cryptol.ModuleSystem.Renamer: namingEnv' :: BindsNames a => a -> Supply -> (NamingEnv, Supply)
- Cryptol.Parser.AST: [mImports] :: Module name -> [Located Import]
- Cryptol.Parser.AST: data Import
- Cryptol.Parser.AST: data Module name
- Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.Module name)
- Cryptol.Parser.AST: instance Control.DeepSeq.NFData Cryptol.Parser.AST.Import
- Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.Module name)
- Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.Module name)
- Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.Module name)
- Cryptol.Parser.AST: instance Cryptol.Utils.PP.PP Cryptol.Parser.AST.Import
- Cryptol.Parser.AST: instance GHC.Classes.Eq Cryptol.Parser.AST.Import
- Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.Module name)
- Cryptol.Parser.AST: instance GHC.Generics.Generic Cryptol.Parser.AST.Import
- Cryptol.Parser.AST: instance GHC.Show.Show Cryptol.Parser.AST.Import
- Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.Module name)
- Cryptol.Parser.Names: allNamesD :: Ord name => Decl name -> [Located name]
- Cryptol.Parser.Names: boundLNames :: Ord name => [Located name] -> Set name -> Set name
- Cryptol.Parser.Names: namesArm :: Ord name => [Match name] -> ([Located name], Set name)
- Cryptol.Parser.Names: namesDef :: Ord name => BindDef name -> Set name
- Cryptol.Parser.Names: namesDs :: Ord name => [Decl name] -> ([Located name], Set name)
- Cryptol.Parser.Names: namesE :: Ord name => Expr name -> Set name
- Cryptol.Parser.Names: namesM :: Ord name => Match name -> ([Located name], Set name)
- Cryptol.Parser.Names: namesPs :: [Pattern name] -> [Located name]
- Cryptol.Parser.Names: namesUF :: Ord name => UpdField name -> Set name
- Cryptol.Parser.Names: tnamesB :: Ord name => Bind name -> Set name
- Cryptol.Parser.Names: tnamesDef :: Ord name => BindDef name -> Set name
- Cryptol.Parser.Names: tnamesDs :: Ord name => [Decl name] -> ([Located name], Set name)
- Cryptol.Parser.Names: tnamesE :: Ord name => Expr name -> Set name
- Cryptol.Parser.Names: tnamesM :: Ord name => Match name -> Set name
- Cryptol.Parser.Names: tnamesP :: Ord name => Pattern name -> Set name
- Cryptol.Parser.Names: tnamesS :: Ord name => Schema name -> Set name
- Cryptol.Parser.Names: tnamesTI :: Ord name => TypeInst name -> Set name
- Cryptol.Parser.Names: tnamesUF :: Ord name => UpdField name -> Set name
- Cryptol.Parser.NoPat: instance Cryptol.Parser.NoPat.RemovePatterns (Cryptol.Parser.AST.Module Cryptol.Parser.Name.PName)
- Cryptol.TypeCheck: [inpSolverConfig] :: InferInput -> SolverConfig
- Cryptol.TypeCheck.AST: ModTParam :: Name -> Kind -> !Int -> Maybe Text -> ModTParam
- Cryptol.TypeCheck.AST: ModVParam :: Name -> Schema -> Maybe Text -> Maybe Fixity -> ModVParam
- Cryptol.TypeCheck.AST: [eBinds] :: ExportSpec name -> Set name
- Cryptol.TypeCheck.AST: [eTypes] :: ExportSpec name -> Set name
- Cryptol.TypeCheck.AST: [mtpDoc] :: ModTParam -> Maybe Text
- Cryptol.TypeCheck.AST: [mtpKind] :: ModTParam -> Kind
- Cryptol.TypeCheck.AST: [mtpName] :: ModTParam -> Name
- Cryptol.TypeCheck.AST: [mtpNumber] :: ModTParam -> !Int
- Cryptol.TypeCheck.AST: [mvpDoc] :: ModVParam -> Maybe Text
- Cryptol.TypeCheck.AST: [mvpFixity] :: ModVParam -> Maybe Fixity
- Cryptol.TypeCheck.AST: [mvpName] :: ModVParam -> Name
- Cryptol.TypeCheck.AST: [mvpType] :: ModVParam -> Schema
- Cryptol.TypeCheck.AST: data ExportSpec name
- Cryptol.TypeCheck.AST: data Import
- Cryptol.TypeCheck.AST: data ModTParam
- Cryptol.TypeCheck.AST: data ModVParam
- Cryptol.TypeCheck.AST: data Module
- Cryptol.TypeCheck.AST: instance Control.DeepSeq.NFData Cryptol.TypeCheck.AST.ModTParam
- Cryptol.TypeCheck.AST: instance Control.DeepSeq.NFData Cryptol.TypeCheck.AST.ModVParam
- Cryptol.TypeCheck.AST: instance Control.DeepSeq.NFData Cryptol.TypeCheck.AST.Module
- Cryptol.TypeCheck.AST: instance Cryptol.Utils.PP.PP (Cryptol.TypeCheck.PP.WithNames Cryptol.TypeCheck.AST.Module)
- Cryptol.TypeCheck.AST: instance Cryptol.Utils.PP.PP Cryptol.TypeCheck.AST.Module
- Cryptol.TypeCheck.AST: instance GHC.Generics.Generic Cryptol.TypeCheck.AST.ModTParam
- Cryptol.TypeCheck.AST: instance GHC.Generics.Generic Cryptol.TypeCheck.AST.ModVParam
- Cryptol.TypeCheck.AST: instance GHC.Generics.Generic Cryptol.TypeCheck.AST.Module
- Cryptol.TypeCheck.AST: instance GHC.Show.Show Cryptol.TypeCheck.AST.ModTParam
- Cryptol.TypeCheck.AST: instance GHC.Show.Show Cryptol.TypeCheck.AST.ModVParam
- Cryptol.TypeCheck.AST: instance GHC.Show.Show Cryptol.TypeCheck.AST.Module
- Cryptol.TypeCheck.AST: mtpParam :: ModTParam -> TParam
- Cryptol.TypeCheck.Depends: AT :: ParameterType Name -> Maybe Text -> TyDecl
- Cryptol.TypeCheck.Depends: NT :: Newtype Name -> Maybe Text -> TyDecl
- Cryptol.TypeCheck.Depends: PS :: PropSyn Name -> Maybe Text -> TyDecl
- Cryptol.TypeCheck.Depends: PT :: PrimType Name -> Maybe Text -> TyDecl
- Cryptol.TypeCheck.Depends: TS :: TySyn Name -> Maybe Text -> TyDecl
- Cryptol.TypeCheck.Depends: class FromDecl d
- Cryptol.TypeCheck.Depends: combine :: [(Name, Located a)] -> InferM (Map Name (Located a))
- Cryptol.TypeCheck.Depends: combineMaps :: [Map Name (Located a)] -> InferM (Map Name (Located a))
- Cryptol.TypeCheck.Depends: data TyDecl
- Cryptol.TypeCheck.Depends: duplicates :: Ord a => [Located a] -> [(a, [Range])]
- Cryptol.TypeCheck.Depends: instance Cryptol.TypeCheck.Depends.FromDecl (Cryptol.Parser.AST.Decl Cryptol.ModuleSystem.Name.Name)
- Cryptol.TypeCheck.Depends: instance Cryptol.TypeCheck.Depends.FromDecl (Cryptol.Parser.AST.TopDecl Cryptol.ModuleSystem.Name.Name)
- Cryptol.TypeCheck.Depends: instance GHC.Show.Show Cryptol.TypeCheck.Depends.TyDecl
- Cryptol.TypeCheck.Depends: isTopDecl :: FromDecl d => d -> Bool
- Cryptol.TypeCheck.Depends: mkScc :: [(a, [Name], [Name])] -> [SCC a]
- Cryptol.TypeCheck.Depends: orderBinds :: [Bind Name] -> [SCC (Bind Name)]
- Cryptol.TypeCheck.Depends: orderTyDecls :: [TyDecl] -> InferM (Either Error [TyDecl])
- Cryptol.TypeCheck.Depends: setDocString :: Maybe Text -> TyDecl -> TyDecl
- Cryptol.TypeCheck.Depends: toBind :: FromDecl d => d -> Maybe (Bind Name)
- Cryptol.TypeCheck.Depends: toParamConstraints :: FromDecl d => d -> [Located (Prop Name)]
- Cryptol.TypeCheck.Depends: toParamFun :: FromDecl d => d -> Maybe (ParameterFun Name)
- Cryptol.TypeCheck.Depends: toTyDecl :: FromDecl d => d -> Maybe TyDecl
- Cryptol.TypeCheck.Infer: inferDs :: FromDecl d => [d] -> ([DeclGroup] -> InferM a) -> InferM a
- Cryptol.TypeCheck.Monad: IsExternal :: DefLoc
- Cryptol.TypeCheck.Monad: IsLocal :: DefLoc
- Cryptol.TypeCheck.Monad: [iAbstractTypes] :: RO -> Map Name (DefLoc, AbstractType)
- Cryptol.TypeCheck.Monad: [iNewtypes] :: RO -> Map Name (DefLoc, Newtype)
- Cryptol.TypeCheck.Monad: [iParamConstraints] :: RO -> [Located Prop]
- Cryptol.TypeCheck.Monad: [iParamFuns] :: RO -> Map Name ModVParam
- Cryptol.TypeCheck.Monad: [iParamTypes] :: RO -> Map Name ModTParam
- Cryptol.TypeCheck.Monad: [iTSyns] :: RO -> Map Name (DefLoc, TySyn)
- Cryptol.TypeCheck.Monad: [inpSolverConfig] :: InferInput -> SolverConfig
- Cryptol.TypeCheck.Monad: data DefLoc
- Cryptol.TypeCheck.Monad: withDecls :: ([TySyn], Map Name Schema) -> InferM a -> InferM a
- Cryptol.TypeCheck.Monad: withNewtype :: Newtype -> InferM a -> InferM a
- Cryptol.TypeCheck.Monad: withParamFuns :: [ModVParam] -> InferM a -> InferM a
- Cryptol.TypeCheck.Monad: withParamType :: ModTParam -> InferM a -> InferM a
- Cryptol.TypeCheck.Monad: withParameterConstraints :: [Located Prop] -> InferM a -> InferM a
- Cryptol.TypeCheck.Monad: withPrimType :: AbstractType -> InferM a -> InferM a
- Cryptol.TypeCheck.Monad: withTySyn :: TySyn -> InferM a -> InferM a
- Cryptol.Utils.PP: alwaysQualify :: NameDisp
- Cryptol.Utils.PP: empty :: Doc
- Cryptol.Utils.PP: fmtModName :: ModName -> NameFormat -> Text
- Cryptol.Utils.PP: liftPJ :: Doc -> Doc
- Cryptol.Utils.PP: liftPJ1 :: (Doc -> Doc) -> Doc -> Doc
- Cryptol.Utils.PP: liftPJ2 :: (Doc -> Doc -> Doc) -> Doc -> Doc -> Doc
- Cryptol.Utils.PP: punctuate :: Doc -> [Doc] -> [Doc]
- Cryptol.Utils.PP: render :: Doc -> String
+ Cryptol.Backend: IndexBackward :: IndexDirection
+ Cryptol.Backend: IndexForward :: IndexDirection
+ Cryptol.Backend: data IndexDirection
+ Cryptol.Backend: enumerateIntBits :: Backend sym => sym -> Nat' -> SInteger sym -> SEval sym (Integer, [SBit sym])
+ Cryptol.Backend: enumerateIntBits' :: Backend sym => sym -> Integer -> SInteger sym -> SEval sym (Integer, [SBit sym])
+ Cryptol.Backend: wordRotateLeft :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Backend: wordRotateRight :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Backend: wordShiftLeft :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Backend: wordShiftRight :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Backend: wordSignedShiftRight :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Backend: wordToSignedInt :: Backend sym => sym -> SWord sym -> SEval sym (SInteger sym)
+ Cryptol.Backend.Monad: data CallStack
+ Cryptol.Backend.Monad: instance GHC.Base.Monoid Cryptol.Backend.Monad.CallStack
+ Cryptol.Backend.Monad: instance GHC.Base.Semigroup Cryptol.Backend.Monad.CallStack
+ Cryptol.Backend.SeqMap: BitIndexSegment :: SBit sym -> IndexSegment sym
+ Cryptol.Backend.SeqMap: WordIndexSegment :: SWord sym -> IndexSegment sym
+ Cryptol.Backend.SeqMap: barrelShifter :: Backend sym => sym -> (SBit sym -> a -> a -> SEval sym a) -> (SeqMap sym a -> Integer -> SEval sym (SeqMap sym a)) -> Nat' -> SeqMap sym a -> Integer -> [IndexSegment sym] -> SEval sym (SeqMap sym a)
+ Cryptol.Backend.SeqMap: concatSeqMap :: Backend sym => Integer -> SeqMap sym a -> SeqMap sym a -> SeqMap sym a
+ Cryptol.Backend.SeqMap: data IndexSegment sym
+ Cryptol.Backend.SeqMap: data SeqMap sym a
+ Cryptol.Backend.SeqMap: delaySeqMap :: Backend sym => sym -> SEval sym (SeqMap sym a) -> SEval sym (SeqMap sym a)
+ Cryptol.Backend.SeqMap: dropSeqMap :: Backend sym => Integer -> SeqMap sym a -> SeqMap sym a
+ Cryptol.Backend.SeqMap: enumerateSeqMap :: (Backend sym, Integral n) => n -> SeqMap sym a -> [SEval sym a]
+ Cryptol.Backend.SeqMap: finiteSeqMap :: Backend sym => sym -> [SEval sym a] -> SeqMap sym a
+ Cryptol.Backend.SeqMap: indexSeqMap :: (Integer -> SEval sym a) -> SeqMap sym a
+ Cryptol.Backend.SeqMap: infiniteSeqMap :: Backend sym => sym -> [SEval sym a] -> SEval sym (SeqMap sym a)
+ Cryptol.Backend.SeqMap: instance Cryptol.Backend.Backend sym => GHC.Base.Functor (Cryptol.Backend.SeqMap.SeqMap sym)
+ Cryptol.Backend.SeqMap: lookupSeqMap :: Backend sym => SeqMap sym a -> Integer -> SEval sym a
+ Cryptol.Backend.SeqMap: mapSeqMap :: Backend sym => sym -> (a -> SEval sym a) -> Nat' -> SeqMap sym a -> SEval sym (SeqMap sym a)
+ Cryptol.Backend.SeqMap: memoMap :: Backend sym => sym -> Nat' -> SeqMap sym a -> SEval sym (SeqMap sym a)
+ Cryptol.Backend.SeqMap: mergeSeqMap :: Backend sym => sym -> (SBit sym -> a -> a -> SEval sym a) -> SBit sym -> SeqMap sym a -> SeqMap sym a -> SeqMap sym a
+ Cryptol.Backend.SeqMap: reverseSeqMap :: Backend sym => Integer -> SeqMap sym a -> SeqMap sym a
+ Cryptol.Backend.SeqMap: shiftSeqByInteger :: Backend sym => sym -> (SBit sym -> a -> a -> SEval sym a) -> (Integer -> Integer -> Maybe Integer) -> SEval sym a -> Nat' -> SeqMap sym a -> SInteger sym -> SEval sym (SeqMap sym a)
+ Cryptol.Backend.SeqMap: splitSeqMap :: Backend sym => Integer -> SeqMap sym a -> (SeqMap sym a, SeqMap sym a)
+ Cryptol.Backend.SeqMap: streamSeqMap :: Backend sym => SeqMap sym a -> [SEval sym a]
+ Cryptol.Backend.SeqMap: updateSeqMap :: SeqMap sym a -> Integer -> SEval sym a -> SeqMap sym a
+ Cryptol.Backend.SeqMap: zipSeqMap :: Backend sym => sym -> (a -> a -> SEval sym a) -> Nat' -> SeqMap sym a -> SeqMap sym a -> SEval sym (SeqMap sym a)
+ Cryptol.Backend.What4: instance GHC.Base.Functor (Cryptol.Backend.What4.W4Result sym)
+ Cryptol.Backend.WordValue: asBitsMap :: Backend sym => sym -> WordValue sym -> SeqMap sym (SBit sym)
+ Cryptol.Backend.WordValue: asWordList :: forall sym. Backend sym => sym -> [WordValue sym] -> SEval sym (Maybe [SWord sym])
+ Cryptol.Backend.WordValue: asWordVal :: Backend sym => sym -> WordValue sym -> SEval sym (SWord sym)
+ Cryptol.Backend.WordValue: assertWordValueInBounds :: Backend sym => sym -> Integer -> WordValue sym -> SEval sym ()
+ Cryptol.Backend.WordValue: bitmapWordVal :: Backend sym => sym -> Integer -> SeqMap sym (SBit sym) -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: data WordValue sym
+ Cryptol.Backend.WordValue: delayWordValue :: Backend sym => sym -> Integer -> SEval sym (WordValue sym) -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: dropWordVal :: Backend sym => sym -> Integer -> Integer -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: enumerateIndexSegments :: Backend sym => sym -> WordValue sym -> SEval sym [IndexSegment sym]
+ Cryptol.Backend.WordValue: enumerateWordValue :: Backend sym => sym -> WordValue sym -> SEval sym [SBit sym]
+ Cryptol.Backend.WordValue: enumerateWordValueRev :: Backend sym => sym -> WordValue sym -> SEval sym [SBit sym]
+ Cryptol.Backend.WordValue: extractWordVal :: Backend sym => sym -> Integer -> Integer -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: forceWordValue :: Backend sym => WordValue sym -> SEval sym ()
+ Cryptol.Backend.WordValue: indexWordValue :: Backend sym => sym -> WordValue sym -> Integer -> SEval sym (SBit sym)
+ Cryptol.Backend.WordValue: instance GHC.Generics.Generic (Cryptol.Backend.WordValue.WordValue sym)
+ Cryptol.Backend.WordValue: joinWordVal :: Backend sym => sym -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: joinWords :: forall sym. Backend sym => sym -> Integer -> Integer -> SeqMap sym (WordValue sym) -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: mergeWord :: Backend sym => sym -> SBit sym -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: mergeWord' :: Backend sym => sym -> SBit sym -> SEval sym (WordValue sym) -> SEval sym (WordValue sym) -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: reverseWordVal :: Backend sym => sym -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: shiftSeqByWord :: Backend sym => sym -> (SBit sym -> a -> a -> SEval sym a) -> (Integer -> Integer -> Maybe Integer) -> SEval sym a -> Nat' -> SeqMap sym a -> WordValue sym -> SEval sym (SeqMap sym a)
+ Cryptol.Backend.WordValue: shiftWordByInteger :: Backend sym => sym -> (SWord sym -> SWord sym -> SEval sym (SWord sym)) -> (Integer -> Integer -> Maybe Integer) -> WordValue sym -> SInteger sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: shiftWordByWord :: Backend sym => sym -> (SWord sym -> SWord sym -> SEval sym (SWord sym)) -> (Integer -> Integer -> Maybe Integer) -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: takeWordVal :: Backend sym => sym -> Integer -> Integer -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: updateWordByWord :: Backend sym => sym -> IndexDirection -> WordValue sym -> WordValue sym -> SEval sym (SBit sym) -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: updateWordValue :: Backend sym => sym -> WordValue sym -> Integer -> SEval sym (SBit sym) -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: wordVal :: SWord sym -> WordValue sym
+ Cryptol.Backend.WordValue: wordValAsLit :: Backend sym => sym -> WordValue sym -> SEval sym (Maybe Integer)
+ Cryptol.Backend.WordValue: wordValLogicOp :: Backend sym => sym -> (SBit sym -> SBit sym -> SEval sym (SBit sym)) -> (SWord sym -> SWord sym -> SEval sym (SWord sym)) -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: wordValUnaryOp :: Backend sym => sym -> (SBit sym -> SEval sym (SBit sym)) -> (SWord sym -> SEval sym (SWord sym)) -> WordValue sym -> SEval sym (WordValue sym)
+ Cryptol.Backend.WordValue: wordValueEqualsInteger :: forall sym. Backend sym => sym -> WordValue sym -> Integer -> SEval sym (SBit sym)
+ Cryptol.Backend.WordValue: wordValueSize :: Backend sym => sym -> WordValue sym -> Integer
+ Cryptol.Eval: [useFieldOrder] :: PPOpts -> FieldOrder
+ Cryptol.Eval.Generic: dropV :: Backend sym => sym -> Integer -> Nat' -> TValue -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
+ Cryptol.Eval.Generic: fromToByLessThanV :: Backend sym => sym -> Prim sym
+ Cryptol.Eval.Generic: fromToByV :: Backend sym => sym -> Prim sym
+ Cryptol.Eval.Generic: fromToDownByGreaterThanV :: Backend sym => sym -> Prim sym
+ Cryptol.Eval.Generic: fromToDownByV :: Backend sym => sym -> Prim sym
+ Cryptol.Eval.Generic: splitV :: Backend sym => sym -> Nat' -> Integer -> TValue -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
+ Cryptol.Eval.Generic: sshrV :: Backend sym => sym -> Prim sym
+ Cryptol.Eval.Generic: takeV :: Backend sym => sym -> Nat' -> Nat' -> TValue -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
+ Cryptol.Eval.Generic: toSignedIntegerV :: Backend sym => sym -> Prim sym
+ Cryptol.Eval.Value: instance GHC.Show.Show (Cryptol.Eval.Value.GenValue sym)
+ Cryptol.Eval.Value: iteValue :: Backend sym => sym -> SBit sym -> SEval sym (GenValue sym) -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
+ Cryptol.Eval.Value: mergeValue :: Backend sym => sym -> SBit sym -> GenValue sym -> GenValue sym -> SEval sym (GenValue sym)
+ Cryptol.Eval.Value: wordRotateLeft :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Eval.Value: wordRotateRight :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Eval.Value: wordShiftLeft :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Eval.Value: wordShiftRight :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Eval.Value: wordSignedShiftRight :: Backend sym => sym -> SWord sym -> SWord sym -> SEval sym (SWord sym)
+ Cryptol.Eval.Value: wordToSignedInt :: Backend sym => sym -> SWord sym -> SEval sym (SInteger sym)
+ Cryptol.ModuleSystem: [deTySyns] :: DynamicEnv -> Map Name TySyn
+ Cryptol.ModuleSystem: [ifModules] :: IfaceDecls -> !Map Name (IfaceG Name)
+ Cryptol.ModuleSystem: data IfaceG mname
+ Cryptol.ModuleSystem: type Iface = IfaceG ModName
+ Cryptol.ModuleSystem.Env: [deTySyns] :: DynamicEnv -> Map Name TySyn
+ Cryptol.ModuleSystem.Env: [lmNamingEnv] :: LoadedModule -> !NamingEnv
+ Cryptol.ModuleSystem.Env: [mctxExported] :: ModContext -> Set Name
+ Cryptol.ModuleSystem.Env: dynModContext :: ModuleEnv -> ModContext
+ Cryptol.ModuleSystem.Env: instance GHC.Base.Monoid Cryptol.ModuleSystem.Env.ModContext
+ Cryptol.ModuleSystem.Env: instance GHC.Base.Semigroup Cryptol.ModuleSystem.Env.ModContext
+ Cryptol.ModuleSystem.Env: modContextOf :: ModName -> ModuleEnv -> Maybe ModContext
+ Cryptol.ModuleSystem.Exports: exportName :: Ord name => Namespace -> TopLevel name -> ExportSpec name
+ Cryptol.ModuleSystem.Exports: exported :: Namespace -> ExportSpec name -> Set name
+ Cryptol.ModuleSystem.Exports: exportedNames :: Ord name => TopDecl name -> [ExportSpec name]
+ Cryptol.ModuleSystem.Exports: isExported :: Ord name => Namespace -> name -> ExportSpec name -> Bool
+ Cryptol.ModuleSystem.Exports: names :: (a -> ([Located a'], b)) -> TopLevel a -> [TopLevel a']
+ Cryptol.ModuleSystem.Exports: newtype ExportSpec name
+ Cryptol.ModuleSystem.Interface: [ifModules] :: IfaceDecls -> !Map Name (IfaceG Name)
+ Cryptol.ModuleSystem.Interface: data IfaceG mname
+ Cryptol.ModuleSystem.Interface: emptyIface :: mname -> IfaceG mname
+ Cryptol.ModuleSystem.Interface: filterIfaceDecls :: (Name -> Bool) -> IfaceDecls -> IfaceDecls
+ Cryptol.ModuleSystem.Interface: flatPublicDecls :: IfaceDecls -> IfaceDecls
+ Cryptol.ModuleSystem.Interface: flatPublicIface :: IfaceG mname -> IfaceDecls
+ Cryptol.ModuleSystem.Interface: ifaceDeclsNames :: IfaceDecls -> Set Name
+ Cryptol.ModuleSystem.Interface: ifaceIsFunctor :: IfaceG mname -> Bool
+ Cryptol.ModuleSystem.Interface: instance Control.DeepSeq.NFData mname => Control.DeepSeq.NFData (Cryptol.ModuleSystem.Interface.IfaceG mname)
+ Cryptol.ModuleSystem.Interface: instance GHC.Generics.Generic (Cryptol.ModuleSystem.Interface.IfaceG mname)
+ Cryptol.ModuleSystem.Interface: instance GHC.Show.Show mname => GHC.Show.Show (Cryptol.ModuleSystem.Interface.IfaceG mname)
+ Cryptol.ModuleSystem.Interface: isEmptyIfaceParams :: IfaceParams -> Bool
+ Cryptol.ModuleSystem.Interface: type Iface = IfaceG ModName
+ Cryptol.ModuleSystem.Monad: getIfaces :: ModuleM (ModName -> Iface)
+ Cryptol.ModuleSystem.Name: NSModule :: Namespace
+ Cryptol.ModuleSystem.Name: NSType :: Namespace
+ Cryptol.ModuleSystem.Name: NSValue :: Namespace
+ Cryptol.ModuleSystem.Name: Nested :: ModPath -> Ident -> ModPath
+ Cryptol.ModuleSystem.Name: TopModule :: ModName -> ModPath
+ Cryptol.ModuleSystem.Name: asOrigName :: Name -> Maybe OrigName
+ Cryptol.ModuleSystem.Name: data ModPath
+ Cryptol.ModuleSystem.Name: data Namespace
+ Cryptol.ModuleSystem.Name: nameNamespace :: Name -> Namespace
+ Cryptol.ModuleSystem.NamingEnv: buildNamingEnv :: BuildNamingEnv -> Supply -> (NamingEnv, Supply)
+ Cryptol.ModuleSystem.NamingEnv: collectNestedModules :: NamingEnv -> Module PName -> Supply -> (NestedMods, Supply)
+ Cryptol.ModuleSystem.NamingEnv: collectNestedModulesDecls :: NamingEnv -> ModName -> [TopDecl PName] -> Supply -> (NestedMods, Supply)
+ Cryptol.ModuleSystem.NamingEnv: collectNestedModulesDs :: ModPath -> NamingEnv -> [TopDecl PName] -> CollectM ()
+ Cryptol.ModuleSystem.NamingEnv: defsOf :: BindsNames a => a -> Supply -> (NamingEnv, Supply)
+ Cryptol.ModuleSystem.NamingEnv: instance Cryptol.ModuleSystem.NamingEnv.BindsNames (Cryptol.ModuleSystem.NamingEnv.InModule (Cryptol.Parser.AST.NestedModule Cryptol.Parser.Name.PName))
+ Cryptol.ModuleSystem.NamingEnv: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.NamingEnv.NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: interpImportEnv :: ImportG name -> NamingEnv -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: interpImportIface :: Import -> IfaceDecls -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: lookupNS :: Namespace -> PName -> NamingEnv -> [Name]
+ Cryptol.ModuleSystem.NamingEnv: moduleDefs :: ModPath -> ModuleG mname PName -> BuildNamingEnv
+ Cryptol.ModuleSystem.NamingEnv: namespaceMap :: Namespace -> NamingEnv -> Map PName [Name]
+ Cryptol.ModuleSystem.NamingEnv: namingEnvNames :: NamingEnv -> Set Name
+ Cryptol.ModuleSystem.NamingEnv: namingEnvRename :: (Name -> Name) -> NamingEnv -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: newtype NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: singletonNS :: Namespace -> PName -> Name -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: type CollectM = StateT NestedMods (SupplyT Id)
+ Cryptol.ModuleSystem.NamingEnv: type NestedMods = Map Name NamingEnv
+ Cryptol.ModuleSystem.Renamer: InvalidDependency :: [DepName] -> RenamerError
+ Cryptol.ModuleSystem.Renamer: NameBind :: NameType
+ Cryptol.ModuleSystem.Renamer: NameUse :: NameType
+ Cryptol.ModuleSystem.Renamer: RenamedModule :: Module Name -> NamingEnv -> NamingEnv -> IfaceDecls -> RenamedModule
+ Cryptol.ModuleSystem.Renamer: RenamerInfo :: Supply -> ModPath -> NamingEnv -> (ModName -> Iface) -> RenamerInfo
+ Cryptol.ModuleSystem.Renamer: UnboundName :: Namespace -> Located PName -> RenamerError
+ Cryptol.ModuleSystem.Renamer: WrongNamespace :: Namespace -> Namespace -> Located PName -> RenamerError
+ Cryptol.ModuleSystem.Renamer: [renContext] :: RenamerInfo -> ModPath
+ Cryptol.ModuleSystem.Renamer: [renEnv] :: RenamerInfo -> NamingEnv
+ Cryptol.ModuleSystem.Renamer: [renIfaces] :: RenamerInfo -> ModName -> Iface
+ Cryptol.ModuleSystem.Renamer: [renSupply] :: RenamerInfo -> Supply
+ Cryptol.ModuleSystem.Renamer: [rmDefines] :: RenamedModule -> NamingEnv
+ Cryptol.ModuleSystem.Renamer: [rmImported] :: RenamedModule -> IfaceDecls
+ Cryptol.ModuleSystem.Renamer: [rmInScope] :: RenamedModule -> NamingEnv
+ Cryptol.ModuleSystem.Renamer: [rmModule] :: RenamedModule -> Module Name
+ Cryptol.ModuleSystem.Renamer: data NameType
+ Cryptol.ModuleSystem.Renamer: data RenamedModule
+ Cryptol.ModuleSystem.Renamer: data RenamerInfo
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename (Cryptol.ModuleSystem.Renamer.WithMods Cryptol.Parser.AST.NestedModule)
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename (Cryptol.ModuleSystem.Renamer.WithMods Cryptol.Parser.AST.TopDecl)
+ Cryptol.ModuleSystem.Renamer: instance Cryptol.ModuleSystem.Renamer.Rename Cryptol.Parser.AST.ImpName
+ Cryptol.ModuleSystem.Renamer: renameTopDecls :: ModName -> [TopDecl PName] -> RenameM (NamingEnv, [TopDecl Name])
+ Cryptol.ModuleSystem.Renamer.Error: BoundReservedType :: PName -> Maybe Range -> Doc -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: ConstratintAt :: Range -> DepName
+ Cryptol.ModuleSystem.Renamer.Error: FixityError :: Located Name -> Fixity -> Located Name -> Fixity -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: InvalidConstraint :: Type PName -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: InvalidDependency :: [DepName] -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: MalformedBuiltin :: Type PName -> PName -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: MultipleSyms :: Located PName -> [Name] -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: NamedThing :: Name -> DepName
+ Cryptol.ModuleSystem.Renamer.Error: OverlappingRecordUpdate :: Located [Selector] -> Located [Selector] -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: OverlappingSyms :: [Name] -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: SymbolShadowed :: PName -> Name -> [Name] -> RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: UnboundName :: Namespace -> Located PName -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: UnusedName :: Name -> RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: WrongNamespace :: Namespace -> Namespace -> Located PName -> RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: data DepName
+ Cryptol.ModuleSystem.Renamer.Error: data RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: data RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: depNameLoc :: DepName -> Range
+ Cryptol.ModuleSystem.Renamer.Error: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Renamer.Error.DepName
+ Cryptol.ModuleSystem.Renamer.Error: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Renamer.Error.RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: instance Control.DeepSeq.NFData Cryptol.ModuleSystem.Renamer.Error.RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.Renamer.Error.DepName
+ Cryptol.ModuleSystem.Renamer.Error: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.Renamer.Error.RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: instance Cryptol.Utils.PP.PP Cryptol.ModuleSystem.Renamer.Error.RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Classes.Eq Cryptol.ModuleSystem.Renamer.Error.DepName
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Classes.Eq Cryptol.ModuleSystem.Renamer.Error.RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Classes.Ord Cryptol.ModuleSystem.Renamer.Error.DepName
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Classes.Ord Cryptol.ModuleSystem.Renamer.Error.RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Generics.Generic Cryptol.ModuleSystem.Renamer.Error.DepName
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Generics.Generic Cryptol.ModuleSystem.Renamer.Error.RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Generics.Generic Cryptol.ModuleSystem.Renamer.Error.RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Show.Show Cryptol.ModuleSystem.Renamer.Error.DepName
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Show.Show Cryptol.ModuleSystem.Renamer.Error.RenamerError
+ Cryptol.ModuleSystem.Renamer.Error: instance GHC.Show.Show Cryptol.ModuleSystem.Renamer.Error.RenamerWarning
+ Cryptol.ModuleSystem.Renamer.Monad: CheckAll :: EnvCheck
+ Cryptol.ModuleSystem.Renamer.Monad: CheckNone :: EnvCheck
+ Cryptol.ModuleSystem.Renamer.Monad: CheckOverlap :: EnvCheck
+ Cryptol.ModuleSystem.Renamer.Monad: NameBind :: NameType
+ Cryptol.ModuleSystem.Renamer.Monad: NameUse :: NameType
+ Cryptol.ModuleSystem.Renamer.Monad: RO :: Range -> NamingEnv -> (ModName -> Iface) -> ModPath -> Map ModPath Name -> RO
+ Cryptol.ModuleSystem.Renamer.Monad: RW :: ![RenamerWarning] -> !Seq RenamerError -> !Supply -> !Map Name Int -> Set Name -> Map DepName (Set Name) -> !IfaceDecls -> RW
+ Cryptol.ModuleSystem.Renamer.Monad: RenameM :: ReaderT RO (StateT RW Lift) a -> RenameM a
+ Cryptol.ModuleSystem.Renamer.Monad: RenamerInfo :: Supply -> ModPath -> NamingEnv -> (ModName -> Iface) -> RenamerInfo
+ Cryptol.ModuleSystem.Renamer.Monad: [renContext] :: RenamerInfo -> ModPath
+ Cryptol.ModuleSystem.Renamer.Monad: [renEnv] :: RenamerInfo -> NamingEnv
+ Cryptol.ModuleSystem.Renamer.Monad: [renIfaces] :: RenamerInfo -> ModName -> Iface
+ Cryptol.ModuleSystem.Renamer.Monad: [renSupply] :: RenamerInfo -> Supply
+ Cryptol.ModuleSystem.Renamer.Monad: [roCurMod] :: RO -> ModPath
+ Cryptol.ModuleSystem.Renamer.Monad: [roIfaces] :: RO -> ModName -> Iface
+ Cryptol.ModuleSystem.Renamer.Monad: [roLoc] :: RO -> Range
+ Cryptol.ModuleSystem.Renamer.Monad: [roNames] :: RO -> NamingEnv
+ Cryptol.ModuleSystem.Renamer.Monad: [roNestedMods] :: RO -> Map ModPath Name
+ Cryptol.ModuleSystem.Renamer.Monad: [rwCurrentDeps] :: RW -> Set Name
+ Cryptol.ModuleSystem.Renamer.Monad: [rwDepGraph] :: RW -> Map DepName (Set Name)
+ Cryptol.ModuleSystem.Renamer.Monad: [rwErrors] :: RW -> !Seq RenamerError
+ Cryptol.ModuleSystem.Renamer.Monad: [rwExternalDeps] :: RW -> !IfaceDecls
+ Cryptol.ModuleSystem.Renamer.Monad: [rwNameUseCount] :: RW -> !Map Name Int
+ Cryptol.ModuleSystem.Renamer.Monad: [rwSupply] :: RW -> !Supply
+ Cryptol.ModuleSystem.Renamer.Monad: [rwWarnings] :: RW -> ![RenamerWarning]
+ Cryptol.ModuleSystem.Renamer.Monad: [unRenameM] :: RenameM a -> ReaderT RO (StateT RW Lift) a
+ Cryptol.ModuleSystem.Renamer.Monad: addDep :: Name -> RenameM ()
+ Cryptol.ModuleSystem.Renamer.Monad: checkEnv :: EnvCheck -> NamingEnv -> NamingEnv -> RW -> (NamingEnv, RW)
+ Cryptol.ModuleSystem.Renamer.Monad: collectIfaceDeps :: RenameM a -> RenameM (IfaceDecls, a)
+ Cryptol.ModuleSystem.Renamer.Monad: containsOverlap :: [Name] -> Seq RenamerError
+ Cryptol.ModuleSystem.Renamer.Monad: curLoc :: RenameM Range
+ Cryptol.ModuleSystem.Renamer.Monad: data EnvCheck
+ Cryptol.ModuleSystem.Renamer.Monad: data NameType
+ Cryptol.ModuleSystem.Renamer.Monad: data RO
+ Cryptol.ModuleSystem.Renamer.Monad: data RW
+ Cryptol.ModuleSystem.Renamer.Monad: data RenamerInfo
+ Cryptol.ModuleSystem.Renamer.Monad: depGroup :: RenameM a -> RenameM (a, Map DepName (Set Name))
+ Cryptol.ModuleSystem.Renamer.Monad: depsOf :: DepName -> RenameM a -> RenameM a
+ Cryptol.ModuleSystem.Renamer.Monad: getCurMod :: RenameM ModPath
+ Cryptol.ModuleSystem.Renamer.Monad: getNamingEnv :: RenameM NamingEnv
+ Cryptol.ModuleSystem.Renamer.Monad: instance (GHC.Base.Semigroup a, GHC.Base.Monoid a) => GHC.Base.Monoid (Cryptol.ModuleSystem.Renamer.Monad.RenameM a)
+ Cryptol.ModuleSystem.Renamer.Monad: instance Cryptol.ModuleSystem.Name.FreshM Cryptol.ModuleSystem.Renamer.Monad.RenameM
+ Cryptol.ModuleSystem.Renamer.Monad: instance GHC.Base.Applicative Cryptol.ModuleSystem.Renamer.Monad.RenameM
+ Cryptol.ModuleSystem.Renamer.Monad: instance GHC.Base.Functor Cryptol.ModuleSystem.Renamer.Monad.RenameM
+ Cryptol.ModuleSystem.Renamer.Monad: instance GHC.Base.Monad Cryptol.ModuleSystem.Renamer.Monad.RenameM
+ Cryptol.ModuleSystem.Renamer.Monad: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Cryptol.ModuleSystem.Renamer.Monad.RenameM a)
+ Cryptol.ModuleSystem.Renamer.Monad: instance GHC.Classes.Eq Cryptol.ModuleSystem.Renamer.Monad.EnvCheck
+ Cryptol.ModuleSystem.Renamer.Monad: instance GHC.Show.Show Cryptol.ModuleSystem.Renamer.Monad.EnvCheck
+ Cryptol.ModuleSystem.Renamer.Monad: located :: a -> RenameM (Located a)
+ Cryptol.ModuleSystem.Renamer.Monad: lookupImport :: Import -> RenameM IfaceDecls
+ Cryptol.ModuleSystem.Renamer.Monad: nestedModuleOrig :: ModPath -> RenameM (Maybe Name)
+ Cryptol.ModuleSystem.Renamer.Monad: newtype RenameM a
+ Cryptol.ModuleSystem.Renamer.Monad: record :: RenamerError -> RenameM ()
+ Cryptol.ModuleSystem.Renamer.Monad: recordUse :: Name -> RenameM ()
+ Cryptol.ModuleSystem.Renamer.Monad: runRenamer :: RenamerInfo -> RenameM a -> (Either [RenamerError] (a, Supply), [RenamerWarning])
+ Cryptol.ModuleSystem.Renamer.Monad: setCurMod :: ModPath -> RenameM a -> RenameM a
+ Cryptol.ModuleSystem.Renamer.Monad: setNestedModule :: Map ModPath Name -> RenameM a -> RenameM a
+ Cryptol.ModuleSystem.Renamer.Monad: shadowNames :: BindsNames env => env -> RenameM a -> RenameM a
+ Cryptol.ModuleSystem.Renamer.Monad: shadowNames' :: BindsNames env => EnvCheck -> env -> RenameM a -> RenameM a
+ Cryptol.ModuleSystem.Renamer.Monad: warnUnused :: ModPath -> NamingEnv -> RW -> [RenamerWarning]
+ Cryptol.ModuleSystem.Renamer.Monad: withLoc :: HasLoc loc => loc -> RenameM a -> RenameM a
+ Cryptol.Parser.AST: DImport :: Located (ImportG (ImpName name)) -> TopDecl name
+ Cryptol.Parser.AST: DModule :: TopLevel (NestedModule name) -> TopDecl name
+ Cryptol.Parser.AST: DRec :: [Bind name] -> Decl name
+ Cryptol.Parser.AST: EFromToBy :: Bool -> Type n -> Type n -> Type n -> Maybe (Type n) -> Expr n
+ Cryptol.Parser.AST: EFromToDownBy :: Bool -> Type n -> Type n -> Type n -> Maybe (Type n) -> Expr n
+ Cryptol.Parser.AST: ImpNested :: name -> ImpName name
+ Cryptol.Parser.AST: ImpTop :: ModName -> ImpName name
+ Cryptol.Parser.AST: NestedModule :: ModuleG name name -> NestedModule name
+ Cryptol.Parser.AST: [bExport] :: Bind name -> !ExportType
+ Cryptol.Parser.AST: data ImpName name
+ Cryptol.Parser.AST: data ImportG mname
+ Cryptol.Parser.AST: data ModuleG mname name
+ Cryptol.Parser.AST: instance (Control.DeepSeq.NFData mname, Control.DeepSeq.NFData name) => Control.DeepSeq.NFData (Cryptol.Parser.AST.ModuleG mname name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show mname, GHC.Show.Show name) => GHC.Show.Show (Cryptol.Parser.AST.ModuleG mname name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName mname, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ModuleG mname name)
+ Cryptol.Parser.AST: instance (GHC.Show.Show name, Cryptol.Utils.PP.PPName name) => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.NestedModule name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData mname => Control.DeepSeq.NFData (Cryptol.Parser.AST.ImportG mname)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.ImpName name)
+ Cryptol.Parser.AST: instance Control.DeepSeq.NFData name => Control.DeepSeq.NFData (Cryptol.Parser.AST.NestedModule name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.ModuleG mname name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.AST.NoPos (Cryptol.Parser.AST.NestedModule name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.ModuleG mname name)
+ Cryptol.Parser.AST: instance Cryptol.Parser.Position.HasLoc (Cryptol.Parser.AST.NestedModule name)
+ Cryptol.Parser.AST: instance Cryptol.Utils.PP.PP mname => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ImportG mname)
+ Cryptol.Parser.AST: instance Cryptol.Utils.PP.PP name => Cryptol.Utils.PP.PP (Cryptol.Parser.AST.ImpName name)
+ Cryptol.Parser.AST: instance GHC.Classes.Eq mname => GHC.Classes.Eq (Cryptol.Parser.AST.ImportG mname)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ImpName name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ImportG mname)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.ModuleG mname name)
+ Cryptol.Parser.AST: instance GHC.Generics.Generic (Cryptol.Parser.AST.NestedModule name)
+ Cryptol.Parser.AST: instance GHC.Show.Show mname => GHC.Show.Show (Cryptol.Parser.AST.ImportG mname)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.ImpName name)
+ Cryptol.Parser.AST: instance GHC.Show.Show name => GHC.Show.Show (Cryptol.Parser.AST.NestedModule name)
+ Cryptol.Parser.AST: mImports :: ModuleG mname name -> [Located Import]
+ Cryptol.Parser.AST: mSubmoduleImports :: ModuleG mname name -> [Located (ImportG name)]
+ Cryptol.Parser.AST: newtype NestedModule name
+ Cryptol.Parser.AST: type Import = ImportG ModName
+ Cryptol.Parser.AST: type Module = ModuleG ModName
+ Cryptol.Parser.Layout: Explicit :: TokenT -> Block
+ Cryptol.Parser.Layout: Virtual :: Int -> Block
+ Cryptol.Parser.Layout: data Block
+ Cryptol.Parser.Layout: endsLayout :: TokenT -> Bool
+ Cryptol.Parser.Layout: errTok :: Range -> TokenErr -> Located Token
+ Cryptol.Parser.Layout: instance GHC.Show.Show Cryptol.Parser.Layout.Block
+ Cryptol.Parser.Layout: layout :: Bool -> [Located Token] -> [Located Token]
+ Cryptol.Parser.Layout: startsLayout :: TokenT -> Bool
+ Cryptol.Parser.Layout: startsParenBlock :: TokenT -> Maybe TokenT
+ Cryptol.Parser.Layout: virt :: Range -> TokenV -> Located Token
+ Cryptol.Parser.Lexer: DotDotGt :: TokenSym
+ Cryptol.Parser.Lexer: Gt :: TokenSym
+ Cryptol.Parser.Lexer: InvalidIndentation :: TokenT -> TokenErr
+ Cryptol.Parser.Lexer: KW_by :: TokenKW
+ Cryptol.Parser.Lexer: KW_down :: TokenKW
+ Cryptol.Parser.Lexer: KW_submodule :: TokenKW
+ Cryptol.Parser.Lexer: dbgLex :: FilePath -> IO ()
+ Cryptol.Parser.NoPat: instance Cryptol.Parser.NoPat.RemovePatterns (Cryptol.Parser.AST.ModuleG mname Cryptol.Parser.Name.PName)
+ Cryptol.Parser.NoPat: instance Cryptol.Parser.NoPat.RemovePatterns (Cryptol.Parser.AST.NestedModule Cryptol.Parser.Name.PName)
+ Cryptol.Parser.Position: instance Data.Foldable.Foldable Cryptol.Parser.Position.Located
+ Cryptol.Parser.Position: instance Data.Traversable.Traversable Cryptol.Parser.Position.Located
+ Cryptol.Parser.Token: ArrL :: TokenSym
+ Cryptol.Parser.Token: ArrR :: TokenSym
+ Cryptol.Parser.Token: At :: TokenOp
+ Cryptol.Parser.Token: BackTick :: TokenSym
+ Cryptol.Parser.Token: Bar :: TokenSym
+ Cryptol.Parser.Token: BlockComment :: TokenW
+ Cryptol.Parser.Token: BracketL :: TokenSym
+ Cryptol.Parser.Token: BracketR :: TokenSym
+ Cryptol.Parser.Token: ChrLit :: !Char -> TokenT
+ Cryptol.Parser.Token: Colon :: TokenSym
+ Cryptol.Parser.Token: Comma :: TokenSym
+ Cryptol.Parser.Token: Complement :: TokenOp
+ Cryptol.Parser.Token: CurlyL :: TokenSym
+ Cryptol.Parser.Token: CurlyR :: TokenSym
+ Cryptol.Parser.Token: Div :: TokenOp
+ Cryptol.Parser.Token: DocStr :: TokenW
+ Cryptol.Parser.Token: Dot :: TokenSym
+ Cryptol.Parser.Token: DotDot :: TokenSym
+ Cryptol.Parser.Token: DotDotDot :: TokenSym
+ Cryptol.Parser.Token: DotDotGt :: TokenSym
+ Cryptol.Parser.Token: DotDotLt :: TokenSym
+ Cryptol.Parser.Token: EOF :: TokenT
+ Cryptol.Parser.Token: EqDef :: TokenSym
+ Cryptol.Parser.Token: Equal :: TokenOp
+ Cryptol.Parser.Token: Err :: !TokenErr -> TokenT
+ Cryptol.Parser.Token: Exp :: TokenOp
+ Cryptol.Parser.Token: FatArrR :: TokenSym
+ Cryptol.Parser.Token: Frac :: !Rational -> !Int -> TokenT
+ Cryptol.Parser.Token: GEQ :: TokenOp
+ Cryptol.Parser.Token: Gt :: TokenSym
+ Cryptol.Parser.Token: Hash :: TokenOp
+ Cryptol.Parser.Token: Ident :: ![Text] -> !Text -> TokenT
+ Cryptol.Parser.Token: InvalidChar :: TokenErr
+ Cryptol.Parser.Token: InvalidIndentation :: TokenT -> TokenErr
+ Cryptol.Parser.Token: InvalidString :: TokenErr
+ Cryptol.Parser.Token: KW :: !TokenKW -> TokenT
+ Cryptol.Parser.Token: KW_Prop :: TokenKW
+ Cryptol.Parser.Token: KW_as :: TokenKW
+ Cryptol.Parser.Token: KW_by :: TokenKW
+ Cryptol.Parser.Token: KW_constraint :: TokenKW
+ Cryptol.Parser.Token: KW_down :: TokenKW
+ Cryptol.Parser.Token: KW_else :: TokenKW
+ Cryptol.Parser.Token: KW_extern :: TokenKW
+ Cryptol.Parser.Token: KW_fin :: TokenKW
+ Cryptol.Parser.Token: KW_hiding :: TokenKW
+ Cryptol.Parser.Token: KW_if :: TokenKW
+ Cryptol.Parser.Token: KW_import :: TokenKW
+ Cryptol.Parser.Token: KW_include :: TokenKW
+ Cryptol.Parser.Token: KW_inf :: TokenKW
+ Cryptol.Parser.Token: KW_infix :: TokenKW
+ Cryptol.Parser.Token: KW_infixl :: TokenKW
+ Cryptol.Parser.Token: KW_infixr :: TokenKW
+ Cryptol.Parser.Token: KW_lengthFromThen :: TokenKW
+ Cryptol.Parser.Token: KW_lengthFromThenTo :: TokenKW
+ Cryptol.Parser.Token: KW_let :: TokenKW
+ Cryptol.Parser.Token: KW_lg2 :: TokenKW
+ Cryptol.Parser.Token: KW_max :: TokenKW
+ Cryptol.Parser.Token: KW_min :: TokenKW
+ Cryptol.Parser.Token: KW_module :: TokenKW
+ Cryptol.Parser.Token: KW_newtype :: TokenKW
+ Cryptol.Parser.Token: KW_parameter :: TokenKW
+ Cryptol.Parser.Token: KW_pragma :: TokenKW
+ Cryptol.Parser.Token: KW_primitive :: TokenKW
+ Cryptol.Parser.Token: KW_private :: TokenKW
+ Cryptol.Parser.Token: KW_property :: TokenKW
+ Cryptol.Parser.Token: KW_submodule :: TokenKW
+ Cryptol.Parser.Token: KW_then :: TokenKW
+ Cryptol.Parser.Token: KW_type :: TokenKW
+ Cryptol.Parser.Token: KW_where :: TokenKW
+ Cryptol.Parser.Token: KW_x :: TokenKW
+ Cryptol.Parser.Token: LEQ :: TokenOp
+ Cryptol.Parser.Token: Lambda :: TokenSym
+ Cryptol.Parser.Token: LexicalError :: TokenErr
+ Cryptol.Parser.Token: LineComment :: TokenW
+ Cryptol.Parser.Token: Lt :: TokenSym
+ Cryptol.Parser.Token: MalformedLiteral :: TokenErr
+ Cryptol.Parser.Token: MalformedSelector :: TokenErr
+ Cryptol.Parser.Token: Minus :: TokenOp
+ Cryptol.Parser.Token: Mod :: TokenOp
+ Cryptol.Parser.Token: Mul :: TokenOp
+ Cryptol.Parser.Token: Num :: !Integer -> !Int -> !Int -> TokenT
+ Cryptol.Parser.Token: Op :: !TokenOp -> TokenT
+ Cryptol.Parser.Token: Other :: [Text] -> Text -> TokenOp
+ Cryptol.Parser.Token: ParenL :: TokenSym
+ Cryptol.Parser.Token: ParenR :: TokenSym
+ Cryptol.Parser.Token: Plus :: TokenOp
+ Cryptol.Parser.Token: RecordSelectorTok :: Text -> SelectorType
+ Cryptol.Parser.Token: Selector :: !SelectorType -> TokenT
+ Cryptol.Parser.Token: Semi :: TokenSym
+ Cryptol.Parser.Token: Space :: TokenW
+ Cryptol.Parser.Token: StrLit :: !String -> TokenT
+ Cryptol.Parser.Token: Sym :: !TokenSym -> TokenT
+ Cryptol.Parser.Token: Token :: !TokenT -> !Text -> Token
+ Cryptol.Parser.Token: TriL :: TokenSym
+ Cryptol.Parser.Token: TriR :: TokenSym
+ Cryptol.Parser.Token: TupleSelectorTok :: Int -> SelectorType
+ Cryptol.Parser.Token: Underscore :: TokenSym
+ Cryptol.Parser.Token: UnterminatedChar :: TokenErr
+ Cryptol.Parser.Token: UnterminatedComment :: TokenErr
+ Cryptol.Parser.Token: UnterminatedString :: TokenErr
+ Cryptol.Parser.Token: VCurlyL :: TokenV
+ Cryptol.Parser.Token: VCurlyR :: TokenV
+ Cryptol.Parser.Token: VSemi :: TokenV
+ Cryptol.Parser.Token: Virt :: !TokenV -> TokenT
+ Cryptol.Parser.Token: White :: !TokenW -> TokenT
+ Cryptol.Parser.Token: [tokenText] :: Token -> !Text
+ Cryptol.Parser.Token: [tokenType] :: Token -> !TokenT
+ Cryptol.Parser.Token: data SelectorType
+ Cryptol.Parser.Token: data Token
+ Cryptol.Parser.Token: data TokenErr
+ Cryptol.Parser.Token: data TokenKW
+ Cryptol.Parser.Token: data TokenOp
+ Cryptol.Parser.Token: data TokenSym
+ Cryptol.Parser.Token: data TokenT
+ Cryptol.Parser.Token: data TokenV
+ Cryptol.Parser.Token: data TokenW
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.SelectorType
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.Token
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.TokenErr
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.TokenKW
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.TokenOp
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.TokenSym
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.TokenT
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.TokenV
+ Cryptol.Parser.Token: instance Control.DeepSeq.NFData Cryptol.Parser.Token.TokenW
+ Cryptol.Parser.Token: instance Cryptol.Utils.PP.PP Cryptol.Parser.Token.Token
+ Cryptol.Parser.Token: instance GHC.Classes.Eq Cryptol.Parser.Token.SelectorType
+ Cryptol.Parser.Token: instance GHC.Classes.Eq Cryptol.Parser.Token.TokenErr
+ Cryptol.Parser.Token: instance GHC.Classes.Eq Cryptol.Parser.Token.TokenKW
+ Cryptol.Parser.Token: instance GHC.Classes.Eq Cryptol.Parser.Token.TokenOp
+ Cryptol.Parser.Token: instance GHC.Classes.Eq Cryptol.Parser.Token.TokenSym
+ Cryptol.Parser.Token: instance GHC.Classes.Eq Cryptol.Parser.Token.TokenT
+ Cryptol.Parser.Token: instance GHC.Classes.Eq Cryptol.Parser.Token.TokenV
+ Cryptol.Parser.Token: instance GHC.Classes.Eq Cryptol.Parser.Token.TokenW
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.SelectorType
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.Token
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.TokenErr
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.TokenKW
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.TokenOp
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.TokenSym
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.TokenT
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.TokenV
+ Cryptol.Parser.Token: instance GHC.Generics.Generic Cryptol.Parser.Token.TokenW
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.SelectorType
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.Token
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.TokenErr
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.TokenKW
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.TokenOp
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.TokenSym
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.TokenT
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.TokenV
+ Cryptol.Parser.Token: instance GHC.Show.Show Cryptol.Parser.Token.TokenW
+ Cryptol.REPL.Browse: BrowseExported :: BrowseHow
+ Cryptol.REPL.Browse: BrowseInScope :: BrowseHow
+ Cryptol.REPL.Browse: browseModContext :: BrowseHow -> ModContext -> Doc Void
+ Cryptol.REPL.Browse: data BrowseHow
+ Cryptol.REPL.Command: withRWTempFile :: String -> (Handle -> IO a) -> IO a
+ Cryptol.REPL.Monad: getTCSolver :: REPL Solver
+ Cryptol.REPL.Monad: instance Cryptol.REPL.Monad.IsEnvVal Cryptol.Utils.PP.FieldOrder
+ Cryptol.REPL.Monad: parseFieldOrder :: String -> Maybe FieldOrder
+ Cryptol.REPL.Monad: parseSearchPath :: String -> [String]
+ Cryptol.REPL.Monad: resetTCSolver :: REPL ()
+ Cryptol.Symbolic: flattenShape :: VarShape sym -> [VarShape sym] -> [VarShape sym]
+ Cryptol.Symbolic: flattenShapes :: [VarShape sym] -> [VarShape sym] -> [VarShape sym]
+ Cryptol.Symbolic.What4: instance Control.Monad.IO.Class.MonadIO Cryptol.Symbolic.What4.MultiSat
+ Cryptol.Symbolic.What4: instance GHC.Base.Applicative Cryptol.Symbolic.What4.MultiSat
+ Cryptol.Symbolic.What4: instance GHC.Base.Functor Cryptol.Symbolic.What4.MultiSat
+ Cryptol.Symbolic.What4: instance GHC.Base.Monad Cryptol.Symbolic.What4.MultiSat
+ Cryptol.TypeCheck: TemporaryError :: Doc -> Error
+ Cryptol.TypeCheck: defaultSolverConfig :: [FilePath] -> SolverConfig
+ Cryptol.TypeCheck.AST: [mFunctors] :: ModuleG mname -> Map Name (ModuleG Name)
+ Cryptol.TypeCheck.AST: [mSubModules] :: ModuleG mname -> Map Name (IfaceG Name)
+ Cryptol.TypeCheck.AST: data ImportG mname
+ Cryptol.TypeCheck.AST: data ModuleG mname
+ Cryptol.TypeCheck.AST: emptyModule :: mname -> ModuleG mname
+ Cryptol.TypeCheck.AST: instance Control.DeepSeq.NFData mname => Control.DeepSeq.NFData (Cryptol.TypeCheck.AST.ModuleG mname)
+ Cryptol.TypeCheck.AST: instance Cryptol.Utils.PP.PP n => Cryptol.Utils.PP.PP (Cryptol.TypeCheck.AST.ModuleG n)
+ Cryptol.TypeCheck.AST: instance Cryptol.Utils.PP.PP n => Cryptol.Utils.PP.PP (Cryptol.TypeCheck.PP.WithNames (Cryptol.TypeCheck.AST.ModuleG n))
+ Cryptol.TypeCheck.AST: instance GHC.Generics.Generic (Cryptol.TypeCheck.AST.ModuleG mname)
+ Cryptol.TypeCheck.AST: instance GHC.Show.Show mname => GHC.Show.Show (Cryptol.TypeCheck.AST.ModuleG mname)
+ Cryptol.TypeCheck.AST: isExported :: Ord name => Namespace -> name -> ExportSpec name -> Bool
+ Cryptol.TypeCheck.AST: newtype ExportSpec name
+ Cryptol.TypeCheck.AST: type Import = ImportG ModName
+ Cryptol.TypeCheck.AST: type Module = ModuleG ModName
+ Cryptol.TypeCheck.Error: TemporaryError :: Doc -> Error
+ Cryptol.TypeCheck.Infer: checkTopDecls :: [TopDecl Name] -> InferM ()
+ Cryptol.TypeCheck.InferTypes: defaultSolverConfig :: [FilePath] -> SolverConfig
+ Cryptol.TypeCheck.Interface: genIface :: ModuleG mname -> IfaceG mname
+ Cryptol.TypeCheck.Interface: mkIfaceDecl :: Decl -> IfaceDecl
+ Cryptol.TypeCheck.Monad: ExternalScope :: ScopeName
+ Cryptol.TypeCheck.Monad: LocalScope :: ScopeName
+ Cryptol.TypeCheck.Monad: MTopModule :: ModName -> ScopeName
+ Cryptol.TypeCheck.Monad: SubModule :: Name -> ScopeName
+ Cryptol.TypeCheck.Monad: [iBindTypes] :: RW -> !Map Name Schema
+ Cryptol.TypeCheck.Monad: [iExtScope] :: RO -> ModuleG ScopeName
+ Cryptol.TypeCheck.Monad: [iScope] :: RW -> ![ModuleG ScopeName]
+ Cryptol.TypeCheck.Monad: addDecls :: DeclGroup -> InferM ()
+ Cryptol.TypeCheck.Monad: addNewtype :: Newtype -> InferM ()
+ Cryptol.TypeCheck.Monad: addParamFun :: ModVParam -> InferM ()
+ Cryptol.TypeCheck.Monad: addParamType :: ModTParam -> InferM ()
+ Cryptol.TypeCheck.Monad: addParameterConstraints :: [Located Prop] -> InferM ()
+ Cryptol.TypeCheck.Monad: addPrimType :: AbstractType -> InferM ()
+ Cryptol.TypeCheck.Monad: addTySyn :: TySyn -> InferM ()
+ Cryptol.TypeCheck.Monad: data ScopeName
+ Cryptol.TypeCheck.Monad: endLocalScope :: InferM ([DeclGroup], Map Name TySyn)
+ Cryptol.TypeCheck.Monad: endModule :: InferM Module
+ Cryptol.TypeCheck.Monad: endModuleInstance :: InferM ()
+ Cryptol.TypeCheck.Monad: endSubmodule :: InferM ()
+ Cryptol.TypeCheck.Monad: getScope :: Semigroup a => (ModuleG ScopeName -> a) -> InferM a
+ Cryptol.TypeCheck.Monad: newLocalScope :: InferM ()
+ Cryptol.TypeCheck.Monad: newModuleScope :: ModName -> [Import] -> ExportSpec Name -> InferM ()
+ Cryptol.TypeCheck.Monad: newScope :: ScopeName -> InferM ()
+ Cryptol.TypeCheck.Monad: newSubmoduleScope :: Name -> [Import] -> ExportSpec Name -> InferM ()
+ Cryptol.TypeCheck.Monad: updScope :: (ModuleG ScopeName -> ModuleG ScopeName) -> InferM ()
+ Cryptol.TypeCheck.Parseable: ($$) :: Doc a -> Doc a -> Doc a
+ Cryptol.TypeCheck.Parseable: infixl 5 $$
+ Cryptol.TypeCheck.Parseable: int :: Int -> Doc a
+ Cryptol.TypeCheck.Parseable: text :: String -> Doc a
+ Cryptol.TypeCheck.Solver.SMT: data SolverConfig
+ Cryptol.TypeCheck.Solver.SMT: resetSolver :: Solver -> SolverConfig -> IO ()
+ Cryptol.TypeCheck.Subst: instance Cryptol.TypeCheck.Subst.TVars Cryptol.TypeCheck.Type.TySyn
+ Cryptol.TypeCheck.Subst: instance Cryptol.TypeCheck.Subst.TVars a => Cryptol.TypeCheck.Subst.TVars (Data.Map.Internal.Map k a)
+ Cryptol.TypeCheck.Type: ModTParam :: Name -> Kind -> !Int -> Maybe Text -> ModTParam
+ Cryptol.TypeCheck.Type: ModVParam :: Name -> Schema -> Maybe Text -> Maybe Fixity -> ModVParam
+ Cryptol.TypeCheck.Type: [mtpDoc] :: ModTParam -> Maybe Text
+ Cryptol.TypeCheck.Type: [mtpKind] :: ModTParam -> Kind
+ Cryptol.TypeCheck.Type: [mtpName] :: ModTParam -> Name
+ Cryptol.TypeCheck.Type: [mtpNumber] :: ModTParam -> !Int
+ Cryptol.TypeCheck.Type: [mvpDoc] :: ModVParam -> Maybe Text
+ Cryptol.TypeCheck.Type: [mvpFixity] :: ModVParam -> Maybe Fixity
+ Cryptol.TypeCheck.Type: [mvpName] :: ModVParam -> Name
+ Cryptol.TypeCheck.Type: [mvpType] :: ModVParam -> Schema
+ Cryptol.TypeCheck.Type: data ModTParam
+ Cryptol.TypeCheck.Type: data ModVParam
+ Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.ModTParam
+ Cryptol.TypeCheck.Type: instance Control.DeepSeq.NFData Cryptol.TypeCheck.Type.ModVParam
+ Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.ModTParam
+ Cryptol.TypeCheck.Type: instance GHC.Generics.Generic Cryptol.TypeCheck.Type.ModVParam
+ Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.ModTParam
+ Cryptol.TypeCheck.Type: instance GHC.Show.Show Cryptol.TypeCheck.Type.ModVParam
+ Cryptol.TypeCheck.Type: mtpParam :: ModTParam -> TParam
+ Cryptol.Utils.Ident: NSModule :: Namespace
+ Cryptol.Utils.Ident: NSType :: Namespace
+ Cryptol.Utils.Ident: NSValue :: Namespace
+ Cryptol.Utils.Ident: Nested :: ModPath -> Ident -> ModPath
+ Cryptol.Utils.Ident: OrigName :: Namespace -> ModPath -> Ident -> OrigName
+ Cryptol.Utils.Ident: TopModule :: ModName -> ModPath
+ Cryptol.Utils.Ident: [ogModule] :: OrigName -> ModPath
+ Cryptol.Utils.Ident: [ogName] :: OrigName -> Ident
+ Cryptol.Utils.Ident: [ogNamespace] :: OrigName -> Namespace
+ Cryptol.Utils.Ident: allNamespaces :: [Namespace]
+ Cryptol.Utils.Ident: apPathRoot :: (ModName -> ModName) -> ModPath -> ModPath
+ Cryptol.Utils.Ident: data ModPath
+ Cryptol.Utils.Ident: data Namespace
+ Cryptol.Utils.Ident: data OrigName
+ Cryptol.Utils.Ident: instance Control.DeepSeq.NFData Cryptol.Utils.Ident.ModPath
+ Cryptol.Utils.Ident: instance Control.DeepSeq.NFData Cryptol.Utils.Ident.Namespace
+ Cryptol.Utils.Ident: instance Control.DeepSeq.NFData Cryptol.Utils.Ident.OrigName
+ Cryptol.Utils.Ident: instance GHC.Classes.Eq Cryptol.Utils.Ident.ModPath
+ Cryptol.Utils.Ident: instance GHC.Classes.Eq Cryptol.Utils.Ident.Namespace
+ Cryptol.Utils.Ident: instance GHC.Classes.Eq Cryptol.Utils.Ident.OrigName
+ Cryptol.Utils.Ident: instance GHC.Classes.Ord Cryptol.Utils.Ident.ModPath
+ Cryptol.Utils.Ident: instance GHC.Classes.Ord Cryptol.Utils.Ident.Namespace
+ Cryptol.Utils.Ident: instance GHC.Classes.Ord Cryptol.Utils.Ident.OrigName
+ Cryptol.Utils.Ident: instance GHC.Enum.Bounded Cryptol.Utils.Ident.Namespace
+ Cryptol.Utils.Ident: instance GHC.Enum.Enum Cryptol.Utils.Ident.Namespace
+ Cryptol.Utils.Ident: instance GHC.Generics.Generic Cryptol.Utils.Ident.ModPath
+ Cryptol.Utils.Ident: instance GHC.Generics.Generic Cryptol.Utils.Ident.Namespace
+ Cryptol.Utils.Ident: instance GHC.Generics.Generic Cryptol.Utils.Ident.OrigName
+ Cryptol.Utils.Ident: instance GHC.Show.Show Cryptol.Utils.Ident.ModPath
+ Cryptol.Utils.Ident: instance GHC.Show.Show Cryptol.Utils.Ident.Namespace
+ Cryptol.Utils.Ident: instance GHC.Show.Show Cryptol.Utils.Ident.OrigName
+ Cryptol.Utils.Ident: modPathCommon :: ModPath -> ModPath -> Maybe (ModPath, [Ident], [Ident])
+ Cryptol.Utils.Ident: modPathSplit :: ModPath -> (ModName, [Ident])
+ Cryptol.Utils.Ident: topModuleFor :: ModPath -> ModName
+ Cryptol.Utils.PP: (</>) :: Doc -> Doc -> Doc
+ Cryptol.Utils.PP: CanonicalOrder :: FieldOrder
+ Cryptol.Utils.PP: DisplayOrder :: FieldOrder
+ Cryptol.Utils.PP: [useFieldOrder] :: PPOpts -> FieldOrder
+ Cryptol.Utils.PP: align :: Doc -> Doc
+ Cryptol.Utils.PP: commaSepFill :: [Doc] -> Doc
+ Cryptol.Utils.PP: data FieldOrder
+ Cryptol.Utils.PP: group :: Doc -> Doc
+ Cryptol.Utils.PP: indent :: Int -> Doc -> Doc
+ Cryptol.Utils.PP: instance Cryptol.Utils.PP.PP Cryptol.Utils.Ident.ModPath
+ Cryptol.Utils.PP: instance Cryptol.Utils.PP.PP Cryptol.Utils.Ident.Namespace
+ Cryptol.Utils.PP: instance Cryptol.Utils.PP.PP Cryptol.Utils.Ident.OrigName
+ Cryptol.Utils.PP: instance Cryptol.Utils.PP.PPName Cryptol.Utils.Ident.ModName
+ Cryptol.Utils.PP: instance GHC.Classes.Eq Cryptol.Utils.PP.FieldOrder
+ Cryptol.Utils.PP: instance GHC.Classes.Ord Cryptol.Utils.PP.FieldOrder
+ Cryptol.Utils.PP: instance GHC.Enum.Bounded Cryptol.Utils.PP.FieldOrder
+ Cryptol.Utils.PP: instance GHC.Enum.Enum Cryptol.Utils.PP.FieldOrder
+ Cryptol.Utils.PP: instance GHC.Read.Read Cryptol.Utils.PP.FieldOrder
+ Cryptol.Utils.PP: instance GHC.Show.Show Cryptol.Utils.PP.FieldOrder
+ Cryptol.Utils.PP: liftPP :: Doc Void -> Doc
+ Cryptol.Utils.PP: liftPP1 :: (Doc Void -> Doc Void) -> Doc -> Doc
+ Cryptol.Utils.PP: liftPP2 :: (Doc Void -> Doc Void -> Doc Void) -> Doc -> Doc -> Doc
+ Cryptol.Utils.PP: ppList :: [Doc] -> Doc
+ Cryptol.Utils.PP: ppRecord :: [Doc] -> Doc
+ Cryptol.Utils.PP: ppTuple :: [Doc] -> Doc
+ Cryptol.Utils.PP: vsep :: [Doc] -> Doc
- Cryptol.Backend: isReady :: Backend sym => sym -> SEval sym a -> Bool
+ Cryptol.Backend: isReady :: Backend sym => sym -> SEval sym a -> SEval sym (Maybe a)
- Cryptol.Eval: PPOpts :: Bool -> Int -> Int -> Int -> PPFloatFormat -> PPOpts
+ Cryptol.Eval: PPOpts :: Bool -> Int -> Int -> Int -> PPFloatFormat -> FieldOrder -> PPOpts
- Cryptol.Eval.Generic: ccatV :: Backend sym => sym -> Nat' -> Nat' -> TValue -> GenValue sym -> GenValue sym -> SEval sym (GenValue sym)
+ Cryptol.Eval.Generic: ccatV :: Backend sym => sym -> Integer -> Nat' -> TValue -> SEval sym (GenValue sym) -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: indexPrim :: Backend sym => sym -> (Nat' -> TValue -> SeqMap sym -> TValue -> SInteger sym -> SEval sym (GenValue sym)) -> (Nat' -> TValue -> SeqMap sym -> TValue -> [SBit sym] -> SEval sym (GenValue sym)) -> (Nat' -> TValue -> SeqMap sym -> TValue -> SWord sym -> SEval sym (GenValue sym)) -> Prim sym
+ Cryptol.Eval.Generic: indexPrim :: Backend sym => sym -> IndexDirection -> (Nat' -> TValue -> SeqMap sym (GenValue sym) -> TValue -> SInteger sym -> SEval sym (GenValue sym)) -> (Nat' -> TValue -> SeqMap sym (GenValue sym) -> TValue -> Integer -> [IndexSegment sym] -> SEval sym (GenValue sym)) -> Prim sym
- Cryptol.Eval.Generic: intShifter :: Backend sym => sym -> String -> (SWord sym -> SWord sym -> SEval sym (SWord sym)) -> (Nat' -> Integer -> Integer -> Maybe Integer) -> Nat' -> TValue -> TValue -> GenValue sym -> SInteger sym -> SEval sym (GenValue sym)
+ Cryptol.Eval.Generic: intShifter :: Backend sym => sym -> String -> (SWord sym -> SWord sym -> SEval sym (SWord sym)) -> (Nat' -> Integer -> Integer -> Maybe Integer) -> Nat' -> TValue -> GenValue sym -> SInteger sym -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: joinSeq :: Backend sym => sym -> Nat' -> Integer -> TValue -> SeqMap sym -> SEval sym (GenValue sym)
+ Cryptol.Eval.Generic: joinSeq :: Backend sym => sym -> Nat' -> Integer -> TValue -> SEval sym (SeqMap sym (GenValue sym)) -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: joinV :: Backend sym => sym -> Nat' -> Integer -> TValue -> GenValue sym -> SEval sym (GenValue sym)
+ Cryptol.Eval.Generic: joinV :: Backend sym => sym -> Nat' -> Integer -> TValue -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: reverseV :: forall sym. Backend sym => sym -> GenValue sym -> SEval sym (GenValue sym)
+ Cryptol.Eval.Generic: reverseV :: forall sym. Backend sym => sym -> Integer -> TValue -> SEval sym (GenValue sym) -> SEval sym (GenValue sym)
- Cryptol.Eval.Generic: sparkParMap :: Backend sym => sym -> (SEval sym (GenValue sym) -> SEval sym (GenValue sym)) -> Integer -> SeqMap sym -> SEval sym (SeqMap sym)
+ Cryptol.Eval.Generic: sparkParMap :: Backend sym => sym -> (SEval sym a -> SEval sym (GenValue sym)) -> Integer -> SeqMap sym a -> SEval sym (SeqMap sym (GenValue sym))
- Cryptol.Eval.Generic: updatePrim :: Backend sym => sym -> (Nat' -> TValue -> WordValue sym -> Either (SInteger sym) (WordValue sym) -> SEval sym (GenValue sym) -> SEval sym (WordValue sym)) -> (Nat' -> TValue -> SeqMap sym -> Either (SInteger sym) (WordValue sym) -> SEval sym (GenValue sym) -> SEval sym (SeqMap sym)) -> Prim sym
+ Cryptol.Eval.Generic: updatePrim :: Backend sym => sym -> (Nat' -> TValue -> WordValue sym -> Either (SInteger sym) (WordValue sym) -> SEval sym (GenValue sym) -> SEval sym (WordValue sym)) -> (Nat' -> TValue -> SeqMap sym (GenValue sym) -> Either (SInteger sym) (WordValue sym) -> SEval sym (GenValue sym) -> SEval sym (SeqMap sym (GenValue sym))) -> Prim sym
- Cryptol.Eval.Value: VSeq :: !Integer -> !SeqMap sym -> GenValue sym
+ Cryptol.Eval.Value: VSeq :: !Integer -> !SeqMap sym (GenValue sym) -> GenValue sym
- Cryptol.Eval.Value: VStream :: !SeqMap sym -> GenValue sym
+ Cryptol.Eval.Value: VStream :: !SeqMap sym (GenValue sym) -> GenValue sym
- Cryptol.Eval.Value: VWord :: !Integer -> !SEval sym (WordValue sym) -> GenValue sym
+ Cryptol.Eval.Value: VWord :: !Integer -> !WordValue sym -> GenValue sym
- Cryptol.Eval.Value: asIndex :: Backend sym => sym -> String -> TValue -> GenValue sym -> SEval sym (Either (SInteger sym) (WordValue sym))
+ Cryptol.Eval.Value: asIndex :: Backend sym => sym -> String -> TValue -> GenValue sym -> Either (SInteger sym) (WordValue sym)
- Cryptol.Eval.Value: fromSeq :: Backend sym => String -> GenValue sym -> SEval sym (SeqMap sym)
+ Cryptol.Eval.Value: fromSeq :: Backend sym => String -> GenValue sym -> SEval sym (SeqMap sym (GenValue sym))
- Cryptol.Eval.Value: fromVSeq :: GenValue sym -> SeqMap sym
+ Cryptol.Eval.Value: fromVSeq :: GenValue sym -> SeqMap sym (GenValue sym)
- Cryptol.Eval.Value: fromWordVal :: Backend sym => String -> GenValue sym -> SEval sym (WordValue sym)
+ Cryptol.Eval.Value: fromWordVal :: Backend sym => String -> GenValue sym -> WordValue sym
- Cryptol.Eval.Value: isReady :: Backend sym => sym -> SEval sym a -> Bool
+ Cryptol.Eval.Value: isReady :: Backend sym => sym -> SEval sym a -> SEval sym (Maybe a)
- Cryptol.Eval.Value: mkSeq :: Backend sym => Nat' -> TValue -> SeqMap sym -> GenValue sym
+ Cryptol.Eval.Value: mkSeq :: Backend sym => sym -> Nat' -> TValue -> SeqMap sym (GenValue sym) -> SEval sym (GenValue sym)
- Cryptol.Eval.Value: tryFromBits :: Backend sym => sym -> [SEval sym (GenValue sym)] -> Maybe (SEval sym (SWord sym))
+ Cryptol.Eval.Value: tryFromBits :: Backend sym => sym -> [SEval sym (GenValue sym)] -> SEval sym (Maybe (SWord sym))
- Cryptol.Eval.Value: word :: Backend sym => sym -> Integer -> Integer -> GenValue sym
+ Cryptol.Eval.Value: word :: Backend sym => sym -> Integer -> Integer -> SEval sym (GenValue sym)
- Cryptol.ModuleSystem: DEnv :: NamingEnv -> [DeclGroup] -> EvalEnv -> DynamicEnv
+ Cryptol.ModuleSystem: DEnv :: NamingEnv -> [DeclGroup] -> Map Name TySyn -> EvalEnv -> DynamicEnv
- Cryptol.ModuleSystem: Iface :: !ModName -> IfaceDecls -> IfaceDecls -> IfaceParams -> Iface
+ Cryptol.ModuleSystem: Iface :: !mname -> IfaceDecls -> IfaceDecls -> IfaceParams -> IfaceG mname
- Cryptol.ModuleSystem: IfaceDecls :: Map Name IfaceTySyn -> Map Name IfaceNewtype -> Map Name IfaceAbstractType -> Map Name IfaceDecl -> IfaceDecls
+ Cryptol.ModuleSystem: IfaceDecls :: Map Name IfaceTySyn -> Map Name IfaceNewtype -> Map Name IfaceAbstractType -> Map Name IfaceDecl -> !Map Name (IfaceG Name) -> IfaceDecls
- Cryptol.ModuleSystem: ModuleEnv :: LoadedModules -> NameSeeds -> SolverConfig -> EvalEnv -> CoreLint -> !Bool -> Maybe ModName -> [FilePath] -> DynamicEnv -> !Supply -> ModuleEnv
+ Cryptol.ModuleSystem: ModuleEnv :: LoadedModules -> NameSeeds -> EvalEnv -> CoreLint -> !Bool -> Maybe ModName -> [FilePath] -> DynamicEnv -> !Supply -> ModuleEnv
- Cryptol.ModuleSystem: [ifModName] :: Iface -> !ModName
+ Cryptol.ModuleSystem: [ifModName] :: IfaceG mname -> !mname
- Cryptol.ModuleSystem: [ifParams] :: Iface -> IfaceParams
+ Cryptol.ModuleSystem: [ifParams] :: IfaceG mname -> IfaceParams
- Cryptol.ModuleSystem: [ifPrivate] :: Iface -> IfaceDecls
+ Cryptol.ModuleSystem: [ifPrivate] :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem: [ifPublic] :: Iface -> IfaceDecls
+ Cryptol.ModuleSystem: [ifPublic] :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem: checkDecls :: [TopDecl PName] -> ModuleCmd (NamingEnv, [DeclGroup])
+ Cryptol.ModuleSystem: checkDecls :: [TopDecl PName] -> ModuleCmd (NamingEnv, [DeclGroup], Map Name TySyn)
- Cryptol.ModuleSystem: genIface :: Module -> Iface
+ Cryptol.ModuleSystem: genIface :: ModuleG mname -> IfaceG mname
- Cryptol.ModuleSystem.Base: checkDecls :: [TopDecl PName] -> ModuleM (NamingEnv, [DeclGroup])
+ Cryptol.ModuleSystem.Base: checkDecls :: [TopDecl PName] -> ModuleM (NamingEnv, [DeclGroup], Map Name TySyn)
- Cryptol.ModuleSystem.Base: checkModule :: ImportSource -> ModulePath -> Module PName -> ModuleM Module
+ Cryptol.ModuleSystem.Base: checkModule :: ImportSource -> ModulePath -> Module PName -> ModuleM (NamingEnv, Module)
- Cryptol.ModuleSystem.Base: checkSingleModule :: Act (Module Name) Module -> ImportSource -> ModulePath -> Module PName -> ModuleM Module
+ Cryptol.ModuleSystem.Base: checkSingleModule :: Act (Module Name) Module -> ImportSource -> ModulePath -> Module PName -> ModuleM (NamingEnv, Module)
- Cryptol.ModuleSystem.Base: declsLinter :: TCLinter [DeclGroup]
+ Cryptol.ModuleSystem.Base: declsLinter :: TCLinter ([DeclGroup], a)
- Cryptol.ModuleSystem.Base: renameModule :: Module PName -> ModuleM (IfaceDecls, NamingEnv, Module Name)
+ Cryptol.ModuleSystem.Base: renameModule :: Module PName -> ModuleM RenamedModule
- Cryptol.ModuleSystem.Env: DEnv :: NamingEnv -> [DeclGroup] -> EvalEnv -> DynamicEnv
+ Cryptol.ModuleSystem.Env: DEnv :: NamingEnv -> [DeclGroup] -> Map Name TySyn -> EvalEnv -> DynamicEnv
- Cryptol.ModuleSystem.Env: LoadedModule :: ModName -> ModulePath -> String -> Iface -> Module -> Fingerprint -> LoadedModule
+ Cryptol.ModuleSystem.Env: LoadedModule :: ModName -> ModulePath -> String -> !NamingEnv -> Iface -> Module -> Fingerprint -> LoadedModule
- Cryptol.ModuleSystem.Env: ModContext :: IfaceParams -> IfaceDecls -> NamingEnv -> NameDisp -> Map Name DeclProvenance -> Map Name DeclProvenance -> ModContext
+ Cryptol.ModuleSystem.Env: ModContext :: IfaceParams -> Set Name -> IfaceDecls -> NamingEnv -> NameDisp -> ModContext
- Cryptol.ModuleSystem.Env: ModuleEnv :: LoadedModules -> NameSeeds -> SolverConfig -> EvalEnv -> CoreLint -> !Bool -> Maybe ModName -> [FilePath] -> DynamicEnv -> !Supply -> ModuleEnv
+ Cryptol.ModuleSystem.Env: ModuleEnv :: LoadedModules -> NameSeeds -> EvalEnv -> CoreLint -> !Bool -> Maybe ModName -> [FilePath] -> DynamicEnv -> !Supply -> ModuleEnv
- Cryptol.ModuleSystem.Env: addLoadedModule :: ModulePath -> String -> Fingerprint -> Module -> LoadedModules -> LoadedModules
+ Cryptol.ModuleSystem.Env: addLoadedModule :: ModulePath -> String -> Fingerprint -> NamingEnv -> Module -> LoadedModules -> LoadedModules
- Cryptol.ModuleSystem.Exports: ExportSpec :: Set name -> Set name -> ExportSpec name
+ Cryptol.ModuleSystem.Exports: ExportSpec :: Map Namespace (Set name) -> ExportSpec name
- Cryptol.ModuleSystem.Exports: modExports :: Ord name => Module name -> ExportSpec name
+ Cryptol.ModuleSystem.Exports: modExports :: Ord name => ModuleG mname name -> ExportSpec name
- Cryptol.ModuleSystem.InstantiateModule: instantiateModule :: FreshM m => Module -> ModName -> Map TParam Type -> Map Name Expr -> m ([Located Prop], Module)
+ Cryptol.ModuleSystem.InstantiateModule: instantiateModule :: FreshM m => Module -> ModName -> Map TParam Type -> Map Name Expr -> m (Name -> Name, [Located Prop], Module)
- Cryptol.ModuleSystem.Interface: Iface :: !ModName -> IfaceDecls -> IfaceDecls -> IfaceParams -> Iface
+ Cryptol.ModuleSystem.Interface: Iface :: !mname -> IfaceDecls -> IfaceDecls -> IfaceParams -> IfaceG mname
- Cryptol.ModuleSystem.Interface: IfaceDecls :: Map Name IfaceTySyn -> Map Name IfaceNewtype -> Map Name IfaceAbstractType -> Map Name IfaceDecl -> IfaceDecls
+ Cryptol.ModuleSystem.Interface: IfaceDecls :: Map Name IfaceTySyn -> Map Name IfaceNewtype -> Map Name IfaceAbstractType -> Map Name IfaceDecl -> !Map Name (IfaceG Name) -> IfaceDecls
- Cryptol.ModuleSystem.Interface: [ifModName] :: Iface -> !ModName
+ Cryptol.ModuleSystem.Interface: [ifModName] :: IfaceG mname -> !mname
- Cryptol.ModuleSystem.Interface: [ifParams] :: Iface -> IfaceParams
+ Cryptol.ModuleSystem.Interface: [ifParams] :: IfaceG mname -> IfaceParams
- Cryptol.ModuleSystem.Interface: [ifPrivate] :: Iface -> IfaceDecls
+ Cryptol.ModuleSystem.Interface: [ifPrivate] :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem.Interface: [ifPublic] :: Iface -> IfaceDecls
+ Cryptol.ModuleSystem.Interface: [ifPublic] :: IfaceG mname -> IfaceDecls
- Cryptol.ModuleSystem.Monad: loadedModule :: ModulePath -> Fingerprint -> Module -> ModuleM ()
+ Cryptol.ModuleSystem.Monad: loadedModule :: ModulePath -> Fingerprint -> NamingEnv -> Module -> ModuleM ()
- Cryptol.ModuleSystem.Name: Declared :: !ModName -> !NameSource -> NameInfo
+ Cryptol.ModuleSystem.Name: Declared :: !ModPath -> !NameSource -> NameInfo
- Cryptol.ModuleSystem.Name: mkDeclared :: ModName -> NameSource -> Ident -> Maybe Fixity -> Range -> Supply -> (Name, Supply)
+ Cryptol.ModuleSystem.Name: mkDeclared :: Namespace -> ModPath -> NameSource -> Ident -> Maybe Fixity -> Range -> Supply -> (Name, Supply)
- Cryptol.ModuleSystem.Name: mkParameter :: Ident -> Range -> Supply -> (Name, Supply)
+ Cryptol.ModuleSystem.Name: mkParameter :: Namespace -> Ident -> Range -> Supply -> (Name, Supply)
- Cryptol.ModuleSystem.NamingEnv: InModule :: !ModName -> a -> InModule a
+ Cryptol.ModuleSystem.NamingEnv: InModule :: Maybe ModPath -> a -> InModule a
- Cryptol.ModuleSystem.NamingEnv: NamingEnv :: !Map PName [Name] -> !Map PName [Name] -> NamingEnv
+ Cryptol.ModuleSystem.NamingEnv: NamingEnv :: Map Namespace (Map PName [Name]) -> NamingEnv
- Cryptol.ModuleSystem.NamingEnv: newLocal :: FreshM m => PName -> Range -> m Name
+ Cryptol.ModuleSystem.NamingEnv: newLocal :: FreshM m => Namespace -> PName -> Range -> m Name
- Cryptol.ModuleSystem.NamingEnv: newTop :: FreshM m => ModName -> PName -> Maybe Fixity -> Range -> m Name
+ Cryptol.ModuleSystem.NamingEnv: newTop :: FreshM m => Namespace -> ModPath -> PName -> Maybe Fixity -> Range -> m Name
- Cryptol.ModuleSystem.NamingEnv: visibleNames :: NamingEnv -> (Set Name, Set Name)
+ Cryptol.ModuleSystem.NamingEnv: visibleNames :: NamingEnv -> Map Namespace (Set Name)
- Cryptol.ModuleSystem.Renamer: BoundReservedType :: PName -> Maybe Range -> Doc -> NameDisp -> RenamerError
+ Cryptol.ModuleSystem.Renamer: BoundReservedType :: PName -> Maybe Range -> Doc -> RenamerError
- Cryptol.ModuleSystem.Renamer: FixityError :: Located Name -> Fixity -> Located Name -> Fixity -> NameDisp -> RenamerError
+ Cryptol.ModuleSystem.Renamer: FixityError :: Located Name -> Fixity -> Located Name -> Fixity -> RenamerError
- Cryptol.ModuleSystem.Renamer: InModule :: !ModName -> a -> InModule a
+ Cryptol.ModuleSystem.Renamer: InModule :: Maybe ModPath -> a -> InModule a
- Cryptol.ModuleSystem.Renamer: InvalidConstraint :: Type PName -> NameDisp -> RenamerError
+ Cryptol.ModuleSystem.Renamer: InvalidConstraint :: Type PName -> RenamerError
- Cryptol.ModuleSystem.Renamer: MalformedBuiltin :: Type PName -> PName -> NameDisp -> RenamerError
+ Cryptol.ModuleSystem.Renamer: MalformedBuiltin :: Type PName -> PName -> RenamerError
- Cryptol.ModuleSystem.Renamer: MultipleSyms :: Located PName -> [Name] -> NameDisp -> RenamerError
+ Cryptol.ModuleSystem.Renamer: MultipleSyms :: Located PName -> [Name] -> RenamerError
- Cryptol.ModuleSystem.Renamer: OverlappingRecordUpdate :: Located [Selector] -> Located [Selector] -> NameDisp -> RenamerError
+ Cryptol.ModuleSystem.Renamer: OverlappingRecordUpdate :: Located [Selector] -> Located [Selector] -> RenamerError
- Cryptol.ModuleSystem.Renamer: OverlappingSyms :: [Name] -> NameDisp -> RenamerError
+ Cryptol.ModuleSystem.Renamer: OverlappingSyms :: [Name] -> RenamerError
- Cryptol.ModuleSystem.Renamer: SymbolShadowed :: Name -> [Name] -> NameDisp -> RenamerWarning
+ Cryptol.ModuleSystem.Renamer: SymbolShadowed :: PName -> Name -> [Name] -> RenamerWarning
- Cryptol.ModuleSystem.Renamer: UnusedName :: Name -> NameDisp -> RenamerWarning
+ Cryptol.ModuleSystem.Renamer: UnusedName :: Name -> RenamerWarning
- Cryptol.ModuleSystem.Renamer: renameModule :: Module PName -> RenameM (NamingEnv, Module Name)
+ Cryptol.ModuleSystem.Renamer: renameModule :: Module PName -> RenameM RenamedModule
- Cryptol.ModuleSystem.Renamer: renameType :: PName -> RenameM Name
+ Cryptol.ModuleSystem.Renamer: renameType :: NameType -> PName -> RenameM Name
- Cryptol.ModuleSystem.Renamer: renameVar :: PName -> RenameM Name
+ Cryptol.ModuleSystem.Renamer: renameVar :: NameType -> PName -> RenameM Name
- Cryptol.ModuleSystem.Renamer: runRenamer :: Supply -> ModName -> NamingEnv -> RenameM a -> (Either [RenamerError] (a, Supply), [RenamerWarning])
+ Cryptol.ModuleSystem.Renamer: runRenamer :: RenamerInfo -> RenameM a -> (Either [RenamerError] (a, Supply), [RenamerWarning])
- Cryptol.Parser.AST: Bind :: Located name -> [Pattern name] -> Located (BindDef name) -> Maybe (Schema name) -> Bool -> Maybe Fixity -> [Pragma] -> Bool -> Maybe Text -> Bind name
+ Cryptol.Parser.AST: Bind :: Located name -> [Pattern name] -> Located (BindDef name) -> Maybe (Schema name) -> Bool -> Maybe Fixity -> [Pragma] -> Bool -> Maybe Text -> !ExportType -> Bind name
- Cryptol.Parser.AST: Import :: !ModName -> Maybe ModName -> Maybe ImportSpec -> Import
+ Cryptol.Parser.AST: Import :: !mname -> Maybe ModName -> Maybe ImportSpec -> ImportG mname
- Cryptol.Parser.AST: LetInput :: Decl name -> ReplInput name
+ Cryptol.Parser.AST: LetInput :: [Decl name] -> ReplInput name
- Cryptol.Parser.AST: Module :: Located ModName -> !Maybe (Located ModName) -> [Located Import] -> [TopDecl name] -> Module name
+ Cryptol.Parser.AST: Module :: Located mname -> !Maybe (Located ModName) -> [TopDecl name] -> ModuleG mname name
- Cryptol.Parser.AST: [iAs] :: Import -> Maybe ModName
+ Cryptol.Parser.AST: [iAs] :: ImportG mname -> Maybe ModName
- Cryptol.Parser.AST: [iModule] :: Import -> !ModName
+ Cryptol.Parser.AST: [iModule] :: ImportG mname -> !mname
- Cryptol.Parser.AST: [iSpec] :: Import -> Maybe ImportSpec
+ Cryptol.Parser.AST: [iSpec] :: ImportG mname -> Maybe ImportSpec
- Cryptol.Parser.AST: [mDecls] :: Module name -> [TopDecl name]
+ Cryptol.Parser.AST: [mDecls] :: ModuleG mname name -> [TopDecl name]
- Cryptol.Parser.AST: [mInstance] :: Module name -> !Maybe (Located ModName)
+ Cryptol.Parser.AST: [mInstance] :: ModuleG mname name -> !Maybe (Located ModName)
- Cryptol.Parser.AST: [mName] :: Module name -> Located ModName
+ Cryptol.Parser.AST: [mName] :: ModuleG mname name -> Located mname
- Cryptol.Symbolic.What4: satProveOffline :: W4ProverConfig -> Bool -> Bool -> ProverCommand -> ((Handle -> IO ()) -> IO ()) -> ModuleCmd (Maybe String)
+ Cryptol.Symbolic.What4: satProveOffline :: Bool -> Bool -> ProverCommand -> ((Handle -> IO ()) -> IO ()) -> ModuleCmd (Maybe String)
- Cryptol.TypeCheck: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> !Map Name ModTParam -> ![Located Prop] -> !Map Name ModVParam -> NameSeeds -> Bool -> Bool -> SolverConfig -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
+ Cryptol.TypeCheck: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> !Map Name ModTParam -> ![Located Prop] -> !Map Name ModVParam -> NameSeeds -> Bool -> Bool -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
- Cryptol.TypeCheck: tcDecls :: FromDecl d => [d] -> InferInput -> IO (InferOutput [DeclGroup])
+ Cryptol.TypeCheck: tcDecls :: [TopDecl Name] -> InferInput -> IO (InferOutput ([DeclGroup], Map Name TySyn))
- Cryptol.TypeCheck: tcModuleInst :: Module -> Module Name -> InferInput -> IO (InferOutput Module)
+ Cryptol.TypeCheck: tcModuleInst :: IORef NamingEnv -> Module -> Module Name -> InferInput -> IO (InferOutput Module)
- Cryptol.TypeCheck.AST: ExportSpec :: Set name -> Set name -> ExportSpec name
+ Cryptol.TypeCheck.AST: ExportSpec :: Map Namespace (Set name) -> ExportSpec name
- Cryptol.TypeCheck.AST: Import :: !ModName -> Maybe ModName -> Maybe ImportSpec -> Import
+ Cryptol.TypeCheck.AST: Import :: !mname -> Maybe ModName -> Maybe ImportSpec -> ImportG mname
- Cryptol.TypeCheck.AST: Module :: !ModName -> ExportSpec Name -> [Import] -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> Map Name ModTParam -> [Located Prop] -> Map Name ModVParam -> [DeclGroup] -> Module
+ Cryptol.TypeCheck.AST: Module :: !mname -> ExportSpec Name -> [Import] -> Map Name (IfaceG Name) -> Map Name ModTParam -> [Located Prop] -> Map Name ModVParam -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> [DeclGroup] -> Map Name (ModuleG Name) -> ModuleG mname
- Cryptol.TypeCheck.AST: [iAs] :: Import -> Maybe ModName
+ Cryptol.TypeCheck.AST: [iAs] :: ImportG mname -> Maybe ModName
- Cryptol.TypeCheck.AST: [iModule] :: Import -> !ModName
+ Cryptol.TypeCheck.AST: [iModule] :: ImportG mname -> !mname
- Cryptol.TypeCheck.AST: [iSpec] :: Import -> Maybe ImportSpec
+ Cryptol.TypeCheck.AST: [iSpec] :: ImportG mname -> Maybe ImportSpec
- Cryptol.TypeCheck.AST: [mDecls] :: Module -> [DeclGroup]
+ Cryptol.TypeCheck.AST: [mDecls] :: ModuleG mname -> [DeclGroup]
- Cryptol.TypeCheck.AST: [mExports] :: Module -> ExportSpec Name
+ Cryptol.TypeCheck.AST: [mExports] :: ModuleG mname -> ExportSpec Name
- Cryptol.TypeCheck.AST: [mImports] :: Module -> [Import]
+ Cryptol.TypeCheck.AST: [mImports] :: ModuleG mname -> [Import]
- Cryptol.TypeCheck.AST: [mName] :: Module -> !ModName
+ Cryptol.TypeCheck.AST: [mName] :: ModuleG mname -> !mname
- Cryptol.TypeCheck.AST: [mNewtypes] :: Module -> Map Name Newtype
+ Cryptol.TypeCheck.AST: [mNewtypes] :: ModuleG mname -> Map Name Newtype
- Cryptol.TypeCheck.AST: [mParamConstraints] :: Module -> [Located Prop]
+ Cryptol.TypeCheck.AST: [mParamConstraints] :: ModuleG mname -> [Located Prop]
- Cryptol.TypeCheck.AST: [mParamFuns] :: Module -> Map Name ModVParam
+ Cryptol.TypeCheck.AST: [mParamFuns] :: ModuleG mname -> Map Name ModVParam
- Cryptol.TypeCheck.AST: [mParamTypes] :: Module -> Map Name ModTParam
+ Cryptol.TypeCheck.AST: [mParamTypes] :: ModuleG mname -> Map Name ModTParam
- Cryptol.TypeCheck.AST: [mPrimTypes] :: Module -> Map Name AbstractType
+ Cryptol.TypeCheck.AST: [mPrimTypes] :: ModuleG mname -> Map Name AbstractType
- Cryptol.TypeCheck.AST: [mTySyns] :: Module -> Map Name TySyn
+ Cryptol.TypeCheck.AST: [mTySyns] :: ModuleG mname -> Map Name TySyn
- Cryptol.TypeCheck.AST: isParametrizedModule :: Module -> Bool
+ Cryptol.TypeCheck.AST: isParametrizedModule :: ModuleG mname -> Bool
- Cryptol.TypeCheck.CheckModuleInstance: checkModuleInstance :: Module -> Module -> InferM Module
+ Cryptol.TypeCheck.CheckModuleInstance: checkModuleInstance :: Module -> Module -> InferM (Name -> Name, Module)
- Cryptol.TypeCheck.Monad: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> !Map Name ModTParam -> ![Located Prop] -> !Map Name ModVParam -> NameSeeds -> Bool -> Bool -> SolverConfig -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
+ Cryptol.TypeCheck.Monad: InferInput :: Range -> Map Name Schema -> Map Name TySyn -> Map Name Newtype -> Map Name AbstractType -> !Map Name ModTParam -> ![Located Prop] -> !Map Name ModVParam -> NameSeeds -> Bool -> Bool -> [FilePath] -> !PrimMap -> !Supply -> Solver -> InferInput
- Cryptol.TypeCheck.Monad: RO :: Range -> Map Name VarType -> [TParam] -> Map Name (DefLoc, TySyn) -> Map Name (DefLoc, Newtype) -> Map Name (DefLoc, AbstractType) -> Map Name ModTParam -> [Located Prop] -> Map Name ModVParam -> Map Int HasGoalSln -> Bool -> Bool -> Solver -> !PrimMap -> !IORef Int -> RO
+ Cryptol.TypeCheck.Monad: RO :: Range -> Map Name VarType -> [TParam] -> ModuleG ScopeName -> Map Int HasGoalSln -> Bool -> Bool -> Solver -> !PrimMap -> !IORef Int -> RO
- Cryptol.TypeCheck.Monad: RW :: ![(Range, Error)] -> ![(Range, Warning)] -> !Subst -> [Map Name Type] -> Map Int HasGoalSln -> !NameSeeds -> !Goals -> ![HasGoal] -> !Supply -> RW
+ Cryptol.TypeCheck.Monad: RW :: ![(Range, Error)] -> ![(Range, Warning)] -> !Subst -> [Map Name Type] -> Map Int HasGoalSln -> !NameSeeds -> !Goals -> ![HasGoal] -> ![ModuleG ScopeName] -> !Map Name Schema -> !Supply -> RW
- Cryptol.TypeCheck.Monad: getAbstractTypes :: InferM (Map Name (DefLoc, AbstractType))
+ Cryptol.TypeCheck.Monad: getAbstractTypes :: InferM (Map Name AbstractType)
- Cryptol.TypeCheck.Monad: getNewtypes :: InferM (Map Name (DefLoc, Newtype))
+ Cryptol.TypeCheck.Monad: getNewtypes :: InferM (Map Name Newtype)
- Cryptol.TypeCheck.Monad: getTSyns :: InferM (Map Name (DefLoc, TySyn))
+ Cryptol.TypeCheck.Monad: getTSyns :: InferM (Map Name TySyn)
- Cryptol.TypeCheck.Monad: newParamName :: Ident -> InferM Name
+ Cryptol.TypeCheck.Monad: newParamName :: Namespace -> Ident -> InferM Name
- Cryptol.TypeCheck.Parseable: maybeNameDoc :: Maybe Name -> Doc
+ Cryptol.TypeCheck.Parseable: maybeNameDoc :: Maybe Name -> Doc Void
- Cryptol.TypeCheck.Parseable: showParseable :: ShowParseable t => t -> Doc
+ Cryptol.TypeCheck.Parseable: showParseable :: ShowParseable t => t -> Doc Void
- Cryptol.TypeCheck.Solver.SMT: startSolver :: SolverConfig -> IO Solver
+ Cryptol.TypeCheck.Solver.SMT: startSolver :: IO () -> SolverConfig -> IO Solver
- Cryptol.TypeCheck.Solver.SMT: withSolver :: SolverConfig -> (Solver -> IO a) -> IO a
+ Cryptol.TypeCheck.Solver.SMT: withSolver :: IO () -> SolverConfig -> (Solver -> IO a) -> IO a
- Cryptol.Utils.PP: Doc :: (NameDisp -> Doc) -> Doc
+ Cryptol.Utils.PP: Doc :: (NameDisp -> Doc Void) -> Doc
- Cryptol.Utils.PP: NameDisp :: (ModName -> Ident -> Maybe NameFormat) -> NameDisp
+ Cryptol.Utils.PP: NameDisp :: (OrigName -> Maybe NameFormat) -> NameDisp
- Cryptol.Utils.PP: PPOpts :: Bool -> Int -> Int -> Int -> PPFloatFormat -> PPOpts
+ Cryptol.Utils.PP: PPOpts :: Bool -> Int -> Int -> Int -> PPFloatFormat -> FieldOrder -> PPOpts
- Cryptol.Utils.PP: getNameFormat :: ModName -> Ident -> NameDisp -> NameFormat
+ Cryptol.Utils.PP: getNameFormat :: OrigName -> NameDisp -> NameFormat
- Cryptol.Utils.PP: infixl 6 <+>
+ Cryptol.Utils.PP: infixl 6 </>
- Cryptol.Utils.PP: liftSep :: ([Doc] -> Doc) -> [Doc] -> Doc
+ Cryptol.Utils.PP: liftSep :: ([Doc Void] -> Doc Void) -> [Doc] -> Doc
- Cryptol.Utils.PP: neverQualifyMod :: ModName -> NameDisp
+ Cryptol.Utils.PP: neverQualifyMod :: ModPath -> NameDisp
- Cryptol.Utils.PP: runDoc :: NameDisp -> Doc -> Doc
+ Cryptol.Utils.PP: runDoc :: NameDisp -> Doc -> Doc Void

Files

CHANGES.md view
@@ -1,3 +1,81 @@+# 2.12.0++## Language changes+* Updates to the layout rule.  We simplified the specification and made+  some minor changes, in particular:+    - Paren blocks nested in a layout block need to respect the indentation+      if the layout block+    - We allow nested layout blocks to have the same indentation, which is+      convenient when writing `private` declarations as they don't need to+      be indented as long as they are at the end of the file.++* New enumeration forms `[x .. y by n]`, `[x .. <y by n]`,+  `[x .. y down by n]` and `[x .. >y down by n]` have been+  implemented. These new forms let the user explicitly specify+  the stride for an enumeration, as opposed to the previous+  `[x, y .. z]` form (where the stride was computed from `x` and `y`).++* Nested modules are now available (from pull request #1048). For example, the following is now valid Cryptol:++        module SubmodTest where++        import submodule B as C++        submodule A where+          propA = C::y > 5++        submodule B where+          y : Integer+          y = 42++## New features++* What4 prover backends now feature an improved multi-SAT procedure+  which is significantly faster than the old algorithm. Thanks to+  Levent Erkök for the suggestion.++* There is a new `w4-abc` solver option, which communicates to ABC+  as an external process via What4.++* Expanded support for declaration forms in the REPL. You can now+  define infix operators, type synonyms and mutually-recursive functions,+  and state signatures and fixity declarations. Multiple declarations+  can be combined into a single line by separating them with `;`,+  which is necessary for stating a signature together with a+  definition, etc.+  +* There is a new `:set path` REPL option that provides an alternative to+  `CRYPTOLPATH` for controlling where to search for imported modules+  (issue #631).++* The `cryptol-remote-api` server now natively supports HTTPS (issue+  #1008), `newtype` values (issue #1033), and safety checking (issue+  #1166).++* Releases optionally include solvers (issue #1111). See the+  `*-with-solvers*` files in the assets list for this release.++## Bug fixes++* Closed issues #422, #436, #619, #631, #633, #640, #680, #734, #735,+  #759, #760, #764, #849, #996, #1000, #1008, #1019, #1032, #1033,+  #1034, #1043, #1047, #1060, #1064, #1083, #1084, #1087, #1102, #1111,+  #1113, #1117, #1125, #1133, #1142, #1144, #1145, #1146, #1157, #1160,+  #1163, #1166, #1169, #1175, #1179, #1182, #1190, #1191, #1196, #1197,+  #1204, #1209, #1210, #1213, #1216, #1223, #1226, #1238, #1239, #1240,+  #1241, #1250, #1256, #1259, #1261, #1266, #1274, #1275, #1283, and+  #1291.++* Merged pull requests #1048, #1128, #1129, #1130, #1131, #1135, #1136,+  #1137, #1139, #1148, #1149, #1150, #1152, #1154, #1156, #1158, #1159,+  #1161, #1164, #1165, #1168, #1170, #1171, #1172, #1173, #1174, #1176,+  #1181, #1183, #1186, #1188, #1192, #1193, #1194, #1195, #1199, #1200,+  #1202, #1203, #1205, #1207, #1211, #1214, #1215, #1218, #1219, #1221,+  #1224, #1225, #1227, #1228, #1230, #1231, #1232, #1234, #1242, #1243,+  #1244, #1245, #1246, #1247, #1248, #1251, #1252, #1254, #1255, #1258,+  #1263, #1265, #1268, #1269, #1270, #1271, #1272, #1273, #1276, #1281,+  #1282, #1284, #1285, #1286, #1287, #1288, #1293, #1294, and #1295.+ # 2.11.0  ## Language changes
cryptol.cabal view
@@ -1,6 +1,6 @@ Cabal-version:       2.4 Name:                cryptol-Version:             2.11.0+Version:             2.12.0 Synopsis:            Cryptol: The Language of Cryptography Description: Cryptol is a domain-specific language for specifying cryptographic algorithms. A Cryptol implementation of an algorithm resembles its mathematical specification more closely than an implementation in a general purpose language. For more, see <http://www.cryptol.net/>. License:             BSD-3-Clause@@ -25,7 +25,8 @@ source-repository this   type:     git   location: https://github.com/GaloisInc/cryptol.git-  tag:      2.11.0+  -- add a tag on release branches+  tag:      2.12.0   flag static@@ -61,11 +62,10 @@                        monad-control     >= 1.0,                        monadLib          >= 3.7.2,                        parameterized-utils >= 2.0.2,-                       pretty            >= 1.1,+                       prettyprinter     >= 1.7.0,                        process           >= 1.2,-                       random            >= 1.0.1,-                       sbv               >= 8.6 && < 8.13,-                       simple-smt        >= 0.7.1,+                       sbv               >= 8.6 && < 8.17,+                       simple-smt        >= 0.9.7,                        stm               >= 2.4,                        strict,                        text              >= 1.1,@@ -74,13 +74,15 @@                        mtl               >= 2.2.1,                        time              >= 1.6.0.1,                        panic             >= 0.3,-                       what4             >= 1.1 && < 1.2+                       what4             >= 1.2 && < 1.3    Build-tool-depends:  alex:alex, happy:happy   hs-source-dirs:      src    Exposed-modules:     Cryptol.Parser,                        Cryptol.Parser.Lexer,+                       Cryptol.Parser.Token,+                       Cryptol.Parser.Layout,                        Cryptol.Parser.AST,                        Cryptol.Parser.Position,                        Cryptol.Parser.Names,@@ -110,9 +112,11 @@                        Cryptol.ModuleSystem.Monad,                        Cryptol.ModuleSystem.Name,                        Cryptol.ModuleSystem.NamingEnv,-                       Cryptol.ModuleSystem.Renamer,                        Cryptol.ModuleSystem.Exports,                        Cryptol.ModuleSystem.InstantiateModule,+                       Cryptol.ModuleSystem.Renamer,+                       Cryptol.ModuleSystem.Renamer.Monad,+                       Cryptol.ModuleSystem.Renamer.Error,                         Cryptol.TypeCheck,                        Cryptol.TypeCheck.Type,@@ -125,12 +129,12 @@                        Cryptol.TypeCheck.Infer,                        Cryptol.TypeCheck.CheckModuleInstance,                        Cryptol.TypeCheck.InferTypes,+                       Cryptol.TypeCheck.Interface,                        Cryptol.TypeCheck.Error,                        Cryptol.TypeCheck.Kind,                        Cryptol.TypeCheck.Subst,                        Cryptol.TypeCheck.Instantiate,                        Cryptol.TypeCheck.Unify,-                       Cryptol.TypeCheck.Depends,                        Cryptol.TypeCheck.PP,                        Cryptol.TypeCheck.Solve,                        Cryptol.TypeCheck.Default,@@ -162,8 +166,10 @@                        Cryptol.Backend.Concrete,                        Cryptol.Backend.FloatHelpers,                        Cryptol.Backend.Monad,+                       Cryptol.Backend.SeqMap,                        Cryptol.Backend.SBV,                        Cryptol.Backend.What4,+                       Cryptol.Backend.WordValue,                         Cryptol.Eval,                        Cryptol.Eval.Concrete,@@ -188,6 +194,7 @@                        Cryptol.Symbolic.What4,                         Cryptol.REPL.Command,+                       Cryptol.REPL.Browse,                        Cryptol.REPL.Monad,                        Cryptol.REPL.Trie @@ -224,6 +231,7 @@                      , directory                      , filepath                      , haskeline >= 0.7 && < 0.9+                     , exceptions                      , monad-control                      , text                      , transformers
cryptol/Main.hs view
@@ -15,7 +15,7 @@  import Cryptol.REPL.Command (loadCmd,loadPrelude,CommandExitCode(..)) import Cryptol.REPL.Monad (REPL,updateREPLTitle,setUpdateREPLTitle,-                   io,prependSearchPath,setSearchPath)+                   io,prependSearchPath,setSearchPath,parseSearchPath) import qualified Cryptol.REPL.Monad as REPL import Cryptol.ModuleSystem.Env(ModulePath(..)) @@ -32,7 +32,7 @@ import System.Directory (getTemporaryDirectory, removeFile) import System.Environment (getArgs, getProgName, lookupEnv) import System.Exit (exitFailure,exitSuccess)-import System.FilePath (searchPathSeparator, splitSearchPath, takeDirectory)+import System.FilePath (searchPathSeparator, takeDirectory) import System.IO (hClose, hPutStr, openTempFile)  @@ -256,14 +256,8 @@   mCryptolPath <- io $ lookupEnv "CRYPTOLPATH"   case mCryptolPath of     Nothing -> return ()-    Just path | optCryptolPathOnly opts -> setSearchPath path'-              | otherwise               -> prependSearchPath path'-#if defined(mingw32_HOST_OS) || defined(__MINGW32__)-      -- Windows paths search from end to beginning-      where path' = reverse (splitSearchPath path)-#else-      where path' = splitSearchPath path-#endif+    Just path | optCryptolPathOnly opts -> setSearchPath (parseSearchPath path)+              | otherwise               -> prependSearchPath (parseSearchPath path)   smoke <- REPL.smokeTest   case smoke of     [] -> return ()
cryptol/REPL/Haskeline.hs view
@@ -16,7 +16,7 @@ import           Cryptol.REPL.Command import           Cryptol.REPL.Monad import           Cryptol.REPL.Trie-import           Cryptol.Utils.PP+import           Cryptol.Utils.PP hiding ((</>)) import           Cryptol.Utils.Logger(stdoutLogger) import           Cryptol.Utils.Ident(modNameToText, interactiveName) @@ -99,7 +99,7 @@ getInputLines = handleInterrupt (MTL.lift (handleCtrlC Interrupted)) . loop []   where   loop ls prompt =-    do mb <- getInputLine prompt+    do mb <- fmap (filter (/= '\r')) <$> getInputLine prompt        let newPropmpt = map (\_ -> ' ') prompt        case mb of          Nothing -> return NoMoreLines
lib/Array.cry view
@@ -11,3 +11,47 @@ primitive arrayLookup : {a, b} (Array a b) -> a -> b primitive arrayUpdate : {a, b} (Array a b) -> a -> b -> (Array a b) +/**+ * Copy elements from the source array to the destination array.+ *+ * 'arrayCopy dest_arr dest_idx src_arr src_idx len' copies the+ * elements from 'src_arr' at indices '[src_idx ..< (src_idx + len)]' into+ * 'dest_arr' at indices '[dest_idx ..< (dest_idx + len)]'.+ *+ * The result is undefined if either 'dest_idx + len' or 'src_idx + len'+ * wraps around.+ */+primitive arrayCopy : {n, a} (Array [n] a) -> [n] -> (Array [n] a) -> [n] -> [n] -> (Array [n] a)+/**+ * Set elements of the given array.+ *+ * 'arraySet' arr idx val len' sets the elements of 'arr' at indices+ * '[idx ..< (idx + len)]' to 'val'.+ *+ * The result is undefined if 'idx + len' wraps around.+ */+primitive arraySet : {n, a} (Array [n] a) -> [n] -> a -> [n] -> (Array [n] a)+/**+ * Check whether the lhs array and rhs array are equal at a range of+ * indices.+ *+ * 'arrayRangeEq sym lhs_arr lhs_idx rhs_arr rhs_idx len' checks whether+ * the elements of 'lhs_arr' at indices '[lhs_idx ..< (lhs_idx + len)]' and+ * the elements of 'rhs_arr' at indices '[rhs_idx ..< (rhs_idx + len)]' are+ * equal.+ *+ * The result is undefined if either 'lhs_idx + len' or 'rhs_idx + len'+ * wraps around.+ */+primitive arrayRangeEqual : {n, a} (Array [n] a) -> [n] -> (Array [n] a) -> [n] -> [n] -> Bool++arrayRangeLookup : {a, b, n} (Integral a, fin n, LiteralLessThan n a) => (Array a b) -> a -> [n]b+arrayRangeLookup arr idx = res+  where+    res @ i = arrayLookup arr (idx + i)++arrayRangeUpdate : {a, b, n} (Integral a, fin n, LiteralLessThan n a) => (Array a b) -> a -> [n]b -> (Array a b)+arrayRangeUpdate arr idx vals = arrs ! 0+  where+    arrs = [arr] # [ arrayUpdate acc (idx + i) val | acc <- arrs | i <- [0 ..< n] | val <- vals ]+
lib/Cryptol.cry view
@@ -32,7 +32,7 @@ /**  * 'Z n' is the type of integers, modulo 'n'.  *- * The values of 'Z n' may be thought of as equivalance+ * The values of 'Z n' may be thought of as equivalence  * classes of integers according to the equivalence  * 'x ~ y' iff 'n' divides 'x - y'.  'Z n' naturally  * forms a ring, but does not support integral division@@ -41,9 +41,9 @@  * However, you may use the 'fromZ' operation  * to project values in 'Z n' into the integers if such operations  * are required.  This will compute the reduced representative- * of the equivalance class. In other words, 'fromZ' computes+ * of the equivalence class. In other words, 'fromZ' computes  * the (unique) integer value 'i'  where '0 <= i < n' and- * 'i' is in the given equivalance class.+ * 'i' is in the given equivalence class.  *  * If the modulus 'n' is prime, 'Z n' also  * supports computing inverses and forms a field.@@ -131,13 +131,13 @@ /** Divide numeric types, rounding up. */ primitive type   { m : #, n : # }-  (fin m, fin n, n >= 1) =>+  (fin n, n >= 1) =>   m /^ n : #  /** How much we need to add to make a proper multiple of the second argument. */ primitive type   { m : #, n : # }-  (fin m, fin n, n >= 1) =>+  (fin n, n >= 1) =>   m %^ n : #  /** The length of an enumeration. */@@ -195,26 +195,76 @@ /**  * A finite sequence counting up from 'first' to 'last'.  *- * '[a..b]' is syntactic sugar for 'fromTo`{first=a,last=b}'.+ * '[x .. y]' is syntactic sugar for 'fromTo`{first=x,last=y}'.  */-primitive fromTo : {first, last, a} (fin last, last >= first,-                                    Literal first a, Literal last a) =>-                                    [1 + (last - first)]a+primitive fromTo : {first, last, a}+  (fin last, last >= first, Literal last a) =>+  [1 + (last - first)]a  /**  * A possibly infinite sequence counting up from 'first' up to (but not including) 'bound'.  *- * Note that if 'first' = 'bound' then the sequence will be empty.+ * '[ x ..< y ]' is syntactic sugar for 'fromToLessThan`{first=x,bound=y}'.+ *+ * Note that if 'first' = 'bound' then the sequence will be empty.  If 'bound = inf'+ * then the sequence will be infinite, and will eventually wrap around for bounded types.  */ primitive fromToLessThan :-  {first, bound, a} (fin first, bound >= first, LiteralLessThan bound a) => [bound - first]a+  {first, bound, a} (fin first, bound >= first, LiteralLessThan bound a) =>+  [bound - first]a +/**+ * A finite sequence counting up from 'first' to 'last' by 'stride'.+ * Note that 'last' will only be an element of the enumeration if+ * 'stride' divides 'last - first' evenly.+ *+ * '[x .. y by n]' is syntactic sugar for 'fromToBy`{first=x,last=y,stride=n}'.+ */+primitive fromToBy : {first, last, stride, a}+  (fin last, fin stride, stride >= 1, last >= first, Literal last a) =>+  [1 + (last - first)/stride]a  /**+ * A finite sequence counting from 'first' up to (but not including) 'bound'+ * by 'stride'.  Note that if 'first = bound' then the sequence will+ * be empty.  If 'bound = inf' then the sequence will be infinite, and will+ * eventually wrap around for bounded types.+ *+ * '[x ..< y by n]' is syntactic sugar for 'fromToByLessThan`{first=x,bound=y,stride=n}'.+ */+primitive fromToByLessThan : {first, bound, stride, a}+  (fin first, fin stride, stride >= 1, bound >= first, LiteralLessThan bound a) =>+  [(bound - first)/^stride]a++/**+ * A finite sequence counting from 'first' down to 'last' by 'stride'.+ * Note that 'last' will only be an element of the enumeration if+ * 'stride' divides 'first - last' evenly.+ *+ * '[x .. y down by n]' is syntactic sugar for 'fromToDownBy`{first=x,last=y,stride=n}'.+ */+primitive fromToDownBy : {first, last, stride, a}+  (fin first, fin stride, stride >= 1, first >= last, Literal first a) =>+  [1 + (first - last)/stride]a++/**+ * A finite sequence counting from 'first' down to (but not including)+ * 'bound' by 'stride'.+ *+ * '[x ..> y down by n]' is syntactic sugar for+ * 'fromToDownByGreaterThan`{first=x,bound=y,stride=n}'.+ *+ * Note that if 'first = bound' the sequence will be empty.+ */+primitive fromToDownByGreaterThan : {first, bound, stride, a}+  (fin first, fin stride, stride >= 1, first >= bound, Literal first a) =>+  [(first - bound)/^stride]a++/**  * A finite arithmetic sequence starting with 'first' and 'next',  * stopping when the values reach or would skip over 'last'.  *- * '[a,b..c]' is syntactic sugar for 'fromThenTo`{first=a,next=b,last=c}'.+ * '[x,y..z]' is syntactic sugar for 'fromThenTo`{first=x,next=y,last=z}'.  */ primitive fromThenTo : {first, next, last, a, len}                        ( fin first, fin next, fin last@@ -224,12 +274,12 @@  // Fractional Literals --------------------- -/** 'FLiteral m n r a' asserts that the type `a' contains the-fraction `m/n`.  The flag `r` indicates if we should round (`r >= 1`)+/** 'FLiteral m n r a' asserts that the type 'a' contains the+fraction 'm/n'.  The flag 'r' indicates if we should round ('r >= 1') or report an error if the number can't be represented exactly. */ primitive type FLiteral : # -> # -> # -> * -> Prop -/** A fractional literal corresponding to `m/n` */+/** A fractional literal corresponding to 'm/n' */ primitive   fraction : { m, n, r, a } FLiteral m n r a => a @@ -387,7 +437,7 @@  /**  * Value types that correspond to a field; that is,- * a ring also posessing multiplicative inverses for+ * a ring also possessing multiplicative inverses for  * non-zero elements.  *  * Floating-point values are only approximately a field,@@ -684,7 +734,12 @@  */ primitive lg2 : {n} (fin n) => [n] -> [n] +/**+ * Convert a signed 2's complement bitvector to an integer.+ */+primitive toSignedInteger : {n} (fin n, n >= 1) => [n] -> Integer + // Rational specific operations ----------------------------------------------  /**@@ -717,8 +772,9 @@  * Splits a sequence into a pair of sequences.  * 'splitAt z = (x, y)' iff 'x # y = z'.  */-primitive splitAt : {front, back, a} (fin front) => [front + back]a-                                                 -> ([front]a, [back]a)+splitAt : {front, back, a} (fin front) => [front + back]a+                                       -> ([front]a, [back]a)+splitAt xs = (take`{front,back} xs, drop`{front,back} xs)  /**  * Concatenates a list of sequences.@@ -745,18 +801,15 @@  */ primitive transpose : {rows, cols, a} [rows][cols]a -> [cols][rows]a - /**  * Select the first (left-most) 'front' elements of a sequence.  */-take : {front, back, a} (fin front) => [front + back]a -> [front]a-take (x # _) = x+primitive take : {front, back, a} [front + back]a -> [front]a  /**  * Select all the elements after (to the right of) the 'front' elements of a sequence.  */-drop : {front, back, a} (fin front) => [front + back]a -> [back]a-drop ((_ : [front] _) # y) = y+primitive drop : {front, back, a} (fin front) => [front + back]a -> [back]a  /**  * Drop the first (left-most) element of a sequence.@@ -899,6 +952,31 @@ generate f = [ f i | i <- [0 .. <n] ]  +/**+ * Sort a sequence of elements. Equivalent to 'sortBy (<=)'.+ */+sort : {a, n} (Cmp a, fin n) => [n]a -> [n]a+sort = sortBy (<=)++/**+ * Sort a sequence according to the given less-than-or-equal relation.+ * The sorting is stable, so it preserves the relative position of any+ * pair of elements that are equivalent according to the order relation.+ */+sortBy : {a, n} (fin n) => (a -> a -> Bit) -> [n]a -> [n]a+sortBy le vs =+  if `n == (0 : Integer) then vs+  else drop`{1 - min 1 n} (insertBy (vs@0) (sortBy le (drop`{min 1 n} vs)))+  where+    insertBy : {k} (fin k) => a -> [k]a -> [k+1]a+    insertBy x0 ys = xys.0 # [last xs]+      where+        xs : [k+1]a+        xs = [x0] # xys.1+        xys : [k](a, a)+        xys = [ if le x y then (x, y) else (y, x) | x <- xs | y <- ys ]++ // GF_2^n polynomial computations -------------------------------------------  /**@@ -920,7 +998,7 @@  /**  * Parallel map.  The given function is applied to each element in the- * given finite seqeuence, and the results are computed in parallel.+ * given finite sequence, and the results are computed in parallel.  * The values in the resulting sequence are reduced to normal form,  * as is done with the deepseq operation.  *
lib/CryptolTC.z3 view
@@ -267,10 +267,12 @@   )) ) -- (declare-fun cryExpUnknown (Int Int) Int) +(assert (forall ((x Int) (y Int))+  (=> (and (> y 0) (> x 0))+      (>= (cryExpUnknown x y) x))))+ (define-fun cryExpTable ((x Int) (y Int)) Int   (ite (= y 0) 1   (ite (= y 1) x@@ -291,15 +293,19 @@ )  (define-fun cryCeilDiv ((x InfNat) (y InfNat)) InfNat-  (ite (or (isErr x) (isErr y) (not (isFin x)) (not (isFin y))) cryErr-  (ite (= (value y) 0) cryErr (cryNat (- (div (- (value x)) (value y)))))-  )+  (ite (or (isErr x) (isErr y) (not (isFin y))) cryErr+  (ite (= (value y) 0) cryErr+  (ite (not (isFin x)) cryInf+    (cryNat (- (div (- (value x)) (value y))))+  ))) )  (define-fun cryCeilMod ((x InfNat) (y InfNat)) InfNat-  (ite (or (isErr x) (isErr y) (not (isFin x)) (not (isFin y))) cryErr-  (ite (= (value y) 0) cryErr (cryNat (mod (- (value x)) (value y))))-  )+  (ite (or (isErr x) (isErr y) (not (isFin y))) cryErr+  (ite (= (value y) 0) cryErr+  (ite (not (isFin x)) (cryNat 0)+    (cryNat (mod (- (value x)) (value y)))+  ))) )  (define-fun cryLenFromThenTo ((x InfNat) (y InfNat) (z InfNat)) InfNat
lib/SuiteB.cry view
@@ -205,7 +205,7 @@     type sha2_padded_size w L = sha2_num_blocks w L * sha2_block_size w      sha2pad : {w, L} (fin w, fin L, w >= 1) => [L] -> [sha2_padded_size w L]-    sha2pad M = M # 0b1 # zero # ((fromInteger `L) : [2*w])+    sha2pad M = rnf (M # 0b1 # zero # ((fromInteger `L) : [2*w]))      sha2blocks : {w, L} (fin w, fin L, w >= 1) =>       [L] -> [sha2_num_blocks w L][16][w]
src/Cryptol/Backend.hs view
@@ -7,7 +7,11 @@   , cryUserError   , cryNoPrimError   , FPArith2+  , IndexDirection(..) +  , enumerateIntBits+  , enumerateIntBits'+     -- * Rationals   , SRational(..)   , intToRational@@ -29,15 +33,21 @@   , iteRational   ) where +import qualified Control.Exception as X import Control.Monad.IO.Class import Data.Kind (Type)  import Cryptol.Backend.FloatHelpers (BF) import Cryptol.Backend.Monad-  ( EvalError(..), CallStack, pushCallFrame )+  ( EvalError(..), Unsupported(..), CallStack, pushCallFrame ) import Cryptol.ModuleSystem.Name(Name) import Cryptol.Parser.Position+import Cryptol.TypeCheck.Solver.InfNat(Nat'(..),widthInteger) +data IndexDirection+  = IndexForward+  | IndexBackward+ invalidIndex :: Backend sym => sym -> Integer -> SEval sym a invalidIndex sym i = raiseError sym (InvalidIndex (Just i)) @@ -191,6 +201,31 @@ iteRational sym p (SRational a b) (SRational c d) =   SRational <$> iteInteger sym p a c <*> iteInteger sym p b d +-- | Compute the list of bits in an integer in big-endian order.+--   The integer argument is a concrete upper bound for+--   the symbolic integer.+enumerateIntBits' :: Backend sym =>+  sym ->+  Integer ->+  SInteger sym ->+  SEval sym (Integer, [SBit sym])+enumerateIntBits' sym n idx =+  do let width = widthInteger n+     w <- wordFromInt sym width idx+     bs <- unpackWord sym w+     pure (width, bs)++-- | Compute the list of bits in an integer in big-endian order.+--   Fails if neither the sequence length nor the type value+--   provide an upper bound for the integer.+enumerateIntBits :: Backend sym =>+  sym ->+  Nat' ->+  SInteger sym ->+  SEval sym (Integer, [SBit sym])+enumerateIntBits sym (Nat n) idx = enumerateIntBits' sym n idx+enumerateIntBits _sym Inf _ = liftIO (X.throw (UnsupportedSymbolicOp "unbounded integer shifting"))+ -- | This type class defines a collection of operations on bits, words and integers that --   are necessary to define generic evaluator primitives that operate on both concrete --   and symbolic values uniformly.@@ -205,7 +240,7 @@    -- | Check if an operation is "ready", which means its   --   evaluation will be trivial.-  isReady :: sym -> SEval sym a -> Bool+  isReady :: sym -> SEval sym a -> SEval sym (Maybe a)    -- | Produce a thunk value which can be filled with its associated computation   --   after the fact.  A preallocated thunk is returned, along with an operation to@@ -488,6 +523,51 @@     SWord sym ->     SEval sym (SWord sym) +  -- | Shift a bitvector left by the specified amount.+  --   The shift amount is considered as an unsigned value.+  --   Shifting by more than the word length results in 0.+  wordShiftLeft ::+    sym ->+    SWord sym {- ^ value to shift -} ->+    SWord sym {- ^ amount to shift by -} ->+    SEval sym (SWord sym)++  -- | Shift a bitvector right by the specified amount.+  --   This is a logical shift, which shifts in 0 values+  --   on the left. The shift amount is considered as an+  --   unsigned value. Shifting by more than the word length+  --   results in 0.+  wordShiftRight ::+    sym ->+    SWord sym {- ^ value to shift -} ->+    SWord sym {- ^ amount to shift by -} ->+    SEval sym (SWord sym)++  -- | Shift a bitvector right by the specified amount.  This is an+  --   arithmetic shift, which shifts in copies of the high bit on the+  --   left. The shift amount is considered as an unsigned+  --   value. Shifting by more than the word length results in filling+  --   the bitvector with the high bit.+  wordSignedShiftRight ::+    sym ->+    SWord sym {- ^ value to shift -} ->+    SWord sym {- ^ amount to shift by -} ->+    SEval sym (SWord sym)++  wordRotateLeft ::+    sym ->+    SWord sym {- ^ value to rotate -} ->+    SWord sym {- ^ amount to rotate by -} ->+    SEval sym (SWord sym)++  wordRotateRight ::+    sym ->+    SWord sym {- ^ value to rotate -} ->+    SWord sym {- ^ amount to rotate by -} ->+    SEval sym (SWord sym)+++   -- | 2's complement negation of bitvectors   wordNegate ::     sym ->@@ -530,6 +610,12 @@    -- | Construct an integer value from the given packed word.   wordToInt ::+    sym ->+    SWord sym ->+    SEval sym (SInteger sym)++  -- | Construct a signed integer value from the given packed word.+  wordToSignedInt ::     sym ->     SWord sym ->     SEval sym (SInteger sym)
src/Cryptol/Backend/Concrete.hs view
@@ -114,7 +114,7 @@   prefix = case base of     2  -> text "0b" <.> padding 1     8  -> text "0o" <.> padding 3-    10 -> empty+    10 -> mempty     16 -> text "0x" <.> padding 4     _  -> text "0"  <.> char '<' <.> int base <.> char '>' @@ -152,8 +152,7 @@   wordUpdate _ (BV w x) idx True  = pure $! BV w (setBit   x (fromInteger (w - 1 - idx)))   wordUpdate _ (BV w x) idx False = pure $! BV w (clearBit x (fromInteger (w - 1 - idx))) -  isReady _ (Ready _) = True-  isReady _ _ = False+  isReady _ = maybeReady    mergeEval _sym f c mx my =     do x <- mx@@ -186,6 +185,7 @@   integerAsLit _ = Just    wordToInt _ (BV _ x) = pure x+  wordToSignedInt _ (BV w x) = pure $! signedValue w x   wordFromInt _ w x = pure $! mkBv w x    packWord _ bits = pure $! BV (toInteger w) a@@ -284,6 +284,33 @@                sy = signedValue i y            pure $! mkBv i (sx `rem` sy)     | otherwise = panic "Attempt to mod words of different sizes: wordSignedMod" [show i, show j]++  wordShiftLeft _sym (BV w ival) (BV _ by)+    | by >= w   = pure $! BV w 0+    | by > toInteger (maxBound :: Int) = panic "shl" ["Shift amount too large", show by]+    | otherwise = pure $! mkBv w (shiftL ival (fromInteger by))++  wordShiftRight _sym (BV w ival) (BV _ by)+    | by >= w   = pure $! BV w 0+    | by > toInteger (maxBound :: Int) = panic "lshr" ["Shift amount too large", show by]+    | otherwise = pure $! BV w (shiftR ival (fromInteger by))++  wordSignedShiftRight _sym (BV w ival) (BV _ by) =+    let by' = min w by in+    if by' > toInteger (maxBound :: Int) then+      panic "wordSignedShiftRight" ["Shift amount too large", show by]+    else+      pure $! mkBv w (shiftR (signedValue w ival) (fromInteger by'))++  wordRotateRight _sym (BV 0 i) _ = pure (BV 0 i)+  wordRotateRight _sym (BV w i) (BV _ by) =+      pure . mkBv w $! (i `shiftR` b) .|. (i `shiftL` (fromInteger w - b))+    where b = fromInteger (by `mod` w)++  wordRotateLeft _sym (BV 0 i) _ = pure (BV 0 i)+  wordRotateLeft _sym (BV w i) (BV _ by) =+      pure . mkBv w $! (i `shiftL` b) .|. (i `shiftR` (fromInteger w - b))+    where b = fromInteger (by `mod` w)    wordLg2 _ (BV i x) = pure $! mkBv i (lg2 x) 
src/Cryptol/Backend/Monad.hs view
@@ -63,12 +63,33 @@  -- | The type of dynamic call stacks for the interpreter. --   New frames are pushed onto the right side of the sequence.-type CallStack = Seq (Name, Range)+data CallStack+  = EmptyCallStack+  | CombineCallStacks !CallStack !CallStack+  | PushCallFrame !Name !Range !CallStack +instance Semigroup CallStack where+  (<>) = CombineCallStacks++instance Monoid CallStack where+  mempty = EmptyCallStack++type CallStack' = Seq (Name, Range)++evalCallStack :: CallStack -> CallStack'+evalCallStack stk =+  case stk of+    EmptyCallStack -> mempty+    CombineCallStacks appstk fnstk -> combineCallStacks' (evalCallStack appstk) (evalCallStack fnstk)+    PushCallFrame n r stk1 -> pushCallFrame' n r (evalCallStack stk1)+ -- | Pretty print a call stack with each call frame on a separate --   line, with most recent call frames at the top. displayCallStack :: CallStack -> Doc-displayCallStack = vcat . map f . toList . Seq.reverse+displayCallStack = displayCallStack' . evalCallStack++displayCallStack' :: CallStack' -> Doc+displayCallStack' = vcat . map f . toList . Seq.reverse   where   f (nm,rng)     | rng == emptyRange = pp nm@@ -92,7 +113,15 @@   CallStack {- ^ call stack of the application context -} ->   CallStack {- ^ call stack of the function being applied -} ->   CallStack-combineCallStacks appstk fnstk = appstk <> dropCommonPrefix appstk fnstk+combineCallStacks appstk EmptyCallStack = appstk+combineCallStacks EmptyCallStack fnstk = fnstk+combineCallStacks appstk fnstk = CombineCallStacks appstk fnstk++combineCallStacks' ::+  CallStack' {- ^ call stack of the application context -} ->+  CallStack' {- ^ call stack of the function being applied -} ->+  CallStack'+combineCallStacks' appstk fnstk = appstk <> dropCommonPrefix appstk fnstk   where   dropCommonPrefix _  Seq.Empty = Seq.Empty   dropCommonPrefix Seq.Empty fs = fs@@ -102,9 +131,12 @@  -- | Add a call frame to the top of a call stack pushCallFrame :: Name -> Range -> CallStack -> CallStack-pushCallFrame nm rng stk@( _ Seq.:|> (nm',rng'))+pushCallFrame nm rng stk = PushCallFrame nm rng stk++pushCallFrame' :: Name -> Range -> CallStack' -> CallStack'+pushCallFrame' nm rng stk@( _ Seq.:|> (nm',rng'))   | nm == nm', rng == rng' = stk-pushCallFrame nm rng stk = stk Seq.:|> (nm,rng)+pushCallFrame' nm rng stk = stk Seq.:|> (nm,rng)   -- | The monad for Cryptol evaluation.@@ -328,13 +360,15 @@   Eval $ \stk ->     do let stk' = f stk        -- putStrLn $ unwords ["Pushing call stack", show (displayCallStack stk')]-       runEval stk' m+       seq stk' (runEval stk' m)+{-# INLINE modifyCallStack #-}  -- | Execute the given evaluation action. runEval :: CallStack -> Eval a -> IO a runEval _   (Ready a)  = return a runEval stk (Eval x)   = x stk runEval _   (Thunk tv) = unDelay tv+{-# INLINE runEval #-}  {-# INLINE evalBind #-} evalBind :: Eval a -> (a -> Eval b) -> Eval b@@ -415,11 +449,12 @@  deriving Typeable  instance PP EvalErrorEx where-  ppPrec _ (EvalErrorEx stk ex) = vcat ([ pp ex ] ++ callStk)+  ppPrec _ (EvalErrorEx stk0 ex) = vcat ([ pp ex ] ++ callStk)     where+    stk = evalCallStack stk0     callStk | Seq.null stk = []-            | otherwise = [ text "-- Backtrace --", displayCallStack stk ]+            | otherwise = [ text "-- Backtrace --", displayCallStack' stk ]  instance Show EvalErrorEx where   show = show . pp
src/Cryptol/Backend/SBV.hs view
@@ -48,7 +48,7 @@ import Cryptol.Backend.Monad   ( Eval(..), blackhole, delayFill, evalSpark   , EvalError(..), EvalErrorEx(..), Unsupported(..)-  , modifyCallStack, getCallStack+  , modifyCallStack, getCallStack, maybeReady   )  import Cryptol.Utils.Panic (panic)@@ -162,8 +162,10 @@     | Just False <- svAsBool cond = raiseError sym err     | otherwise = SBVEval (pure (SBVResult cond ())) -  isReady _ (SBVEval (Ready _)) = True-  isReady _ _ = False+  isReady _ (SBVEval m) = SBVEval $+    maybeReady m >>= \case+      Just x  -> pure (Just <$> x)+      Nothing -> pure (pure Nothing)    sDelayFill _ m retry msg = SBVEval $     do m' <- delayFill (sbvEval m) (sbvEval <$> retry) msg@@ -262,6 +264,12 @@   wordMult  _ a b = pure $! svTimes a b   wordNegate _ a  = pure $! svUNeg a +  wordShiftLeft _ a b   = pure $! shl a b+  wordShiftRight _ a b  = pure $! lshr a b+  wordRotateLeft _ a b  = pure $! SBV.svRotateLeft a b+  wordRotateRight _ a b = pure $! SBV.svRotateRight a b+  wordSignedShiftRight _ a b = pure $! ashr a b+   wordDiv sym a b =     do let z = literalSWord (intSizeOf b) 0        assertSideCondition sym (svNot (svEqual b z)) DivideByZero@@ -285,6 +293,7 @@   wordLg2 _ a = sLg2 a    wordToInt _ x = pure $! svToInteger x+  wordToSignedInt _ x = pure $! svToInteger (svSign x)   wordFromInt _ w i = pure $! svFromInteger w i    intEq _ a b = pure $! svEqual a b
+ src/Cryptol/Backend/SeqMap.hs view
@@ -0,0 +1,301 @@+-- |+-- Module      :  Cryptol.Backend.SeqMap+-- Copyright   :  (c) 2013-2021 Galois, Inc.+-- License     :  BSD3+-- Maintainer  :  cryptol@galois.com+-- Stability   :  provisional+-- Portability :  portable++{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DoAndIfThenElse #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ImplicitParams #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternGuards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}++module Cryptol.Backend.SeqMap+  ( -- * Sequence Maps+    SeqMap+  , indexSeqMap+  , lookupSeqMap+  , finiteSeqMap+  , infiniteSeqMap+  , enumerateSeqMap+  , streamSeqMap+  , reverseSeqMap+  , updateSeqMap+  , dropSeqMap+  , concatSeqMap+  , splitSeqMap+  , memoMap+  , delaySeqMap+  , zipSeqMap+  , mapSeqMap+  , mergeSeqMap+  , barrelShifter+  , shiftSeqByInteger++  , IndexSegment(..)+  ) where++import qualified Control.Exception as X+import Control.Monad+import Control.Monad.IO.Class+import Data.Bits+import Data.List+import Data.IORef+import Data.Map.Strict (Map)+import qualified Data.Map.Strict as Map++import Cryptol.Backend+import Cryptol.Backend.Concrete (Concrete)+import Cryptol.Backend.Monad (Unsupported(..))++import Cryptol.TypeCheck.Solver.InfNat(Nat'(..))+import Cryptol.Utils.Panic++-- | A sequence map represents a mapping from nonnegative integer indices+--   to values.  These are used to represent both finite and infinite sequences.+data SeqMap sym a+  = IndexSeqMap  !(Integer -> SEval sym a)+  | UpdateSeqMap !(Map Integer (SEval sym a))+                 !(SeqMap sym a)+  | MemoSeqMap+     !Nat'+     !(IORef (Map Integer a))+     !(IORef (Integer -> SEval sym a))++indexSeqMap :: (Integer -> SEval sym a) -> SeqMap sym a+indexSeqMap = IndexSeqMap++lookupSeqMap :: Backend sym => SeqMap sym a -> Integer -> SEval sym a+lookupSeqMap (IndexSeqMap f) i = f i+lookupSeqMap (UpdateSeqMap m xs) i =+  case Map.lookup i m of+    Just x  -> x+    Nothing -> lookupSeqMap xs i+lookupSeqMap (MemoSeqMap sz cache eval) i =+  do mz <- liftIO (Map.lookup i <$> readIORef cache)+     case mz of+       Just z  -> return z+       Nothing ->+         do f <- liftIO (readIORef eval)+            v <- f i+            msz <- liftIO $ atomicModifyIORef' cache (\m ->+                        let m' = Map.insert i v m in (m', Map.size m'))+            -- If we memoize the entire map, overwrite the evaluation closure to let+            -- the garbage collector reap it+            when (case sz of Inf -> False; Nat sz' -> toInteger msz >= sz')+                 (liftIO (writeIORef eval+                    (\j -> panic "lookupSeqMap" ["Messed up size accounting", show sz, show j])))+            return v++instance Backend sym => Functor (SeqMap sym) where+  fmap f xs = IndexSeqMap (\i -> f <$> lookupSeqMap xs i)++-- | Generate a finite sequence map from a list of values+finiteSeqMap :: Backend sym => sym -> [SEval sym a] -> SeqMap sym a+finiteSeqMap sym xs =+   UpdateSeqMap+      (Map.fromList (zip [0..] xs))+      (IndexSeqMap (\i -> invalidIndex sym i))++-- | Generate an infinite sequence map from a stream of values+infiniteSeqMap :: Backend sym => sym -> [SEval sym a] -> SEval sym (SeqMap sym a)+infiniteSeqMap sym xs =+   -- TODO: use an int-trie?+   memoMap sym Inf (IndexSeqMap $ \i -> genericIndex xs i)++-- | Create a finite list of length @n@ of the values from @[0..n-1]@ in+--   the given the sequence emap.+enumerateSeqMap :: (Backend sym, Integral n) => n -> SeqMap sym a -> [SEval sym a]+enumerateSeqMap n m = [ lookupSeqMap m  i | i <- [0 .. (toInteger n)-1] ]++-- | Create an infinite stream of all the values in a sequence map+streamSeqMap :: Backend sym => SeqMap sym a -> [SEval sym a]+streamSeqMap m = [ lookupSeqMap m i | i <- [0..] ]++-- | Reverse the order of a finite sequence map+reverseSeqMap :: Backend sym =>+  Integer {- ^ Size of the sequence map -} ->+  SeqMap sym a ->+  SeqMap sym a+reverseSeqMap n vals = IndexSeqMap $ \i -> lookupSeqMap vals (n - 1 - i)++updateSeqMap :: SeqMap sym a -> Integer -> SEval sym a -> SeqMap sym a+updateSeqMap (UpdateSeqMap m sm) i x = UpdateSeqMap (Map.insert i x m) sm+updateSeqMap xs i x = UpdateSeqMap (Map.singleton i x) xs++-- | Concatenate the first @n@ values of the first sequence map onto the+--   beginning of the second sequence map.+concatSeqMap :: Backend sym => Integer -> SeqMap sym a -> SeqMap sym a -> SeqMap sym a+concatSeqMap n x y =+    IndexSeqMap $ \i ->+       if i < n+         then lookupSeqMap x i+         else lookupSeqMap y (i-n)++-- | Given a number @n@ and a sequence map, return two new sequence maps:+--   the first containing the values from @[0..n-1]@ and the next containing+--   the values from @n@ onward.+splitSeqMap :: Backend sym => Integer -> SeqMap sym a -> (SeqMap sym a, SeqMap sym a)+splitSeqMap n xs = (hd,tl)+  where+  hd = xs+  tl = IndexSeqMap $ \i -> lookupSeqMap xs (i+n)++-- | Drop the first @n@ elements of the given 'SeqMap'.+dropSeqMap :: Backend sym => Integer -> SeqMap sym a -> SeqMap sym a+dropSeqMap 0 xs = xs+dropSeqMap n xs = IndexSeqMap $ \i -> lookupSeqMap xs (i+n)++delaySeqMap :: Backend sym => sym -> SEval sym (SeqMap sym a) -> SEval sym (SeqMap sym a)+delaySeqMap sym xs =+  do xs' <- sDelay sym xs+     pure $ IndexSeqMap $ \i -> do m <- xs'; lookupSeqMap m i++-- | Given a sequence map, return a new sequence map that is memoized using+--   a finite map memo table.+memoMap :: Backend sym => sym -> Nat' -> SeqMap sym a -> SEval sym (SeqMap sym a)++-- Sequence is alreay memoized, just return it+memoMap _sym _sz x@(MemoSeqMap{}) = pure x++memoMap sym sz x = do+  stk <- sGetCallStack sym+  cache <- liftIO $ newIORef $ Map.empty+  evalRef <- liftIO $ newIORef $ eval stk+  return (MemoSeqMap sz cache evalRef)++  where+    eval stk i = sWithCallStack sym stk (lookupSeqMap x i)+++-- | Apply the given evaluation function pointwise to the two given+--   sequence maps.+zipSeqMap ::+  Backend sym =>+  sym ->+  (a -> a -> SEval sym a) ->+  Nat' ->+  SeqMap sym a ->+  SeqMap sym a ->+  SEval sym (SeqMap sym a)+zipSeqMap sym f sz x y =+  memoMap sym sz (IndexSeqMap $ \i -> join (f <$> lookupSeqMap x i <*> lookupSeqMap y i))++-- | Apply the given function to each value in the given sequence map+mapSeqMap ::+  Backend sym =>+  sym ->+  (a -> SEval sym a) ->+  Nat' ->+  SeqMap sym a ->+  SEval sym (SeqMap sym a)+mapSeqMap sym f sz x =+  memoMap sym sz (IndexSeqMap $ \i -> f =<< lookupSeqMap x i)+++{-# INLINE mergeSeqMap #-}+mergeSeqMap :: Backend sym =>+  sym ->+  (SBit sym -> a -> a -> SEval sym a) ->+  SBit sym ->+  SeqMap sym a ->+  SeqMap sym a ->+  SeqMap sym a+mergeSeqMap sym f c x y =+  IndexSeqMap $ \i -> mergeEval sym f c (lookupSeqMap x i) (lookupSeqMap y i)+++{-# INLINE shiftSeqByInteger #-}+shiftSeqByInteger :: Backend sym =>+  sym ->+  (SBit sym -> a -> a -> SEval sym a)+     {- ^ if/then/else operation of values -} ->+  (Integer -> Integer -> Maybe Integer)+     {- ^ reindexing operation -} ->+  SEval sym a {- ^ zero value -} ->+  Nat' {- ^ size of the sequence -} ->+  SeqMap sym a {- ^ sequence to shift -} ->+  SInteger sym {- ^ shift amount, assumed to be in range [0,len] -} ->+  SEval sym (SeqMap sym a)+shiftSeqByInteger sym merge reindex zro m xs idx+  | Just j <- integerAsLit sym idx = shiftOp xs j+  | otherwise =+      do (n, idx_bits) <- enumerateIntBits sym m idx+         barrelShifter sym merge shiftOp m xs n (map BitIndexSegment idx_bits)+ where+   shiftOp vs shft =+     pure $ indexSeqMap $ \i ->+       case reindex i shft of+         Nothing -> zro+         Just i' -> lookupSeqMap vs i'+++data IndexSegment sym+  = BitIndexSegment (SBit sym)+  | WordIndexSegment (SWord sym)++{-# SPECIALIZE+  barrelShifter ::+  Concrete ->+  (SBit Concrete -> a -> a -> SEval Concrete a) ->+  (SeqMap Concrete a -> Integer -> SEval Concrete (SeqMap Concrete a)) ->+  Nat' ->+  SeqMap Concrete a ->+  Integer ->+  [IndexSegment Concrete] ->+  SEval Concrete (SeqMap Concrete a)+ #-}+barrelShifter :: Backend sym =>+  sym ->+  (SBit sym -> a -> a -> SEval sym a)+     {- ^ if/then/else operation of values -} ->+  (SeqMap sym a -> Integer -> SEval sym (SeqMap sym a))+     {- ^ concrete shifting operation -} ->+  Nat' {- ^ Size of the map being shifted -} ->+  SeqMap sym a {- ^ initial value -} ->+  Integer {- Number of bits in shift amount -} ->+  [IndexSegment sym]  {- ^ segments of the shift amount, in big-endian order -} ->+  SEval sym (SeqMap sym a)+barrelShifter sym mux shift_op sz x0 n0 bs0+  | n0 >= toInteger (maxBound :: Int) =+      liftIO (X.throw (UnsupportedSymbolicOp ("Barrel shifter with too many bits in shift amount: " ++ show n0)))+  | otherwise = go x0 (fromInteger n0) bs0++  where+  go x !_n [] = return x++  go x !n (WordIndexSegment w:bs) =+    let n' = n - fromInteger (wordLen sym w) in+    case wordAsLit sym w of+      Just (_,0) -> go x n' bs+      Just (_,j) ->+        do x_shft <- shift_op x (j * bit n')+           go x_shft n' bs+      Nothing ->+        do wbs <- unpackWord sym w+           go x n (map BitIndexSegment wbs ++ bs)++  go x !n (BitIndexSegment b:bs) =+    let n' = n - 1 in+    case bitAsLit sym b of+      Just False -> go x n' bs+      Just True ->+        do x_shft <- shift_op x (bit n')+           go x_shft n' bs+      Nothing ->+        do x_shft <- shift_op x (bit n')+           x' <- memoMap sym sz (mergeSeqMap sym mux b x_shft x)+           go x' n' bs
src/Cryptol/Backend/What4.hs view
@@ -39,7 +39,7 @@ import Cryptol.Backend.Monad    ( Eval(..), EvalError(..), EvalErrorEx(..)    , Unsupported(..), delayFill, blackhole, evalSpark-   , modifyCallStack, getCallStack+   , modifyCallStack, getCallStack, maybeReady    ) import Cryptol.Utils.Panic @@ -76,7 +76,7 @@   | W4Result !(W4.Pred sym) !a     -- ^ safety predicate and result: the result only makes sense when     -- the predicate holds.-+ deriving Functor  -------------------------------------------------------------------------------- -- Moving between the layers@@ -215,10 +215,10 @@     | Just False <- W4.asConstantPred cond = evalError err     | otherwise = addSafety cond -  isReady sym m =-    case w4Eval m (w4 sym) of-      Ready _ -> True-      _ -> False+  isReady sym m = W4Eval $ W4Conn $ \_ ->+    maybeReady (w4Eval m (w4 sym)) >>= \case+      Just x  -> pure (Just <$> x)+      Nothing -> pure (W4Result (W4.backendPred (w4 sym) True) Nothing)    sDelayFill _ m retry msg =     total@@ -342,6 +342,12 @@   wordNegate sym x   = liftIO (SW.bvNeg (w4 sym) x)   wordLg2    sym x   = sLg2 (w4 sym) x  +  wordShiftLeft   sym x y = w4bvShl (w4 sym) x y+  wordShiftRight  sym x y = w4bvLshr (w4 sym) x y+  wordRotateLeft  sym x y = w4bvRol (w4 sym) x y+  wordRotateRight sym x y = w4bvRor (w4 sym) x y+  wordSignedShiftRight sym x y = w4bvAshr (w4 sym) x y+   wordDiv sym x y =      do assertBVDivisor sym y         liftIO (SW.bvUDiv (w4 sym) x y)@@ -356,6 +362,7 @@         liftIO (SW.bvSRem (w4 sym) x y)    wordToInt sym x = liftIO (SW.bvToInteger (w4 sym) x)+  wordToSignedInt sym x = liftIO (SW.sbvToInteger (w4 sym) x)   wordFromInt sym width i = liftIO (SW.integerToBV (w4 sym) i width)    intPlus   sym x y  = liftIO $ W4.intAdd (w4 sym) x y
+ src/Cryptol/Backend/WordValue.hs view
@@ -0,0 +1,759 @@+-- |+-- Module      :  Cryptol.Backend.WordValue+-- Copyright   :  (c) 2013-2021 Galois, Inc.+-- License     :  BSD3+-- Maintainer  :  cryptol@galois.com+-- Stability   :  provisional+-- Portability :  portable++{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DoAndIfThenElse #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ImplicitParams #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternGuards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}++module Cryptol.Backend.WordValue+  ( -- * WordValue+    WordValue+  , wordVal+  , bitmapWordVal+  , asWordList+  , asWordVal+  , asBitsMap+  , joinWordVal+  , takeWordVal+  , dropWordVal+  , extractWordVal+  , wordValLogicOp+  , wordValUnaryOp+  , assertWordValueInBounds+  , enumerateWordValue+  , enumerateWordValueRev+  , enumerateIndexSegments+  , wordValueSize+  , indexWordValue+  , updateWordValue+  , delayWordValue+  , joinWords+  , shiftSeqByWord+  , shiftWordByInteger+  , shiftWordByWord+  , wordValAsLit+  , reverseWordVal+  , forceWordValue+  , wordValueEqualsInteger+  , updateWordByWord++  , mergeWord+  , mergeWord'+  ) where++import Control.Monad (unless)+import Data.Bits+import GHC.Generics (Generic)++import Cryptol.Backend+import Cryptol.Backend.Concrete (Concrete(..))+import Cryptol.Backend.Monad (EvalError(..))+import Cryptol.Backend.SeqMap++import Cryptol.TypeCheck.Solver.InfNat(widthInteger, Nat'(..))++-- | Force the evaluation of a word value+forceWordValue :: Backend sym => WordValue sym -> SEval sym ()+forceWordValue (WordVal w)  = seq w (return ())+forceWordValue (ThunkWordVal _ m)  = forceWordValue =<< m+forceWordValue (BitmapVal _n packed _) = do w <- packed; seq w (return ())++-- | An arbitrarily-chosen number of elements where we switch from a dense+--   sequence representation of bit-level words to 'SeqMap' representation.+largeBitSize :: Integer+largeBitSize = bit 32++-- | For efficiency reasons, we handle finite sequences of bits as special cases+--   in the evaluator.  In cases where we know it is safe to do so, we prefer to+--   used a "packed word" representation of bit sequences.  This allows us to rely+--   directly on Integer types (in the concrete evaluator) and SBV's Word types (in+--   the symbolic simulator).+--+--   However, if we cannot be sure all the bits of the sequence+--   will eventually be forced, we must instead rely on an explicit sequence of bits+--   representation.+data WordValue sym+  = ThunkWordVal Integer !(SEval sym (WordValue sym))+  | WordVal !(SWord sym)                      -- ^ Packed word representation for bit sequences.+  | BitmapVal+       !Integer -- ^ Length of the word+       !(SEval sym (SWord sym)) -- ^ Thunk for packing the word+       !(SeqMap sym (SBit sym)) -- ^+ deriving (Generic)++wordVal :: SWord sym -> WordValue sym+wordVal = WordVal++packBitmap :: Backend sym => sym -> Integer -> SeqMap sym (SBit sym) -> SEval sym (SWord sym)+packBitmap sym sz bs = packWord sym =<< sequence (enumerateSeqMap sz bs)++unpackBitmap :: Backend sym => sym -> SWord sym -> SeqMap sym (SBit sym)+unpackBitmap sym w = indexSeqMap $ \i -> wordBit sym w i++bitmapWordVal :: Backend sym => sym -> Integer -> SeqMap sym (SBit sym) -> SEval sym (WordValue sym)+bitmapWordVal sym sz bs =+  do packed <- sDelay sym (packBitmap sym sz bs)+     pure (BitmapVal sz packed bs)++{-# INLINE joinWordVal #-}+joinWordVal :: Backend sym => sym -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)+joinWordVal sym wv1 wv2 =+  let fallback = fallbackWordJoin sym wv1 wv2 in+  case (wv1, wv2) of+    (WordVal w1, WordVal w2) ->+      WordVal <$> joinWord sym w1 w2++    (ThunkWordVal _ m1, _) ->+      isReady sym m1 >>= \case+        Just x -> joinWordVal sym x wv2+        Nothing -> fallback++    (_,ThunkWordVal _ m2) ->+      isReady sym m2 >>= \case+        Just x   -> joinWordVal sym wv1 x+        Nothing  -> fallback++    (WordVal w1, BitmapVal _ packed2 _) ->+      isReady sym packed2 >>= \case+        Just w2 -> WordVal <$> joinWord sym w1 w2+        Nothing  -> fallback++    (BitmapVal _ packed1 _, WordVal w2) ->+      isReady sym packed1 >>= \case+        Just w1 -> WordVal <$> joinWord sym w1 w2+        Nothing -> fallback++    (BitmapVal _ packed1 _, BitmapVal _ packed2 _) ->+      do r1 <- isReady sym packed1+         r2 <- isReady sym packed2+         case (r1,r2) of+           (Just w1, Just w2) -> WordVal <$> joinWord sym w1 w2+           _ -> fallback++{-# INLINE fallbackWordJoin #-}+fallbackWordJoin :: Backend sym => sym -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)+fallbackWordJoin sym w1 w2 =+  do let n1 = wordValueSize sym w1+     let n2 = wordValueSize sym w2+     let len = n1 + n2+     packed <- sDelay sym+                 (do a <- asWordVal sym w1+                     b <- asWordVal sym w2+                     joinWord sym a b)+     let bs = concatSeqMap n1 (asBitsMap sym w1) (asBitsMap sym w2)+     pure (BitmapVal len packed bs)+++{-# INLINE takeWordVal #-}+takeWordVal ::+  Backend sym =>+  sym ->+  Integer ->+  Integer ->+  WordValue sym ->+  SEval sym (WordValue sym)+takeWordVal sym leftWidth rigthWidth (WordVal w) =+  do (lw, _rw) <- splitWord sym leftWidth rigthWidth w+     pure (WordVal lw)++takeWordVal sym leftWidth rightWidth (ThunkWordVal _ m) =+  isReady sym m >>= \case+    Just w -> takeWordVal sym leftWidth rightWidth w+    Nothing ->+      do m' <- sDelay sym (takeWordVal sym leftWidth rightWidth =<< m)+         return (ThunkWordVal leftWidth m')++takeWordVal sym leftWidth rightWidth (BitmapVal _n packed xs) =+  isReady sym packed >>= \case+    Just w -> do (lw, _rw) <- splitWord sym leftWidth rightWidth w+                 pure (WordVal lw)+    Nothing -> bitmapWordVal sym leftWidth xs++{-# INLINE dropWordVal #-}+dropWordVal ::+  Backend sym =>+  sym ->+  Integer ->+  Integer ->+  WordValue sym ->+  SEval sym (WordValue sym)+dropWordVal sym leftWidth rigthWidth (WordVal w) =+  do (_lw, rw) <- splitWord sym leftWidth rigthWidth w+     pure (WordVal rw)++dropWordVal sym leftWidth rightWidth (ThunkWordVal _ m) =+  isReady sym m >>= \case+    Just w -> dropWordVal sym leftWidth rightWidth w+    Nothing ->+      do m' <- sDelay sym (dropWordVal sym leftWidth rightWidth =<< m)+         return (ThunkWordVal rightWidth m')++dropWordVal sym leftWidth rightWidth (BitmapVal _n packed xs) =+  isReady sym packed >>= \case+    Just w -> do (_lw, rw) <- splitWord sym leftWidth rightWidth w+                 pure (WordVal rw)+    Nothing ->+      do let rxs = dropSeqMap leftWidth xs+         bitmapWordVal sym rightWidth rxs++{-# INLINE extractWordVal #-}++-- | Extract a subsequence of bits from a @WordValue@.+--   The first integer argument is the number of bits in the+--   resulting word.  The second integer argument is the+--   number of less-significant digits to discard.  Stated another+--   way, the operation `extractWordVal n i w` is equivalent to+--   first shifting `w` right by `i` bits, and then truncating to+--   `n` bits.+extractWordVal ::+  Backend sym =>+  sym ->+  Integer ->+  Integer ->+  WordValue sym ->+  SEval sym (WordValue sym)+extractWordVal sym len start (WordVal w) =+   WordVal <$> extractWord sym len start w+extractWordVal sym len start (ThunkWordVal _n m) =+  isReady sym m >>= \case+    Just w -> extractWordVal sym len start w+    Nothing ->+      do m' <- sDelay sym (extractWordVal sym len start =<< m)+         pure (ThunkWordVal len m')+extractWordVal sym len start (BitmapVal n packed xs) =+  isReady sym packed >>= \case+    Just w -> WordVal <$> extractWord sym len start w+    Nothing ->+      do let xs' = dropSeqMap (n - start - len) xs+         bitmapWordVal sym len xs'++{-# INLINE wordValLogicOp #-}++wordValLogicOp ::+  Backend sym =>+  sym ->+  (SBit sym -> SBit sym -> SEval sym (SBit sym)) ->+  (SWord sym -> SWord sym -> SEval sym (SWord sym)) ->+  WordValue sym ->+  WordValue sym ->+  SEval sym (WordValue sym)+wordValLogicOp _sym _ wop (WordVal w1) (WordVal w2) = WordVal <$> wop w1 w2++wordValLogicOp sym bop wop (WordVal w1) (BitmapVal n2 packed2 bs2) =+  isReady sym packed2 >>= \case+    Just w2 -> WordVal <$> wop w1 w2+    Nothing -> bitmapWordVal sym n2 =<< zipSeqMap sym bop (Nat n2) (unpackBitmap sym w1) bs2++wordValLogicOp sym bop wop (BitmapVal n1 packed1 bs1) (WordVal w2) =+  isReady sym packed1 >>= \case+    Just w1 -> WordVal <$> wop w1 w2+    Nothing -> bitmapWordVal sym n1 =<< zipSeqMap sym bop (Nat n1) bs1 (unpackBitmap sym w2)++wordValLogicOp sym bop wop (BitmapVal n1 packed1 bs1) (BitmapVal _n2 packed2 bs2) =+  do r1 <- isReady sym packed1+     r2 <- isReady sym packed2+     case (r1,r2) of+       (Just w1, Just w2) -> WordVal <$> wop w1 w2+       _ -> bitmapWordVal sym n1 =<< zipSeqMap sym bop (Nat n1) bs1 bs2++wordValLogicOp sym bop wop (ThunkWordVal _ m1) w2 =+  do w1 <- m1+     wordValLogicOp sym bop wop w1 w2++wordValLogicOp sym bop wop w1 (ThunkWordVal _ m2) =+  do w2 <- m2+     wordValLogicOp sym bop wop w1 w2++{-# INLINE wordValUnaryOp #-}+wordValUnaryOp ::+  Backend sym =>+  sym ->+  (SBit sym -> SEval sym (SBit sym)) ->+  (SWord sym -> SEval sym (SWord sym)) ->+  WordValue sym ->+  SEval sym (WordValue sym)+wordValUnaryOp _ _ wop (WordVal w)  = WordVal <$> wop w+wordValUnaryOp sym bop wop (ThunkWordVal _ m) = wordValUnaryOp sym bop wop =<< m+wordValUnaryOp sym bop wop (BitmapVal n packed xs) =+  isReady sym packed >>= \case+    Just w  -> WordVal <$> wop w+    Nothing -> bitmapWordVal sym n =<< mapSeqMap sym bop (Nat n) xs++{-# SPECIALIZE joinWords ::+  Concrete ->+  Integer ->+  Integer ->+  SeqMap Concrete (WordValue Concrete)->+  SEval Concrete (WordValue Concrete)+  #-}+joinWords :: forall sym.+  Backend sym =>+  sym ->+  Integer ->+  Integer ->+  SeqMap sym (WordValue sym) ->+  SEval sym (WordValue sym)++-- small enough to pack+joinWords sym nParts nEach xs | nParts * nEach < largeBitSize =+  do z <- wordLit sym 0 0+     loop (wordVal z) (enumerateSeqMap nParts xs)++ where+ loop :: WordValue sym -> [SEval sym (WordValue sym)] -> SEval sym (WordValue sym)+ loop !wv [] = pure wv+ loop !wv (w : ws) =+    do w'  <- delayWordValue sym nEach w+       wv' <- joinWordVal sym wv w'+       loop wv' ws++-- too large to pack+joinWords sym nParts nEach xs = bitmapWordVal sym (nParts * nEach) zs+  where+    zs = indexSeqMap $ \i ->+            do let (q,r) = divMod i nEach+               ys <- lookupSeqMap xs q+               indexWordValue sym ys r++reverseWordVal :: Backend sym => sym -> WordValue sym -> SEval sym (WordValue sym)+reverseWordVal sym w =+  let m = wordValueSize sym w in+  bitmapWordVal sym m <$> reverseSeqMap m $ asBitsMap sym w++wordValAsLit :: Backend sym => sym -> WordValue sym -> SEval sym (Maybe Integer)+wordValAsLit sym (WordVal w) = pure (snd <$> wordAsLit sym w)+wordValAsLit sym (ThunkWordVal _ m) =+  isReady sym m >>= \case+    Just v  -> wordValAsLit sym v+    Nothing -> pure Nothing+wordValAsLit sym (BitmapVal _ packed _) =+  isReady sym packed >>= \case+    Just w  -> pure (snd <$> wordAsLit sym w)+    Nothing -> pure Nothing++-- | Force a word value into packed word form+asWordVal :: Backend sym => sym -> WordValue sym -> SEval sym (SWord sym)+asWordVal _   (WordVal w)            = return w+asWordVal sym (ThunkWordVal _ m)     = asWordVal sym =<< m+asWordVal _   (BitmapVal _ packed _) = packed++wordValueEqualsInteger :: forall sym. Backend sym =>+  sym ->+  WordValue sym ->+  Integer ->+  SEval sym (SBit sym)+wordValueEqualsInteger sym wv i+  | wordValueSize sym wv < widthInteger i = return (bitLit sym False)+  | otherwise = loop wv++ where+   loop (ThunkWordVal _ m) = loop =<< m+   loop (WordVal w) = wordEq sym w =<< wordLit sym (wordLen sym w) i+   loop (BitmapVal n packed bs) =+     isReady sym packed >>= \case+       Just w  -> loop (WordVal w)+       Nothing -> bitsAre i =<< sequence (enumerateSeqMap n (reverseSeqMap n bs))++   -- NB little-endian sequence of bits+   bitsAre :: Integer -> [SBit sym] -> SEval sym (SBit sym)+   bitsAre !n [] = return (bitLit sym (n == 0))+   bitsAre !n (b:bs) =+     do pb  <- bitIs (testBit n 0) b+        pbs <- bitsAre (n `shiftR` 1) bs+        bitAnd sym pb pbs++   bitIs :: Bool -> SBit sym -> SEval sym (SBit sym)+   bitIs b x = if b then pure x else bitComplement sym x++asWordList :: forall sym. Backend sym => sym -> [WordValue sym] -> SEval sym (Maybe [SWord sym])+asWordList sym = loop id+ where+   loop :: ([SWord sym] -> [SWord sym]) -> [WordValue sym] -> SEval sym (Maybe [SWord sym])+   loop f [] = pure (Just (f []))+   loop f (WordVal x : vs) = loop (f . (x:)) vs+   loop f (ThunkWordVal _ m : vs) =+     isReady sym m >>= \case+       Just m' -> loop f (m' : vs)+       Nothing -> pure Nothing+   loop f (BitmapVal _ packed _ : vs) =+     isReady sym packed >>= \case+       Just x -> loop (f . (x:)) vs+       Nothing -> pure Nothing++-- | Force a word value into a sequence of bits+asBitsMap :: Backend sym => sym -> WordValue sym -> SeqMap sym (SBit sym)+asBitsMap _   (BitmapVal _ _ xs)  = xs+asBitsMap sym (WordVal w)         = indexSeqMap $ \i -> wordBit sym w i+asBitsMap sym (ThunkWordVal _ m)  =+  indexSeqMap $ \i ->+    do mp <- asBitsMap sym <$> (unwindThunks m)+       lookupSeqMap mp i++-- | Turn a word value into a sequence of bits, forcing each bit.+--   The sequence is returned in big-endian order.+enumerateWordValue :: Backend sym => sym -> WordValue sym -> SEval sym [SBit sym]+enumerateWordValue sym (WordVal w) = unpackWord sym w+enumerateWordValue sym (ThunkWordVal _ m) = enumerateWordValue sym =<< m+  -- TODO? used the packed value if it is ready?+enumerateWordValue _ (BitmapVal n _ xs) = sequence (enumerateSeqMap n xs)++-- | Turn a word value into a sequence of bits, forcing each bit.+--   The sequence is returned in reverse of the usual order, which is little-endian order.+enumerateWordValueRev :: Backend sym => sym -> WordValue sym -> SEval sym [SBit sym]+enumerateWordValueRev sym (WordVal w)  = reverse <$> unpackWord sym w+enumerateWordValueRev sym (ThunkWordVal _ m)  = enumerateWordValueRev sym =<< m+  -- TODO? used the packed value if it is ready?+enumerateWordValueRev _   (BitmapVal n _ xs) = sequence (enumerateSeqMap n (reverseSeqMap n xs))+++enumerateIndexSegments :: Backend sym => sym -> WordValue sym -> SEval sym [IndexSegment sym]+enumerateIndexSegments _sym (WordVal w) = pure [WordIndexSegment w]+enumerateIndexSegments sym (ThunkWordVal _ m) = enumerateIndexSegments sym =<< m+enumerateIndexSegments sym (BitmapVal n packed xs) =+  isReady sym packed >>= \case+    Just w  -> pure [WordIndexSegment w]+    Nothing -> traverse (BitIndexSegment <$>) (enumerateSeqMap n xs)++{-# SPECIALIZE bitsValueLessThan ::+  Concrete ->+  Integer ->+  [SBit Concrete] ->+  Integer ->+  SEval Concrete (SBit Concrete)+  #-}+bitsValueLessThan ::+  Backend sym =>+  sym ->+  Integer {- ^ bit-width -} ->+  [SBit sym] {- ^ big-endian list of index bits -} ->+  Integer {- ^ Upper bound to test against -} ->+  SEval sym (SBit sym)+bitsValueLessThan sym _w [] _n = pure $ bitLit sym False+bitsValueLessThan sym w (b:bs) n+  | nbit =+      do notb <- bitComplement sym b+         bitOr sym notb =<< bitsValueLessThan sym (w-1) bs n+  | otherwise =+      do notb <- bitComplement sym b+         bitAnd sym notb =<< bitsValueLessThan sym (w-1) bs n+ where+ nbit = testBit n (fromInteger (w-1))+++assertWordValueInBounds ::+  Backend sym => sym -> Integer -> WordValue sym -> SEval sym ()++-- Can't index out of bounds for a sequence that is+-- longer than the expressible index values+assertWordValueInBounds sym n idx+  | n >= 2^(wordValueSize sym idx)+  = return ()++assertWordValueInBounds sym n (WordVal idx)+  | Just (_w,i) <- wordAsLit sym idx+  = unless (i < n) (raiseError sym (InvalidIndex (Just i)))++-- If the index is a packed word, test that it+-- is less than the concrete value of n, which+-- fits into w bits because of the above test.+assertWordValueInBounds sym n (WordVal idx) =+  do n' <- wordLit sym (wordLen sym idx) n+     p <- wordLessThan sym idx n'+     assertSideCondition sym p (InvalidIndex Nothing)++-- Force thunks+assertWordValueInBounds sym n (ThunkWordVal _ m) =+  assertWordValueInBounds sym n =<< m++-- If the index is an unpacked word, force all the bits+-- and compute the unsigned less-than test directly.+assertWordValueInBounds sym n (BitmapVal sz packed bits) =+  isReady sym packed >>= \case+    Just w -> assertWordValueInBounds sym n (WordVal w)+    Nothing ->+      do bitsList <- sequence (enumerateSeqMap sz bits)+         p <- bitsValueLessThan sym sz bitsList n+         assertSideCondition sym p (InvalidIndex Nothing)++delayWordValue :: Backend sym => sym -> Integer -> SEval sym (WordValue sym) -> SEval sym (WordValue sym)+delayWordValue sym sz m =+  isReady sym m >>= \case+    Just w  -> pure w+    Nothing -> ThunkWordVal sz <$> sDelay sym (unwindThunks m)++-- If we are calling this, we know the spine of the word value has been+-- demanded, so we unwind any chains of `ThunkWordValue` that may have built up.+unwindThunks :: Backend sym => SEval sym (WordValue sym) -> SEval sym (WordValue sym)+unwindThunks m =+  m >>= \case+    ThunkWordVal _ m' -> unwindThunks m'+    x -> pure x++{-# INLINE shiftWordByInteger #-}+shiftWordByInteger ::+  Backend sym =>+  sym ->+  (SWord sym -> SWord sym -> SEval sym (SWord sym)) +    {- ^ operation on word values -} ->+  (Integer -> Integer -> Maybe Integer)+    {- ^ reindexing operation -} ->+  WordValue sym {- ^ word value to shift -} ->+  SInteger sym {- ^ shift amount, assumed to be in range [0,len] -} ->+  SEval sym (WordValue sym)++shiftWordByInteger sym wop reindex x idx =+  case x of+    ThunkWordVal w wm ->+      isReady sym wm >>= \case+        Just x' -> shiftWordByInteger sym wop reindex x' idx+        Nothing ->+         do m' <- sDelay sym+                     (do x' <- wm+                         shiftWordByInteger sym wop reindex x' idx)+            return (ThunkWordVal w m')++    WordVal x' -> WordVal <$> (wop x' =<< wordFromInt sym (wordLen sym x') idx)++    BitmapVal n packed bs0 ->+      isReady sym packed >>= \case+        Just w -> shiftWordByInteger sym wop reindex (WordVal w) idx+        Nothing ->+          bitmapWordVal sym n =<<+            shiftSeqByInteger sym (iteBit sym) reindex (pure (bitLit sym False)) (Nat n) bs0 idx+++{-# INLINE shiftWordByWord #-}+shiftWordByWord ::+  Backend sym =>+  sym ->+  (SWord sym -> SWord sym -> SEval sym (SWord sym))+    {- ^ operation on word values -} ->+  (Integer -> Integer -> Maybe Integer)+    {- ^ reindexing operation -} ->+  WordValue sym {- ^ value to shift -} ->+  WordValue sym {- ^ amount to shift -} ->+  SEval sym (WordValue sym)+shiftWordByWord sym wop reindex x idx =+  case x of+    ThunkWordVal w wm ->+      isReady sym wm >>= \case+        Just wm' -> shiftWordByWord sym wop reindex wm' idx+        Nothing ->+         do m' <- sDelay sym (do wm' <- wm+                                 shiftWordByWord sym wop reindex wm' idx)+            return (ThunkWordVal w m')++    WordVal x' -> WordVal <$> (wop x' =<< asWordVal sym idx)++    BitmapVal n packed bs0 ->+      isReady sym packed >>= \case+        Just w -> shiftWordByWord sym wop reindex (WordVal w) idx+        Nothing ->+          bitmapWordVal sym n =<<+            shiftSeqByWord sym (iteBit sym) reindex (pure (bitLit sym False)) (Nat n) bs0 idx+++{-# INLINE updateWordByWord #-}+updateWordByWord ::+  Backend sym =>+  sym ->+  IndexDirection ->+  WordValue sym {- ^ value to update -} ->+  WordValue sym {- ^ index to update at -} ->+  SEval sym (SBit sym) {- ^ fresh bit -} ->+  SEval sym (WordValue sym)+updateWordByWord sym dir w0 idx bitval =+  wordValAsLit sym idx >>= \case+    Just j ->+      let sz = wordValueSize sym w0 in+      case dir of+        IndexForward  -> updateWordValue sym w0 j bitval+        IndexBackward -> updateWordValue sym w0 (sz - j - 1) bitval+    Nothing -> loop w0++ where+   loop (ThunkWordVal sz m) =+     isReady sym m >>= \case+       Just w' -> loop w'+       Nothing -> delayWordValue sym sz (loop =<< m)++   loop (BitmapVal sz packed bs) =+     isReady sym packed >>= \case+       Just w -> loop (WordVal w)+       Nothing ->+         case dir of+           IndexForward ->+             bitmapWordVal sym sz $ indexSeqMap $ \i ->+               do b <- wordValueEqualsInteger sym idx i+                  mergeEval sym (iteBit sym) b bitval (lookupSeqMap bs i)+           IndexBackward ->+             bitmapWordVal sym sz $ indexSeqMap $ \i ->+               do b <- wordValueEqualsInteger sym idx (sz - i - 1)+                  mergeEval sym (iteBit sym) b bitval (lookupSeqMap bs i)++   loop (WordVal wv) = WordVal <$>+      -- TODO, this is too strict in bit+      do let sz = wordLen sym wv+         b <- bitval+         msk <- case dir of+                  IndexForward ->+                    do highbit <- wordLit sym sz (bit (fromInteger (sz-1)))+                       wordShiftRight sym highbit =<< asWordVal sym idx+                  IndexBackward ->+                    do lowbit <- wordLit sym sz 1+                       wordShiftLeft sym lowbit =<< asWordVal sym idx+         case bitAsLit sym b of+           Just True  -> wordOr  sym wv msk+           Just False -> wordAnd sym wv =<< wordComplement sym msk+           Nothing ->+             do zro <- wordLit sym sz 0+                one <- wordComplement sym zro+                q   <- iteWord sym b one zro+                w'  <- wordAnd sym wv =<< wordComplement sym msk+                wordXor sym w' =<< wordAnd sym msk q+++{-# INLINE shiftSeqByWord #-}+shiftSeqByWord  ::+  Backend sym =>+  sym ->+  (SBit sym -> a -> a -> SEval sym a)+     {- ^ if/then/else operation of values -} ->+  (Integer -> Integer -> Maybe Integer)+     {- ^ reindexing operation -} ->+  SEval sym a  {- ^ zero value -} ->+  Nat' {- ^ size of the sequence -} ->+  SeqMap sym a {- ^ sequence to shift -} ->+  WordValue sym {- ^ shift amount -} ->+  SEval sym (SeqMap sym a)+shiftSeqByWord sym merge reindex zro sz xs idx =+  wordValAsLit sym idx >>= \case+    Just j -> shiftOp xs j+    Nothing ->+      do idx_segs <- enumerateIndexSegments sym idx+         barrelShifter sym merge shiftOp sz xs idx_bits idx_segs+  where+   idx_bits = wordValueSize sym idx++   shiftOp vs shft =+     pure $ indexSeqMap $ \i ->+       case reindex i shft of+         Nothing -> zro+         Just i' -> lookupSeqMap vs i'++-- | Compute the size of a word value+-- TODO, can we get rid of this? If feels like it should be+--  unnecessary.+wordValueSize :: Backend sym => sym -> WordValue sym -> Integer+wordValueSize sym (WordVal w)  = wordLen sym w+wordValueSize _ (ThunkWordVal n _) = n+wordValueSize _ (BitmapVal n _ _) = n++-- | Select an individual bit from a word value+indexWordValue :: Backend sym => sym -> WordValue sym -> Integer -> SEval sym (SBit sym)+indexWordValue sym (ThunkWordVal _ m) idx = do m' <- m ; indexWordValue sym m' idx+indexWordValue sym (WordVal w) idx+   | 0 <= idx && idx < wordLen sym w = wordBit sym w idx+   | otherwise = invalidIndex sym idx+indexWordValue sym (BitmapVal n _packed xs) idx+   | 0 <= idx && idx < n = lookupSeqMap xs idx+   | otherwise = invalidIndex sym idx++-- | Produce a new 'WordValue' from the one given by updating the @i@th bit with the+--   given bit value.+updateWordValue :: Backend sym =>+  sym -> WordValue sym -> Integer -> SEval sym (SBit sym) -> SEval sym (WordValue sym)+updateWordValue sym wv0 idx b = loop wv0+  where+    loop (ThunkWordVal sz m) =+      isReady sym m >>= \case+        Just w  -> loop w+        Nothing -> delayWordValue sym sz (loop =<< m)++    loop (WordVal w)+      | idx < 0 || idx >= wordLen sym w = invalidIndex sym idx+      | otherwise =+          isReady sym b >>= \case+            Just b' -> WordVal <$> wordUpdate sym w idx b'+            Nothing ->+              do let bs = unpackBitmap sym w+                 bitmapWordVal sym (wordLen sym w) $ updateSeqMap bs idx b++    loop (BitmapVal sz packed bs)+      | 0 <= idx && idx < sz =+          isReady sym packed >>= \case+            Just w  -> loop (WordVal w)+            Nothing -> bitmapWordVal sym sz $ updateSeqMap bs idx b+      | otherwise = invalidIndex sym idx++{-# INLINE mergeWord #-}+mergeWord :: Backend sym =>+  sym ->+  SBit sym ->+  WordValue sym ->+  WordValue sym ->+  SEval sym (WordValue sym)+mergeWord sym c (ThunkWordVal _ m1) (ThunkWordVal _ m2) =+  mergeWord' sym c (unwindThunks m1) (unwindThunks m2)+mergeWord sym c (ThunkWordVal _ m1) w2 =+  mergeWord' sym c (unwindThunks m1) (pure w2)+mergeWord sym c w1 (ThunkWordVal _ m2) =+  mergeWord' sym c (pure w1) (unwindThunks m2)++mergeWord sym c (WordVal w1) (WordVal w2) =+  WordVal <$> iteWord sym c w1 w2++mergeWord sym c (BitmapVal n1 packed1 bs1) (WordVal w2) =+  isReady sym packed1 >>= \case+    Just w1 -> WordVal <$> iteWord sym c w1 w2+    Nothing -> mergeBitmaps sym c n1 bs1 (unpackBitmap sym w2)++mergeWord sym c (WordVal w1) (BitmapVal n2 packed2 bs2) =+  isReady sym packed2 >>= \case+    Just w2 -> WordVal <$> iteWord sym c w1 w2+    Nothing -> mergeBitmaps sym c n2 (unpackBitmap sym w1) bs2++mergeWord sym c (BitmapVal n1 packed1 bs1) (BitmapVal _n2 packed2 bs2) =+  do r1 <- isReady sym packed1+     r2 <- isReady sym packed2+     case (r1,r2) of+       (Just w1, Just w2) -> WordVal <$> iteWord sym c w1 w2+       _ -> mergeBitmaps sym c n1 bs1 bs2++mergeBitmaps :: Backend sym =>+  sym ->+  SBit sym ->+  Integer ->+  SeqMap sym (SBit sym) ->+  SeqMap sym (SBit sym) ->+  SEval sym (WordValue sym)+mergeBitmaps sym c sz bs1 bs2 =+  do bs <- memoMap sym (Nat sz) (mergeSeqMap sym (iteBit sym) c bs1 bs2)+     bitmapWordVal sym sz bs++{-# INLINE mergeWord' #-}+mergeWord' :: Backend sym =>+  sym ->+  SBit sym ->+  SEval sym (WordValue sym) ->+  SEval sym (WordValue sym) ->+  SEval sym (WordValue sym)+mergeWord' sym c x y+  | Just b <- bitAsLit sym c = if b then x else y+  | otherwise = mergeEval sym (mergeWord sym) c x y
src/Cryptol/Eval.hs view
@@ -40,7 +40,9 @@ import Cryptol.Backend import Cryptol.Backend.Concrete( Concrete(..) ) import Cryptol.Backend.Monad-import Cryptol.Eval.Generic ( iteValue )+import Cryptol.Backend.SeqMap+import Cryptol.Backend.WordValue+ import Cryptol.Eval.Env import Cryptol.Eval.Prims import Cryptol.Eval.Type@@ -122,14 +124,14 @@     -- NB, even if the list cannot be packed, we must use `VWord`     -- when the element type is `Bit`.     | isTBit tyv -> {-# SCC "evalExpr->Elist/bit" #-}-        return $ VWord len $-          case tryFromBits sym vs of-            Just w  -> WordVal <$> w-            Nothing -> do xs <- mapM (sDelay sym) vs-                          return $ LargeBitsVal len $ finiteSeqMap xs+        VWord len <$>+          (tryFromBits sym vs >>= \case+             Just w  -> pure (wordVal w)+             Nothing -> do xs <- mapM (\x -> sDelay sym (fromVBit <$> x)) vs+                           bitmapWordVal sym len $ finiteSeqMap sym xs)     | otherwise -> {-# SCC "evalExpr->EList" #-} do         xs <- mapM (sDelay sym) vs-        return $ VSeq len $ finiteSeqMap xs+        return $ VSeq len $ finiteSeqMap sym xs    where     tyv = evalValType (envTypes env) ty     vs  = map eval es@@ -362,186 +364,12 @@   GenEvalEnv sym ->   (Name, Schema, SEval sym (GenValue sym), SEval sym (GenValue sym) -> SEval sym ()) ->   SEval sym ()-fillHole sym env (nm, sch, _, fill) = do+fillHole _sym env (nm, _sch, _, fill) = do   case lookupVar nm env of-    Just (Right v)-     | isValueType env sch ->-               fill =<< sDelayFill sym v-                          (Just (etaDelay sym env sch v))-                          (show (ppLocName nm))--     | otherwise -> fill (etaDelay sym env sch v)-+    Just (Right v) -> fill v     _ -> evalPanic "fillHole" ["Recursive definition not completed", show (ppLocName nm)] --- | 'Value' types are non-polymorphic types recursive constructed from---   bits, finite sequences, tuples and records.  Types of this form can---   be implemented rather more efficiently than general types because we can---   rely on the 'delayFill' operation to build a thunk that falls back on performing---   eta-expansion rather than doing it eagerly.-isValueType :: GenEvalEnv sym -> Schema -> Bool-isValueType env Forall{ sVars = [], sProps = [], sType = t0 }-   = go (evalValType (envTypes env) t0)- where-  go TVBit = True-  go (TVSeq _ x)  = go x-  go (TVTuple xs) = and (map go xs)-  go (TVRec xs)   = and (fmap go xs)-  go (TVNewtype _ _ xs) = and (fmap go xs)-  go _            = False -isValueType _ _ = False---{-# SPECIALIZE etaWord  ::-  Concrete ->-  Integer ->-  SEval Concrete (GenValue Concrete) ->-  SEval Concrete (WordValue Concrete)-  #-}---- | Eta-expand a word value.  This forces an unpacked word representation.-etaWord  ::-  Backend sym =>-  sym ->-  Integer ->-  SEval sym (GenValue sym) ->-  SEval sym (WordValue sym)-etaWord sym n val = do-  w <- sDelay sym (fromWordVal "during eta-expansion" =<< val)-  xs <- memoMap sym $ IndexSeqMap $ \i ->-          do w' <- w; VBit <$> indexWordValue sym w' i-  pure $ LargeBitsVal n xs--{-# SPECIALIZE etaDelay ::-  Concrete ->-  GenEvalEnv Concrete ->-  Schema ->-  SEval Concrete (GenValue Concrete) ->-  SEval Concrete (GenValue Concrete)-  #-}---- | Given a simulator value and its type, fully eta-expand the value.  This---   is a type-directed pass that always produces a canonical value of the---   expected shape.  Eta expansion of values is sometimes necessary to ensure---   the correct evaluation semantics of recursive definitions.  Otherwise,---   expressions that should be expected to produce well-defined values in the---   denotational semantics will fail to terminate instead.-etaDelay ::-  Backend sym =>-  sym ->-  GenEvalEnv sym ->-  Schema ->-  SEval sym (GenValue sym) ->-  SEval sym (GenValue sym)-etaDelay sym env0 Forall{ sVars = vs0, sType = tp0 } = goTpVars env0 vs0-  where-  goTpVars env []     val =-     do stk <- sGetCallStack sym-        go stk (evalValType (envTypes env) tp0) val-  goTpVars env (v:vs) val =-    case tpKind v of-      KType -> tlam sym $ \t ->-                  goTpVars (bindType (tpVar v) (Right t) env) vs ( ($t) . fromVPoly sym =<< val )-      KNum  -> nlam sym $ \n ->-                  goTpVars (bindType (tpVar v) (Left n) env) vs ( ($n) . fromVNumPoly sym =<< val )-      k     -> panic "[Eval] etaDelay" ["invalid kind on type abstraction", show k]--  go stk tp x | isReady sym x = x >>= \case-      VBit{}      -> x-      VInteger{}  -> x-      VWord{}     -> x-      VRational{} -> x-      VFloat{}    -> x-      VSeq n xs ->-        case tp of-          TVSeq _nt el -> return $ VSeq n $ IndexSeqMap $ \i -> go stk el (lookupSeqMap xs i)-          _ -> evalPanic "type mismatch during eta-expansion" ["Expected sequence type, but got " ++ show tp]--      VStream xs ->-        case tp of-          TVStream el -> return $ VStream $ IndexSeqMap $ \i -> go stk el (lookupSeqMap xs i)-          _ -> evalPanic "type mismatch during eta-expansion" ["Expected stream type, but got " ++ show tp]--      VTuple xs ->-        case tp of-          TVTuple ts | length ts == length xs -> return $ VTuple (zipWith (go stk) ts xs)-          _ -> evalPanic "type mismatch during eta-expansion" ["Expected tuple type with " ++ show (length xs)-                                   ++ " elements, but got " ++ show tp]--      VRecord fs ->-        case tp of-          TVNewtype _ _ fts ->-            do let res = zipRecords (\_ v t -> go stk t v) fs fts-               case res of-                 Left (Left f)  -> evalPanic "type mismatch during eta-expansion" ["missing field " ++ show f]-                 Left (Right f) -> evalPanic "type mismatch during eta-expansion" ["unexpected field " ++ show f]-                 Right fs' -> return (VRecord fs')-          TVRec fts ->-            do let res = zipRecords (\_ v t -> go stk t v) fs fts-               case res of-                 Left (Left f)  -> evalPanic "type mismatch during eta-expansion" ["missing field " ++ show f]-                 Left (Right f) -> evalPanic "type mismatch during eta-expansion" ["unexpected field " ++ show f]-                 Right fs' -> return (VRecord fs')-          _ -> evalPanic "type mismatch during eta-expansion" ["Expected record type, but got " ++ show tp]--      f@VFun{} ->-        case tp of-          TVFun _t1 t2 -> lam sym $ \a -> go stk t2 (fromVFun sym f a)-          _ -> evalPanic "type mismatch during eta-expansion" ["Expected function type but got " ++ show tp]--      VPoly{} ->-        evalPanic "type mismatch during eta-expansion" ["Encountered polymorphic value"]--      VNumPoly{} ->-        evalPanic "type mismatch during eta-expansion" ["Encountered numeric polymorphic value"]--  go stk tp v = sWithCallStack sym stk $-    case tp of-      TVBit -> v-      TVInteger -> v-      TVFloat {} -> v-      TVIntMod _ -> v-      TVRational -> v-      TVArray{} -> v--      TVSeq n TVBit ->-          do w <- sDelayFill sym (fromWordVal "during eta-expansion" =<< v) (Just (etaWord sym n v)) ""-             return $ VWord n w--      TVSeq n el ->-          do x' <- sDelay sym (fromSeq "during eta-expansion" =<< v)-             return $ VSeq n $ IndexSeqMap $ \i -> do-               go stk el (flip lookupSeqMap i =<< x')--      TVStream el ->-          do x' <- sDelay sym (fromSeq "during eta-expansion" =<< v)-             return $ VStream $ IndexSeqMap $ \i ->-               go stk el (flip lookupSeqMap i =<< x')--      TVFun _t1 t2 ->-          do v' <- sDelay sym (fromVFun sym <$> v)-             lam sym $ \a -> go stk t2 ( ($a) =<< v' )--      TVTuple ts ->-          do let n = length ts-             v' <- sDelay sym (fromVTuple <$> v)-             return $ VTuple $-                [ go stk t =<< (flip genericIndex i <$> v')-                | i <- [0..(n-1)]-                | t <- ts-                ]--      TVRec fs ->-          do v' <- sDelay sym (fromVRecord <$> v)-             let err f = evalPanic "expected record value with field" [show f]-             let eta f t = go stk t =<< (fromMaybe (err f) . lookupField f <$> v')-             return $ VRecord (mapWithFieldName eta fs)--      TVAbstract {} -> v--      TVNewtype _ _ body -> go stk (TVRec body) v- {-# SPECIALIZE declHole ::   Concrete ->   Decl ->@@ -600,9 +428,11 @@   SEval Concrete (GenValue Concrete)   #-} --- | Apply the the given "selector" form to the given value.  This function pushes---   tuple and record selections pointwise down into other value constructs---   (e.g., streams and functions).+-- | Apply the the given "selector" form to the given value.  Note that+--   selectors are expected to apply only to values of the right type,+--   e.g. tuple selectors expect only tuple values.  The lifting of+--   tuple an record selectors over functions and sequences has already+--   been resolved earlier in the typechecker. evalSel ::   Backend sym =>   sym ->@@ -636,7 +466,7 @@     case v of       VSeq _ vs       -> lookupSeqMap vs (toInteger n)       VStream vs      -> lookupSeqMap vs (toInteger n)-      VWord _ wv      -> VBit <$> (flip (indexWordValue sym) (toInteger n) =<< wv)+      VWord _ wv      -> VBit <$> indexWordValue sym wv (toInteger n)       _               -> do vdoc <- ppValue sym defaultPPOpts val                             evalPanic "Cryptol.Eval.evalSel"                               [ "Unexpected value in list selection"@@ -685,8 +515,7 @@     case e of       VSeq i mp  -> pure $ VSeq i  $ updateSeqMap mp n v       VStream mp -> pure $ VStream $ updateSeqMap mp n v-      VWord i m  -> pure $ VWord i $ do m1 <- m-                                        updateWordValue sym m1 n asBit+      VWord i m  -> VWord i <$> updateWordValue sym m n asBit       _ -> bad "Sequence update on a non-sequence."    asBit = do res <- v@@ -776,7 +605,7 @@   SEval sym (GenValue sym) evalComp sym env len elty body ms =        do lenv <- mconcat <$> mapM (branchEnvs sym (toListEnv env)) ms-          mkSeq len elty <$> memoMap sym (IndexSeqMap $ \i -> do+          mkSeq sym len elty =<< memoMap sym len (indexSeqMap $ \i -> do               evalExpr sym (evalListEnv lenv i) body)  {-# SPECIALIZE branchEnvs ::@@ -794,24 +623,24 @@   ListEnv sym ->   [Match] ->   SEval sym (ListEnv sym)-branchEnvs sym env matches = foldM (evalMatch sym) env matches+branchEnvs sym env matches = snd <$> foldM (evalMatch sym) (1, env) matches  {-# SPECIALIZE evalMatch ::   (?range :: Range, ConcPrims) =>   Concrete ->-  ListEnv Concrete ->+  (Integer, ListEnv Concrete) ->   Match ->-  SEval Concrete (ListEnv Concrete)+  SEval Concrete (Integer, ListEnv Concrete)   #-}  -- | Turn a match into the list of environments it represents. evalMatch ::   (?range :: Range, EvalPrims sym) =>   sym ->-  ListEnv sym ->+  (Integer, ListEnv sym) ->   Match ->-  SEval sym (ListEnv sym)-evalMatch sym lenv m = case m of+  SEval sym (Integer, ListEnv sym)+evalMatch sym (lsz, lenv) m = seq lsz $ case m of    -- many envs   From n l _ty expr ->@@ -819,16 +648,16 @@       -- Select from a sequence of finite length.  This causes us to 'stutter'       -- through our previous choices `nLen` times.       Nat nLen -> do-        vss <- memoMap sym $ IndexSeqMap $ \i -> evalExpr sym (evalListEnv lenv i) expr+        vss <- memoMap sym (Nat lsz) $ indexSeqMap $ \i -> evalExpr sym (evalListEnv lenv i) expr         let stutter xs = \i -> xs (i `div` nLen)         let lenv' = lenv { leVars = fmap stutter (leVars lenv) }         let vs i = do let (q, r) = i `divMod` nLen                       lookupSeqMap vss q >>= \case-                        VWord _ w   -> VBit <$> (flip (indexWordValue sym) r =<< w)+                        VWord _ w   -> VBit <$> indexWordValue sym w r                         VSeq _ xs'  -> lookupSeqMap xs' r                         VStream xs' -> lookupSeqMap xs' r                         _           -> evalPanic "evalMatch" ["Not a list value"]-        return $ bindVarList n vs lenv'+        return (lsz * nLen, bindVarList n vs lenv')        -- Select from a sequence of infinite length.  Note that this means we       -- will never need to backtrack into previous branches.  Thus, we can convert@@ -842,11 +671,13 @@         let env   = EvalEnv allvars (leTypes lenv)         xs <- evalExpr sym env expr         let vs i = case xs of-                     VWord _ w   -> VBit <$> (flip (indexWordValue sym) i =<< w)+                     VWord _ w   -> VBit <$> indexWordValue sym w i                      VSeq _ xs'  -> lookupSeqMap xs' i                      VStream xs' -> lookupSeqMap xs' i                      _           -> evalPanic "evalMatch" ["Not a list value"]-        return $ bindVarList n vs lenv'+        -- Selecting from an infinite list effectively resets the length of the+        -- list environment, so return 1 as the length+        return (1, bindVarList n vs lenv')      where       len  = evalNumType (leTypes lenv) l@@ -854,7 +685,7 @@   -- XXX we don't currently evaluate these as though they could be recursive, as   -- they are typechecked that way; the read environment to evalExpr is the same   -- as the environment to bind a new name in.-  Let d -> return $ bindVarList (dName d) (\i -> f (evalListEnv lenv i)) lenv+  Let d -> return (lsz, bindVarList (dName d) (\i -> f (evalListEnv lenv i)) lenv)     where       f env =           case dDefinition d of
src/Cryptol/Eval/Concrete.hs view
@@ -26,7 +26,6 @@   ) where  import Control.Monad (guard, zipWithM, foldM, mzero)-import Data.Bits (Bits(..)) import Data.Ratio(numerator,denominator) import Data.Word(Word32, Word64) import MonadLib( ChoiceT, findOne, lift )@@ -42,8 +41,10 @@ import Cryptol.Backend.Concrete import Cryptol.Backend.FloatHelpers import Cryptol.Backend.Monad+import Cryptol.Backend.SeqMap+import Cryptol.Backend.WordValue -import Cryptol.Eval.Generic hiding (logicShift)+import Cryptol.Eval.Generic import Cryptol.Eval.Prims import Cryptol.Eval.Type import Cryptol.Eval.Value@@ -110,7 +111,7 @@         do ses <- traverse (go b) =<< lift (sequence (enumerateSeqMap n svs))            pure $ EList ses (tValTy b)       (TVSeq n TVBit, VWord _ wval) ->-        do BV _ v <- lift (asWordVal Concrete =<< wval)+        do BV _ v <- lift (asWordVal Concrete wval)            pure $ ETApp (ETApp (prim "number") (tNum v)) (tWord (tNum n))        (_,VStream{})  -> mzero@@ -125,7 +126,7 @@            panic "Cryptol.Eval.Concrete.toExpr"              ["type mismatch:"              , pretty (tValTy ty)-             , render doc+             , show doc              ]  floatToExpr :: PrimMap -> AST.Type -> AST.Type -> FP.BigFloat -> AST.Expr@@ -159,24 +160,11 @@    Map.fromList $ map (\(n, v) -> (prelPrim n, v)) -  [ (">>$"        , {-# SCC "Prelude::(>>$)" #-}-                    sshrV)--    -- Shifts and rotates-  , ("<<"         , {-# SCC "Prelude::(<<)" #-}-                    logicShift shiftLW shiftLS)-  , (">>"         , {-# SCC "Prelude::(>>)" #-}-                    logicShift shiftRW shiftRS)-  , ("<<<"        , {-# SCC "Prelude::(<<<)" #-}-                    logicShift rotateLW rotateLS)-  , (">>>"        , {-# SCC "Prelude::(>>>)" #-}-                    logicShift rotateRW rotateRS)--    -- Indexing and updates-  , ("@"          , {-# SCC "Prelude::(@)" #-}-                    indexPrim sym indexFront_int indexFront_bits indexFront)+  [ -- Indexing and updates+    ("@"          , {-# SCC "Prelude::(@)" #-}+                    indexPrim sym IndexForward indexFront_int indexFront_segs)   , ("!"          , {-# SCC "Prelude::(!)" #-}-                    indexPrim sym indexBack_int indexBack_bits indexBack)+                    indexPrim sym IndexBackward indexFront_int indexFront_segs)    , ("update"     , {-# SCC "Prelude::update" #-}                     updatePrim sym updateFront_word updateFront)@@ -194,7 +182,7 @@                       F2.pmult (fromInteger (u+1)) x y                     else                       F2.pmult (fromInteger (v+1)) y x-             in return . VWord (1+u+v) . pure . WordVal . mkBv (1+u+v) $! z)+             in return . VWord (1+u+v) . wordVal . mkBv (1+u+v) $! z)     , ("pmod",         PFinPoly \_u ->@@ -203,7 +191,7 @@         PWordFun \(BV _ m) ->         PPrim           do assertSideCondition sym (m /= 0) DivideByZero-             return . VWord v . pure . WordVal . mkBv v $! F2.pmod (fromInteger w) x m)+             return . VWord v . wordVal . mkBv v $! F2.pmod (fromInteger w) x m)    , ("pdiv",         PFinPoly \_u ->@@ -212,7 +200,7 @@         PWordFun \(BV _ m) ->         PPrim           do assertSideCondition sym (m /= 0) DivideByZero-             return . VWord w . pure . WordVal . mkBv w $! F2.pdiv (fromInteger w) x m)+             return . VWord w . wordVal . mkBv w $! F2.pdiv (fromInteger w) x m)   ]  @@ -230,7 +218,7 @@        PFinPoly \p ->        PFun     \s ->        PFun     \t ->-       PPrim +       PPrim           do s' <- toProjectivePoint =<< s              t' <- toProjectivePoint =<< t              let r = PrimeEC.ec_add_nonzero (PrimeEC.primeModulus p) s' t'@@ -285,8 +273,8 @@               foldM (\st blk -> seq st (SHA.processSHA256Block st <$> (toSHA256Block =<< blk)))                     SHA.initialSHA224State blks            let f :: Word32 -> Eval Value-               f = pure . VWord 32 . pure . WordVal . BV 32 . toInteger-               zs = finiteSeqMap (map f [w0,w1,w2,w3,w4,w5,w6])+               f = pure . VWord 32 . wordVal . BV 32 . toInteger+               zs = finiteSeqMap Concrete (map f [w0,w1,w2,w3,w4,w5,w6])            seq zs (pure (VSeq 7 zs)))    , ("processSHA2_256", {-# SCC "SuiteB::processSHA2_256" #-}@@ -298,8 +286,8 @@              foldM (\st blk -> seq st (SHA.processSHA256Block st <$> (toSHA256Block =<< blk)))                    SHA.initialSHA256State blks            let f :: Word32 -> Eval Value-               f = pure . VWord 32 . pure . WordVal . BV 32 . toInteger-               zs = finiteSeqMap (map f [w0,w1,w2,w3,w4,w5,w6,w7])+               f = pure . VWord 32 . wordVal . BV 32 . toInteger+               zs = finiteSeqMap Concrete (map f [w0,w1,w2,w3,w4,w5,w6,w7])            seq zs (pure (VSeq 8 zs)))    , ("processSHA2_384", {-# SCC "SuiteB::processSHA2_384" #-}@@ -311,8 +299,8 @@              foldM (\st blk -> seq st (SHA.processSHA512Block st <$> (toSHA512Block =<< blk)))                    SHA.initialSHA384State blks            let f :: Word64 -> Eval Value-               f = pure . VWord 64 . pure . WordVal . BV 64 . toInteger-               zs = finiteSeqMap (map f [w0,w1,w2,w3,w4,w5])+               f = pure . VWord 64 . wordVal . BV 64 . toInteger+               zs = finiteSeqMap Concrete (map f [w0,w1,w2,w3,w4,w5])            seq zs (pure (VSeq 6 zs)))    , ("processSHA2_512", {-# SCC "SuiteB::processSHA2_512" #-}@@ -324,8 +312,8 @@              foldM (\st blk -> seq st (SHA.processSHA512Block st <$> (toSHA512Block =<< blk)))                    SHA.initialSHA512State blks            let f :: Word64 -> Eval Value-               f = pure . VWord 64 . pure . WordVal . BV 64 . toInteger-               zs = finiteSeqMap (map f [w0,w1,w2,w3,w4,w5,w6,w7])+               f = pure . VWord 64 . wordVal . BV 64 . toInteger+               zs = finiteSeqMap Concrete (map f [w0,w1,w2,w3,w4,w5,w6,w7])            seq zs (pure (VSeq 8 zs)))    , ("AESKeyExpand", {-# SCC "SuiteB::AESKeyExpand" #-}@@ -336,11 +324,11 @@             let toWord :: Integer -> Eval Word32                 toWord i = fromInteger. bvVal <$> (fromVWord Concrete "AESInfKeyExpand" =<< lookupSeqMap ss i)             let fromWord :: Word32 -> Eval Value-                fromWord = pure . VWord 32 . pure . WordVal . BV 32 . toInteger+                fromWord = pure . VWord 32 . wordVal . BV 32 . toInteger             kws <- mapM toWord [0 .. k-1]             let ws = AES.keyExpansionWords k kws             let len = 4*(k+7)-            pure (VSeq len (finiteSeqMap (map fromWord ws))))+            pure (VSeq len (finiteSeqMap Concrete (map fromWord ws))))    , ("AESInvMixColumns", {-# SCC "SuiteB::AESInvMixColumns" #-}       PFun \st ->@@ -349,10 +337,10 @@             let toWord :: Integer -> Eval Word32                 toWord i = fromInteger. bvVal <$> (fromVWord Concrete "AESInvMixColumns" =<< lookupSeqMap ss i)             let fromWord :: Word32 -> Eval Value-                fromWord = pure . VWord 32 . pure . WordVal . BV 32 . toInteger+                fromWord = pure . VWord 32 . wordVal . BV 32 . toInteger             ws <- mapM toWord [0,1,2,3]             let ws' = AES.invMixColumns ws-            pure . VSeq 4 . finiteSeqMap . map fromWord $ ws')+            pure . VSeq 4 . finiteSeqMap Concrete . map fromWord $ ws')    , ("AESEncRound", {-# SCC "SuiteB::AESEncRound" #-}       PFun \st ->@@ -361,10 +349,10 @@             let toWord :: Integer -> Eval Word32                 toWord i = fromInteger. bvVal <$> (fromVWord Concrete "AESEncRound" =<< lookupSeqMap ss i)             let fromWord :: Word32 -> Eval Value-                fromWord = pure . VWord 32 . pure . WordVal . BV 32 . toInteger+                fromWord = pure . VWord 32 . wordVal . BV 32 . toInteger             ws <- mapM toWord [0,1,2,3]             let ws' = AES.aesRound ws-            pure . VSeq 4 . finiteSeqMap . map fromWord $ ws')+            pure . VSeq 4 . finiteSeqMap Concrete . map fromWord $ ws')    , ("AESEncFinalRound", {-# SCC "SuiteB::AESEncFinalRound" #-}      PFun \st ->@@ -373,10 +361,10 @@             let toWord :: Integer -> Eval Word32                 toWord i = fromInteger. bvVal <$> (fromVWord Concrete "AESEncFinalRound" =<< lookupSeqMap ss i)             let fromWord :: Word32 -> Eval Value-                fromWord = pure . VWord 32 . pure . WordVal . BV 32 . toInteger+                fromWord = pure . VWord 32 . wordVal . BV 32 . toInteger             ws <- mapM toWord [0,1,2,3]             let ws' = AES.aesFinalRound ws-            pure . VSeq 4 . finiteSeqMap . map fromWord $ ws')+            pure . VSeq 4 . finiteSeqMap Concrete . map fromWord $ ws')    , ("AESDecRound", {-# SCC "SuiteB::AESDecRound" #-}       PFun \st ->@@ -385,10 +373,10 @@             let toWord :: Integer -> Eval Word32                 toWord i = fromInteger. bvVal <$> (fromVWord Concrete "AESDecRound" =<< lookupSeqMap ss i)             let fromWord :: Word32 -> Eval Value-                fromWord = pure . VWord 32 . pure . WordVal . BV 32 . toInteger+                fromWord = pure . VWord 32 . wordVal . BV 32 . toInteger             ws <- mapM toWord [0,1,2,3]             let ws' = AES.aesInvRound ws-            pure . VSeq 4 . finiteSeqMap . map fromWord $ ws')+            pure . VSeq 4 . finiteSeqMap Concrete . map fromWord $ ws')    , ("AESDecFinalRound", {-# SCC "SuiteB::AESDecFinalRound" #-}      PFun \st ->@@ -397,10 +385,10 @@             let toWord :: Integer -> Eval Word32                 toWord i = fromInteger. bvVal <$> (fromVWord Concrete "AESDecFinalRound" =<< lookupSeqMap ss i)             let fromWord :: Word32 -> Eval Value-                fromWord = pure . VWord 32 . pure . WordVal . BV 32 . toInteger+                fromWord = pure . VWord 32 . wordVal . BV 32 . toInteger             ws <- mapM toWord [0,1,2,3]             let ws' = AES.aesInvFinalRound ws-            pure . VSeq 4 . finiteSeqMap . map fromWord $ ws')+            pure . VSeq 4 . finiteSeqMap Concrete . map fromWord $ ws')   ]  @@ -449,152 +437,39 @@         (toWord 14) <*>         (toWord 15) --------------------------------------------------------------------------------- -sshrV :: Prim Concrete-sshrV =-  PNumPoly \_n ->-  PTyPoly  \ix ->-  PWordFun \(BV w x) ->-  PFun     \y ->-  PPrim-   do idx <- y >>= asIndex Concrete ">>$" ix >>= \case-                 Left idx -> pure idx-                 Right wv -> bvVal <$> asWordVal Concrete wv-      return $ VWord w $ pure $ WordVal $ mkBv w $ signedShiftRW w x idx--logicShift :: (Integer -> Integer -> Integer -> Integer)-              -- ^ The function may assume its arguments are masked.-              -- It is responsible for masking its result if needed.-           -> (Nat' -> TValue -> SeqMap Concrete -> Integer -> SeqMap Concrete)-           -> Prim Concrete-logicShift opW opS =-  PNumPoly \a ->-  PTyPoly  \_ix ->-  PTyPoly  \c ->-  PFun     \l ->-  PFun     \r ->-  PPrim-     do i <- r >>= \case-          VInteger i -> pure i-          VWord _ wval -> bvVal <$> (asWordVal Concrete =<< wval)-          _ -> evalPanic "logicShift" ["not an index"]-        l >>= \case-          VWord w wv -> return $ VWord w $ wv >>= \case-                          WordVal (BV _ x) -> return $ WordVal (BV w (opW w x i))-                          LargeBitsVal n xs -> return $ LargeBitsVal n $ opS (Nat n) c xs i--          _ -> mkSeq a c <$> (opS a c <$> (fromSeq "logicShift" =<< l) <*> return i)---- Left shift for words.-shiftLW :: Integer -> Integer -> Integer -> Integer-shiftLW w ival by-  | by <  0   = shiftRW w ival (negate by)-  | by >= w   = 0-  | by > toInteger (maxBound :: Int) = panic "shiftLW" ["Shift amount too large", show by]-  | otherwise = mask w (shiftL ival (fromInteger by))---- Right shift for words-shiftRW :: Integer -> Integer -> Integer -> Integer-shiftRW w ival by-  | by <  0   = shiftLW w ival (negate by)-  | by >= w   = 0-  | by > toInteger (maxBound :: Int) = panic "shiftRW" ["Shift amount too large", show by]-  | otherwise = shiftR ival (fromInteger by)---- signed right shift for words-signedShiftRW :: Integer -> Integer -> Integer -> Integer-signedShiftRW w ival by-  | by < 0    = shiftLW w ival (negate by)-  | otherwise =-     let by' = min w by in-     if by' > toInteger (maxBound :: Int) then-       panic "signedShiftRW" ["Shift amount too large", show by]-     else-       shiftR (signedValue w ival) (fromInteger by')--shiftLS :: Nat' -> TValue -> SeqMap Concrete -> Integer -> SeqMap Concrete-shiftLS w ety vs by-  | by < 0 = shiftRS w ety vs (negate by)--shiftLS w ety vs by = IndexSeqMap $ \i ->-  case w of-    Nat len-      | i+by < len -> lookupSeqMap vs (i+by)-      | i    < len -> zeroV Concrete ety-      | otherwise  -> evalPanic "shiftLS" ["Index out of bounds"]-    Inf            -> lookupSeqMap vs (i+by)--shiftRS :: Nat' -> TValue -> SeqMap Concrete -> Integer -> SeqMap Concrete-shiftRS w ety vs by-  | by < 0 = shiftLS w ety vs (negate by)--shiftRS w ety vs by = IndexSeqMap $ \i ->-  case w of-    Nat len-      | i >= by   -> lookupSeqMap vs (i-by)-      | i < len   -> zeroV Concrete ety-      | otherwise -> evalPanic "shiftLS" ["Index out of bounds"]-    Inf-      | i >= by   -> lookupSeqMap vs (i-by)-      | otherwise -> zeroV Concrete ety----- XXX integer doesn't implement rotateL, as there's no bit bound-rotateLW :: Integer -> Integer -> Integer -> Integer-rotateLW 0 i _  = i-rotateLW w i by = mask w $ (i `shiftL` b) .|. (i `shiftR` (fromInteger w - b))-  where b = fromInteger (by `mod` w)--rotateLS :: Nat' -> TValue -> SeqMap Concrete -> Integer -> SeqMap Concrete-rotateLS w _ vs by = IndexSeqMap $ \i ->-  case w of-    Nat len -> lookupSeqMap vs ((by + i) `mod` len)-    _ -> panic "Cryptol.Eval.Prim.rotateLS" [ "unexpected infinite sequence" ]---- XXX integer doesn't implement rotateR, as there's no bit bound-rotateRW :: Integer -> Integer -> Integer -> Integer-rotateRW 0 i _  = i-rotateRW w i by = mask w $ (i `shiftR` b) .|. (i `shiftL` (fromInteger w - b))-  where b = fromInteger (by `mod` w)--rotateRS :: Nat' -> TValue -> SeqMap Concrete -> Integer -> SeqMap Concrete-rotateRS w _ vs by = IndexSeqMap $ \i ->-  case w of-    Nat len -> lookupSeqMap vs ((len - by + i) `mod` len)-    _ -> panic "Cryptol.Eval.Prim.rotateRS" [ "unexpected infinite sequence" ]-- -- Sequence Primitives --------------------------------------------------------- -indexFront :: Nat' -> TValue -> SeqMap Concrete -> TValue -> BV -> Eval Value-indexFront _mblen _a vs _ix (bvVal -> ix) = lookupSeqMap vs ix--indexFront_bits :: Nat' -> TValue -> SeqMap Concrete -> TValue -> [Bool] -> Eval Value-indexFront_bits mblen a vs ix bs = indexFront mblen a vs ix =<< packWord Concrete bs--indexFront_int :: Nat' -> TValue -> SeqMap Concrete -> TValue -> Integer -> Eval Value+indexFront_int :: Nat' -> TValue -> SeqMap Concrete (GenValue Concrete) -> TValue -> Integer -> Eval Value indexFront_int _mblen _a vs _ix idx = lookupSeqMap vs idx -indexBack :: Nat' -> TValue -> SeqMap Concrete -> TValue -> BV -> Eval Value-indexBack mblen a vs ix (bvVal -> idx) = indexBack_int mblen a vs ix idx--indexBack_bits :: Nat' -> TValue -> SeqMap Concrete -> TValue -> [Bool] -> Eval Value-indexBack_bits mblen a vs ix bs = indexBack mblen a vs ix =<< packWord Concrete bs+indexFront_segs :: Nat' -> TValue -> SeqMap Concrete (GenValue Concrete) -> TValue -> Integer -> [IndexSegment Concrete] -> Eval Value+indexFront_segs _mblen _a vs _ix idx_bits segs = lookupSeqMap vs $! packSegments idx_bits segs -indexBack_int :: Nat' -> TValue -> SeqMap Concrete -> TValue -> Integer -> Eval Value-indexBack_int mblen _a vs _ix idx =-  case mblen of-    Nat len -> lookupSeqMap vs (len - idx - 1)-    Inf     -> evalPanic "indexBack" ["unexpected infinite sequence"]+packSegments :: Integer -> [IndexSegment Concrete] -> Integer+packSegments = loop 0+  where+  loop !val !n segs =+    case segs of+      [] -> val+      [WordIndexSegment (BV _ x)] -> val + x+      WordIndexSegment (BV xlen x) : bs ->+        let n' = n - xlen+         in loop (val + (x*2^n')) n' bs+      BitIndexSegment True : bs ->+        let n' = n - 1+         in loop (val + 2^n') n' bs+      BitIndexSegment False : bs ->+        let n' = n - 1+         in loop val n' bs  updateFront ::   Nat'               {- ^ length of the sequence -} ->   TValue             {- ^ type of values in the sequence -} ->-  SeqMap Concrete    {- ^ sequence to update -} ->+  SeqMap Concrete (GenValue Concrete) {- ^ sequence to update -} ->   Either Integer (WordValue Concrete) {- ^ index -} ->   Eval Value         {- ^ new value at index -} ->-  Eval (SeqMap Concrete)+  Eval (SeqMap Concrete (GenValue Concrete)) updateFront _len _eltTy vs (Left idx) val = do   return $ updateSeqMap vs idx val @@ -619,10 +494,10 @@ updateBack ::   Nat'               {- ^ length of the sequence -} ->   TValue             {- ^ type of values in the sequence -} ->-  SeqMap Concrete    {- ^ sequence to update -} ->+  SeqMap Concrete (GenValue Concrete) {- ^ sequence to update -} ->   Either Integer (WordValue Concrete) {- ^ index -} ->   Eval Value         {- ^ new value at index -} ->-  Eval (SeqMap Concrete)+  Eval (SeqMap Concrete (GenValue Concrete)) updateBack Inf _eltTy _vs _w _val =   evalPanic "Unexpected infinite sequence in updateEnd" [] updateBack (Nat n) _eltTy vs (Left idx) val = do
src/Cryptol/Eval/Env.hs view
@@ -6,8 +6,6 @@ -- Stability   :  provisional -- Portability :  portable -{-# LANGUAGE Safe #-}- {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE DeriveAnyClass #-}
src/Cryptol/Eval/Generic.hs view
@@ -19,25 +19,28 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE BangPatterns #-}+ {-# OPTIONS_GHC -fno-warn-orphans #-} module Cryptol.Eval.Generic where  import qualified Control.Exception as X+import Control.Monad(join) import Control.Monad.IO.Class (MonadIO(..))-import Control.Monad (join, unless) import System.Random.TF.Gen (seedTFGen) -import Data.Bits (testBit, (.&.), shiftR)+import Data.Bits ((.&.), shiftR) import Data.Maybe (fromMaybe) import qualified Data.Map.Strict as Map import Data.Map(Map) import Data.Ratio ((%))  import Cryptol.TypeCheck.AST-import Cryptol.TypeCheck.Solver.InfNat (Nat'(..),nMul,widthInteger)+import Cryptol.TypeCheck.Solver.InfNat (Nat'(..),nMul) import Cryptol.Backend import Cryptol.Backend.Concrete (Concrete(..)) import Cryptol.Backend.Monad( Eval, evalPanic, EvalError(..), Unsupported(..) )+import Cryptol.Backend.SeqMap+import Cryptol.Backend.WordValue import Cryptol.Testing.Random( randomValue )  import Cryptol.Eval.Prims@@ -63,7 +66,7 @@       | m == 0                   -> evalPanic "mkLit" ["0 modulus not allowed"]       | otherwise                -> VInteger <$> integerLit sym (i `mod` m)     TVFloat e p                  -> VFloat <$> fpLit sym e p (fromInteger i)-    TVSeq w TVBit                -> pure $ word sym w i+    TVSeq w TVBit                -> word sym w i     TVRational                   -> VRational <$> (intToRational sym =<< integerLit sym i)     _                            -> evalPanic "Cryptol.Eval.Prim.evalConst"                                     [ "Invalid type for number" ]@@ -217,14 +220,14 @@                   lw <- fromVWord sym "ringLeft" l                   rw <- fromVWord sym "ringRight" r                   stk <- sGetCallStack sym-                  return $ VWord w (WordVal <$> (sWithCallStack sym stk (opw w lw rw)))-      | otherwise -> VSeq w <$> (join (zipSeqMap sym (loop a) <$>+                  VWord w . wordVal <$> (sWithCallStack sym stk (opw w lw rw))+      | otherwise -> VSeq w <$> (join (zipSeqMap sym (loop a) (Nat w) <$>                                       (fromSeq "ringBinary left" l) <*>                                       (fromSeq "ringBinary right" r)))      TVStream a ->       -- streams-      VStream <$> (join (zipSeqMap sym (loop a) <$>+      VStream <$> (join (zipSeqMap sym (loop a) Inf <$>                              (fromSeq "ringBinary left" l) <*>                              (fromSeq "ringBinary right" r))) @@ -303,11 +306,11 @@       | isTBit a -> do               wx <- fromVWord sym "ringUnary" v               stk <- sGetCallStack sym-              return $ VWord w (WordVal <$> sWithCallStack sym stk (opw w wx))-      | otherwise -> VSeq w <$> (mapSeqMap sym (loop a) =<< fromSeq "ringUnary" v)+              VWord w . wordVal <$> sWithCallStack sym stk (opw w wx)+      | otherwise -> VSeq w <$> (mapSeqMap sym (loop a) (Nat w) =<< fromSeq "ringUnary" v)      TVStream a ->-      VStream <$> (mapSeqMap sym (loop a) =<< fromSeq "ringUnary" v)+      VStream <$> (mapSeqMap sym (loop a) Inf =<< fromSeq "ringUnary" v)      -- functions     TVFun _ ety ->@@ -372,14 +375,14 @@           -- words and finite sequences           | isTBit a ->              do stk <- sGetCallStack sym-                pure $ VWord w $ (WordVal <$> sWithCallStack sym stk (opw w))+                VWord w . wordVal <$> sWithCallStack sym stk (opw w)           | otherwise ->              do v <- sDelay sym (loop a)-                pure $ VSeq w $ IndexSeqMap \_i -> v+                pure $ VSeq w $ indexSeqMap \_i -> v          TVStream a ->              do v <- sDelay sym (loop a)-                pure $ VStream $ IndexSeqMap \_i -> v+                pure $ VStream $ indexSeqMap \_i -> v          TVFun _ b ->              do v <- sDelay sym (loop b)@@ -420,7 +423,7 @@           do wl <- fromVWord sym "integralBinary left" l              wr <- fromVWord sym "integralBinary right" r              stk <- sGetCallStack sym-             return $ VWord w (WordVal <$> sWithCallStack sym stk (opw w wl wr))+             VWord w . wordVal <$> sWithCallStack sym stk (opw w wl wr)      _ -> evalPanic "integralBinary" [show ty ++ " not int class `Integral`"] @@ -509,7 +512,7 @@                       intV sym onei aty                  | n > 0 ->-                    do ebits <- enumerateIntBits' sym n ei+                    do (_,ebits) <- enumerateIntBits' sym n ei                        computeExponent sym aty a ebits                  | otherwise -> raiseError sym NegativeExponent@@ -517,7 +520,7 @@               Nothing -> liftIO (X.throw (UnsupportedSymbolicOp "integer exponentiation"))            TVSeq _w el | isTBit el ->-            do ebits <- enumerateWordValue sym =<< fromWordVal "(^^)" e+            do ebits <- enumerateWordValue sym (fromWordVal "(^^)" e)                computeExponent sym aty a ebits            _ -> evalPanic "expV" [show ety ++ " not int class `Integral`"]@@ -695,7 +698,7 @@ lg2V sym =   PFinPoly \w ->   PWordFun \x ->-  PVal (VWord w (WordVal <$> wordLg2 sym x))+  PPrim (VWord w . wordVal <$> wordLg2 sym x)  {-# SPECIALIZE sdivV :: Concrete -> Prim Concrete #-} sdivV :: Backend sym => sym -> Prim sym@@ -703,7 +706,7 @@   PFinPoly \w ->   PWordFun \x ->   PWordFun \y ->-  PVal (VWord w (WordVal <$> wordSignedDiv sym x y))+  PPrim (VWord w . wordVal <$> wordSignedDiv sym x y)  {-# SPECIALIZE smodV :: Concrete -> Prim Concrete #-} smodV :: Backend sym => sym -> Prim sym@@ -711,8 +714,15 @@   PFinPoly \w ->   PWordFun \x ->   PWordFun \y ->-  PVal (VWord w (WordVal <$> wordSignedMod sym x y))+  PPrim (VWord w . wordVal <$> wordSignedMod sym x y) +{-# SPECIALIZE toSignedIntegerV :: Concrete -> Prim Concrete #-}+toSignedIntegerV :: Backend sym => sym -> Prim sym+toSignedIntegerV sym =+  PFinPoly \_w ->+  PWordFun \x ->+  PPrim (VInteger <$> wordToSignedInt sym x)+ -- Cmp -------------------------------------------------------------------------  {-# SPECIALIZE cmpValue ::@@ -915,14 +925,14 @@    -- sequences   TVSeq w ety-      | isTBit ety -> pure $ word sym w 0+      | isTBit ety -> word sym w 0       | otherwise  ->            do z <- sDelay sym (zeroV sym ety)-              pure $ VSeq w (IndexSeqMap \_i -> z)+              pure $ VSeq w (indexSeqMap \_i -> z)    TVStream ety ->      do z <- sDelay sym (zeroV sym ety)-        pure $ VStream (IndexSeqMap \_i -> z)+        pure $ VStream (indexSeqMap \_i -> z)    -- functions   TVFun _ bty ->@@ -943,52 +953,13 @@    TVNewtype {} -> evalPanic "zeroV" [ "Newtype not in `Zero`" ] ---  | otherwise = evalPanic "zeroV" ["invalid type for zero"] -{-# INLINE joinWordVal #-}-joinWordVal :: Backend sym => sym -> WordValue sym -> WordValue sym -> SEval sym (WordValue sym)-joinWordVal sym (WordVal w1) (WordVal w2)-  | wordLen sym w1 + wordLen sym w2 < largeBitSize-  = WordVal <$> joinWord sym w1 w2-joinWordVal sym w1 w2-  = pure $ LargeBitsVal (n1+n2) (concatSeqMap n1 (asBitsMap sym w1) (asBitsMap sym w2))- where n1 = wordValueSize sym w1-       n2 = wordValueSize sym w2---{-# SPECIALIZE joinWords ::-  Concrete ->-  Integer ->-  Integer ->-  SeqMap Concrete ->-  SEval Concrete (GenValue Concrete)-  #-}-joinWords :: forall sym.-  Backend sym =>-  sym ->-  Integer ->-  Integer ->-  SeqMap sym ->-  SEval sym (GenValue sym)-joinWords sym nParts nEach xs =-  loop (WordVal <$> wordLit sym 0 0) (enumerateSeqMap nParts xs)-- where- loop :: SEval sym (WordValue sym) -> [SEval sym (GenValue sym)] -> SEval sym (GenValue sym)- loop !wv [] =-    VWord (nParts * nEach) <$> sDelay sym wv- loop !wv (w : ws) =-    w >>= \case-      VWord _ w' ->-        loop (join (joinWordVal sym <$> wv <*> w')) ws-      _ -> evalPanic "joinWords: expected word value" []- {-# SPECIALIZE joinSeq ::   Concrete ->   Nat' ->   Integer ->   TValue ->-  SeqMap Concrete ->+  SEval Concrete (SeqMap Concrete (GenValue Concrete)) ->   SEval Concrete (GenValue Concrete)   #-} joinSeq ::@@ -997,35 +968,32 @@   Nat' ->   Integer ->   TValue ->-  SeqMap sym ->+  SEval sym (SeqMap sym (GenValue sym)) ->   SEval sym (GenValue sym)  -- Special case for 0 length inner sequences.-joinSeq sym _parts 0 a _xs+joinSeq sym _parts 0 a _val   = zeroV sym (TVSeq 0 a)  -- finite sequence of words-joinSeq sym (Nat parts) each TVBit xs-  | parts * each < largeBitSize-  = joinWords sym parts each xs-  | otherwise-  = do let zs = IndexSeqMap $ \i ->-                  do let (q,r) = divMod i each-                     ys <- fromWordVal "join seq" =<< lookupSeqMap xs q-                     VBit <$> indexWordValue sym ys r-       return $ VWord (parts * each) $ pure $ LargeBitsVal (parts * each) zs+joinSeq sym (Nat parts) each TVBit val+  = do w <- delayWordValue sym (parts*each)+              (joinWords sym parts each . fmap (fromWordVal "joinV") =<< val)+       pure (VWord (parts*each) w)  -- infinite sequence of words-joinSeq sym Inf each TVBit xs-  = return $ VStream $ IndexSeqMap $ \i ->+joinSeq sym Inf each TVBit val+  = return $ VStream $ indexSeqMap $ \i ->       do let (q,r) = divMod i each-         ys <- fromWordVal "join seq" =<< lookupSeqMap xs q+         xs <- val+         ys <- fromWordVal "join seq" <$> lookupSeqMap xs q          VBit <$> indexWordValue sym ys r  -- finite or infinite sequence of non-words-joinSeq _sym parts each _a xs-  = return $ vSeq $ IndexSeqMap $ \i -> do+joinSeq _sym parts each _a val+  = return $ vSeq $ indexSeqMap $ \i -> do       let (q,r) = divMod i each+      xs <- val       ys <- fromSeq "join seq" =<< lookupSeqMap xs q       lookupSeqMap ys r   where@@ -1044,146 +1012,115 @@   Nat' ->   Integer ->   TValue ->-  GenValue sym ->+  SEval sym (GenValue sym) ->   SEval sym (GenValue sym)-joinV sym parts each a val = joinSeq sym parts each a =<< fromSeq "joinV" val---{-# INLINE splitWordVal #-}--splitWordVal ::-  Backend sym =>-  sym ->-  Integer ->-  Integer ->-  WordValue sym ->-  SEval sym (WordValue sym, WordValue sym)-splitWordVal sym leftWidth rightWidth (WordVal w) =-  do (lw, rw) <- splitWord sym leftWidth rightWidth w-     pure (WordVal lw, WordVal rw)-splitWordVal _ leftWidth rightWidth (LargeBitsVal _n xs) =-  let (lxs, rxs) = splitSeqMap leftWidth xs-   in pure (LargeBitsVal leftWidth lxs, LargeBitsVal rightWidth rxs)+joinV sym parts each a val =+  do xs <- sDelay sym (fromSeq "joinV" =<< val)+     joinSeq sym parts each a xs -{-# INLINE splitAtV #-}-splitAtV ::+{-# INLINE takeV #-}+takeV ::   Backend sym =>   sym ->   Nat' ->   Nat' ->   TValue ->-  GenValue sym ->+  SEval sym (GenValue sym) ->   SEval sym (GenValue sym)-splitAtV sym front back a val =-  case back of--    Nat rightWidth | aBit -> do-          ws <- sDelay sym (splitWordVal sym leftWidth rightWidth =<< fromWordVal "splitAtV" val)-          return $ VTuple-                   [ VWord leftWidth  . pure . fst <$> ws-                   , VWord rightWidth . pure . snd <$> ws-                   ]--    Inf | aBit -> do-       vs <- sDelay sym (fromSeq "splitAtV" val)-       ls <- sDelay sym (fst . splitSeqMap leftWidth <$> vs)-       rs <- sDelay sym (snd . splitSeqMap leftWidth <$> vs)-       return $ VTuple [ return $ VWord leftWidth (LargeBitsVal leftWidth <$> ls)-                       , VStream <$> rs-                       ]--    _ -> do-       vs <- sDelay sym (fromSeq "splitAtV" val)-       ls <- sDelay sym (fst . splitSeqMap leftWidth <$> vs)-       rs <- sDelay sym (snd . splitSeqMap leftWidth <$> vs)-       return $ VTuple [ VSeq leftWidth <$> ls-                       , mkSeq back a <$> rs-                       ]--  where-  aBit = isTBit a--  leftWidth = case front of-    Nat n -> n-    _     -> evalPanic "splitAtV" ["invalid `front` len"]+takeV sym front back a val =+  case front of+    Inf -> val+    Nat front' ->+      case back of+        Nat back' | isTBit a ->+          do w <- delayWordValue sym front' (takeWordVal sym front' back' =<< (fromWordVal "takeV" <$> val))+             pure (VWord front' w) +        Inf | isTBit a ->+          do w <- delayWordValue sym front' (bitmapWordVal sym front' . fmap fromVBit =<< (fromSeq "takeV" =<< val))+             pure (VWord front' w) -{-# INLINE extractWordVal #-}+        _ ->+          do xs <- delaySeqMap sym (fromSeq "takeV" =<< val)+             pure (VSeq front' xs) --- | Extract a subsequence of bits from a @WordValue@.---   The first integer argument is the number of bits in the---   resulting word.  The second integer argument is the---   number of less-significant digits to discard.  Stated another---   way, the operation `extractWordVal n i w` is equivalent to---   first shifting `w` right by `i` bits, and then truncating to---   `n` bits.-extractWordVal ::+{-# INLINE dropV #-}+dropV ::   Backend sym =>   sym ->   Integer ->-  Integer ->-  WordValue sym ->-  SEval sym (WordValue sym)-extractWordVal sym len start (WordVal w) =-   WordVal <$> extractWord sym len start w-extractWordVal _ len start (LargeBitsVal n xs) =-   let xs' = dropSeqMap (n - start - len) xs-    in pure $ LargeBitsVal len xs'+  Nat' ->+  TValue ->+  SEval sym (GenValue sym) ->+  SEval sym (GenValue sym)+dropV sym front back a val =+  case back of+    Nat back' | isTBit a ->+      do w <- delayWordValue sym back' (dropWordVal sym front back' =<< (fromWordVal "dropV" <$> val))+         pure (VWord back' w) -{-# INLINE ecSplitV #-}+    _ ->+      do xs <- delaySeqMap sym (dropSeqMap front <$> (fromSeq "dropV" =<< val))+         mkSeq sym back a xs ++{-# INLINE splitV #-}+ -- | Split implementation.-ecSplitV :: Backend sym => sym -> Prim sym-ecSplitV sym =-  PNumPoly \parts ->-  PNumPoly \each ->-  PTyPoly  \a ->-  PFun     \val ->-  PPrim+splitV :: Backend sym =>+  sym ->+  Nat' ->+  Integer ->+  TValue ->+  SEval sym (GenValue sym) ->+  SEval sym (GenValue sym)+splitV sym parts each a val =     case (parts, each) of-       (Nat p, Nat e) | isTBit a -> do-          ~(VWord _ val') <- val-          return $ VSeq p $ IndexSeqMap $ \i ->-            pure $ VWord e (extractWordVal sym e ((p-i-1)*e) =<< val')-       (Inf, Nat e) | isTBit a -> do-          val' <- sDelay sym (fromSeq "ecSplitV" =<< val)-          return $ VStream $ IndexSeqMap $ \i ->-            return $ VWord e $ return $ LargeBitsVal e $ IndexSeqMap $ \j ->+       (Nat p, e) | isTBit a -> do+          val' <- sDelay sym (fromWordVal "splitV" <$> val)+          return $ VSeq p $ indexSeqMap $ \i ->+            VWord e <$> (extractWordVal sym e ((p-i-1)*e) =<< val')+       (Inf, e) | isTBit a -> do+          val' <- sDelay sym (fromSeq "splitV" =<< val)+          return $ VStream $ indexSeqMap $ \i ->+            VWord e <$> bitmapWordVal sym e (indexSeqMap $ \j ->               let idx = i*e + toInteger j                in idx `seq` do                       xs <- val'-                      lookupSeqMap xs idx-       (Nat p, Nat e) -> do-          val' <- sDelay sym (fromSeq "ecSplitV" =<< val)-          return $ VSeq p $ IndexSeqMap $ \i ->-            return $ VSeq e $ IndexSeqMap $ \j -> do+                      fromVBit <$> lookupSeqMap xs idx)+       (Nat p, e) -> do+          val' <- sDelay sym (fromSeq "splitV" =<< val)+          return $ VSeq p $ indexSeqMap $ \i ->+            return $ VSeq e $ indexSeqMap $ \j -> do               xs <- val'               lookupSeqMap xs (e * i + j)-       (Inf  , Nat e) -> do-          val' <- sDelay sym (fromSeq "ecSplitV" =<< val)-          return $ VStream $ IndexSeqMap $ \i ->-            return $ VSeq e $ IndexSeqMap $ \j -> do+       (Inf  , e) -> do+          val' <- sDelay sym (fromSeq "splitV" =<< val)+          return $ VStream $ indexSeqMap $ \i ->+            return $ VSeq e $ indexSeqMap $ \j -> do               xs <- val'               lookupSeqMap xs (e * i + j)-       _              -> evalPanic "splitV" ["invalid type arguments to split"] + {-# INLINE reverseV #-}  reverseV :: forall sym.   Backend sym =>   sym ->-  GenValue sym ->+  Integer ->+  TValue ->+  SEval sym (GenValue sym) ->   SEval sym (GenValue sym)-reverseV _ (VSeq n xs) =-  return $ VSeq n $ reverseSeqMap n xs-reverseV sym (VWord n x) = return (VWord n (revword <$> x))- where- revword wv =-   let m = wordValueSize sym wv in-   LargeBitsVal m $ reverseSeqMap m $ asBitsMap sym wv-reverseV _ _ =-  evalPanic "reverseV" ["Not a finite sequence"] +reverseV sym n TVBit val =+  do w <- delayWordValue sym n (reverseWordVal sym . fromWordVal "reverseV" =<< val)+     pure (VWord n w)++reverseV sym n _a val =+  do xs <- delaySeqMap sym (reverseSeqMap n <$> (fromSeq "reverseV" =<< val))+     pure (VSeq n xs)++ {-# INLINE transposeV #-}  transposeV ::@@ -1196,28 +1133,28 @@   SEval sym (GenValue sym) transposeV sym a b c xs   | isTBit c, Nat na <- a = -- Fin a => [a][b]Bit -> [b][a]Bit-      return $ bseq $ IndexSeqMap $ \bi ->-        return $ VWord na $ return $ LargeBitsVal na $ IndexSeqMap $ \ai ->+      return $ bseq $ indexSeqMap $ \bi ->+        VWord na <$> bitmapWordVal sym na (indexSeqMap $ \ai ->          do xs' <- fromSeq "transposeV" xs             ys <- lookupSeqMap xs' ai             case ys of-              VStream ys' -> lookupSeqMap ys' bi-              VWord _ wv  -> VBit <$> (flip (indexWordValue sym) bi =<< wv)-              _ -> evalPanic "transpose" ["expected sequence of bits"]+              VStream ys' -> fromVBit <$> lookupSeqMap ys' bi+              VWord _ wv  -> indexWordValue sym wv bi+              _ -> evalPanic "transpose" ["expected sequence of bits"])    | isTBit c, Inf <- a = -- [inf][b]Bit -> [b][inf]Bit-      return $ bseq $ IndexSeqMap $ \bi ->-        return $ VStream $ IndexSeqMap $ \ai ->+      return $ bseq $ indexSeqMap $ \bi ->+        return $ VStream $ indexSeqMap $ \ai ->          do xs' <- fromSeq "transposeV" xs             ys  <- lookupSeqMap xs' ai             case ys of               VStream ys' -> lookupSeqMap ys' bi-              VWord _ wv  -> VBit <$> (flip (indexWordValue sym) bi =<< wv)+              VWord _ wv  -> VBit <$> indexWordValue sym wv bi               _ -> evalPanic "transpose" ["expected sequence of bits"]    | otherwise = -- [a][b]c -> [b][a]c-      return $ bseq $ IndexSeqMap $ \bi ->-        return $ aseq $ IndexSeqMap $ \ai -> do+      return $ bseq $ indexSeqMap $ \bi ->+        return $ aseq $ indexSeqMap $ \ai -> do           xs' <- fromSeq "transposeV 1" xs           ys  <- fromSeq "transposeV 2" =<< lookupSeqMap xs' ai           z   <- lookupSeqMap ys bi@@ -1239,54 +1176,52 @@ ccatV ::   Backend sym =>   sym ->-  Nat' ->+  Integer ->   Nat' ->   TValue ->-  (GenValue sym) ->-  (GenValue sym) ->+  SEval sym (GenValue sym) ->+  SEval sym (GenValue sym) ->   SEval sym (GenValue sym) -ccatV sym _front _back _elty (VWord m l) (VWord n r) =-  return $ VWord (m+n) (join (joinWordVal sym <$> l <*> r))+-- Finite bitvectors+ccatV sym front (Nat back) TVBit l r =+  do ml <- isReady sym l+     mr <- isReady sym r+     case (ml, mr) of+       (Just l', Just r') ->+         VWord (front+back) <$>+           joinWordVal sym (fromWordVal "ccatV left" l') (fromWordVal "ccatV right" r')+       _ ->+         VWord (front+back) <$> delayWordValue sym (front+back)+                (do l' <- fromWordVal "ccatV left"  <$> l+                    r' <- fromWordVal "ccatV right" <$> r+                    joinWordVal sym l' r') -ccatV sym _front _back _elty (VWord m l) (VStream r) = do-  l' <- sDelay sym l-  return $ VStream $ IndexSeqMap $ \i ->-    if i < m then-      VBit <$> (flip (indexWordValue sym) i =<< l')-    else-      lookupSeqMap r (i-m)+-- Infinite bitstream+ccatV sym front Inf TVBit l r =+  do l'' <- sDelay sym (asBitsMap sym  . fromWordVal "ccatV left" <$> l)+     r'' <- sDelay sym (fromSeq "ccatV right" =<< r)+     pure $ VStream $ indexSeqMap $ \i ->+      if i < front then do+        ls <- l''+        VBit <$> lookupSeqMap ls i+      else do+        rs <- r''+        lookupSeqMap rs (i-front) -ccatV sym front back elty l r = do-       l'' <- sDelay sym (fromSeq "ccatV left" l)-       r'' <- sDelay sym (fromSeq "ccatV right" r)-       let Nat n = front-       mkSeq (evalTF TCAdd [front,back]) elty <$> return (IndexSeqMap $ \i ->-        if i < n then do-         ls <- l''-         lookupSeqMap ls i-        else do-         rs <- r''-         lookupSeqMap rs (i-n))+-- streams/sequences of nonbits+ccatV sym front back elty l r =+  do l'' <- sDelay sym (fromSeq "ccatV left" =<< l)+     r'' <- sDelay sym (fromSeq "ccatV right" =<< r)+     mkSeq sym (evalTF TCAdd [Nat front,back]) elty $ indexSeqMap $ \i ->+      if i < front then do+        ls <- l''+        lookupSeqMap ls i+      else do+        rs <- r''+        lookupSeqMap rs (i-front) -{-# INLINE wordValLogicOp #-} -wordValLogicOp ::-  Backend sym =>-  sym ->-  (SBit sym -> SBit sym -> SEval sym (SBit sym)) ->-  (SWord sym -> SWord sym -> SEval sym (SWord sym)) ->-  WordValue sym ->-  WordValue sym ->-  SEval sym (WordValue sym)-wordValLogicOp _sym _ wop (WordVal w1) (WordVal w2) = WordVal <$> wop w1 w2--wordValLogicOp sym bop _ w1 w2 = LargeBitsVal (wordValueSize sym w1) <$> zs-     where zs = memoMap sym $ IndexSeqMap $ \i -> join (op <$> (lookupSeqMap xs i) <*> (lookupSeqMap ys i))-           xs = asBitsMap sym w1-           ys = asBitsMap sym w2-           op x y = VBit <$> (bop (fromVBit x) (fromVBit y))- {-# SPECIALIZE logicBinary ::   Concrete ->   (SBit Concrete -> SBit Concrete -> SEval Concrete (SBit Concrete)) ->@@ -1325,20 +1260,19 @@     TVSeq w aty          -- words          | isTBit aty-              -> do v <- sDelay sym $ join-                            (wordValLogicOp sym opb opw <$>-                                    fromWordVal "logicBinary l" l <*>-                                    fromWordVal "logicBinary r" r)-                    return $ VWord w v+              -> VWord w <$> delayWordValue sym w+                               (wordValLogicOp sym opb opw+                                    (fromWordVal "logicBinary l" l)+                                    (fromWordVal "logicBinary r" r))           -- finite sequences          | otherwise -> VSeq w <$>-                           (join (zipSeqMap sym (loop aty) <$>+                           (join (zipSeqMap sym (loop aty) (Nat w) <$>                                     (fromSeq "logicBinary left" l)                                     <*> (fromSeq "logicBinary right" r)))      TVStream aty ->-        VStream <$> (join (zipSeqMap sym (loop aty) <$>+        VStream <$> (join (zipSeqMap sym (loop aty) Inf <$>                           (fromSeq "logicBinary left" l) <*>                           (fromSeq "logicBinary right" r))) @@ -1362,18 +1296,6 @@     TVNewtype {} -> evalPanic "logicBinary"                         [ "Newtype not in `Logic`" ] -{-# INLINE wordValUnaryOp #-}-wordValUnaryOp ::-  Backend sym =>-  sym ->-  (SBit sym -> SEval sym (SBit sym)) ->-  (SWord sym -> SEval sym (SWord sym)) ->-  WordValue sym ->-  SEval sym (WordValue sym)-wordValUnaryOp _ _ wop (WordVal w)  = WordVal <$> (wop w)-wordValUnaryOp sym bop _ (LargeBitsVal n xs) = LargeBitsVal n <$> mapSeqMap sym f xs-  where f x = VBit <$> (bop (fromVBit x))- {-# SPECIALIZE logicUnary ::   Concrete ->   (SBit Concrete -> SEval Concrete (SBit Concrete)) ->@@ -1405,16 +1327,15 @@     TVSeq w ety          -- words          | isTBit ety-              -> do v <- sDelay sym (wordValUnaryOp sym opb opw =<< fromWordVal "logicUnary" val)-                    return $ VWord w v+              -> VWord w <$> delayWordValue sym w (wordValUnaryOp sym opb opw (fromWordVal "logicUnary" val))           -- finite sequences          | otherwise-              -> VSeq w <$> (mapSeqMap sym (loop ety) =<< fromSeq "logicUnary" val)+              -> VSeq w <$> (mapSeqMap sym (loop ety) (Nat w) =<< fromSeq "logicUnary" val)           -- streams     TVStream ety ->-         VStream <$> (mapSeqMap sym (loop ety) =<< fromSeq "logicUnary" val)+         VStream <$> (mapSeqMap sym (loop ety) Inf =<< fromSeq "logicUnary" val)      TVTuple etys ->       do as <- mapM (sDelay sym) (fromVTuple val)@@ -1433,32 +1354,7 @@      TVNewtype {} -> evalPanic "logicUnary" [ "Newtype not in `Logic`" ] -{-# SPECIALIZE bitsValueLessThan ::-  Concrete ->-  Integer ->-  [SBit Concrete] ->-  Integer ->-  SEval Concrete (SBit Concrete)-  #-}-bitsValueLessThan ::-  Backend sym =>-  sym ->-  Integer {- ^ bit-width -} ->-  [SBit sym] {- ^ big-endian list of index bits -} ->-  Integer {- ^ Upper bound to test against -} ->-  SEval sym (SBit sym)-bitsValueLessThan sym _w [] _n = pure $ bitLit sym False-bitsValueLessThan sym w (b:bs) n-  | nbit =-      do notb <- bitComplement sym b-         bitOr sym notb =<< bitsValueLessThan sym (w-1) bs n-  | otherwise =-      do notb <- bitComplement sym b-         bitAnd sym notb =<< bitsValueLessThan sym (w-1) bs n- where- nbit = testBit n (fromInteger (w-1)) - {-# INLINE assertIndexInBounds #-} assertIndexInBounds ::   Backend sym =>@@ -1486,30 +1382,8 @@  -- Can't index out of bounds for a sequence that is -- longer than the expressible index values-assertIndexInBounds sym (Nat n) (Right idx)-  | n >= 2^(wordValueSize sym idx)-  = return ()---- If the index is concrete, test it directly-assertIndexInBounds sym (Nat n) (Right (WordVal idx))-  | Just (_w,i) <- wordAsLit sym idx-  = unless (i < n) (raiseError sym (InvalidIndex (Just i)))---- If the index is a packed word, test that it--- is less than the concrete value of n, which--- fits into w bits because of the above test.-assertIndexInBounds sym (Nat n) (Right (WordVal idx)) =-  do n' <- wordLit sym (wordLen sym idx) n-     p <- wordLessThan sym idx n'-     assertSideCondition sym p (InvalidIndex Nothing)---- If the index is an unpacked word, force all the bits--- and compute the unsigned less-than test directly.-assertIndexInBounds sym (Nat n) (Right (LargeBitsVal w bits)) =-  do bitsList <- traverse (fromVBit <$>) (enumerateSeqMap w bits)-     p <- bitsValueLessThan sym w bitsList n-     assertSideCondition sym p (InvalidIndex Nothing)-+assertIndexInBounds sym (Nat n) (Right idx) =+  assertWordValueInBounds sym n idx  -- | Indexing operations. @@ -1517,11 +1391,11 @@ indexPrim ::   Backend sym =>   sym ->-  (Nat' -> TValue -> SeqMap sym -> TValue -> SInteger sym -> SEval sym (GenValue sym)) ->-  (Nat' -> TValue -> SeqMap sym -> TValue -> [SBit sym] -> SEval sym (GenValue sym)) ->-  (Nat' -> TValue -> SeqMap sym -> TValue -> SWord sym -> SEval sym (GenValue sym)) ->+  IndexDirection ->+  (Nat' -> TValue -> SeqMap sym (GenValue sym) -> TValue -> SInteger sym -> SEval sym (GenValue sym)) ->+  (Nat' -> TValue -> SeqMap sym (GenValue sym) -> TValue -> Integer -> [IndexSegment sym] -> SEval sym (GenValue sym)) ->   Prim sym-indexPrim sym int_op bits_op word_op =+indexPrim sym dir int_op word_op =   PNumPoly \len ->   PTyPoly  \eltTy ->   PTyPoly  \ix ->@@ -1529,16 +1403,19 @@   PFun     \idx ->   PPrim    do vs <- xs >>= \case-               VWord _ w  -> w >>= \w' -> return $ IndexSeqMap (\i -> VBit <$> indexWordValue sym w' i)+               VWord _ w  -> return $ indexSeqMap (\i -> VBit <$> indexWordValue sym w i)                VSeq _ vs  -> return vs                VStream vs -> return vs                _ -> evalPanic "Expected sequence value" ["indexPrim"]-      idx' <- asIndex sym "index" ix =<< idx+      let vs' = case (len, dir) of+                  (_    , IndexForward)  -> vs+                  (Nat n, IndexBackward) -> reverseSeqMap n vs+                  (Inf  , IndexBackward) -> evalPanic "Expected finite sequence" ["!"]+      idx' <- asIndex sym "index" ix <$> idx       assertIndexInBounds sym len idx'       case idx' of-        Left i                    -> int_op  len eltTy vs ix i-        Right (WordVal w')        -> word_op len eltTy vs ix w'-        Right (LargeBitsVal m bs) -> bits_op len eltTy vs ix =<< traverse (fromVBit <$>) (enumerateSeqMap m bs)+        Left i  -> int_op  len eltTy vs' ix i+        Right w -> word_op len eltTy vs' ix (wordValueSize sym w) =<< enumerateIndexSegments sym w  {-# INLINE updatePrim #-} @@ -1546,7 +1423,7 @@   Backend sym =>   sym ->   (Nat' -> TValue -> WordValue sym -> Either (SInteger sym) (WordValue sym) -> SEval sym (GenValue sym) -> SEval sym (WordValue sym)) ->-  (Nat' -> TValue -> SeqMap sym    -> Either (SInteger sym) (WordValue sym) -> SEval sym (GenValue sym) -> SEval sym (SeqMap sym)) ->+  (Nat' -> TValue -> SeqMap sym (GenValue sym) -> Either (SInteger sym) (WordValue sym) -> SEval sym (GenValue sym) -> SEval sym (SeqMap sym (GenValue sym))) ->   Prim sym updatePrim sym updateWord updateSeq =   PNumPoly \len ->@@ -1556,17 +1433,17 @@   PFun     \idx ->   PFun     \val ->   PPrim-   do idx' <- asIndex sym "update" ix =<< idx+   do idx' <- asIndex sym "update" ix <$> idx       assertIndexInBounds sym len idx'-      xs >>= \case-        VWord l w  -> do w' <- sDelay sym w-                         return $ VWord l (w' >>= \w'' -> updateWord len eltTy w'' idx' val)-        VSeq l vs  -> VSeq l  <$> updateSeq len eltTy vs idx' val-        VStream vs -> VStream <$> updateSeq len eltTy vs idx' val-        _ -> evalPanic "Expected sequence value" ["updatePrim"]+      case (len, eltTy) of+        (Nat n, TVBit) -> VWord n <$> delayWordValue sym n+                             (do w <- fromWordVal "updatePrim" <$> xs; updateWord len eltTy w idx' val)+        (Nat n, _    ) -> VSeq n <$> delaySeqMap sym+                             (do vs <- fromSeq "updatePrim" =<< xs; updateSeq len eltTy vs idx' val)+        (Inf  , _    ) -> VStream <$> delaySeqMap sym+                             (do vs <- fromSeq "updatePrim" =<< xs; updateSeq len eltTy vs idx' val)  {-# INLINE fromToV #-}- -- @[ 0 .. 10 ]@ fromToV :: Backend sym => sym -> Prim sym fromToV sym =@@ -1578,26 +1455,10 @@     case (first, lst) of       (Nat first', Nat lst') ->         let len = 1 + (lst' - first')-        in VSeq len $ IndexSeqMap $ \i -> f (first' + i)+        in VSeq len $ indexSeqMap $ \i -> f (first' + i)       _ -> evalPanic "fromToV" ["invalid arguments"] -{-# INLINE fromToLessThanV #-}---- @[ 0 .. <10 ]@-fromToLessThanV :: Backend sym => sym -> Prim sym-fromToLessThanV sym =-  PFinPoly \first ->-  PNumPoly \bound ->-  PTyPoly  \ty ->-  PVal-    let !f = mkLit sym ty-        ss = IndexSeqMap $ \i -> f (first + i)-    in case bound of-         Inf        -> VStream ss-         Nat bound' -> VSeq (bound' - first) ss- {-# INLINE fromThenToV #-}- -- @[ 0, 1 .. 10 ]@ fromThenToV :: Backend sym => sym -> Prim sym fromThenToV sym =@@ -1611,9 +1472,78 @@     case (first, next, lst, len) of       (Nat first', Nat next', Nat _lst', Nat len') ->         let diff = next' - first'-        in VSeq len' $ IndexSeqMap $ \i -> f (first' + i*diff)+        in VSeq len' $ indexSeqMap $ \i -> f (first' + i*diff)       _ -> evalPanic "fromThenToV" ["invalid arguments"] +{-# INLINE fromToLessThanV #-}+-- @[ 0 .. <10 ]@+fromToLessThanV :: Backend sym => sym -> Prim sym+fromToLessThanV sym =+  PFinPoly \first ->+  PNumPoly \bound ->+  PTyPoly  \ty ->+  PVal+    let !f = mkLit sym ty+        ss = indexSeqMap $ \i -> f (first + i)+    in case bound of+         Inf        -> VStream ss+         Nat bound' -> VSeq (bound' - first) ss++{-# INLINE fromToByV #-}+-- @[ 0 .. 10 by 2 ]@+fromToByV :: Backend sym => sym -> Prim sym+fromToByV sym =+  PFinPoly \first ->+  PFinPoly \lst ->+  PFinPoly \stride ->+  PTyPoly  \ty ->+  PVal+    let !f = mkLit sym ty+        ss = indexSeqMap $ \i -> f (first + i*stride)+     in VSeq (1 + ((lst - first) `div` stride)) ss++{-# INLINE fromToByLessThanV #-}+-- @[ 0 .. <10 by 2 ]@+fromToByLessThanV :: Backend sym => sym -> Prim sym+fromToByLessThanV sym =+  PFinPoly \first ->+  PNumPoly \bound ->+  PFinPoly \stride ->+  PTyPoly  \ty ->+  PVal+    let !f = mkLit sym ty+        ss = indexSeqMap $ \i -> f (first + i*stride)+     in case bound of+          Inf -> VStream ss+          Nat bound' -> VSeq ((bound' - first + stride - 1) `div` stride) ss+++{-# INLINE fromToDownByV #-}+-- @[ 10 .. 0 down by 2 ]@+fromToDownByV :: Backend sym => sym -> Prim sym+fromToDownByV sym =+  PFinPoly \first ->+  PFinPoly \lst ->+  PFinPoly \stride ->+  PTyPoly  \ty ->+  PVal+    let !f = mkLit sym ty+        ss = indexSeqMap $ \i -> f (first - i*stride)+     in VSeq (1 + ((first - lst) `div` stride)) ss++{-# INLINE fromToDownByGreaterThanV #-}+-- @[ 10 .. >0 down by 2 ]@+fromToDownByGreaterThanV :: Backend sym => sym -> Prim sym+fromToDownByGreaterThanV sym =+  PFinPoly \first ->+  PFinPoly \bound ->+  PFinPoly \stride ->+  PTyPoly  \ty ->+  PVal+    let !f = mkLit sym ty+        ss = indexSeqMap $ \i -> f (first - i*stride)+     in VSeq ((first - bound + stride - 1) `div` stride) ss+ {-# INLINE infFromV #-} infFromV :: Backend sym => sym -> Prim sym infFromV sym =@@ -1621,7 +1551,7 @@   PFun    \x ->   PPrim     do mx <- sDelay sym x-       return $ VStream $ IndexSeqMap $ \i ->+       return $ VStream $ indexSeqMap $ \i ->          do x' <- mx             i' <- integerLit sym i             addV sym ty x' =<< intV sym i' ty@@ -1638,37 +1568,14 @@                    y <- next                    d <- subV sym ty y x                    pure (x,d))-       return $ VStream $ IndexSeqMap $ \i -> do+       return $ VStream $ indexSeqMap $ \i -> do          (x,d) <- mxd          i' <- integerLit sym i          addV sym ty x =<< mulV sym ty d =<< intV sym i' ty  -- Shifting --------------------------------------------------- -barrelShifter :: Backend sym =>-  sym ->-  (SeqMap sym -> Integer -> SEval sym (SeqMap sym))-     {- ^ concrete shifting operation -} ->-  SeqMap sym  {- ^ initial value -} ->-  [SBit sym]  {- ^ bits of shift amount, in big-endian order -} ->-  SEval sym (SeqMap sym)-barrelShifter sym shift_op = go-  where-  go x [] = return x -  go x (b:bs)-    | Just True <- bitAsLit sym b-    = do x_shft <- shift_op x (2 ^ length bs)-         go x_shft bs--    | Just False <- bitAsLit sym b-    = do go x bs--    | otherwise-    = do x_shft <- shift_op x (2 ^ length bs)-         x' <- memoMap sym (mergeSeqMap sym b x_shft x)-         go x' bs- {-# INLINE shiftLeftReindex #-} shiftLeftReindex :: Nat' -> Integer -> Integer -> Maybe Integer shiftLeftReindex sz i shft =@@ -1695,30 +1602,8 @@      Inf -> evalPanic "cannot rotate infinite sequence" []      Nat n -> Just ((i+n-shft) `mod` n) --- | Compute the list of bits in an integer in big-endian order.---   Fails if neither the sequence length nor the type value---   provide an upper bound for the integer.-enumerateIntBits :: Backend sym =>-  sym ->-  Nat' ->-  TValue ->-  SInteger sym ->-  SEval sym [SBit sym]-enumerateIntBits sym (Nat n) _ idx = enumerateIntBits' sym n idx-enumerateIntBits _sym Inf _ _ = liftIO (X.throw (UnsupportedSymbolicOp "unbounded integer shifting")) --- | Compute the list of bits in an integer in big-endian order.---   The integer argument is a concrete upper bound for---   the symbolic integer.-enumerateIntBits' :: Backend sym =>-  sym ->-  Integer ->-  SInteger sym ->-  SEval sym [SBit sym]-enumerateIntBits' sym n idx =-  do w <- wordFromInt sym (widthInteger n) idx-     unpackWord sym w-+{-# INLINE logicShift #-} -- | Generic implementation of shifting. --   Uses the provided word-level operation to perform the shift, when --   possible.  Otherwise falls back on a barrel shifter that uses@@ -1749,16 +1634,19 @@   PFun     \y ->   PPrim     do xs' <- xs-       y' <- asIndex sym "shift" ix =<< y+       y' <- asIndex sym "shift" ix <$> y        case y' of          Left int_idx ->            do pneg <- intLessThan sym int_idx =<< integerLit sym 0               iteValue sym pneg-                (intShifter sym nm wopNeg reindexNeg m ix a xs' =<< shrinkRange sym m ix =<< intNegate sym int_idx)-                (intShifter sym nm wopPos reindexPos m ix a xs' =<< shrinkRange sym m ix int_idx)+                (intShifter sym nm wopNeg reindexNeg m a xs' =<< shrinkRange sym m ix =<< intNegate sym int_idx)+                (intShifter sym nm wopPos reindexPos m a xs' =<< shrinkRange sym m ix int_idx)          Right idx ->            wordShifter sym nm wopPos reindexPos m a xs' idx +++{-# INLINE intShifter #-} intShifter :: Backend sym =>    sym ->    String ->@@ -1766,36 +1654,18 @@    (Nat' -> Integer -> Integer -> Maybe Integer) ->    Nat' ->    TValue ->-   TValue ->    GenValue sym ->    SInteger sym ->    SEval sym (GenValue sym)-intShifter sym nm wop reindex m ix a xs idx =-   do let shiftOp vs shft =-              memoMap sym $ IndexSeqMap $ \i ->-                case reindex m i shft of-                  Nothing -> zeroV sym a-                  Just i' -> lookupSeqMap vs i'-      case xs of-        VWord w x ->-           return $ VWord w $ do-             x >>= \case-               WordVal x' -> WordVal <$> (wop x' =<< wordFromInt sym w idx)-               LargeBitsVal n bs0 ->-                 do idx_bits <- enumerateIntBits sym m ix idx-                    LargeBitsVal n <$> barrelShifter sym shiftOp bs0 idx_bits--        VSeq w vs0 ->-           do idx_bits <- enumerateIntBits sym m ix idx-              VSeq w <$> barrelShifter sym shiftOp vs0 idx_bits--        VStream vs0 ->-           do idx_bits <- enumerateIntBits sym m ix idx-              VStream <$> barrelShifter sym shiftOp vs0 idx_bits--        _ -> evalPanic "expected sequence value in shift operation" [nm]+intShifter sym nm wop reindex m a xs idx =+  case xs of+    VWord w x  -> VWord w <$> shiftWordByInteger sym wop (reindex m) x idx+    VSeq w vs  -> VSeq w  <$> shiftSeqByInteger sym (mergeValue sym) (reindex m) (zeroV sym a) m vs idx+    VStream vs -> VStream <$> shiftSeqByInteger sym (mergeValue sym) (reindex m) (zeroV sym a) m vs idx+    _ -> evalPanic "expected sequence value in shift operation" [nm]  +{-# INLINE wordShifter #-} wordShifter :: Backend sym =>    sym ->    String ->@@ -1807,31 +1677,15 @@    WordValue sym ->    SEval sym (GenValue sym) wordShifter sym nm wop reindex m a xs idx =-  let shiftOp vs shft =-          memoMap sym $ IndexSeqMap $ \i ->-            case reindex m i shft of-              Nothing -> zeroV sym a-              Just i' -> lookupSeqMap vs i'-   in case xs of-        VWord w x ->-           return $ VWord w $ do-             x >>= \case-               WordVal x' -> WordVal <$> (wop x' =<< asWordVal sym idx)-               LargeBitsVal n bs0 ->-                 do idx_bits <- enumerateWordValue sym idx-                    LargeBitsVal n <$> barrelShifter sym shiftOp bs0 idx_bits+  case xs of+    VWord w x  -> VWord w <$> shiftWordByWord sym wop (reindex m) x idx+    VSeq w vs  -> VSeq w  <$> shiftSeqByWord sym (mergeValue sym) (reindex m) (zeroV sym a) (Nat w) vs idx+    VStream vs -> VStream <$> shiftSeqByWord sym (mergeValue sym) (reindex m) (zeroV sym a) Inf     vs idx+    _ -> evalPanic "expected sequence value in shift operation" [nm] -        VSeq w vs0 ->-           do idx_bits <- enumerateWordValue sym idx-              VSeq w <$> barrelShifter sym shiftOp vs0 idx_bits -        VStream vs0 ->-           do idx_bits <- enumerateWordValue sym idx-              VStream <$> barrelShifter sym shiftOp vs0 idx_bits -        _ -> evalPanic "expected sequence value in shift operation" [nm]--+{-# INLINE shiftShrink #-} shiftShrink :: Backend sym => sym -> Nat' -> TValue -> SInteger sym -> SEval sym (SInteger sym) shiftShrink _sym Inf _ x = return x shiftShrink sym (Nat w) _ x =@@ -1839,6 +1693,7 @@      p  <- intLessThan sym w' x      iteInteger sym p w' x +{-# INLINE rotateShrink #-} rotateShrink :: Backend sym => sym -> Nat' -> TValue -> SInteger sym -> SEval sym (SInteger sym) rotateShrink _sym Inf _ _ = panic "rotateShrink" ["expected finite sequence in rotate"] rotateShrink sym (Nat 0) _ _ = integerLit sym 0@@ -1846,6 +1701,30 @@   do w' <- integerLit sym w      intMod sym x w' +{-# INLINE sshrV #-}+sshrV :: Backend sym => sym -> Prim sym+sshrV sym =+  PFinPoly \n ->+  PTyPoly  \ix ->+  PWordFun \x ->+  PStrict  \y ->+  PPrim $+    case asIndex sym ">>$" ix y of+       Left i ->+         do pneg <- intLessThan sym i =<< integerLit sym 0+            VWord n <$> mergeWord' sym+              pneg+              (do i' <- shiftShrink sym (Nat n) ix =<< intNegate sym i+                  amt <- wordFromInt sym n i'+                  wordVal <$> wordShiftLeft sym x amt)+              (do i' <- shiftShrink sym (Nat n) ix i+                  amt <- wordFromInt sym n i'+                  wordVal <$> wordSignedShiftRight sym x amt)++       Right wv ->+         do amt <- asWordVal sym wv+            VWord n . wordVal <$> wordSignedShiftRight sym x amt+ -- Miscellaneous ---------------------------------------------------------------  {-# SPECIALIZE errorV ::@@ -1860,38 +1739,9 @@   TValue ->   String ->   SEval sym (GenValue sym)-errorV sym ty0 msg =-     do stk <- sGetCallStack sym-        loop stk ty0-  where-  err stk = sWithCallStack sym stk (cryUserError sym msg)--  loop stk = \case-       TVBit -> err stk-       TVInteger -> err stk-       TVIntMod _ -> err stk-       TVRational -> err stk-       TVArray{} -> err stk-       TVFloat {} -> err stk--       -- sequences-       TVSeq w ety-          | isTBit ety -> return $ VWord w $ return $ LargeBitsVal w $ IndexSeqMap $ \_ -> err stk-          | otherwise  -> return $ VSeq w $ IndexSeqMap $ \_ -> loop stk ety--       TVStream ety -> return $ VStream $ IndexSeqMap $ \_ -> loop stk ety--       -- functions-       TVFun _ bty -> lam sym (\ _ -> loop stk bty)--       -- tuples-       TVTuple tys -> return $ VTuple (map (\t -> loop stk t) tys)--       -- records-       TVRec fields -> return $ VRecord $ fmap (\t -> loop stk t) $ fields--       TVAbstract {} -> err stk-       TVNewtype {} -> err stk+errorV sym _ty msg =+  do stk <- sGetCallStack sym+     sWithCallStack sym stk (cryUserError sym msg)  {-# INLINE valueToChar #-} @@ -1900,7 +1750,7 @@ --   Otherwise, return a '?' character valueToChar :: Backend sym => sym -> GenValue sym -> SEval sym Char valueToChar sym (VWord 8 wval) =-  do w <- asWordVal sym =<< wval+  do w <- asWordVal sym wval      pure $! fromMaybe '?' (wordAsChar sym w) valueToChar _ _ = evalPanic "valueToChar" ["Not an 8-bit bitvector"] @@ -1910,90 +1760,7 @@ valueToString sym (VSeq n vals) = traverse (valueToChar sym =<<) (enumerateSeqMap n vals) valueToString _ _ = evalPanic "valueToString" ["Not a finite sequence"] --- Merge and if/then/else -{-# INLINE iteValue #-}-iteValue :: Backend sym =>-  sym ->-  SBit sym ->-  SEval sym (GenValue sym) ->-  SEval sym (GenValue sym) ->-  SEval sym (GenValue sym)-iteValue sym b x y-  | Just True  <- bitAsLit sym b = x-  | Just False <- bitAsLit sym b = y-  | otherwise = mergeValue' sym b x y--{-# INLINE mergeWord #-}-mergeWord :: Backend sym =>-  sym ->-  SBit sym ->-  WordValue sym ->-  WordValue sym ->-  SEval sym (WordValue sym)-mergeWord sym c (WordVal w1) (WordVal w2) =-  WordVal <$> iteWord sym c w1 w2-mergeWord sym c w1 w2 =-  LargeBitsVal (wordValueSize sym w1) <$> memoMap sym (mergeSeqMap sym c (asBitsMap sym w1) (asBitsMap sym w2))--{-# INLINE mergeWord' #-}-mergeWord' :: Backend sym =>-  sym ->-  SBit sym ->-  SEval sym (WordValue sym) ->-  SEval sym (WordValue sym) ->-  SEval sym (WordValue sym)-mergeWord' sym = mergeEval sym (mergeWord sym)--{-# INLINE mergeValue' #-}-mergeValue' :: Backend sym =>-  sym ->-  SBit sym ->-  SEval sym (GenValue sym) ->-  SEval sym (GenValue sym) ->-  SEval sym (GenValue sym)-mergeValue' sym = mergeEval sym (mergeValue sym)--mergeValue :: Backend sym =>-  sym ->-  SBit sym ->-  GenValue sym ->-  GenValue sym ->-  SEval sym (GenValue sym)-mergeValue sym c v1 v2 =-  case (v1, v2) of-    (VRecord fs1 , VRecord fs2 ) ->-      do let res = zipRecords (\_lbl -> mergeValue' sym c) fs1 fs2-         case res of-           Left f -> panic "Cryptol.Eval.Generic" [ "mergeValue: incompatible record values", show f ]-           Right r -> pure (VRecord r)-    (VTuple vs1  , VTuple vs2  ) | length vs1 == length vs2  ->-                                  pure $ VTuple $ zipWith (mergeValue' sym c) vs1 vs2-    (VBit b1     , VBit b2     ) -> VBit <$> iteBit sym c b1 b2-    (VInteger i1 , VInteger i2 ) -> VInteger <$> iteInteger sym c i1 i2-    (VRational q1, VRational q2) -> VRational <$> iteRational sym c q1 q2-    (VFloat f1   , VFloat f2)    -> VFloat <$> iteFloat sym c f1 f2-    (VWord n1 w1 , VWord n2 w2 ) | n1 == n2 -> pure $ VWord n1 $ mergeWord' sym c w1 w2-    (VSeq n1 vs1 , VSeq n2 vs2 ) | n1 == n2 -> VSeq n1 <$> memoMap sym (mergeSeqMap sym c vs1 vs2)-    (VStream vs1 , VStream vs2 ) -> VStream <$> memoMap sym (mergeSeqMap sym c vs1 vs2)-    (f1@VFun{}   , f2@VFun{}   ) -> lam sym $ \x -> mergeValue' sym c (fromVFun sym f1 x) (fromVFun sym f2 x)-    (f1@VPoly{}  , f2@VPoly{}  ) -> tlam sym $ \x -> mergeValue' sym c (fromVPoly sym f1 x) (fromVPoly sym f2 x)-    (_           , _           ) -> panic "Cryptol.Eval.Generic"-                                  [ "mergeValue: incompatible values" ]--{-# INLINE mergeSeqMap #-}-mergeSeqMap :: Backend sym =>-  sym ->-  SBit sym ->-  SeqMap sym ->-  SeqMap sym ->-  SeqMap sym-mergeSeqMap sym c x y =-  IndexSeqMap $ \i ->-    iteValue sym c (lookupSeqMap x i) (lookupSeqMap y i)--- foldlV :: Backend sym => sym -> Prim sym foldlV sym =   PNumPoly \_n ->@@ -2005,7 +1772,7 @@   PPrim     case v of       VSeq n m    -> go0 f z (enumerateSeqMap n m)-      VWord _n wv -> go0 f z . map (pure . VBit) =<< (enumerateWordValue sym =<< wv)+      VWord _n wv -> go0 f z . map (pure . VBit) =<< (enumerateWordValue sym wv)       _ -> panic "Cryptol.Eval.Generic.foldlV" ["Expected finite sequence"]   where   go0 _f a [] = a@@ -2029,7 +1796,7 @@   PPrim     case v of       VSeq n m    -> go0 f z (enumerateSeqMap n m)-      VWord _n wv -> go0 f z . map (pure . VBit) =<< (enumerateWordValue sym =<< wv)+      VWord _n wv -> go0 f z . map (pure . VBit) =<< (enumerateWordValue sym wv)       _ -> panic "Cryptol.Eval.Generic.foldlV" ["Expected finite sequence"]   where   go0 _f a [] = a@@ -2081,9 +1848,9 @@        xs' <- xs        case xs' of           VWord n w ->-            do m <- asBitsMap sym <$> w-               m' <- sparkParMap sym f' n m-               pure (VWord n (pure (LargeBitsVal n m')))+            do let m = asBitsMap sym w+               m' <- sparkParMap sym (\x -> f' (VBit <$> x)) n m+               VWord n <$> (bitmapWordVal sym n (fromVBit <$> m'))           VSeq n m ->             VSeq n <$> sparkParMap sym f' n m @@ -2093,12 +1860,12 @@ sparkParMap ::   Backend sym =>   sym ->-  (SEval sym (GenValue sym) -> SEval sym (GenValue sym)) ->+  (SEval sym a -> SEval sym (GenValue sym)) ->   Integer ->-  SeqMap sym ->-  SEval sym (SeqMap sym)+  SeqMap sym a ->+  SEval sym (SeqMap sym (GenValue sym)) sparkParMap sym f n m =-  finiteSeqMap <$> mapM (sSpark sym . g) (enumerateSeqMap n m)+  finiteSeqMap sym <$> mapM (sSpark sym . g) (enumerateSeqMap n m)  where  g x =    do z <- sDelay sym (f x)@@ -2149,9 +1916,8 @@     , "fpPosInf"    ~> fpConst (fpPosInf sym)     , "fpFromBits"  ~> PFinPoly \e -> PFinPoly \p -> PWordFun \w ->                        PPrim (VFloat <$> fpFromBits sym e p w)-    , "fpToBits"    ~> PFinPoly \e -> PFinPoly \p -> PFloatFun \x -> PVal-                            $ VWord (e+p)-                            $ WordVal <$> fpToBits sym x+    , "fpToBits"    ~> PFinPoly \e -> PFinPoly \p -> PFloatFun \x -> PPrim+                            (VWord (e+p) . wordVal <$> fpToBits sym x)     , "=.="         ~> PFinPoly \_ -> PFinPoly \_ -> PFloatFun \x -> PFloatFun \y ->                        PPrim (VBit <$> fpLogicalEq sym x y) @@ -2272,6 +2038,9 @@                     unary (roundToEvenV sym))      -- Bitvector specific operations+  , ("toSignedInteger"+                  , {-# SCC "Prelude::toSignedInteger" #-}+                    toSignedIntegerV sym)   , ("/$"         , {-# SCC "Prelude::(/$)" #-}                     sdivV sym)   , ("%$"         , {-# SCC "Prelude::(%$)" #-}@@ -2308,6 +2077,20 @@                   , {-# SCC "Prelude::fromToLessThan" #-}                     fromToLessThanV sym) +  , ("fromToBy"   , {-# SCC "Prelude::fromToBy" #-}+                    fromToByV sym)++  , ("fromToByLessThan",+                    {-# SCC "Prelude::fromToByLessThan" #-}+                    fromToByLessThanV sym)++  , ("fromToDownBy", {-# SCC "Prelude::fromToDownBy" #-}+                     fromToDownByV sym)++  , ("fromToDownByGreaterThan"+                  , {-# SCC "Prelude::fromToDownByGreaterThan" #-}+                    fromToDownByGreaterThanV sym)+     -- Sequence manipulations   , ("#"          , {-# SCC "Prelude::(#)" #-}                     PFinPoly \front ->@@ -2315,37 +2098,69 @@                     PTyPoly  \elty  ->                     PFun \l ->                     PFun \r ->-                    PPrim (join (ccatV sym (Nat front) back elty <$> l <*> r)))+                    PPrim $ ccatV sym front back elty l r)    , ("join"       , {-# SCC "Prelude::join" #-}                     PNumPoly \parts ->                     PFinPoly \each  ->                     PTyPoly  \a     ->-                    PStrict  \x   ->+                    PFun     \x   ->                     PPrim $ joinV sym parts each a x)    , ("split"      , {-# SCC "Prelude::split" #-}-                    ecSplitV sym)+                    PNumPoly \parts ->+                    PFinPoly \each ->+                    PTyPoly  \a ->+                    PFun     \val ->+                    PPrim $ splitV sym parts each a val) -  , ("splitAt"    , {-# SCC "Prelude::splitAt" #-}+  , ("take"       , {-# SCC "Preldue::take" #-}                     PNumPoly \front ->-                    PNumPoly \back  ->-                    PTyPoly  \a     ->-                    PStrict  \x   ->-                    PPrim $ splitAtV sym front back a x)+                    PNumPoly \back ->+                    PTyPoly  \a ->+                    PFun     \xs ->+                    PPrim $ takeV sym front back a xs) +  , ("drop"       , {-# SCC "Preldue::drop" #-}+                    PFinPoly \front ->+                    PNumPoly \back ->+                    PTyPoly  \a ->+                    PFun     \xs ->+                    PPrim $ dropV sym front back a xs)+   , ("reverse"    , {-# SCC "Prelude::reverse" #-}-                    PFinPoly \_a ->-                    PTyPoly  \_b ->-                    PStrict  \xs ->-                    PPrim $ reverseV sym xs)+                    PFinPoly \a ->+                    PTyPoly  \b ->+                    PFun     \xs ->+                    PPrim $ reverseV sym a b xs)    , ("transpose"  , {-# SCC "Prelude::transpose" #-}                     PNumPoly \a ->                     PNumPoly \b ->                     PTyPoly  \c ->-                    PStrict  \xs ->-                    PPrim $ transposeV sym a b c xs)+                    PFun     \xs ->+                    PPrim $ transposeV sym a b c =<< xs)++    -- Shifts and rotates+  , ("<<"         , {-# SCC "Prelude::(<<)" #-}+                    logicShift sym "<<" shiftShrink+                      (wordShiftLeft sym) (wordShiftRight sym)+                      shiftLeftReindex shiftRightReindex)+  , (">>"         , {-# SCC "Prelude::(>>)" #-}+                    logicShift sym ">>"  shiftShrink+                      (wordShiftRight sym) (wordShiftLeft sym)+                      shiftRightReindex shiftLeftReindex)+  , ("<<<"        , {-# SCC "Prelude::(<<<)" #-}+                    logicShift sym "<<<" rotateShrink+                      (wordRotateLeft sym) (wordRotateRight sym)+                      rotateLeftReindex rotateRightReindex)+  , (">>>"        , {-# SCC "Prelude::(>>>)" #-}+                    logicShift sym ">>>" rotateShrink+                      (wordRotateRight sym) (wordRotateLeft sym)+                      rotateRightReindex rotateLeftReindex)++  , (">>$"        , {-# SCC "Prelude::(>>$)" #-}+                    sshrV sym)      -- Misc 
src/Cryptol/Eval/Reference.lhs view
@@ -251,7 +251,7 @@ > instance Semigroup Env where >   l <> r = Env >     { envVars  = envVars  l <> envVars  r->     , envTypes = envTypes l <> envTypes r +>     , envTypes = envTypes l <> envTypes r >     } > > instance Monoid Env where@@ -523,7 +523,7 @@ that consumes and ignores its type arguments.  > evalNewtypeDecl :: Env -> Newtype -> Env-> evalNewtypeDecl env nt = bindVar (ntName nt, pure val) env +> evalNewtypeDecl env nt = bindVar (ntName nt, pure val) env >   where >     val = foldr tabs con (ntParams nt) >     con = VFun (\x -> x)@@ -541,7 +541,7 @@ > evalPrim :: Name -> Value > evalPrim n >   | Just i <- asPrim n, Just v <- Map.lookup i primTable = v->   | otherwise = evalPanic "evalPrim" ["Unimplemented primitive", show n]+>   | otherwise = evalPanic "evalPrim" ["Unimplemented primitive", show (pp n)]  Cryptol primitives fall into several groups, mostly delineated by corresponding type classes:@@ -560,13 +560,15 @@  * Comparison: `<`, `>`, `<=`, `>=`, `==`, `!=` -* Sequences: `#`, `join`, `split`, `splitAt`, `reverse`, `transpose`+* Sequences: `#`, `join`, `split`, `take`, `drop`, `reverse`, `transpose`  * Shifting: `<<`, `>>`, `<<<`, `>>>`  * Indexing: `@`, `@@`, `!`, `!!`, `update`, `updateEnd` -* Enumerations: `fromTo`, `fromThenTo`, `infFrom`, `infFromThen`+* Enumerations: `fromTo`, `fromThenTo`, `fromToLessThan`, `fromToBy`,+                `fromToByLessThan`, `fromToDownBy`, `fromToDownByGreaterThan`,+                `infFrom`, `infFromThen`  * Polynomials: `pmult`, `pdiv`, `pmod` @@ -734,17 +736,21 @@ >                           do vs <- fromVList <$> val >                              indexFront (nMul parts (Nat each)) vs (i * each + j) >->   , "splitAt"    ~> vFinPoly $ \front -> pure $+>   , "take"       ~> VNumPoly $ \front -> pure $+>                     VNumPoly $ \back  -> pure $+>                     VPoly    $ \_a    -> pure $+>                     VFun     $ \v ->+>                       pure $ generateV front $ \i ->+>                                do vs <- fromVList <$> v+>                                   indexFront (nAdd front back) vs i+>+>   , "drop"       ~> vFinPoly $ \front -> pure $ >                     VNumPoly $ \back -> pure $ >                     VPoly $ \_a -> pure $ >                     VFun $ \v ->->                       let xs = pure $ generateV (Nat front) $ \i ->->                                  do vs <- fromVList <$> v->                                     indexFront (nAdd (Nat front) back) vs i->                           ys = pure $ generateV back $ \i ->->                                  do vs <- fromVList <$> v->                                     indexFront (nAdd (Nat front) back) vs (front+i)->                        in pure (VTuple [ xs, ys ])+>                       pure $ generateV back $ \i ->+>                                do vs <- fromVList <$> v+>                                   indexFront (nAdd (Nat front) back) vs (front+i) > >   , "reverse"    ~> vFinPoly $ \n -> pure $ >                     VPoly $ \_a -> pure $@@ -778,18 +784,71 @@ >   -- Enumerations >   , "fromTo"     ~> vFinPoly $ \first -> pure $ >                     vFinPoly $ \lst   -> pure $->                     VPoly    $ \ty  ->->                     let f i = literal i ty->                     in pure (VList (Nat (1 + lst - first)) (map f [first .. lst]))+>                     VPoly    $ \ty    -> pure $+>                     let f i = literal i ty in+>                     VList (Nat (1 + lst - first)) (map f [first .. lst]) >+>   , "fromToLessThan" ~>+>                     vFinPoly $ \first -> pure $+>                     VNumPoly $ \bound -> pure $+>                     VPoly    $ \ty    -> pure $+>                     let f i = literal i ty in+>                     case bound of+>                       Inf -> VList Inf (map f [first ..])+>                       Nat bound' ->+>                         let len = bound' - first in+>                         VList (Nat len) (map f (genericTake len [first ..]))+>+>   , "fromToBy"   ~> vFinPoly $ \first  -> pure $+>                     vFinPoly $ \lst    -> pure $+>                     vFinPoly $ \stride -> pure $+>                     VPoly    $ \ty     -> pure $+>                     let f i = literal i ty in+>                     let vs  = [ f (first + i*stride) | i <- [0..] ] in+>                     let len = 1 + ((lst-first) `div` stride) in+>                     VList (Nat len) (genericTake len vs)+>+>   , "fromToByLessThan" ~>+>                     vFinPoly $ \first  -> pure $+>                     VNumPoly $ \bound  -> pure $+>                     vFinPoly $ \stride -> pure $+>                     VPoly    $ \ty     -> pure $+>                     let f i = literal i ty in+>                     let vs  = [ f (first + i*stride) | i <- [0..] ] in+>                     case bound of+>                       Inf -> VList Inf vs+>                       Nat bound' ->+>                         let len = (bound'-first+stride-1) `div` stride in+>                         VList (Nat len) (genericTake len vs)+>+>   , "fromToDownBy" ~>+>                     vFinPoly $ \first  -> pure $+>                     vFinPoly $ \lst    -> pure $+>                     vFinPoly $ \stride -> pure $+>                     VPoly    $ \ty     -> pure $+>                     let f i = literal i ty in+>                     let vs  = [ f (first - i*stride) | i <- [0..] ] in+>                     let len = 1 + ((first-lst) `div` stride) in+>                     VList (Nat len) (genericTake len vs)+>+>   , "fromToDownByGreaterThan" ~>+>                     vFinPoly $ \first  -> pure $+>                     vFinPoly $ \lst    -> pure $+>                     vFinPoly $ \stride -> pure $+>                     VPoly    $ \ty     -> pure $+>                     let f i = literal i ty in+>                     let vs  = [ f (first - i*stride) | i <- [0..] ] in+>                     let len = (first-lst+stride-1) `div` stride in+>                     VList (Nat len) (genericTake len vs)+> >   , "fromThenTo" ~> vFinPoly $ \first -> pure $ >                     vFinPoly $ \next  -> pure $ >                     vFinPoly $ \_lst  -> pure $ >                     VPoly    $ \ty    -> pure $->                     vFinPoly $ \len   ->->                     let f i = literal i ty->                     in pure (VList (Nat len)->                               (map f (genericTake len [first, next ..])))+>                     vFinPoly $ \len   -> pure $+>                     let f i = literal i ty in+>                     VList (Nat len)+>                           (map f (genericTake len [first, next ..])) > >   , "infFrom"    ~> VPoly $ \ty -> pure $ >                     VFun $ \first ->@@ -1711,11 +1770,10 @@ >           case traverse isBit vs of >             Just bs -> ppBV opts (mkBv n (bitsToInteger bs)) >             Nothing -> ppList (map (ppEValue opts) vs)->       where ppList docs = brackets (fsep (punctuate comma docs))->             isBit v = case v of Value (VBit b) -> Just b+>       where isBit v = case v of Value (VBit b) -> Just b >                                 _      -> Nothing->     VTuple vs  -> parens (sep (punctuate comma (map (ppEValue opts) vs)))->     VRecord fs -> braces (sep (punctuate comma (map ppField fs)))+>     VTuple vs  -> ppTuple (map (ppEValue opts) vs)+>     VRecord fs -> ppRecord (map ppField fs) >       where ppField (f,r) = pp f <+> char '=' <+> ppEValue opts r >     VFun _     -> text "<function>" >     VPoly _    -> text "<polymorphic value>"@@ -1732,7 +1790,7 @@ > evaluate expr minp = return (Right (val, modEnv), []) >   where >     modEnv = M.minpModuleEnv minp->     extDgs = concatMap mDecls (M.loadedModules modEnv)+>     extDgs = concatMap mDecls (M.loadedModules modEnv) ++ M.deDecls (M.meDynEnv modEnv) >     nts    = Map.elems (M.loadedNewtypes modEnv) >     env    = foldl evalDeclGroup (foldl evalNewtypeDecl mempty nts) extDgs >     val    = evalExpr env expr
src/Cryptol/Eval/SBV.hs view
@@ -23,21 +23,22 @@  import qualified Control.Exception as X import           Control.Monad.IO.Class (MonadIO(..))-import           Data.Bits (bit, shiftL) import qualified Data.Map as Map import qualified Data.Text as T  import Data.SBV.Dynamic as SBV  import Cryptol.Backend-import Cryptol.Backend.Monad ( EvalError(..), Unsupported(..) )+import Cryptol.Backend.Monad (Unsupported(..), EvalError(..) ) import Cryptol.Backend.SBV+import Cryptol.Backend.SeqMap+import Cryptol.Backend.WordValue  import Cryptol.Eval.Type (TValue(..)) import Cryptol.Eval.Generic import Cryptol.Eval.Prims import Cryptol.Eval.Value-import Cryptol.TypeCheck.Solver.InfNat (Nat'(..), widthInteger)+import Cryptol.TypeCheck.Solver.InfNat (Nat'(..)) import Cryptol.Utils.Ident  -- Values ----------------------------------------------------------------------@@ -52,36 +53,9 @@   Map.union (genericPrimTable sym getEOpts) $   Map.fromList $ map (\(n, v) -> (prelPrim (T.pack n), v)) -  [ (">>$"         , sshrV sym)--    -- Shifts and rotates-  , ("<<"          , logicShift sym "<<"-                       shiftShrink-                       (\x y -> pure (shl x y))-                       (\x y -> pure (lshr x y))-                       shiftLeftReindex shiftRightReindex)--  , (">>"          , logicShift sym ">>"-                       shiftShrink-                       (\x y -> pure (lshr x y))-                       (\x y -> pure (shl x y))-                       shiftRightReindex shiftLeftReindex)--  , ("<<<"         , logicShift sym "<<<"-                       rotateShrink-                       (\x y -> pure (SBV.svRotateLeft x y))-                       (\x y -> pure (SBV.svRotateRight x y))-                       rotateLeftReindex rotateRightReindex)--  , (">>>"         , logicShift sym ">>>"-                       rotateShrink-                       (\x y -> pure (SBV.svRotateRight x y))-                       (\x y -> pure (SBV.svRotateLeft x y))-                       rotateRightReindex rotateLeftReindex)--    -- Indexing and updates-  , ("@"           , indexPrim sym (indexFront sym) (indexFront_bits sym) (indexFront sym))-  , ("!"           , indexPrim sym (indexBack sym) (indexBack_bits sym) (indexBack sym))+  [ -- Indexing and updates+    ("@"           , indexPrim sym IndexForward  (indexFront sym) (indexFront_segs sym))+  , ("!"           , indexPrim sym IndexBackward (indexFront sym) (indexFront_segs sym))    , ("update"      , updatePrim sym (updateFrontSym_word sym) (updateFrontSym sym))   , ("updateEnd"   , updatePrim sym (updateBackSym_word sym) (updateBackSym sym))@@ -92,7 +66,7 @@   SBV ->   Nat' ->   TValue ->-  SeqMap SBV ->+  SeqMap SBV (GenValue SBV) ->   TValue ->   SVal ->   SEval SBV Value@@ -102,125 +76,77 @@    | Nat n <- mblen   , TVSeq wlen TVBit <- a-  = do wvs <- traverse (fromWordVal "indexFront" =<<) (enumerateSeqMap n xs)-       case asWordList wvs of+  = do wvs <- traverse (fromWordVal "indexFront" <$>) (enumerateSeqMap n xs)+       asWordList sym wvs >>= \case          Just ws ->            do z <- wordLit sym wlen 0-              return $ VWord wlen $ pure $ WordVal $ SBV.svSelect ws z idx-         Nothing -> folded+              return $ VWord wlen $ wordVal $ SBV.svSelect ws z idx+         Nothing -> folded' -  | otherwise-  = folded+  | otherwise = folded' +  where     k = SBV.kindOf idx-    def = zeroV sym a-    f n y = iteValue sym (SBV.svEqual idx (SBV.svInteger k n)) (lookupSeqMap xs n) y++    f n (Just y) = Just $ iteValue sym (SBV.svEqual idx (SBV.svInteger k n)) (lookupSeqMap xs n) y+    f n Nothing  = Just $ lookupSeqMap xs n++    folded' =+      case folded of+        Nothing -> raiseError sym (InvalidIndex Nothing)+        Just m  -> m+     folded =       case k of         KBounded _ w ->           case mblen of-            Nat n | n < 2^w -> foldr f def [0 .. n-1]-            _ -> foldr f def [0 .. 2^w - 1]+            Nat n | n < 2^w -> foldr f Nothing [0 .. n-1]+            _ -> foldr f Nothing [0 .. 2^w - 1]         _ ->           case mblen of-            Nat n -> foldr f def [0 .. n-1]-            Inf -> liftIO (X.throw (UnsupportedSymbolicOp "unbounded integer indexing"))--indexBack ::-  SBV ->-  Nat' ->-  TValue ->-  SeqMap SBV ->-  TValue ->-  SWord SBV ->-  SEval SBV Value-indexBack sym (Nat n) a xs ix idx = indexFront sym (Nat n) a (reverseSeqMap n xs) ix idx-indexBack _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["indexBack"]--indexFront_bits ::-  SBV ->-  Nat' ->-  TValue ->-  SeqMap SBV ->-  TValue ->-  [SBit SBV] ->-  SEval SBV Value-indexFront_bits sym mblen _a xs _ix bits0 = go 0 (length bits0) bits0- where-  go :: Integer -> Int -> [SBit SBV] -> SEval SBV Value-  go i _k []-    -- For indices out of range, fail-    | Nat n <- mblen-    , i >= n-    = raiseError sym (InvalidIndex (Just i))--    | otherwise-    = lookupSeqMap xs i--  go i k (b:bs)-    -- Fail early when all possible indices we could compute from here-    -- are out of bounds-    | Nat n <- mblen-    , (i `shiftL` k) >= n-    = raiseError sym (InvalidIndex Nothing)--    | otherwise-    = iteValue sym b-         (go ((i `shiftL` 1) + 1) (k-1) bs)-         (go  (i `shiftL` 1)      (k-1) bs)-+            Nat n -> foldr f Nothing [0 .. n-1]+            Inf -> Just (liftIO (X.throw (UnsupportedSymbolicOp "unbounded integer indexing"))) -indexBack_bits ::+indexFront_segs ::   SBV ->   Nat' ->   TValue ->-  SeqMap SBV ->+  SeqMap SBV (GenValue SBV) ->   TValue ->-  [SBit SBV] ->+  Integer ->+  [IndexSegment SBV] ->   SEval SBV Value-indexBack_bits sym (Nat n) a xs ix idx = indexFront_bits sym (Nat n) a (reverseSeqMap n xs) ix idx-indexBack_bits _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["indexBack_bits"]-+indexFront_segs sym mblen a xs ix _idx_bits [WordIndexSegment w] =+  indexFront sym mblen a xs ix w --- | Compare a symbolic word value with a concrete integer.-wordValueEqualsInteger :: SBV -> WordValue SBV -> Integer -> SEval SBV (SBit SBV)-wordValueEqualsInteger sym wv i-  | wordValueSize sym wv < widthInteger i = return SBV.svFalse-  | otherwise =-    case wv of-      WordVal w -> return $ SBV.svEqual w (literalSWord (SBV.intSizeOf w) i)-      _ -> bitsAre i <$> enumerateWordValueRev sym wv -- little-endian+indexFront_segs sym mblen _a xs _ix idx_bits segs =+  do xs' <- barrelShifter sym (mergeValue sym) shiftOp mblen xs idx_bits segs+     lookupSeqMap xs' 0   where-    bitsAre :: Integer -> [SBit SBV] -> SBit SBV-    bitsAre n [] = SBV.svBool (n == 0)-    bitsAre n (b : bs) = SBV.svAnd (bitIs (odd n) b) (bitsAre (n `div` 2) bs)--    bitIs :: Bool -> SBit SBV -> SBit SBV-    bitIs b x = if b then x else SBV.svNot x+    shiftOp vs amt = pure (indexSeqMap (\i -> lookupSeqMap vs $! amt+i))   updateFrontSym ::   SBV ->   Nat' ->   TValue ->-  SeqMap SBV ->+  SeqMap SBV (GenValue SBV) ->   Either (SInteger SBV) (WordValue SBV) ->   SEval SBV (GenValue SBV) ->-  SEval SBV (SeqMap SBV)+  SEval SBV (SeqMap SBV (GenValue SBV)) updateFrontSym sym _len _eltTy vs (Left idx) val =   case SBV.svAsInteger idx of     Just i -> return $ updateSeqMap vs i val-    Nothing -> return $ IndexSeqMap $ \i ->+    Nothing -> return $ indexSeqMap $ \i ->       do b <- intEq sym idx =<< integerLit sym i          iteValue sym b val (lookupSeqMap vs i)  updateFrontSym sym _len _eltTy vs (Right wv) val =-  case wv of-    WordVal w | Just j <- SBV.svAsInteger w ->-      return $ updateSeqMap vs j val-    _ ->-      return $ IndexSeqMap $ \i ->+  wordValAsLit sym wv >>= \case+   Just j -> return $ updateSeqMap vs j val+   Nothing ->+      return $ indexSeqMap $ \i ->       do b <- wordValueEqualsInteger sym wv i          iteValue sym b val (lookupSeqMap vs i) @@ -234,56 +160,35 @@   SEval SBV (WordValue SBV) updateFrontSym_word _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["updateFrontSym_bits"] -updateFrontSym_word sym (Nat _) eltTy (LargeBitsVal n bv) idx val =-  LargeBitsVal n <$> updateFrontSym sym (Nat n) eltTy bv idx val--updateFrontSym_word sym (Nat n) eltTy (WordVal bv) (Left idx) val =+updateFrontSym_word sym (Nat n) _eltTy w (Left idx) val =   do idx' <- wordFromInt sym n idx-     updateFrontSym_word sym (Nat n) eltTy (WordVal bv) (Right (WordVal idx')) val--updateFrontSym_word sym (Nat n) eltTy bv (Right wv) val =-  case wv of-    WordVal idx-      | Just j <- SBV.svAsInteger idx ->-          updateWordValue sym bv j (fromVBit <$> val)--      | WordVal bw <- bv ->-        WordVal <$>-          do b <- fromVBit <$> val-             let sz   = SBV.intSizeOf bw-             let z    = literalSWord sz 0-             let znot = SBV.svNot z-             let q    = SBV.svSymbolicMerge (SBV.kindOf bw) True b znot z-             let msk  = SBV.svShiftRight (literalSWord sz (bit (sz-1))) idx-             let bw'  = SBV.svAnd bw (SBV.svNot msk)-             return $! SBV.svXOr bw' (SBV.svAnd q msk)--    _ -> LargeBitsVal n <$> updateFrontSym sym (Nat n) eltTy (asBitsMap sym bv) (Right wv) val+     updateWordByWord sym IndexForward w (wordVal idx') (fromVBit <$> val)+updateFrontSym_word sym (Nat _n) _eltTy w (Right idx) val =+  updateWordByWord sym IndexForward w idx (fromVBit <$> val)   updateBackSym ::   SBV ->   Nat' ->   TValue ->-  SeqMap SBV ->+  SeqMap SBV (GenValue SBV) ->   Either (SInteger SBV) (WordValue SBV) ->   SEval SBV (GenValue SBV) ->-  SEval SBV (SeqMap SBV)+  SEval SBV (SeqMap SBV (GenValue SBV)) updateBackSym _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["updateBackSym"]  updateBackSym sym (Nat n) _eltTy vs (Left idx) val =   case SBV.svAsInteger idx of     Just i -> return $ updateSeqMap vs (n - 1 - i) val-    Nothing -> return $ IndexSeqMap $ \i ->+    Nothing -> return $ indexSeqMap $ \i ->       do b <- intEq sym idx =<< integerLit sym (n - 1 - i)          iteValue sym b val (lookupSeqMap vs i)  updateBackSym sym (Nat n) _eltTy vs (Right wv) val =-  case wv of-    WordVal w | Just j <- SBV.svAsInteger w ->-      return $ updateSeqMap vs (n - 1 - j) val-    _ ->-      return $ IndexSeqMap $ \i ->+  wordValAsLit sym wv >>= \case+    Just j -> return $ updateSeqMap vs (n - 1 - j) val+    Nothing ->+      return $ indexSeqMap $ \i ->       do b <- wordValueEqualsInteger sym wv (n - 1 - i)          iteValue sym b val (lookupSeqMap vs i) @@ -297,56 +202,9 @@   SEval SBV (WordValue SBV) updateBackSym_word _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["updateBackSym_bits"] -updateBackSym_word sym (Nat _) eltTy (LargeBitsVal n bv) idx val =-  LargeBitsVal n <$> updateBackSym sym (Nat n) eltTy bv idx val--updateBackSym_word sym (Nat n) eltTy (WordVal bv) (Left idx) val =+updateBackSym_word sym (Nat n) _eltTy w (Left idx) val =   do idx' <- wordFromInt sym n idx-     updateBackSym_word sym (Nat n) eltTy (WordVal bv) (Right (WordVal idx')) val--updateBackSym_word sym (Nat n) eltTy bv (Right wv) val = do-  case wv of-    WordVal idx-      | Just j <- SBV.svAsInteger idx ->-          updateWordValue sym bv (n - 1 - j) (fromVBit <$> val)--      | WordVal bw <- bv ->-        WordVal <$>-          do b <- fromVBit <$> val-             let sz   = SBV.intSizeOf bw-             let z    = literalSWord sz 0-             let znot = SBV.svNot z-             let q    = SBV.svSymbolicMerge (SBV.kindOf bw) True b znot z-             let msk  = SBV.svShiftLeft (literalSWord sz 1) idx-             let bw'  = SBV.svAnd bw (SBV.svNot msk)-             return $! SBV.svXOr bw' (SBV.svAnd q msk)--    _ -> LargeBitsVal n <$> updateBackSym sym (Nat n) eltTy (asBitsMap sym bv) (Right wv) val---asWordList :: [WordValue SBV] -> Maybe [SWord SBV]-asWordList = go id- where go :: ([SWord SBV] -> [SWord SBV]) -> [WordValue SBV] -> Maybe [SWord SBV]-       go f [] = Just (f [])-       go f (WordVal x :vs) = go (f . (x:)) vs-       go _f (LargeBitsVal _ _ : _) = Nothing--sshrV :: SBV -> Prim SBV-sshrV sym =-  PNumPoly \n ->-  PTyPoly  \ix ->-  PWordFun \x ->-  PStrict  \y ->-  PPrim $-   asIndex sym ">>$" ix y >>= \case-     Left idx ->-       do let w = toInteger (SBV.intSizeOf x)-          let pneg = svLessThan idx (svInteger KUnbounded 0)-          zneg <- shl x  . svFromInteger w <$> shiftShrink sym n ix (SBV.svUNeg idx)-          zpos <- ashr x . svFromInteger w <$> shiftShrink sym n ix idx-          let z = svSymbolicMerge (kindOf x) True pneg zneg zpos-          return . VWord w . pure . WordVal $ z+     updateWordByWord sym IndexBackward w (wordVal idx') (fromVBit <$> val)+updateBackSym_word sym (Nat _n) _eltTy w (Right idx) val =+  updateWordByWord sym IndexBackward w idx (fromVBit <$> val) -     Right wv ->-       do z <- ashr x <$> asWordVal sym wv-          return . VWord (toInteger (SBV.intSizeOf x)) . pure . WordVal $ z
src/Cryptol/Eval/Value.hs view
@@ -6,6 +6,7 @@ -- Stability   :  provisional -- Portability :  portable +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-}@@ -16,7 +17,6 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PatternGuards #-}-{-# LANGUAGE Safe #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TupleSections #-}@@ -26,7 +26,6 @@ module Cryptol.Eval.Value   ( -- * GenericValue     GenValue(..)-  , forceWordValue   , forceValue   , Backend(..)   , asciiMode@@ -39,9 +38,6 @@   , tlam   , nlam   , ilam-  , toStream-  , toFinSeq-  , toSeq   , mkSeq     -- ** Value eliminators   , fromVBit@@ -64,59 +60,32 @@     -- ** Pretty printing   , defaultPPOpts   , ppValue--    -- * Sequence Maps-  , SeqMap (..)-  , lookupSeqMap-  , finiteSeqMap-  , infiniteSeqMap-  , enumerateSeqMap-  , streamSeqMap-  , reverseSeqMap-  , updateSeqMap-  , dropSeqMap-  , concatSeqMap-  , splitSeqMap-  , memoMap-  , zipSeqMap-  , mapSeqMap-  , largeBitSize-    -- * WordValue-  , WordValue(..)-  , asWordVal-  , asBitsMap-  , enumerateWordValue-  , enumerateWordValueRev-  , wordValueSize-  , indexWordValue-  , updateWordValue+    -- * Merge and if/then/else+  , iteValue+  , mergeValue   ) where -import Control.Monad.IO.Class-import Data.Bits-import Data.IORef-import Data.Map.Strict (Map) import Data.Ratio-import qualified Data.Map.Strict as Map-import MonadLib import Numeric (showIntAtBase)  import Cryptol.Backend+import Cryptol.Backend.SeqMap import qualified Cryptol.Backend.Arch as Arch import Cryptol.Backend.Monad   ( evalPanic, wordTooWide, CallStack, combineCallStacks ) import Cryptol.Backend.FloatHelpers (fpPP)+import Cryptol.Backend.WordValue+ import Cryptol.Eval.Type  import Cryptol.TypeCheck.Solver.InfNat(Nat'(..))+ import Cryptol.Utils.Ident (Ident) import Cryptol.Utils.Logger(Logger) import Cryptol.Utils.Panic(panic) import Cryptol.Utils.PP import Cryptol.Utils.RecordMap -import Data.List(genericIndex)- import GHC.Generics (Generic)  -- | Some options for evalutaion@@ -127,186 +96,6 @@  -- Values ---------------------------------------------------------------------- --- | A sequence map represents a mapping from nonnegative integer indices---   to values.  These are used to represent both finite and infinite sequences.-data SeqMap sym-  = IndexSeqMap  !(Integer -> SEval sym (GenValue sym))-  | UpdateSeqMap !(Map Integer (SEval sym (GenValue sym)))-                 !(Integer -> SEval sym (GenValue sym))--lookupSeqMap :: SeqMap sym -> Integer -> SEval sym (GenValue sym)-lookupSeqMap (IndexSeqMap f) i = f i-lookupSeqMap (UpdateSeqMap m f) i =-  case Map.lookup i m of-    Just x  -> x-    Nothing -> f i---- | An arbitrarily-chosen number of elements where we switch from a dense---   sequence representation of bit-level words to 'SeqMap' representation.-largeBitSize :: Integer-largeBitSize = 1 `shiftL` 48---- | Generate a finite sequence map from a list of values-finiteSeqMap :: [SEval sym (GenValue sym)] -> SeqMap sym-finiteSeqMap xs =-   UpdateSeqMap-      (Map.fromList (zip [0..] xs))-      (\i -> panic "finiteSeqMap" ["Out of bounds access of finite seq map", "length: " ++ show (length xs), show i])---- | Generate an infinite sequence map from a stream of values-infiniteSeqMap :: Backend sym => sym -> [SEval sym (GenValue sym)] -> SEval sym (SeqMap sym)-infiniteSeqMap sym xs =-   -- TODO: use an int-trie?-   memoMap sym (IndexSeqMap $ \i -> genericIndex xs i)---- | Create a finite list of length @n@ of the values from @[0..n-1]@ in---   the given the sequence emap.-enumerateSeqMap :: (Integral n) => n -> SeqMap sym -> [SEval sym (GenValue sym)]-enumerateSeqMap n m = [ lookupSeqMap m  i | i <- [0 .. (toInteger n)-1] ]---- | Create an infinite stream of all the values in a sequence map-streamSeqMap :: SeqMap sym -> [SEval sym (GenValue sym)]-streamSeqMap m = [ lookupSeqMap m i | i <- [0..] ]---- | Reverse the order of a finite sequence map-reverseSeqMap :: Integer     -- ^ Size of the sequence map-              -> SeqMap sym-              -> SeqMap sym-reverseSeqMap n vals = IndexSeqMap $ \i -> lookupSeqMap vals (n - 1 - i)--updateSeqMap :: SeqMap sym -> Integer -> SEval sym (GenValue sym) -> SeqMap sym-updateSeqMap (UpdateSeqMap m sm) i x = UpdateSeqMap (Map.insert i x m) sm-updateSeqMap (IndexSeqMap f) i x = UpdateSeqMap (Map.singleton i x) f---- | Concatenate the first @n@ values of the first sequence map onto the---   beginning of the second sequence map.-concatSeqMap :: Integer -> SeqMap sym -> SeqMap sym -> SeqMap sym-concatSeqMap n x y =-    IndexSeqMap $ \i ->-       if i < n-         then lookupSeqMap x i-         else lookupSeqMap y (i-n)---- | Given a number @n@ and a sequence map, return two new sequence maps:---   the first containing the values from @[0..n-1]@ and the next containing---   the values from @n@ onward.-splitSeqMap :: Integer -> SeqMap sym -> (SeqMap sym, SeqMap sym)-splitSeqMap n xs = (hd,tl)-  where-  hd = xs-  tl = IndexSeqMap $ \i -> lookupSeqMap xs (i+n)---- | Drop the first @n@ elements of the given 'SeqMap'.-dropSeqMap :: Integer -> SeqMap sym -> SeqMap sym-dropSeqMap 0 xs = xs-dropSeqMap n xs = IndexSeqMap $ \i -> lookupSeqMap xs (i+n)---- | Given a sequence map, return a new sequence map that is memoized using---   a finite map memo table.-memoMap :: Backend sym => sym -> SeqMap sym -> SEval sym (SeqMap sym)-memoMap sym x = do-  stk <- sGetCallStack sym-  cache <- liftIO $ newIORef $ Map.empty-  return $ IndexSeqMap (memo cache stk)--  where-  memo cache stk i = do-    mz <- liftIO (Map.lookup i <$> readIORef cache)-    case mz of-      Just z  -> return z-      Nothing -> sWithCallStack sym stk (doEval cache i)--  doEval cache i = do-    v <- lookupSeqMap x i-    liftIO $ atomicModifyIORef' cache (\m -> (Map.insert i v m, ()))-    return v---- | Apply the given evaluation function pointwise to the two given---   sequence maps.-zipSeqMap ::-  Backend sym =>-  sym ->-  (GenValue sym -> GenValue sym -> SEval sym (GenValue sym)) ->-  SeqMap sym ->-  SeqMap sym ->-  SEval sym (SeqMap sym)-zipSeqMap sym f x y =-  memoMap sym (IndexSeqMap $ \i -> join (f <$> lookupSeqMap x i <*> lookupSeqMap y i))---- | Apply the given function to each value in the given sequence map-mapSeqMap ::-  Backend sym =>-  sym ->-  (GenValue sym -> SEval sym (GenValue sym)) ->-  SeqMap sym -> SEval sym (SeqMap sym)-mapSeqMap sym f x =-  memoMap sym (IndexSeqMap $ \i -> f =<< lookupSeqMap x i)---- | For efficiency reasons, we handle finite sequences of bits as special cases---   in the evaluator.  In cases where we know it is safe to do so, we prefer to---   used a "packed word" representation of bit sequences.  This allows us to rely---   directly on Integer types (in the concrete evaluator) and SBV's Word types (in---   the symbolic simulator).------   However, if we cannot be sure all the bits of the sequence---   will eventually be forced, we must instead rely on an explicit sequence of bits---   representation.-data WordValue sym-  = WordVal !(SWord sym)                      -- ^ Packed word representation for bit sequences.-  | LargeBitsVal !Integer !(SeqMap sym)       -- ^ A large bitvector sequence, represented as a-                                            --   'SeqMap' of bits.- deriving (Generic)---- | Force a word value into packed word form-asWordVal :: Backend sym => sym -> WordValue sym -> SEval sym (SWord sym)-asWordVal _   (WordVal w)         = return w-asWordVal sym (LargeBitsVal n xs) = packWord sym =<< traverse (fromVBit <$>) (enumerateSeqMap n xs)---- | Force a word value into a sequence of bits-asBitsMap :: Backend sym => sym -> WordValue sym -> SeqMap sym-asBitsMap sym (WordVal w)  = IndexSeqMap $ \i -> VBit <$> (wordBit sym w i)-asBitsMap _   (LargeBitsVal _ xs) = xs---- | Turn a word value into a sequence of bits, forcing each bit.---   The sequence is returned in big-endian order.-enumerateWordValue :: Backend sym => sym -> WordValue sym -> SEval sym [SBit sym]-enumerateWordValue sym (WordVal w) = unpackWord sym w-enumerateWordValue _ (LargeBitsVal n xs) = traverse (fromVBit <$>) (enumerateSeqMap n xs)---- | Turn a word value into a sequence of bits, forcing each bit.---   The sequence is returned in reverse of the usual order, which is little-endian order.-enumerateWordValueRev :: Backend sym => sym -> WordValue sym -> SEval sym [SBit sym]-enumerateWordValueRev sym (WordVal w)  = reverse <$> unpackWord sym w-enumerateWordValueRev _   (LargeBitsVal n xs) = traverse (fromVBit <$>) (enumerateSeqMap n (reverseSeqMap n xs))---- | Compute the size of a word value-wordValueSize :: Backend sym => sym -> WordValue sym -> Integer-wordValueSize sym (WordVal w)  = wordLen sym w-wordValueSize _ (LargeBitsVal n _) = n---- | Select an individual bit from a word value-indexWordValue :: Backend sym => sym -> WordValue sym -> Integer -> SEval sym (SBit sym)-indexWordValue sym (WordVal w) idx-   | 0 <= idx && idx < wordLen sym w = wordBit sym w idx-   | otherwise = invalidIndex sym idx-indexWordValue sym (LargeBitsVal n xs) idx-   | 0 <= idx && idx < n = fromVBit <$> lookupSeqMap xs idx-   | otherwise = invalidIndex sym idx---- | Produce a new 'WordValue' from the one given by updating the @i@th bit with the---   given bit value.-updateWordValue :: Backend sym =>-  sym -> WordValue sym -> Integer -> SEval sym (SBit sym) -> SEval sym (WordValue sym)-updateWordValue sym (WordVal w) idx b-   | idx < 0 || idx >= wordLen sym w = invalidIndex sym idx-   | isReady sym b = WordVal <$> (wordUpdate sym w idx =<< b)--updateWordValue sym wv idx b-   | 0 <= idx && idx < wordValueSize sym wv =-        pure $ LargeBitsVal (wordValueSize sym wv) $ updateSeqMap (asBitsMap sym wv) idx (VBit <$> b)-   | otherwise = invalidIndex sym idx-- -- | Generic value type, parameterized by bit and word types. -- --   NOTE: we maintain an important invariant regarding sequence types.@@ -320,21 +109,16 @@   | VInteger !(SInteger sym)                   -- ^ @ Integer @ or @ Z n @   | VRational !(SRational sym)                 -- ^ @ Rational @   | VFloat !(SFloat sym)-  | VSeq !Integer !(SeqMap sym)                -- ^ @ [n]a   @+  | VSeq !Integer !(SeqMap sym (GenValue sym)) -- ^ @ [n]a   @                                                --   Invariant: VSeq is never a sequence of bits-  | VWord !Integer !(SEval sym (WordValue sym))  -- ^ @ [n]Bit @-  | VStream !(SeqMap sym)                   -- ^ @ [inf]a @+  | VWord !Integer !(WordValue sym)            -- ^ @ [n]Bit @+  | VStream !(SeqMap sym (GenValue sym))       -- ^ @ [inf]a @   | VFun  CallStack (SEval sym (GenValue sym) -> SEval sym (GenValue sym)) -- ^ functions   | VPoly CallStack (TValue -> SEval sym (GenValue sym))   -- ^ polymorphic values (kind *)   | VNumPoly CallStack (Nat' -> SEval sym (GenValue sym))  -- ^ polymorphic values (kind #)  deriving Generic  --- | Force the evaluation of a word value-forceWordValue :: Backend sym => WordValue sym -> SEval sym ()-forceWordValue (WordVal w)  = seq w (return ())-forceWordValue (LargeBitsVal n xs) = mapM_ (\x -> const () <$> x) (enumerateSeqMap n xs)- -- | Force the evaluation of a value forceValue :: Backend sym => GenValue sym -> SEval sym () forceValue v = case v of@@ -345,7 +129,7 @@   VInteger i  -> seq i (return ())   VRational q -> seq q (return ())   VFloat f    -> seq f (return ())-  VWord _ wv  -> forceWordValue =<< wv+  VWord _ wv  -> forceWordValue wv   VStream _   -> return ()   VFun{}      -> return ()   VPoly{}     -> return ()@@ -353,7 +137,7 @@   -instance Backend sym => Show (GenValue sym) where+instance Show (GenValue sym) where   show v = case v of     VRecord fs -> "record:" ++ show (displayOrder fs)     VTuple xs  -> "tuple:" ++ show (length xs)@@ -368,7 +152,6 @@     VPoly{}    -> "poly"     VNumPoly{} -> "numpoly" - -- Pretty Printing -------------------------------------------------------------  ppValue :: forall sym.@@ -382,30 +165,32 @@   loop :: GenValue sym -> SEval sym Doc   loop val = case val of     VRecord fs         -> do fs' <- traverse (>>= loop) fs-                             return $ braces (sep (punctuate comma (map ppField (displayFields fs'))))+                             return $ ppRecord (map ppField (fields fs'))       where       ppField (f,r) = pp f <+> char '=' <+> r     VTuple vals        -> do vals' <- traverse (>>=loop) vals-                             return $ parens (sep (punctuate comma vals'))+                             return $ ppTuple vals'     VBit b             -> ppSBit x b     VInteger i         -> ppSInteger x i     VRational q        -> ppSRational x q     VFloat i           -> ppSFloat x opts i     VSeq sz vals       -> ppWordSeq sz vals-    VWord _ wv         -> ppWordVal =<< wv+    VWord _ wv         -> ppWordVal wv     VStream vals       -> do vals' <- traverse (>>=loop) $ enumerateSeqMap (useInfLength opts) vals-                             return $ brackets $ fsep-                                   $ punctuate comma-                                   ( vals' ++ [text "..."]-                                   )+                             return $ ppList ( vals' ++ [text "..."] )     VFun{}             -> return $ text "<function>"     VPoly{}            -> return $ text "<polymorphic value>"     VNumPoly{}         -> return $ text "<polymorphic value>" +  fields :: RecordMap Ident Doc -> [(Ident, Doc)]+  fields = case useFieldOrder opts of+    DisplayOrder -> displayFields+    CanonicalOrder -> canonicalFields+   ppWordVal :: WordValue sym -> SEval sym Doc   ppWordVal w = ppSWord x opts =<< asWordVal x w -  ppWordSeq :: Integer -> SeqMap sym -> SEval sym Doc+  ppWordSeq :: Integer -> SeqMap sym (GenValue sym) -> SEval sym Doc   ppWordSeq sz vals = do     ws <- sequence (enumerateSeqMap sz vals)     case ws of@@ -416,9 +201,9 @@               case traverse (wordAsChar x) vs of                 Just str -> return $ text (show str)                 _ -> do vs' <- mapM (ppSWord x opts) vs-                        return $ brackets (fsep (punctuate comma vs'))+                        return $ ppList vs'       _ -> do ws' <- traverse loop ws-              return $ brackets (fsep (punctuate comma ws'))+              return $ ppList ws'  ppSBit :: Backend sym => sym -> SBit sym -> SEval sym Doc ppSBit sym b =@@ -485,7 +270,7 @@   prefix len = case base of     2  -> text "0b" <.> padding 1 len     8  -> text "0o" <.> padding 3 len-    10 -> empty+    10 -> mempty     16 -> text "0x" <.> padding 4 len     _  -> text "0"  <.> char '<' <.> int base <.> char '>' @@ -514,10 +299,10 @@ -- Value Constructors ----------------------------------------------------------  -- | Create a packed word of n bits.-word :: Backend sym => sym -> Integer -> Integer -> GenValue sym+word :: Backend sym => sym -> Integer -> Integer -> SEval sym (GenValue sym) word sym n i   | n >= Arch.maxBigIntWidth = wordTooWide n-  | otherwise                = VWord n (WordVal <$> wordLit sym n i)+  | otherwise                = VWord n . wordVal <$> wordLit sym n i   -- | Construct a function value@@ -544,36 +329,14 @@                      Nat i -> f i                      Inf   -> panic "ilam" [ "Unexpected `inf`" ]) --- | Generate a stream.-toStream :: Backend sym => sym -> [GenValue sym] -> SEval sym (GenValue sym)-toStream sym vs =-   VStream <$> infiniteSeqMap sym (map pure vs)--toFinSeq ::-  Backend sym =>-  sym -> Integer -> TValue -> [GenValue sym] -> GenValue sym-toFinSeq sym len elty vs-   | isTBit elty = VWord len (WordVal <$> packWord sym (map fromVBit vs))-   | otherwise   = VSeq len $ finiteSeqMap (map pure vs)- -- | Construct either a finite sequence, or a stream.  In the finite case, -- record whether or not the elements were bits, to aid pretty-printing.-toSeq ::-  Backend sym =>-  sym -> Nat' -> TValue -> [GenValue sym] -> SEval sym (GenValue sym)-toSeq sym len elty vals = case len of-  Nat n -> return $ toFinSeq sym n elty vals-  Inf   -> toStream sym vals----- | Construct either a finite sequence, or a stream.  In the finite case,--- record whether or not the elements were bits, to aid pretty-printing.-mkSeq :: Backend sym => Nat' -> TValue -> SeqMap sym -> GenValue sym-mkSeq len elty vals = case len of+mkSeq :: Backend sym => sym -> Nat' -> TValue -> SeqMap sym (GenValue sym) -> SEval sym (GenValue sym)+mkSeq sym len elty vals = case len of   Nat n-    | isTBit elty -> VWord n $ pure $ LargeBitsVal n vals-    | otherwise   -> VSeq n vals-  Inf             -> VStream vals+    | isTBit elty -> VWord n <$> bitmapWordVal sym n (fromVBit <$> vals)+    | otherwise   -> pure $ VSeq n vals+  Inf             -> pure $ VStream vals   -- Value Destructors -----------------------------------------------------------@@ -582,47 +345,47 @@ fromVBit :: GenValue sym -> SBit sym fromVBit val = case val of   VBit b -> b-  _      -> evalPanic "fromVBit" ["not a Bit"]+  _      -> evalPanic "fromVBit" ["not a Bit", show val]  -- | Extract an integer value. fromVInteger :: GenValue sym -> SInteger sym fromVInteger val = case val of   VInteger i -> i-  _      -> evalPanic "fromVInteger" ["not an Integer"]+  _      -> evalPanic "fromVInteger" ["not an Integer", show val]  -- | Extract a rational value. fromVRational :: GenValue sym -> SRational sym fromVRational val = case val of   VRational q -> q-  _      -> evalPanic "fromVRational" ["not a Rational"]+  _      -> evalPanic "fromVRational" ["not a Rational", show val]  -- | Extract a finite sequence value.-fromVSeq :: GenValue sym -> SeqMap sym+fromVSeq :: GenValue sym -> SeqMap sym (GenValue sym) fromVSeq val = case val of   VSeq _ vs -> vs-  _         -> evalPanic "fromVSeq" ["not a sequence"]+  _         -> evalPanic "fromVSeq" ["not a sequence", show val]  -- | Extract a sequence.-fromSeq :: Backend sym => String -> GenValue sym -> SEval sym (SeqMap sym)+fromSeq :: Backend sym => String -> GenValue sym -> SEval sym (SeqMap sym (GenValue sym)) fromSeq msg val = case val of   VSeq _ vs   -> return vs   VStream vs  -> return vs-  _           -> evalPanic "fromSeq" ["not a sequence", msg]+  _           -> evalPanic "fromSeq" ["not a sequence", msg, show val] -fromWordVal :: Backend sym => String -> GenValue sym -> SEval sym (WordValue sym)+fromWordVal :: Backend sym => String -> GenValue sym -> WordValue sym fromWordVal _msg (VWord _ wval) = wval-fromWordVal msg _ = evalPanic "fromWordVal" ["not a word value", msg]+fromWordVal msg val = evalPanic "fromWordVal" ["not a word value", msg, show val]  asIndex :: Backend sym =>-  sym -> String -> TValue -> GenValue sym -> SEval sym (Either (SInteger sym) (WordValue sym))-asIndex _sym _msg TVInteger (VInteger i) = pure (Left i)-asIndex _sym _msg _ (VWord _ wval) = Right <$> wval-asIndex _sym  msg _ _ = evalPanic "asIndex" ["not an index value", msg]+  sym -> String -> TValue -> GenValue sym -> Either (SInteger sym) (WordValue sym)+asIndex _sym _msg TVInteger (VInteger i) = Left i+asIndex _sym _msg _ (VWord _ wval) = Right wval+asIndex _sym  msg _ val = evalPanic "asIndex" ["not an index value", msg, show val]  -- | Extract a packed word. fromVWord :: Backend sym => sym -> String -> GenValue sym -> SEval sym (SWord sym)-fromVWord sym _msg (VWord _ wval) = wval >>= asWordVal sym-fromVWord _ msg _ = evalPanic "fromVWord" ["not a word", msg]+fromVWord sym _msg (VWord _ wval) = asWordVal sym wval+fromVWord _ msg val = evalPanic "fromVWord" ["not a word", msg, show val]  vWordLen :: Backend sym => GenValue sym -> Maybe Integer vWordLen val = case val of@@ -632,55 +395,119 @@ -- | If the given list of values are all fully-evaluated thunks --   containing bits, return a packed word built from the same bits. --   However, if any value is not a fully-evaluated bit, return 'Nothing'.-tryFromBits :: Backend sym => sym -> [SEval sym (GenValue sym)] -> Maybe (SEval sym (SWord sym))+tryFromBits :: Backend sym => sym -> [SEval sym (GenValue sym)] -> SEval sym (Maybe (SWord sym)) tryFromBits sym = go id   where-  go f [] = Just (packWord sym =<< sequence (f []))-  go f (v : vs) | isReady sym v = go (f . ((fromVBit <$> v):)) vs-  go _ (_ : _) = Nothing+  go f [] = Just <$> (packWord sym (f []))+  go f (v : vs) =+    isReady sym v >>= \case+      Just v' -> go (f . ((fromVBit v'):)) vs+      Nothing -> pure Nothing  -- | Extract a function from a value. fromVFun :: Backend sym => sym -> GenValue sym -> (SEval sym (GenValue sym) -> SEval sym (GenValue sym)) fromVFun sym val = case val of   VFun fnstk f ->     \x -> sModifyCallStack sym (\stk -> combineCallStacks stk fnstk) (f x)-  _ -> evalPanic "fromVFun" ["not a function"]+  _ -> evalPanic "fromVFun" ["not a function", show val]  -- | Extract a polymorphic function from a value. fromVPoly :: Backend sym => sym -> GenValue sym -> (TValue -> SEval sym (GenValue sym)) fromVPoly sym val = case val of   VPoly fnstk f ->     \x -> sModifyCallStack sym (\stk -> combineCallStacks stk fnstk) (f x)-  _ -> evalPanic "fromVPoly" ["not a polymorphic value"]+  _ -> evalPanic "fromVPoly" ["not a polymorphic value", show val]  -- | Extract a polymorphic function from a value. fromVNumPoly :: Backend sym => sym -> GenValue sym -> (Nat' -> SEval sym (GenValue sym)) fromVNumPoly sym val = case val of   VNumPoly fnstk f ->     \x -> sModifyCallStack sym (\stk -> combineCallStacks stk fnstk) (f x)-  _  -> evalPanic "fromVNumPoly" ["not a polymorphic value"]+  _  -> evalPanic "fromVNumPoly" ["not a polymorphic value", show val]  -- | Extract a tuple from a value. fromVTuple :: GenValue sym -> [SEval sym (GenValue sym)] fromVTuple val = case val of   VTuple vs -> vs-  _         -> evalPanic "fromVTuple" ["not a tuple"]+  _         -> evalPanic "fromVTuple" ["not a tuple", show val]  -- | Extract a record from a value. fromVRecord :: GenValue sym -> RecordMap Ident (SEval sym (GenValue sym)) fromVRecord val = case val of   VRecord fs -> fs-  _          -> evalPanic "fromVRecord" ["not a record"]+  _          -> evalPanic "fromVRecord" ["not a record", show val]  fromVFloat :: GenValue sym -> SFloat sym fromVFloat val =   case val of     VFloat x -> x-    _        -> evalPanic "fromVFloat" ["not a Float"]+    _        -> evalPanic "fromVFloat" ["not a Float", show val]  -- | Lookup a field in a record. lookupRecord :: Ident -> GenValue sym -> SEval sym (GenValue sym) lookupRecord f val =   case lookupField f (fromVRecord val) of     Just x  -> x-    Nothing -> evalPanic "lookupRecord" ["malformed record"]+    Nothing -> evalPanic "lookupRecord" ["malformed record", show val]+++-- Merge and if/then/else++{-# INLINE iteValue #-}+iteValue :: Backend sym =>+  sym ->+  SBit sym ->+  SEval sym (GenValue sym) ->+  SEval sym (GenValue sym) ->+  SEval sym (GenValue sym)+iteValue sym b x y+  | Just True  <- bitAsLit sym b = x+  | Just False <- bitAsLit sym b = y+  | otherwise = mergeValue' sym b x y++{-# INLINE mergeValue' #-}+mergeValue' :: Backend sym =>+  sym ->+  SBit sym ->+  SEval sym (GenValue sym) ->+  SEval sym (GenValue sym) ->+  SEval sym (GenValue sym)+mergeValue' sym = mergeEval sym (mergeValue sym)++mergeValue :: Backend sym =>+  sym ->+  SBit sym ->+  GenValue sym ->+  GenValue sym ->+  SEval sym (GenValue sym)+mergeValue sym c v1 v2 =+  case (v1, v2) of+    (VRecord fs1 , VRecord fs2 ) ->+      do let res = zipRecords (\_lbl -> mergeValue' sym c) fs1 fs2+         case res of+           Left f -> panic "Cryptol.Eval.Value" [ "mergeValue: incompatible record values", show f ]+           Right r -> pure (VRecord r)+    (VTuple vs1  , VTuple vs2  ) | length vs1 == length vs2  ->+                                  pure $ VTuple $ zipWith (mergeValue' sym c) vs1 vs2+    (VBit b1     , VBit b2     ) -> VBit <$> iteBit sym c b1 b2+    (VInteger i1 , VInteger i2 ) -> VInteger <$> iteInteger sym c i1 i2+    (VRational q1, VRational q2) -> VRational <$> iteRational sym c q1 q2+    (VFloat f1   , VFloat f2)    -> VFloat <$> iteFloat sym c f1 f2+    (VWord n1 w1 , VWord n2 w2 ) | n1 == n2 -> VWord n1 <$> mergeWord sym c w1 w2+    (VSeq n1 vs1 , VSeq n2 vs2 ) | n1 == n2 -> VSeq n1 <$> memoMap sym (Nat n1) (mergeSeqMapVal sym c vs1 vs2)+    (VStream vs1 , VStream vs2 ) -> VStream <$> memoMap sym Inf (mergeSeqMapVal sym c vs1 vs2)+    (f1@VFun{}   , f2@VFun{}   ) -> lam sym $ \x -> mergeValue' sym c (fromVFun sym f1 x) (fromVFun sym f2 x)+    (f1@VPoly{}  , f2@VPoly{}  ) -> tlam sym $ \x -> mergeValue' sym c (fromVPoly sym f1 x) (fromVPoly sym f2 x)+    (_           , _           ) -> panic "Cryptol.Eval.Value"+                                  [ "mergeValue: incompatible values", show v1, show v2 ]++{-# INLINE mergeSeqMapVal #-}+mergeSeqMapVal :: Backend sym =>+  sym ->+  SBit sym ->+  SeqMap sym (GenValue sym)->+  SeqMap sym (GenValue sym)->+  SeqMap sym (GenValue sym)+mergeSeqMapVal sym c x y =+  indexSeqMap $ \i ->+    iteValue sym c (lookupSeqMap x i) (lookupSeqMap y i)
src/Cryptol/Eval/What4.hs view
@@ -24,7 +24,7 @@ import           Control.Concurrent.MVar import           Control.Monad (foldM) import           Control.Monad.IO.Class-import           Data.Bits+ import qualified Data.Map as Map import qualified Data.Set as Set import           Data.Text (Text)@@ -40,6 +40,8 @@  import Cryptol.Backend import Cryptol.Backend.Monad ( EvalError(..), Unsupported(..) )+import Cryptol.Backend.SeqMap+import Cryptol.Backend.WordValue import Cryptol.Backend.What4  import Cryptol.Eval.Generic@@ -47,9 +49,10 @@ import Cryptol.Eval.Type (TValue(..)) import Cryptol.Eval.Value + import qualified Cryptol.SHA as SHA -import Cryptol.TypeCheck.Solver.InfNat( Nat'(..), widthInteger )+import Cryptol.TypeCheck.Solver.InfNat( Nat'(..) )  import Cryptol.Utils.Ident import Cryptol.Utils.Panic@@ -60,7 +63,6 @@ -- See also Cryptol.Prims.Eval.primTable primTable :: W4.IsSymExprBuilder sym => What4 sym -> IO EvalOpts -> Map.Map PrimIdent (Prim (What4 sym)) primTable sym getEOpts =-  let w4sym = w4 sym in   Map.union (suiteBPrims sym) $   Map.union (primeECPrims sym) $   Map.union (genericFloatTable sym) $@@ -68,25 +70,9 @@    Map.fromList $ map (\(n, v) -> (prelPrim n, v)) -  [ (">>$"         , sshrV sym)--    -- Shifts and rotates-  , ("<<"          , logicShift sym "<<"  shiftShrink-                        (w4bvShl w4sym) (w4bvLshr w4sym)-                        shiftLeftReindex shiftRightReindex)-  , (">>"          , logicShift sym ">>"  shiftShrink-                        (w4bvLshr w4sym) (w4bvShl w4sym)-                        shiftRightReindex shiftLeftReindex)-  , ("<<<"         , logicShift sym "<<<" rotateShrink-                        (w4bvRol w4sym) (w4bvRor w4sym)-                        rotateLeftReindex rotateRightReindex)-  , (">>>"         , logicShift sym ">>>" rotateShrink-                        (w4bvRor w4sym) (w4bvRol w4sym)-                        rotateRightReindex rotateLeftReindex)--    -- Indexing and updates-  , ("@"           , indexPrim sym (indexFront_int sym) (indexFront_bits sym) (indexFront_word sym))-  , ("!"           , indexPrim sym (indexBack_int sym) (indexBack_bits sym) (indexBack_word sym))+  [ -- Indexing and updates+    ("@"           , indexPrim sym IndexForward  (indexFront_int sym) (indexFront_segs sym))+  , ("!"           , indexPrim sym IndexBackward (indexFront_int sym) (indexFront_segs sym))    , ("update"      , updatePrim sym (updateFrontSym_word sym) (updateFrontSym sym))   , ("updateEnd"   , updatePrim sym (updateBackSym_word sym)  (updateBackSym sym))@@ -235,7 +221,7 @@              fn <- liftIO $ getUninterpFn sym ("AESKeyExpand" <> Text.pack (show k)) args (W4.BaseStructRepr ret)              z  <- liftIO $ W4.applySymFn (w4 sym) fn ws              -- compute a sequence that projects the relevant fields from the outout tuple-             pure $ VSeq (4*(k+7)) $ IndexSeqMap $ \i ->+             pure $ VSeq (4*(k+7)) $ indexSeqMap $ \i ->                case intIndex (fromInteger i) (size ret) of                  Just (Some idx) | Just W4.Refl <- W4.testEquality (ret!idx) (W4.BaseBVRepr (W4.knownNat @32)) ->                    fromWord32 =<< liftIO (W4.structField (w4 sym) z idx)@@ -250,7 +236,7 @@           addUninterpWarning sym "SHA-224"           initSt <- liftIO (mkSHA256InitialState sym SHA.initialSHA224State)           finalSt <- foldM (\st blk -> processSHA256Block sym st =<< blk) initSt blks-          pure $ VSeq 7 $ IndexSeqMap \i ->+          pure $ VSeq 7 $ indexSeqMap \i ->             case intIndex (fromInteger i) (knownSize :: Size SHA256State) of               Just (Some idx) ->                 do z <- liftIO $ W4.structField (w4 sym) finalSt idx@@ -268,7 +254,7 @@           addUninterpWarning sym "SHA-256"           initSt <- liftIO (mkSHA256InitialState sym SHA.initialSHA256State)           finalSt <- foldM (\st blk -> processSHA256Block sym st =<< blk) initSt blks-          pure $ VSeq 8 $ IndexSeqMap \i ->+          pure $ VSeq 8 $ indexSeqMap \i ->             case intIndex (fromInteger i) (knownSize :: Size SHA256State) of               Just (Some idx) ->                 do z <- liftIO $ W4.structField (w4 sym) finalSt idx@@ -286,7 +272,7 @@           addUninterpWarning sym "SHA-384"           initSt <- liftIO (mkSHA512InitialState sym SHA.initialSHA384State)           finalSt <- foldM (\st blk -> processSHA512Block sym st =<< blk) initSt blks-          pure $ VSeq 6 $ IndexSeqMap \i ->+          pure $ VSeq 6 $ indexSeqMap \i ->             case intIndex (fromInteger i) (knownSize :: Size SHA512State) of               Just (Some idx) ->                 do z <- liftIO $ W4.structField (w4 sym) finalSt idx@@ -304,7 +290,7 @@           addUninterpWarning sym "SHA-512"           initSt <- liftIO (mkSHA512InitialState sym SHA.initialSHA512State)           finalSt <- foldM (\st blk -> processSHA512Block sym st =<< blk) initSt blks-          pure $ VSeq 8 $ IndexSeqMap \i ->+          pure $ VSeq 8 $ indexSeqMap \i ->             case intIndex (fromInteger i) (knownSize :: Size SHA512State) of               Just (Some idx) ->                 do z <- liftIO $ W4.structField (w4 sym) finalSt idx@@ -459,7 +445,7 @@                            ]  toWord32 :: W4.IsSymExprBuilder sym =>-  What4 sym -> String -> SeqMap (What4 sym) -> Integer -> SEval (What4 sym) (W4.SymBV sym 32)+  What4 sym -> String -> SeqMap (What4 sym) (GenValue (What4 sym)) -> Integer -> SEval (What4 sym) (W4.SymBV sym 32) toWord32 sym nm ss i =   do x <- fromVWord sym nm =<< lookupSeqMap ss i      case x of@@ -467,11 +453,10 @@        _ -> panic nm ["Unexpected word size", show (SW.bvWidth x)]  fromWord32 :: W4.IsSymExprBuilder sym => W4.SymBV sym 32 -> SEval (What4 sym) (Value sym)-fromWord32 = pure . VWord 32 . pure . WordVal . SW.DBV-+fromWord32 = pure . VWord 32 . wordVal . SW.DBV  toWord64 :: W4.IsSymExprBuilder sym =>-  What4 sym -> String -> SeqMap (What4 sym) -> Integer -> SEval (What4 sym) (W4.SymBV sym 64)+  What4 sym -> String -> SeqMap (What4 sym) (GenValue (What4 sym)) -> Integer -> SEval (What4 sym) (W4.SymBV sym 64) toWord64 sym nm ss i =   do x <- fromVWord sym nm =<< lookupSeqMap ss i      case x of@@ -479,7 +464,7 @@        _ -> panic nm ["Unexpected word size", show (SW.bvWidth x)]  fromWord64 :: W4.IsSymExprBuilder sym => W4.SymBV sym 64 -> SEval (What4 sym) (Value sym)-fromWord64 = pure . VWord 64 . pure . WordVal . SW.DBV+fromWord64 = pure . VWord 64 . wordVal . SW.DBV   @@ -496,7 +481,7 @@      w3 <- toWord32 sym nm ss 3      fn <- liftIO $ getUninterpFn sym funNm argCtx (W4.BaseStructRepr argCtx)      z  <- liftIO $ W4.applySymFn (w4 sym) fn (Empty :> w0 :> w1 :> w2 :> w3)-     pure $ VSeq 4 $ IndexSeqMap \i ->+     pure $ VSeq 4 $ indexSeqMap \i ->        if | i == 0 -> fromWord32 =<< liftIO (W4.structField (w4 sym) z (natIndex @0))           | i == 1 -> fromWord32 =<< liftIO (W4.structField (w4 sym) z (natIndex @1))           | i == 2 -> fromWord32 =<< liftIO (W4.structField (w4 sym) z (natIndex @2))@@ -511,34 +496,12 @@    argCtx = W4.knownRepr  -sshrV :: W4.IsSymExprBuilder sym => What4 sym -> Prim (What4 sym)-sshrV sym =-  PFinPoly \n ->-  PTyPoly  \ix ->-  PWordFun \x ->-  PStrict  \y ->-  PPrim $-    asIndex sym ">>$" ix y >>= \case-       Left i ->-         do pneg <- intLessThan sym i =<< integerLit sym 0-            zneg <- do i' <- shiftShrink sym (Nat n) ix =<< intNegate sym i-                       amt <- wordFromInt sym n i'-                       w4bvShl (w4 sym) x amt-            zpos <- do i' <- shiftShrink sym (Nat n) ix i-                       amt <- wordFromInt sym n i'-                       w4bvAshr (w4 sym) x amt-            return (VWord (SW.bvWidth x) (WordVal <$> iteWord sym pneg zneg zpos))--       Right wv ->-         do amt <- asWordVal sym wv-            return (VWord (SW.bvWidth x) (WordVal <$> w4bvAshr (w4 sym) x amt))- indexFront_int ::   W4.IsSymExprBuilder sym =>   What4 sym ->   Nat' ->   TValue ->-  SeqMap (What4 sym) ->+  SeqMap (What4 sym) (GenValue (What4 sym)) ->   TValue ->   SInteger (What4 sym) ->   SEval (What4 sym) (Value sym)@@ -547,7 +510,9 @@   = lookupSeqMap xs i    | (lo, Just hi) <- bounds-  = foldr f def [lo .. hi]+  = case foldr f Nothing [lo .. hi] of+      Nothing -> raiseError sym (InvalidIndex Nothing)+      Just m  -> m    | otherwise   = liftIO (X.throw (UnsupportedSymbolicOp "unbounded integer indexing"))@@ -555,11 +520,10 @@  where     w4sym = w4 sym -    def = raiseError sym (InvalidIndex Nothing)--    f n y =+    f n (Just y) = Just $        do p <- liftIO (W4.intEq w4sym idx =<< W4.intLit w4sym n)           iteValue sym p (lookupSeqMap xs n) y+    f n Nothing = Just $ lookupSeqMap xs n      bounds =       (case W4.rangeLowBound (W4.integerBounds idx) of@@ -581,44 +545,34 @@         (Nat n, _)           -> Just n         (_    , TVIntMod m)  -> Just m         _                    -> Nothing--indexBack_int ::-  W4.IsSymExprBuilder sym =>-  What4 sym ->-  Nat' ->-  TValue ->-  SeqMap (What4 sym) ->-  TValue ->-  SInteger (What4 sym) ->-  SEval (What4 sym) (Value sym)-indexBack_int sym (Nat n) a xs ix idx = indexFront_int sym (Nat n) a (reverseSeqMap n xs) ix idx-indexBack_int _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["indexBack_int"]--indexFront_word ::+indexFront_segs ::   W4.IsSymExprBuilder sym =>   What4 sym ->   Nat' ->   TValue ->-  SeqMap (What4 sym) ->+  SeqMap (What4 sym) (GenValue (What4 sym)) ->   TValue ->-  SWord (What4 sym) ->+  Integer ->+  [IndexSegment (What4 sym)] ->   SEval (What4 sym) (Value sym)-indexFront_word sym mblen _a xs _ix idx+indexFront_segs sym mblen _a xs _ix _idx_bits [WordIndexSegment idx]   | Just i <- SW.bvAsUnsignedInteger idx   = lookupSeqMap xs i    | otherwise-  = foldr f def idxs+  = case foldr f Nothing idxs of+      Nothing -> raiseError sym (InvalidIndex Nothing)+      Just m  -> m   where     w4sym = w4 sym      w = SW.bvWidth idx-    def = raiseError sym (InvalidIndex Nothing) -    f n y =+    f n (Just y) = Just $        do p <- liftIO (SW.bvEq w4sym idx =<< SW.bvLit w4sym w n)           iteValue sym p (lookupSeqMap xs n) y+    f n Nothing = Just $ lookupSeqMap xs n      -- maximum possible in-bounds index given the bitwidth     -- of the index value and the length of the sequence@@ -635,112 +589,34 @@         Just (lo, hi) -> [lo .. min hi maxIdx]         _ -> [0 .. maxIdx] -indexBack_word ::-  W4.IsSymExprBuilder sym =>-  What4 sym ->-  Nat' ->-  TValue ->-  SeqMap (What4 sym) ->-  TValue ->-  SWord (What4 sym) ->-  SEval (What4 sym) (Value sym)-indexBack_word sym (Nat n) a xs ix idx = indexFront_word sym (Nat n) a (reverseSeqMap n xs) ix idx-indexBack_word _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["indexBack_word"]--indexFront_bits :: forall sym.-  W4.IsSymExprBuilder sym =>-  What4 sym ->-  Nat' ->-  TValue ->-  SeqMap (What4 sym) ->-  TValue ->-  [SBit (What4 sym)] ->-  SEval (What4 sym) (Value sym)-indexFront_bits sym mblen _a xs _ix bits0 = go 0 (length bits0) bits0- where-  go :: Integer -> Int -> [W4.Pred sym] -> W4Eval sym (Value sym)-  go i _k []-    -- For indices out of range, fail-    | Nat n <- mblen-    , i >= n-    = raiseError sym (InvalidIndex (Just i))--    | otherwise-    = lookupSeqMap xs i--  go i k (b:bs)-    -- Fail early when all possible indices we could compute from here-    -- are out of bounds-    | Nat n <- mblen-    , (i `shiftL` k) >= n-    = raiseError sym (InvalidIndex Nothing)--    | otherwise-    = iteValue sym b-         (go ((i `shiftL` 1) + 1) (k-1) bs)-         (go  (i `shiftL` 1)      (k-1) bs)--indexBack_bits ::-  W4.IsSymExprBuilder sym =>-  What4 sym ->-  Nat' ->-  TValue ->-  SeqMap (What4 sym) ->-  TValue ->-  [SBit (What4 sym)] ->-  SEval (What4 sym) (Value sym)-indexBack_bits sym (Nat n) a xs ix idx = indexFront_bits sym (Nat n) a (reverseSeqMap n xs) ix idx-indexBack_bits _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["indexBack_bits"]----- | Compare a symbolic word value with a concrete integer.-wordValueEqualsInteger :: forall sym.-  W4.IsSymExprBuilder sym =>-  What4 sym ->-  WordValue (What4 sym) ->-  Integer ->-  W4Eval sym (W4.Pred sym)-wordValueEqualsInteger sym wv i-  | wordValueSize sym wv < widthInteger i = return (W4.falsePred w4sym)-  | otherwise =-    case wv of-      WordVal w -> liftIO (SW.bvEq w4sym w =<< SW.bvLit w4sym (SW.bvWidth w) i)-      _ -> liftIO . bitsAre i =<< enumerateWordValueRev sym wv -- little-endian+indexFront_segs sym mblen _a xs _ix idx_bits segs =+  do xs' <- barrelShifter sym (mergeValue sym) shiftOp mblen xs idx_bits segs+     lookupSeqMap xs' 0   where-    w4sym = w4 sym+    shiftOp vs amt = pure (indexSeqMap (\i -> lookupSeqMap vs $! amt+i)) -    bitsAre :: Integer -> [W4.Pred sym] -> IO (W4.Pred sym)-    bitsAre n [] = pure (W4.backendPred w4sym (n == 0))-    bitsAre n (b : bs) =-      do pb  <- bitIs (testBit n 0) b-         pbs <- bitsAre (n `shiftR` 1) bs-         W4.andPred w4sym pb pbs -    bitIs :: Bool -> W4.Pred sym -> IO (W4.Pred sym)-    bitIs b x = if b then pure x else W4.notPred w4sym x- updateFrontSym ::   W4.IsSymExprBuilder sym =>   What4 sym ->   Nat' ->   TValue ->-  SeqMap (What4 sym) ->+  SeqMap (What4 sym) (GenValue (What4 sym)) ->   Either (SInteger (What4 sym)) (WordValue (What4 sym)) ->   SEval (What4 sym) (Value sym) ->-  SEval (What4 sym) (SeqMap (What4 sym))+  SEval (What4 sym) (SeqMap (What4 sym) (GenValue (What4 sym))) updateFrontSym sym _len _eltTy vs (Left idx) val =   case W4.asInteger idx of     Just i -> return $ updateSeqMap vs i val-    Nothing -> return $ IndexSeqMap $ \i ->+    Nothing -> return $ indexSeqMap $ \i ->       do b <- intEq sym idx =<< integerLit sym i          iteValue sym b val (lookupSeqMap vs i) -updateFrontSym sym _len _eltTy vs (Right wv) val =-  case wv of-    WordVal w | Just j <- SW.bvAsUnsignedInteger w ->-      return $ updateSeqMap vs j val-    _ ->-      memoMap sym $ IndexSeqMap $ \i ->+updateFrontSym sym len _eltTy vs (Right wv) val =+  wordValAsLit sym wv >>= \case+    Just j -> return $ updateSeqMap vs j val+    Nothing ->+      memoMap sym len $ indexSeqMap $ \i ->       do b <- wordValueEqualsInteger sym wv i          iteValue sym b val (lookupSeqMap vs i) @@ -749,25 +625,25 @@   What4 sym ->   Nat' ->   TValue ->-  SeqMap (What4 sym) ->+  SeqMap (What4 sym) (GenValue (What4 sym)) ->   Either (SInteger (What4 sym)) (WordValue (What4 sym)) ->   SEval (What4 sym) (Value sym) ->-  SEval (What4 sym) (SeqMap (What4 sym))+  SEval (What4 sym) (SeqMap (What4 sym) (GenValue (What4 sym))) updateBackSym _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["updateBackSym"]  updateBackSym sym (Nat n) _eltTy vs (Left idx) val =   case W4.asInteger idx of     Just i -> return $ updateSeqMap vs (n - 1 - i) val-    Nothing -> return $ IndexSeqMap $ \i ->+    Nothing -> return $ indexSeqMap $ \i ->       do b <- intEq sym idx =<< integerLit sym (n - 1 - i)          iteValue sym b val (lookupSeqMap vs i)  updateBackSym sym (Nat n) _eltTy vs (Right wv) val =-  case wv of-    WordVal w | Just j <- SW.bvAsUnsignedInteger w ->+  wordValAsLit sym wv >>= \case+    Just j ->       return $ updateSeqMap vs (n - 1 - j) val-    _ ->-      memoMap sym $ IndexSeqMap $ \i ->+    Nothing ->+      memoMap sym (Nat n) $ indexSeqMap $ \i ->       do b <- wordValueEqualsInteger sym wv (n - 1 - i)          iteValue sym b val (lookupSeqMap vs i) @@ -783,36 +659,11 @@   SEval (What4 sym) (WordValue (What4 sym)) updateFrontSym_word _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["updateFrontSym_word"] -updateFrontSym_word sym (Nat _) eltTy (LargeBitsVal n bv) idx val =-  LargeBitsVal n <$> updateFrontSym sym (Nat n) eltTy bv idx val--updateFrontSym_word sym (Nat n) eltTy (WordVal bv) (Left idx) val =+updateFrontSym_word sym (Nat n) _eltTy w (Left idx) val =   do idx' <- wordFromInt sym n idx-     updateFrontSym_word sym (Nat n) eltTy (WordVal bv) (Right (WordVal idx')) val--updateFrontSym_word sym (Nat n) eltTy bv (Right wv) val =-  case wv of-    WordVal idx-      | Just j <- SW.bvAsUnsignedInteger idx ->-          updateWordValue sym bv j (fromVBit <$> val)--      | WordVal bw <- bv ->-        WordVal <$>-          do b <- fromVBit <$> val-             let sz = SW.bvWidth bw-             highbit <- liftIO (SW.bvLit (w4 sym) sz (bit (fromInteger (sz-1))))-             msk <- w4bvLshr (w4 sym) highbit idx-             liftIO $-               case W4.asConstantPred b of-                 Just True  -> SW.bvOr  (w4 sym) bw msk-                 Just False -> SW.bvAnd (w4 sym) bw =<< SW.bvNot (w4 sym) msk-                 Nothing ->-                   do q <- SW.bvFill (w4 sym) sz b-                      bw' <- SW.bvAnd (w4 sym) bw =<< SW.bvNot (w4 sym) msk-                      SW.bvXor (w4 sym) bw' =<< SW.bvAnd (w4 sym) q msk--    _ -> LargeBitsVal (wordValueSize sym wv) <$>-           updateFrontSym sym (Nat n) eltTy (asBitsMap sym bv) (Right wv) val+     updateWordByWord sym IndexForward w (wordVal idx') (fromVBit <$> val)+updateFrontSym_word sym (Nat _n) _eltTy w (Right idx) val =+  updateWordByWord sym IndexForward w idx (fromVBit <$> val)   updateBackSym_word ::@@ -824,35 +675,10 @@   Either (SInteger (What4 sym)) (WordValue (What4 sym)) ->   SEval (What4 sym) (GenValue (What4 sym)) ->   SEval (What4 sym) (WordValue (What4 sym))-updateBackSym_word _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["updateBackSym_word"]--updateBackSym_word sym (Nat _) eltTy (LargeBitsVal n bv) idx val =-  LargeBitsVal n <$> updateBackSym sym (Nat n) eltTy bv idx val+updateBackSym_word _ Inf _ _ _ _ = evalPanic "Expected finite sequence" ["updateFrontSym_word"] -updateBackSym_word sym (Nat n) eltTy (WordVal bv) (Left idx) val =+updateBackSym_word sym (Nat n) _eltTy w (Left idx) val =   do idx' <- wordFromInt sym n idx-     updateBackSym_word sym (Nat n) eltTy (WordVal bv) (Right (WordVal idx')) val--updateBackSym_word sym (Nat n) eltTy bv (Right wv) val =-  case wv of-    WordVal idx-      | Just j <- SW.bvAsUnsignedInteger idx ->-          updateWordValue sym bv (n - 1 - j) (fromVBit <$> val)--      | WordVal bw <- bv ->-        WordVal <$>-          do b <- fromVBit <$> val-             let sz = SW.bvWidth bw-             lowbit <- liftIO (SW.bvLit (w4 sym) sz 1)-             msk <- w4bvShl (w4 sym) lowbit idx-             liftIO $-               case W4.asConstantPred b of-                 Just True  -> SW.bvOr  (w4 sym) bw msk-                 Just False -> SW.bvAnd (w4 sym) bw =<< SW.bvNot (w4 sym) msk-                 Nothing ->-                   do q <- SW.bvFill (w4 sym) sz b-                      bw' <- SW.bvAnd (w4 sym) bw =<< SW.bvNot (w4 sym) msk-                      SW.bvXor (w4 sym) bw' =<< SW.bvAnd (w4 sym) q msk--    _ -> LargeBitsVal (wordValueSize sym wv) <$>-           updateBackSym sym (Nat n) eltTy (asBitsMap sym bv) (Right wv) val+     updateWordByWord sym IndexBackward w (wordVal idx') (fromVBit <$> val)+updateBackSym_word sym (Nat _n) _eltTy w (Right idx) val =+  updateWordByWord sym IndexBackward w idx (fromVBit <$> val)
src/Cryptol/F2.hs view
@@ -32,7 +32,7 @@   pmod :: Int -> Integer -> Integer -> Integer-pmod w x m = mask .&. go 0 0 (reduce 1)+pmod w x m = go degree (x .&. mask) (clearBit m degree)   where     degree :: Int     degree = fromInteger (widthInteger m - 1)@@ -43,6 +43,7 @@      mask = bit degree - 1 +    -- invariant: z and p are in the range [0..mask]     go !i !z !p       | i < w     = go (i+1) (if testBit x i then z `xor` p else z) (reduce (p `shiftL` 1))       | otherwise = z
src/Cryptol/ModuleSystem.hs view
@@ -29,10 +29,12 @@   , renameType      -- * Interfaces-  , Iface(..), IfaceParams(..), IfaceDecls(..), genIface+  , Iface, IfaceG(..), IfaceParams(..), IfaceDecls(..), T.genIface   , IfaceTySyn, IfaceDecl(..)   ) where +import Data.Map (Map)+ import qualified Cryptol.Eval.Concrete as Concrete import           Cryptol.ModuleSystem.Env import           Cryptol.ModuleSystem.Interface@@ -44,6 +46,7 @@ import           Cryptol.Parser.Name (PName) import           Cryptol.Parser.NoPat (RemovePatterns) import qualified Cryptol.TypeCheck.AST     as T+import qualified Cryptol.TypeCheck.Interface as T import qualified Cryptol.Utils.Ident as M  -- Public Interface ------------------------------------------------------------@@ -93,7 +96,7 @@ evalExpr e env = runModuleM env (interactive (Base.evalExpr e))  -- | Typecheck top-level declarations.-checkDecls :: [P.TopDecl PName] -> ModuleCmd (R.NamingEnv,[T.DeclGroup])+checkDecls :: [P.TopDecl PName] -> ModuleCmd (R.NamingEnv,[T.DeclGroup], Map Name T.TySyn) checkDecls ds env = runModuleM env                   $ interactive                   $ Base.checkDecls ds@@ -105,10 +108,14 @@ noPat :: RemovePatterns a => a -> ModuleCmd a noPat a env = runModuleM env (interactive (Base.noPat a)) +-- | Rename a *use* of a value name. The distinction between uses and+-- binding is used to keep track of dependencies. renameVar :: R.NamingEnv -> PName -> ModuleCmd Name renameVar names n env = runModuleM env $ interactive $-  Base.rename M.interactiveName names (R.renameVar n)+  Base.rename M.interactiveName names (R.renameVar R.NameUse n) +-- | Rename a *use* of a type name. The distinction between uses and+-- binding is used to keep track of dependencies. renameType :: R.NamingEnv -> PName -> ModuleCmd Name renameType names n env = runModuleM env $ interactive $-  Base.rename M.interactiveName names (R.renameType n)+  Base.rename M.interactiveName names (R.renameType R.NameUse n)
src/Cryptol/ModuleSystem/Base.hs view
@@ -12,14 +12,38 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ImplicitParams #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-}  module Cryptol.ModuleSystem.Base where +import qualified Control.Exception as X+import Control.Monad (unless,when)+import Data.Maybe (fromMaybe)+import Data.Monoid ((<>))+import Data.Text.Encoding (decodeUtf8')+import Data.IORef(newIORef,readIORef)+import System.Directory (doesFileExist, canonicalizePath)+import System.FilePath ( addExtension+                       , isAbsolute+                       , joinPath+                       , (</>)+                       , normalise+                       , takeDirectory+                       , takeFileName+                       )+import qualified System.IO.Error as IOE+import qualified Data.Map as Map++import Prelude ()+import Prelude.Compat hiding ( (<>) )+++ import Cryptol.ModuleSystem.Env (DynamicEnv(..)) import Cryptol.ModuleSystem.Fingerprint import Cryptol.ModuleSystem.Interface import Cryptol.ModuleSystem.Monad-import Cryptol.ModuleSystem.Name (Name,liftSupply,PrimMap)+import Cryptol.ModuleSystem.Name (Name,liftSupply,PrimMap,ModPath(..)) import Cryptol.ModuleSystem.Env (lookupModule                                 , LoadedModule(..)                                 , meCoreLint, CoreLint(..)@@ -53,33 +77,21 @@                        , suiteBContents, primeECContents, preludeReferenceContents ) import Cryptol.Transform.MonoValues (rewModule) -import qualified Control.Exception as X-import Control.Monad (unless,when)-import Data.Maybe (fromMaybe)-import Data.Monoid ((<>))-import Data.Text.Encoding (decodeUtf8')-import System.Directory (doesFileExist, canonicalizePath)-import System.FilePath ( addExtension-                       , isAbsolute-                       , joinPath-                       , (</>)-                       , normalise-                       , takeDirectory-                       , takeFileName-                       )-import qualified System.IO.Error as IOE-import qualified Data.Map as Map -import Prelude ()-import Prelude.Compat hiding ( (<>) )-- -- Renaming --------------------------------------------------------------------  rename :: ModName -> R.NamingEnv -> R.RenameM a -> ModuleM a rename modName env m = do+  ifaces <- getIfaces   (res,ws) <- liftSupply $ \ supply ->-    case R.runRenamer supply modName env m of+    let info = R.RenamerInfo+                 { renSupply  = supply+                 , renContext = TopModule modName+                 , renEnv     = env+                 , renIfaces  = ifaces+                 }+    in+    case R.runRenamer info m of       (Right (a,supply'),ws) -> ((Right a,ws),supply')       (Left errs,ws)         -> ((Left errs,ws),supply) @@ -89,12 +101,8 @@     Left errs -> renamerErrors errs  -- | Rename a module in the context of its imported modules.-renameModule :: P.Module PName-             -> ModuleM (IfaceDecls,R.NamingEnv,P.Module Name)-renameModule m = do-  (decls,menv) <- importIfaces (map thing (P.mImports m))-  (declsEnv,rm) <- rename (thing (mName m)) menv (R.renameModule m)-  return (decls,declsEnv,rm)+renameModule :: P.Module PName -> ModuleM R.RenamedModule+renameModule m = rename (thing (mName m)) mempty (R.renameModule m)   -- NoPat -----------------------------------------------------------------------@@ -200,15 +208,18 @@       unless quiet $ withLogger logPutStrLn        ("Loading module " ++ pretty (P.thing (P.mName pm)))-     tcm <- optionalInstantiate =<< checkModule isrc path pm ++     (nameEnv,tcmod) <- checkModule isrc path pm+     tcm <- optionalInstantiate tcmod+      -- extend the eval env, unless a functor.      tbl <- Concrete.primTable <$> getEvalOptsAction      let ?evalPrim = \i -> Right <$> Map.lookup i tbl      callStacks <- getCallStacks      let ?callStacks = callStacks      unless (T.isParametrizedModule tcm) $ modifyEvalEnv (E.moduleEnv Concrete tcm)-     loadedModule path fp tcm+     loadedModule path fp nameEnv tcm       return tcm   where@@ -231,17 +242,6 @@ fullyQualified :: P.Import -> P.Import fullyQualified i = i { iAs = Just (iModule i) } --- | Find the interface referenced by an import, and generate the naming--- environment that it describes.-importIface :: P.Import -> ModuleM (IfaceDecls,R.NamingEnv)-importIface imp =-  do Iface { .. } <- getIface (T.iModule imp)-     return (ifPublic, R.interpImport imp ifPublic)---- | Load a series of interfaces, merging their public interfaces.-importIfaces :: [P.Import] -> ModuleM (IfaceDecls,R.NamingEnv)-importIfaces is = mconcat `fmap` mapM importIface is- moduleFile :: ModName -> String -> FilePath moduleFile n = addExtension (joinPath (modNameChunks n)) @@ -299,13 +299,13 @@ addPrelude m   | preludeName == P.thing (P.mName m) = m   | preludeName `elem` importedMods    = m-  | otherwise                          = m { mImports = importPrelude : mImports m }+  | otherwise                          = m { mDecls = importPrelude : mDecls m }   where   importedMods  = map (P.iModule . P.thing) (P.mImports m)-  importPrelude = P.Located+  importPrelude = P.DImport P.Located     { P.srcRange = emptyRange     , P.thing    = P.Import-      { iModule    = preludeName+      { iModule    = P.ImpTop preludeName       , iAs        = Nothing       , iSpec      = Nothing       }@@ -353,23 +353,20 @@ -- | Typecheck a group of declarations. -- -- INVARIANT: This assumes that NoPat has already been run on the declarations.-checkDecls :: [P.TopDecl PName] -> ModuleM (R.NamingEnv,[T.DeclGroup])+checkDecls :: [P.TopDecl PName] -> ModuleM (R.NamingEnv,[T.DeclGroup], Map.Map Name T.TySyn) checkDecls ds = do   fe <- getFocusedEnv   let params = mctxParams fe       decls  = mctxDecls  fe       names  = mctxNames  fe -  -- introduce names for the declarations before renaming them-  declsEnv <- liftSupply (R.namingEnv' (map (R.InModule interactiveName) ds))-  rds <- rename interactiveName (declsEnv `R.shadowing` names)-             (traverse R.rename ds)-+  (declsEnv,rds) <- rename interactiveName names+                  $ R.renameTopDecls interactiveName ds   prims <- getPrimMap   let act  = TCAction { tcAction = T.tcDecls, tcLinter = declsLinter                       , tcPrims = prims }-  ds' <- typecheck act rds params decls-  return (declsEnv,ds')+  (ds',tyMap) <- typecheck act rds params decls+  return (declsEnv,ds',tyMap)  -- | Generate the primitive map. If the prelude is currently being loaded, this -- should be generated directly from the naming environment given to the renamer@@ -390,12 +387,23 @@                   [ "Unable to find the prelude" ]  -- | Load a module, be it a normal module or a functor instantiation.-checkModule :: ImportSource -> ModulePath -> P.Module PName -> ModuleM T.Module+checkModule ::+  ImportSource -> ModulePath -> P.Module PName ->+  ModuleM (R.NamingEnv, T.Module) checkModule isrc path m =   case P.mInstance m of     Nothing -> checkSingleModule T.tcModule isrc path m-    Just fmName -> do tf <- getLoaded (thing fmName)-                      checkSingleModule (T.tcModuleInst tf) isrc path m+    Just fmName ->+      do mbtf <- getLoadedMaybe (thing fmName)+         case mbtf of+           Just tf ->+             do renThis <- io $ newIORef (lmNamingEnv tf)+                let how = T.tcModuleInst renThis (lmModule tf)+                (_,m') <- checkSingleModule how isrc path m+                newEnv <- io $ readIORef renThis+                pure (newEnv,m')+           Nothing -> panic "checkModule"+                        [ "Functor of module instantiation not loaded" ]   -- | Typecheck a single module.  If the module is an instantiation@@ -406,7 +414,7 @@   ImportSource                 {- ^ why are we loading this -} ->   ModulePath                   {- path -} ->   P.Module PName               {- ^ module to check -} ->-  ModuleM T.Module+  ModuleM (R.NamingEnv,T.Module) checkSingleModule how isrc path m = do    -- check that the name of the module matches expectations@@ -432,13 +440,13 @@   npm <- noPat nim    -- rename everything-  (tcEnv,declsEnv,scm) <- renameModule npm+  renMod <- renameModule npm    -- when generating the prim map for the typechecker, if we're checking the   -- prelude, we have to generate the map from the renaming environment, as we   -- don't have the interface yet.   prims <- if thing (mName m) == preludeName-              then return (R.toPrimMap declsEnv)+              then return (R.toPrimMap (R.rmDefines renMod))               else getPrimMap    -- typecheck@@ -447,11 +455,12 @@                      , tcPrims  = prims }  -  tcm0 <- typecheck act scm noIfaceParams tcEnv+  tcm0 <- typecheck act (R.rmModule renMod) noIfaceParams (R.rmImported renMod)    let tcm = tcm0 -- fromMaybe tcm0 (addModParams tcm0) -  liftSupply (`rewModule` tcm)+  rewMod <- liftSupply (`rewModule` tcm)+  pure (R.rmInScope renMod,rewMod)  data TCLinter o = TCLinter   { lintCheck ::@@ -473,11 +482,11 @@   , lintModule = Nothing   } -declsLinter :: TCLinter [ T.DeclGroup ]+declsLinter :: TCLinter ([ T.DeclGroup ], a) declsLinter = TCLinter-  { lintCheck = \ds' i -> case TcSanity.tcDecls i ds' of-                            Left err -> Left err-                            Right os -> Right os+  { lintCheck = \(ds',_) i -> case TcSanity.tcDecls i ds' of+                                Left err -> Left err+                                Right os -> Right os    , lintModule = Nothing   }@@ -529,16 +538,17 @@  -- | Generate input for the typechecker. genInferInput :: Range -> PrimMap -> IfaceParams -> IfaceDecls -> ModuleM T.InferInput-genInferInput r prims params env = do+genInferInput r prims params env' = do   seeds <- getNameSeeds   monoBinds <- getMonoBinds-  cfg <- getSolverConfig   solver <- getTCSolver   supply <- getSupply   searchPath <- getSearchPath   callStacks <- getCallStacks    -- TODO: include the environment needed by the module+  let env = flatPublicDecls env'+            -- XXX: we should really just pass this directly   return T.InferInput     { T.inpRange     = r     , T.inpVars      = Map.map ifDeclSig (ifDecls env)@@ -548,7 +558,6 @@     , T.inpNameSeeds = seeds     , T.inpMonoBinds = monoBinds     , T.inpCallStacks = callStacks-    , T.inpSolverConfig = cfg     , T.inpSearchPath = searchPath     , T.inpSupply    = supply     , T.inpPrimNames = prims
src/Cryptol/ModuleSystem/Env.hs view
@@ -11,6 +11,7 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-} module Cryptol.ModuleSystem.Env where  #ifndef RELOCATABLE@@ -24,6 +25,7 @@ import qualified Cryptol.ModuleSystem.NamingEnv as R import Cryptol.Parser.AST import qualified Cryptol.TypeCheck as T+import qualified Cryptol.TypeCheck.Interface as T import qualified Cryptol.TypeCheck.AST as T import Cryptol.Utils.PP (PP(..),text,parens,NameDisp) @@ -31,6 +33,7 @@ import Control.Monad (guard,mplus) import qualified Control.Exception as X import Data.Function (on)+import Data.Set(Set) import Data.Map (Map) import qualified Data.Map as Map import Data.Semigroup@@ -60,9 +63,6 @@   , meNameSeeds     :: T.NameSeeds     -- ^ A source of new names for the type checker. -  , meSolverConfig  :: T.SolverConfig-    -- ^ Configuration settings for the SMT solver used for type-checking.-   , meEvalEnv       :: EvalEnv     -- ^ The evaluation environment.  Contains the values for all loaded     -- modules, both public and private.@@ -150,12 +150,6 @@     , meSearchPath    = searchPath     , meDynEnv        = mempty     , meMonoBinds     = True-    , meSolverConfig  = T.SolverConfig-                          { T.solverPath = "z3"-                          , T.solverArgs = [ "-smt2", "-in" ]-                          , T.solverVerbose = 0-                          , T.solverPreludePath = searchPath-                          }     , meCoreLint      = NoCoreLint     , meSupply        = emptySupply     }@@ -194,91 +188,79 @@ -- or type check new expressions. data ModContext = ModContext   { mctxParams          :: IfaceParams+  , mctxExported        :: Set Name   , mctxDecls           :: IfaceDecls+    -- ^ Should contain at least names in NamingEnv, but may have more   , mctxNames           :: R.NamingEnv+    -- ^ What's in scope inside the module   , mctxNameDisp        :: NameDisp-  , mctxTypeProvenace   :: Map Name DeclProvenance-  , mctxValueProvenance :: Map Name DeclProvenance   } --- | Specifies how a declared name came to be in scope.-data DeclProvenance =-    NameIsImportedFrom ModName-  | NameIsLocalPublic-  | NameIsLocalPrivate-  | NameIsParameter-  | NameIsDynamicDecl-    deriving (Eq,Ord)+-- This instance is a bit bogus.  It is mostly used to add the dynamic+-- environemnt to an existing module, and it makes sense for that use case.+instance Semigroup ModContext where+  x <> y = ModContext { mctxParams   = jnParams (mctxParams x) (mctxParams y)+                      , mctxExported = mctxExported x <> mctxExported y+                      , mctxDecls    = mctxDecls x  <> mctxDecls  y+                      , mctxNames    = names+                      , mctxNameDisp = R.toNameDisp names+                      } +      where+      names = mctxNames x `R.shadowing` mctxNames y+      jnParams a b+        | isEmptyIfaceParams a = b+        | isEmptyIfaceParams b = a+        | otherwise =+          panic "ModContext" [ "Cannot combined 2 parameterized contexts" ] --- | Given the state of the environment, compute information about what's--- in scope on the REPL.  This includes what's in the focused module, plus any--- additional definitions from the REPL (e.g., let bound names, and @it@).-focusedEnv :: ModuleEnv -> ModContext-focusedEnv me =-  ModContext-    { mctxParams   = parameters-    , mctxDecls    = mconcat (dynDecls : localDecls : importedDecls)-    , mctxNames    = namingEnv-    , mctxNameDisp = R.toNameDisp namingEnv-    , mctxTypeProvenace = fst provenance-    , mctxValueProvenance = snd provenance-    }+instance Monoid ModContext where+  mempty = ModContext { mctxParams   = noIfaceParams+                      , mctxDecls    = mempty+                      , mctxExported = mempty+                      , mctxNames    = mempty+                      , mctxNameDisp = R.toNameDisp mempty+                      } -  where-  (importedNames,importedDecls,importedProvs) = unzip3 (map loadImport imports)-  localDecls    = publicDecls `mappend` privateDecls-  localNames    = R.unqualifiedEnv localDecls `mappend`-                                                R.modParamsNamingEnv parameters-  dynDecls      = deIfaceDecls (meDynEnv me)-  dynNames      = deNames (meDynEnv me) -  namingEnv     = dynNames   `R.shadowing`-                   localNames `R.shadowing`-                   mconcat importedNames -  provenance    = shadowProvs-                $ declsProv NameIsDynamicDecl dynDecls-                : declsProv NameIsLocalPublic publicDecls-                : declsProv NameIsLocalPrivate privateDecls-                : paramProv parameters-                : importedProvs+modContextOf :: ModName -> ModuleEnv -> Maybe ModContext+modContextOf mname me =+  do lm <- lookupModule mname me+     let localIface  = lmInterface lm+         localNames  = lmNamingEnv lm+         loadedDecls = map (ifPublic . lmInterface)+                     $ getLoadedModules (meLoadedModules me)+     pure ModContext+       { mctxParams   = ifParams localIface+       , mctxExported = ifaceDeclsNames (ifPublic localIface)+       , mctxDecls    = mconcat (ifPrivate localIface : loadedDecls)+       , mctxNames    = localNames+       , mctxNameDisp = R.toNameDisp localNames+       } -  (imports, parameters, publicDecls, privateDecls) =-    case meFocusedModule me of-      Nothing -> (mempty, noIfaceParams, mempty, mempty)-      Just fm ->-        case lookupModule fm me of-          Just lm ->-            let Iface { .. } = lmInterface lm-            in (T.mImports (lmModule lm), ifParams, ifPublic, ifPrivate)-          Nothing -> panic "focusedEnv" ["Focused module is not loaded."]+dynModContext :: ModuleEnv -> ModContext+dynModContext me = mempty { mctxNames    = dynNames+                          , mctxNameDisp = R.toNameDisp dynNames+                          , mctxDecls    = deIfaceDecls (meDynEnv me)+                          }+  where dynNames = deNames (meDynEnv me) -  loadImport imp =-    case lookupModule (iModule imp) me of-      Just lm ->-        let decls = ifPublic (lmInterface lm)-        in ( R.interpImport imp decls-           , decls-           , declsProv (NameIsImportedFrom (iModule imp)) decls-           )-      Nothing -> panic "focusedEnv"-                   [ "Missing imported module: " ++ show (pp (iModule imp)) ]  -  -- earlier ones shadow-  shadowProvs ps = let (tss,vss) = unzip ps-                   in (Map.unions tss, Map.unions vss) -  paramProv IfaceParams { .. } = (doMap ifParamTypes, doMap ifParamFuns)-    where doMap mp = const NameIsParameter <$> mp--  declsProv prov IfaceDecls { .. } =-    ( Map.unions [ doMap ifTySyns, doMap ifNewtypes, doMap ifAbstractTypes ]-    , doMap ifDecls-    )-    where doMap mp = const prov <$> mp-+-- | Given the state of the environment, compute information about what's+-- in scope on the REPL.  This includes what's in the focused module, plus any+-- additional definitions from the REPL (e.g., let bound names, and @it@).+focusedEnv :: ModuleEnv -> ModContext+focusedEnv me =+  case meFocusedModule me of+    Nothing -> dynModContext me+    Just fm -> case modContextOf fm me of+                 Just c -> dynModContext me <> c+                 Nothing -> panic "focusedEnv"+                              [ "Focused modules not loaded: " ++ show (pp fm) ]+    -- Loaded Modules -------------------------------------------------------------- @@ -350,9 +332,11 @@     -- For files we just use the cononical path, for in memory things we     -- use their label. +  , lmNamingEnv         :: !R.NamingEnv+    -- ^ What's in scope in this module+   , lmInterface         :: Iface-    -- ^ The module's interface. This is for convenient.  At the moment-    -- we have the whole module in 'lmModule', so this could be computer.+    -- ^ The module's interface.    , lmModule            :: T.Module     -- ^ The actual type-checked module@@ -378,8 +362,9 @@ -- | Add a freshly loaded module.  If it was previously loaded, then -- the new version is ignored. addLoadedModule ::-  ModulePath -> String -> Fingerprint -> T.Module -> LoadedModules -> LoadedModules-addLoadedModule path ident fp tm lm+  ModulePath -> String -> Fingerprint -> R.NamingEnv -> T.Module ->+  LoadedModules -> LoadedModules+addLoadedModule path ident fp nameEnv tm lm   | isLoaded (T.mName tm) lm  = lm   | T.isParametrizedModule tm = lm { lmLoadedParamModules = loaded :                                                 lmLoadedParamModules lm }@@ -390,7 +375,8 @@     { lmName            = T.mName tm     , lmFilePath        = path     , lmModuleId        = ident-    , lmInterface       = genIface tm+    , lmNamingEnv       = nameEnv+    , lmInterface       = T.genIface tm     , lmModule          = tm     , lmFingerprint     = fp     }@@ -414,37 +400,43 @@ data DynamicEnv = DEnv   { deNames :: R.NamingEnv   , deDecls :: [T.DeclGroup]+  , deTySyns :: Map Name T.TySyn   , deEnv   :: EvalEnv   } deriving Generic  instance Semigroup DynamicEnv where   de1 <> de2 = DEnv-    { deNames = deNames de1 <> deNames de2-    , deDecls = deDecls de1 <> deDecls de2-    , deEnv   = deEnv   de1 <> deEnv   de2+    { deNames  = deNames de1  <> deNames de2+    , deDecls  = deDecls de1  <> deDecls de2+    , deTySyns = deTySyns de1 <> deTySyns de2+    , deEnv    = deEnv   de1  <> deEnv   de2     }  instance Monoid DynamicEnv where   mempty = DEnv-    { deNames = mempty-    , deDecls = mempty-    , deEnv   = mempty+    { deNames  = mempty+    , deDecls  = mempty+    , deTySyns = mempty+    , deEnv    = mempty     }   mappend de1 de2 = de1 <> de2  -- | Build 'IfaceDecls' that correspond to all of the bindings in the -- dynamic environment. ----- XXX: if we ever add type synonyms or newtypes at the REPL, revisit+-- XXX: if we add newtypes, etc. at the REPL, revisit -- this. deIfaceDecls :: DynamicEnv -> IfaceDecls-deIfaceDecls DEnv { deDecls = dgs } =-  mconcat [ IfaceDecls-            { ifTySyns   = Map.empty-            , ifNewtypes = Map.empty-            , ifAbstractTypes = Map.empty-            , ifDecls    = Map.singleton (ifDeclName ifd) ifd-            }-          | decl <- concatMap T.groupDecls dgs-          , let ifd = mkIfaceDecl decl-          ]+deIfaceDecls DEnv { deDecls = dgs, deTySyns = tySyns } =+    IfaceDecls { ifTySyns = tySyns+               , ifNewtypes = Map.empty+               , ifAbstractTypes = Map.empty+               , ifDecls = decls+               , ifModules = Map.empty+               }+  where+    decls = mconcat+      [ Map.singleton (ifDeclName ifd) ifd+      | decl <- concatMap T.groupDecls dgs+      , let ifd = T.mkIfaceDecl decl+      ]
src/Cryptol/ModuleSystem/Exports.hs view
@@ -3,63 +3,80 @@  import Data.Set(Set) import qualified Data.Set as Set+import Data.Map(Map)+import qualified Data.Map as Map import Data.Foldable(fold) import Control.DeepSeq(NFData) import GHC.Generics (Generic)  import Cryptol.Parser.AST-import Cryptol.Parser.Names+import Cryptol.Parser.Names(namesD,tnamesD,tnamesNT)+import Cryptol.ModuleSystem.Name -modExports :: Ord name => Module name -> ExportSpec name+modExports :: Ord name => ModuleG mname name -> ExportSpec name modExports m = fold (concat [ exportedNames d | d <- mDecls m ])-  where-  names by td = [ td { tlValue = thing n } | n <- fst (by (tlValue td)) ] -  exportedNames (Decl td) = map exportBind  (names  namesD td)-                         ++ map exportType (names tnamesD td)-  exportedNames (DPrimType t) = [ exportType (thing . primTName <$> t) ]-  exportedNames (TDNewtype nt) = map exportType (names tnamesNT nt)-  exportedNames (Include {})  = []-  exportedNames (DParameterFun {}) = []-  exportedNames (DParameterType {}) = []-  exportedNames (DParameterConstraint {}) = [] +exportedNames :: Ord name => TopDecl name -> [ExportSpec name]+exportedNames (Decl td) = map exportBind  (names namesD td)+                       ++ map exportType (names tnamesD td)+exportedNames (DPrimType t) = [ exportType (thing . primTName <$> t) ]+exportedNames (TDNewtype nt) = map exportType (names tnamesNT nt)+exportedNames (Include {})  = []+exportedNames (DImport {}) = []+exportedNames (DParameterFun {}) = []+exportedNames (DParameterType {}) = []+exportedNames (DParameterConstraint {}) = []+exportedNames (DModule nested) =+  case tlValue nested of+    NestedModule x ->+      [exportName NSModule nested { tlValue = thing (mName x) }] +names :: (a -> ([Located a'], b)) -> TopLevel a -> [TopLevel a']+names by td = [ td { tlValue = thing n } | n <- fst (by (tlValue td)) ] -data ExportSpec name = ExportSpec { eTypes  :: Set name-                                  , eBinds  :: Set name-                                  } deriving (Show, Generic) +newtype ExportSpec name = ExportSpec (Map Namespace (Set name))+                                        deriving (Show, Generic)+ instance NFData name => NFData (ExportSpec name)  instance Ord name => Semigroup (ExportSpec name) where-  l <> r = ExportSpec { eTypes = eTypes l <> eTypes r-                      , eBinds = eBinds l <> eBinds  r-                      }+  ExportSpec l <> ExportSpec r = ExportSpec (Map.unionWith Set.union l r)  instance Ord name => Monoid (ExportSpec name) where-  mempty  = ExportSpec { eTypes = mempty, eBinds = mempty }-  mappend = (<>)+  mempty  = ExportSpec Map.empty +exportName :: Ord name => Namespace -> TopLevel name -> ExportSpec name+exportName ns n+  | tlExport n == Public = ExportSpec+                         $ Map.singleton ns+                         $ Set.singleton (tlValue n)+  | otherwise = mempty++exported :: Namespace -> ExportSpec name -> Set name+exported ns (ExportSpec mp) = Map.findWithDefault Set.empty ns mp+ -- | Add a binding name to the export list, if it should be exported. exportBind :: Ord name => TopLevel name -> ExportSpec name-exportBind n-  | tlExport n == Public = mempty { eBinds = Set.singleton (tlValue n) }-  | otherwise            = mempty+exportBind = exportName NSValue  -- | Add a type synonym name to the export list, if it should be exported. exportType :: Ord name => TopLevel name -> ExportSpec name-exportType n-  | tlExport n == Public = mempty { eTypes = Set.singleton (tlValue n) }-  | otherwise            = mempty+exportType = exportName NSType +++isExported :: Ord name => Namespace -> name -> ExportSpec name -> Bool+isExported ns x (ExportSpec s) =+  case Map.lookup ns s of+    Nothing -> False+    Just mp -> Set.member x mp+ -- | Check to see if a binding is exported. isExportedBind :: Ord name => name -> ExportSpec name -> Bool-isExportedBind n = Set.member n . eBinds+isExportedBind = isExported NSValue  -- | Check to see if a type synonym is exported. isExportedType :: Ord name => name -> ExportSpec name -> Bool-isExportedType n = Set.member n . eTypes---+isExportedType = isExported NSType
src/Cryptol/ModuleSystem/InstantiateModule.hs view
@@ -1,4 +1,5 @@ {-# Language FlexibleInstances, PatternGuards #-}+{-# Language BlockArguments #-} -- | Assumes that local names do not shadow top level names. module Cryptol.ModuleSystem.InstantiateModule   ( instantiateModule@@ -10,12 +11,13 @@ import qualified Data.Map as Map import           MonadLib(ReaderT,runReaderT,ask) +import Cryptol.Utils.Panic(panic)+import Cryptol.Utils.Ident(ModName,modParamIdent) import Cryptol.Parser.Position(Located(..)) import Cryptol.ModuleSystem.Name import Cryptol.TypeCheck.AST import Cryptol.TypeCheck.Subst(listParamSubst, apSubst) import Cryptol.TypeCheck.SimpType(tRebuild)-import Cryptol.Utils.Ident(ModName,modParamIdent)  {- XXX: Should we simplify constraints in the instantiated modules?@@ -33,15 +35,23 @@                      ModName          {- ^ Name of the new module -} ->                      Map TParam Type  {- ^ Type params -} ->                      Map Name Expr    {- ^ Value parameters -} ->-                     m ([Located Prop], Module)-                     -- ^ Instantiated constraints, fresh module, new supply-instantiateModule func newName tpMap vpMap =-  runReaderT newName $+                     m (Name -> Name, [Located Prop], Module)+                     -- ^ Renaming, instantiated constraints, fresh module, new supply+instantiateModule func newName tpMap vpMap+  | not (null (mSubModules func)) =+      panic "instantiateModule"+        [ "XXX: we don't support functors with nested moduels yet." ]+  | otherwise  =+  runReaderT (TopModule newName) $     do let oldVpNames = Map.keys vpMap        newVpNames <- mapM freshParamName (Map.keys vpMap)        let vpNames = Map.fromList (zip oldVpNames newVpNames)         env <- computeEnv func tpMap vpNames+       let ren x = case nameNamespace x of+                     NSValue -> Map.findWithDefault x x (funNameMap env)+                     NSType  -> Map.findWithDefault x x (tyNameMap env)+                     NSModule -> x         let rnMp :: Inst a => (a -> Name) -> Map Name a -> Map Name a            rnMp f m = Map.fromList [ (f x, x) | a <- Map.elems m@@ -60,7 +70,8 @@        let renamedDecls = inst env (mDecls func)            paramDecls = map (mkParamDecl su vpNames) (Map.toList vpMap) -       return ( goals+       return ( ren+              , goals               , Module                  { mName              = newName                  , mExports           = renamedExports@@ -72,6 +83,9 @@                  , mParamConstraints  = []                  , mParamFuns         = Map.empty                  , mDecls             = paramDecls ++ renamedDecls++                 , mSubModules        = mempty+                 , mFunctors          = mempty                  } )    where@@ -110,7 +124,7 @@  -------------------------------------------------------------------------------- -type InstM = ReaderT ModName+type InstM = ReaderT ModPath  -- | Generate a new instance of a declared name. freshenName :: FreshM m => Name -> InstM m Name@@ -119,13 +133,15 @@      let sys = case nameInfo x of                  Declared _ s -> s                  _            -> UserName-     liftSupply (mkDeclared m sys (nameIdent x) (nameFixity x) (nameLoc x))+     liftSupply (mkDeclared (nameNamespace x)+                             m sys (nameIdent x) (nameFixity x) (nameLoc x))  freshParamName :: FreshM m => Name -> InstM m Name freshParamName x =   do m <- ask      let newName = modParamIdent (nameIdent x)-     liftSupply (mkDeclared m UserName newName (nameFixity x) (nameLoc x))+     liftSupply (mkDeclared (nameNamespace x)+                          m UserName newName (nameFixity x) (nameLoc x))   @@ -263,11 +279,14 @@     where y = Map.findWithDefault x x (tyNameMap env)  instance Inst (ExportSpec Name) where-  inst env es = ExportSpec { eTypes = Set.map instT (eTypes es)-                           , eBinds = Set.map instV (eBinds es)-                           }-    where instT x = Map.findWithDefault x x (tyNameMap env)-          instV x = Map.findWithDefault x x (funNameMap env)+  inst env (ExportSpec spec) = ExportSpec (Map.mapWithKey doNS spec)+    where+    doNS ns =+      case ns of+        NSType  -> Set.map \x -> Map.findWithDefault x x (tyNameMap env)+        NSValue -> Set.map \x -> Map.findWithDefault x x (funNameMap env)+        NSModule -> id+  instance Inst TySyn where   inst env ts = TySyn { tsName = instTyName env x
src/Cryptol/ModuleSystem/Interface.hs view
@@ -12,24 +12,27 @@ {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-} module Cryptol.ModuleSystem.Interface (-    Iface(..)+    Iface+  , IfaceG(..)   , IfaceDecls(..)   , IfaceTySyn, ifTySynName   , IfaceNewtype-  , IfaceDecl(..), mkIfaceDecl+  , IfaceDecl(..)   , IfaceParams(..) -  , genIface+  , emptyIface   , ifacePrimMap   , noIfaceParams+  , isEmptyIfaceParams+  , ifaceIsFunctor+  , flatPublicIface+  , flatPublicDecls+  , filterIfaceDecls+  , ifaceDeclsNames   ) where -import           Cryptol.ModuleSystem.Name-import           Cryptol.TypeCheck.AST-import           Cryptol.Utils.Ident (ModName)-import           Cryptol.Utils.Panic(panic)-import           Cryptol.Parser.Position(Located)-+import           Data.Set(Set)+import qualified Data.Set as Set import qualified Data.Map as Map import           Data.Semigroup import           Data.Text (Text)@@ -40,15 +43,52 @@ import Prelude () import Prelude.Compat +import Cryptol.ModuleSystem.Name+import Cryptol.Utils.Ident (ModName)+import Cryptol.Utils.Panic(panic)+import Cryptol.Utils.Fixity(Fixity)+import Cryptol.Parser.AST(Pragma)+import Cryptol.Parser.Position(Located)+import Cryptol.TypeCheck.Type + -- | The resulting interface generated by a module that has been typechecked.-data Iface = Iface-  { ifModName   :: !ModName     -- ^ Module name+data IfaceG mname = Iface+  { ifModName   :: !mname       -- ^ Module name   , ifPublic    :: IfaceDecls   -- ^ Exported definitions   , ifPrivate   :: IfaceDecls   -- ^ Private defintiions   , ifParams    :: IfaceParams  -- ^ Uninterpreted constants (aka module params)   } deriving (Show, Generic, NFData) +ifaceIsFunctor :: IfaceG mname -> Bool+ifaceIsFunctor = not . isEmptyIfaceParams . ifParams++-- | The public declarations in all modules, including nested+-- The modules field contains public functors+-- Assumes that we are not a functor.+flatPublicIface :: IfaceG mname -> IfaceDecls+flatPublicIface iface = flatPublicDecls (ifPublic iface)+++flatPublicDecls :: IfaceDecls -> IfaceDecls+flatPublicDecls ifs = mconcat ( ifs { ifModules = fun }+                              : map flatPublicIface (Map.elems nofun)+                              )++  where+  (fun,nofun) = Map.partition ifaceIsFunctor (ifModules ifs)+++type Iface = IfaceG ModName++emptyIface :: mname -> IfaceG mname+emptyIface nm = Iface+  { ifModName = nm+  , ifPublic  = mempty+  , ifPrivate = mempty+  , ifParams  = noIfaceParams+  }+ data IfaceParams = IfaceParams   { ifParamTypes       :: Map.Map Name ModTParam   , ifParamConstraints :: [Located Prop] -- ^ Constraints on param. types@@ -62,29 +102,57 @@   , ifParamFuns = Map.empty   } +isEmptyIfaceParams :: IfaceParams -> Bool+isEmptyIfaceParams IfaceParams { .. } =+  Map.null ifParamTypes && null ifParamConstraints && Map.null ifParamFuns+ data IfaceDecls = IfaceDecls   { ifTySyns        :: Map.Map Name IfaceTySyn   , ifNewtypes      :: Map.Map Name IfaceNewtype   , ifAbstractTypes :: Map.Map Name IfaceAbstractType   , ifDecls         :: Map.Map Name IfaceDecl+  , ifModules       :: !(Map.Map Name (IfaceG Name))   } deriving (Show, Generic, NFData) +filterIfaceDecls :: (Name -> Bool) -> IfaceDecls -> IfaceDecls+filterIfaceDecls p ifs = IfaceDecls+  { ifTySyns        = filterMap (ifTySyns ifs)+  , ifNewtypes      = filterMap (ifNewtypes ifs)+  , ifAbstractTypes = filterMap (ifAbstractTypes ifs)+  , ifDecls         = filterMap (ifDecls ifs)+  , ifModules       = filterMap (ifModules ifs)+  }+  where+  filterMap :: Map.Map Name a -> Map.Map Name a+  filterMap = Map.filterWithKey (\k _ -> p k)++ifaceDeclsNames :: IfaceDecls -> Set Name+ifaceDeclsNames i = Set.unions [ Map.keysSet (ifTySyns i)+                               , Map.keysSet (ifNewtypes i)+                               , Map.keysSet (ifAbstractTypes i)+                               , Map.keysSet (ifDecls i)+                               , Map.keysSet (ifModules i)+                               ]++ instance Semigroup IfaceDecls where   l <> r = IfaceDecls     { ifTySyns   = Map.union (ifTySyns l)   (ifTySyns r)     , ifNewtypes = Map.union (ifNewtypes l) (ifNewtypes r)     , ifAbstractTypes = Map.union (ifAbstractTypes l) (ifAbstractTypes r)     , ifDecls    = Map.union (ifDecls l)    (ifDecls r)+    , ifModules  = Map.union (ifModules l)  (ifModules r)     }  instance Monoid IfaceDecls where-  mempty      = IfaceDecls Map.empty Map.empty Map.empty Map.empty+  mempty      = IfaceDecls Map.empty Map.empty Map.empty Map.empty Map.empty   mappend l r = l <> r   mconcat ds  = IfaceDecls     { ifTySyns   = Map.unions (map ifTySyns   ds)     , ifNewtypes = Map.unions (map ifNewtypes ds)     , ifAbstractTypes = Map.unions (map ifAbstractTypes ds)     , ifDecls    = Map.unions (map ifDecls    ds)+    , ifModules  = Map.unions (map ifModules ds)     }  type IfaceTySyn = TySyn@@ -103,61 +171,6 @@   , ifDeclFixity  :: Maybe Fixity   -- ^ Fixity information   , ifDeclDoc     :: Maybe Text     -- ^ Documentation   } deriving (Show, Generic, NFData)--mkIfaceDecl :: Decl -> IfaceDecl-mkIfaceDecl d = IfaceDecl-  { ifDeclName    = dName d-  , ifDeclSig     = dSignature d-  , ifDeclPragmas = dPragmas d-  , ifDeclInfix   = dInfix d-  , ifDeclFixity  = dFixity d-  , ifDeclDoc     = dDoc d-  }---- | Generate an Iface from a typechecked module.-genIface :: Module -> Iface-genIface m = Iface-  { ifModName = mName m--  , ifPublic      = IfaceDecls-    { ifTySyns    = tsPub-    , ifNewtypes  = ntPub-    , ifAbstractTypes = atPub-    , ifDecls     = dPub-    }--  , ifPrivate = IfaceDecls-    { ifTySyns    = tsPriv-    , ifNewtypes  = ntPriv-    , ifAbstractTypes = atPriv-    , ifDecls     = dPriv-    }--  , ifParams = IfaceParams-    { ifParamTypes = mParamTypes m-    , ifParamConstraints = mParamConstraints m-    , ifParamFuns  = mParamFuns m-    }-  }-  where--  (tsPub,tsPriv) =-      Map.partitionWithKey (\ qn _ -> qn `isExportedType` mExports m )-                          (mTySyns m)-  (ntPub,ntPriv) =-      Map.partitionWithKey (\ qn _ -> qn `isExportedType` mExports m )-                           (mNewtypes m)--  (atPub,atPriv) =-    Map.partitionWithKey (\qn _ -> qn `isExportedType` mExports m)-                         (mPrimTypes m)--  (dPub,dPriv) =-      Map.partitionWithKey (\ qn _ -> qn `isExportedBind` mExports m)-      $ Map.fromList [ (qn,mkIfaceDecl d) | dg <- mDecls m-                                          , d  <- groupDecls dg-                                          , let qn = dName d-                                          ]   -- | Produce a PrimMap from an interface.
src/Cryptol/ModuleSystem/Monad.hs view
@@ -21,6 +21,7 @@ import           Cryptol.ModuleSystem.Interface import           Cryptol.ModuleSystem.Name (FreshM(..),Supply) import           Cryptol.ModuleSystem.Renamer (RenamerError(),RenamerWarning())+import           Cryptol.ModuleSystem.NamingEnv(NamingEnv) import qualified Cryptol.Parser     as Parser import qualified Cryptol.Parser.AST as P import           Cryptol.Parser.Position (Located)@@ -201,7 +202,7 @@     FailedToParameterizeModDefs x xs ->       hang (text "[error] Parameterized module" <+> pp x <+>             text "has polymorphic parameters:")-        4 (hsep $ punctuate comma $ map pp xs)+         4 (commaSep (map pp xs))      NotAParameterizedModule x ->       text "[error] Module" <+> pp x <+> text "does not have parameters."@@ -463,12 +464,16 @@     _      -> return (FromModule noModuleName)  getIface :: P.ModName -> ModuleM Iface-getIface mn =-  do env <- ModuleT get-     case lookupModule mn env of-       Just lm -> return (lmInterface lm)-       Nothing -> panic "ModuleSystem" ["Interface not available", show (pp mn)]+getIface mn = ($ mn) <$> getIfaces +getIfaces :: ModuleM (P.ModName -> Iface)+getIfaces = doLookup <$> ModuleT get+  where+  doLookup env mn =+    case lookupModule mn env of+      Just lm -> lmInterface lm+      Nothing -> panic "ModuleSystem" ["Interface not available", show (pp mn)]+ getLoaded :: P.ModName -> ModuleM T.Module getLoaded mn = ModuleT $   do env <- get@@ -505,14 +510,16 @@   env <- get   set $! env { meLoadedModules = removeLoadedModule rm (meLoadedModules env) } -loadedModule :: ModulePath -> Fingerprint -> T.Module -> ModuleM ()-loadedModule path fp m = ModuleT $ do+loadedModule ::+  ModulePath -> Fingerprint -> NamingEnv -> T.Module -> ModuleM ()+loadedModule path fp nameEnv m = ModuleT $ do   env <- get   ident <- case path of              InFile p  -> unModuleT $ io (canonicalizePath p)              InMem l _ -> pure l -  set $! env { meLoadedModules = addLoadedModule path ident fp m (meLoadedModules env) }+  set $! env { meLoadedModules = addLoadedModule path ident fp nameEnv m+                                                        (meLoadedModules env) }  modifyEvalEnv :: (EvalEnv -> E.Eval EvalEnv) -> ModuleM () modifyEvalEnv f = ModuleT $ do@@ -569,16 +576,6 @@ setDynEnv denv = ModuleT $ do   me <- get   set $! me { meDynEnv = denv }--setSolver :: T.SolverConfig -> ModuleM ()-setSolver cfg = ModuleT $ do-  me <- get-  set $! me { meSolverConfig = cfg }--getSolverConfig :: ModuleM T.SolverConfig-getSolverConfig  = ModuleT $ do-  me <- get-  return (meSolverConfig me)  -- | Usefule for logging.  For example: @withLogger logPutStrLn "Hello"@ withLogger :: (Logger -> a -> IO b) -> a -> ModuleM b
src/Cryptol/ModuleSystem/Name.hs view
@@ -14,6 +14,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-} -- for the instances of RunM and BaseM {-# LANGUAGE UndecidableInstances #-} @@ -26,10 +27,13 @@   , nameInfo   , nameLoc   , nameFixity+  , nameNamespace   , asPrim-  , cmpNameLexical-  , cmpNameDisplay+  , asOrigName   , ppLocName+  , Namespace(..)+  , ModPath(..)+  , cmpNameDisplay      -- ** Creation   , mkDeclared@@ -49,33 +53,35 @@   , lookupPrimType   ) where -import           Cryptol.Parser.Position (Range,Located(..),emptyRange)-import           Cryptol.Utils.Fixity-import           Cryptol.Utils.Ident-import           Cryptol.Utils.Panic-import           Cryptol.Utils.PP-- import           Control.DeepSeq import qualified Data.Map as Map import qualified Data.Monoid as M-import           Data.Ord (comparing)-import qualified Data.Text as Text-import           Data.Char(isAlpha,toUpper) import           GHC.Generics (Generic) import           MonadLib import           Prelude () import           Prelude.Compat+import qualified Data.Text as Text+import           Data.Char(isAlpha,toUpper)  ++import           Cryptol.Parser.Position (Range,Located(..),emptyRange)+import           Cryptol.Utils.Fixity+import           Cryptol.Utils.Ident+import           Cryptol.Utils.Panic+import           Cryptol.Utils.PP+++ -- Names ----------------------------------------------------------------------- -- | Information about the binding site of the name.-data NameInfo = Declared !ModName !NameSource+data NameInfo = Declared !ModPath !NameSource                 -- ^ This name refers to a declaration from this module               | Parameter                 -- ^ This name is a parameter (function or type)                 deriving (Eq, Show, Generic, NFData) + data Name = Name { nUnique :: {-# UNPACK #-} !Int                    -- ^ INVARIANT: this field uniquely identifies a name for one                    -- session with the Cryptol library. Names are unique to@@ -84,6 +90,8 @@                  , nInfo :: !NameInfo                    -- ^ Information about the origin of this name. +                 , nNamespace :: !Namespace+                  , nIdent :: !Ident                    -- ^ The name of the identifier @@ -100,6 +108,7 @@ data NameSource = SystemName | UserName                     deriving (Generic, NFData, Show, Eq) + instance Eq Name where   a == b = compare a b == EQ   a /= b = compare a b /= EQ@@ -107,54 +116,41 @@ instance Ord Name where   compare a b = compare (nUnique a) (nUnique b) --- | Compare two names lexically.-cmpNameLexical :: Name -> Name -> Ordering-cmpNameLexical l r =-  case (nameInfo l, nameInfo r) of -    (Declared nsl _,Declared nsr _) ->-      case compare nsl nsr of-        EQ  -> comparing nameIdent l r-        cmp -> cmp -    (Parameter,Parameter) -> comparing nameIdent l r--    (Declared nsl _,Parameter) -> compare (modNameToText nsl)-                                          (identText (nameIdent r))-    (Parameter,Declared nsr _) -> compare (identText (nameIdent l))-                                          (modNameToText nsr)-- -- | Compare two names by the way they would be displayed.+-- This is used to order names nicely when showing what's in scope cmpNameDisplay :: NameDisp -> Name -> Name -> Ordering cmpNameDisplay disp l r =-  case (nameInfo l, nameInfo r) of+  case (asOrigName l, asOrigName r) of -    (Declared nsl _, Declared nsr _) -> -- XXX: uses system name info?-      let pfxl = fmtModName nsl (getNameFormat nsl (nameIdent l) disp)-          pfxr = fmtModName nsr (getNameFormat nsr (nameIdent r) disp)-       in case cmpText pfxl pfxr of-            EQ  -> cmpName l r-            cmp -> cmp+    (Just ogl, Just ogr) -> -- XXX: uses system name info?+       case cmpText (fmtPref ogl) (fmtPref ogr) of+         EQ  -> cmpName l r+         cmp -> cmp -    (Parameter,Parameter) -> cmpName l r+    (Nothing,Nothing) -> cmpName l r -    (Declared nsl _,Parameter) ->-      let pfxl = fmtModName nsl (getNameFormat nsl (nameIdent l) disp)-       in case cmpText pfxl (identText (nameIdent r)) of-            EQ  -> GT-            cmp -> cmp+    (Just ogl,Nothing) ->+       case cmpText (fmtPref ogl) (identText (nameIdent r)) of+         EQ  -> GT+         cmp -> cmp -    (Parameter,Declared nsr _) ->-      let pfxr = fmtModName nsr (getNameFormat nsr (nameIdent r) disp)-       in case cmpText (identText (nameIdent l)) pfxr of-            EQ  -> LT-            cmp -> cmp+    (Nothing,Just ogr) ->+       case cmpText (identText (nameIdent l)) (fmtPref ogr) of+         EQ  -> LT+         cmp -> cmp    where   cmpName xs ys  = cmpIdent (nameIdent xs) (nameIdent ys)   cmpIdent xs ys = cmpText (identText xs) (identText ys) +      --- let pfxl = fmtModName nsl (getNameFormat nsl (nameIdent l) disp)+  fmtPref og = case getNameFormat og disp of+                 UnQualified -> ""+                 Qualified q -> modNameToText q+                 NotInScope  -> Text.pack $ show $ pp (ogModule og)+   -- Note that this assumes that `xs` is `l` and `ys` is `r`   cmpText xs ys =     case (Text.null xs, Text.null ys) of@@ -169,23 +165,18 @@                | a == '_'   = 1                | otherwise  = 0 ++ -- | Figure out how the name should be displayed, by referencing the display -- function in the environment. NOTE: this function doesn't take into account -- the need for parentheses. ppName :: Name -> Doc-ppName Name { .. } =-  case nInfo of+ppName nm =+  case asOrigName nm of+    Just og -> pp og+    Nothing -> pp (nameIdent nm) -    Declared m _ -> withNameDisp $ \disp ->-      case getNameFormat m nIdent disp of-        Qualified m' -> ppQual m' <.> pp nIdent-        UnQualified  ->               pp nIdent-        NotInScope   -> ppQual m  <.> pp nIdent -- XXX: only when not in scope?-      where-      ppQual mo = if mo == exprModName then empty else pp mo <.> text "::" -    Parameter -> pp nIdent- instance PP Name where   ppPrec _ = ppPrefixName @@ -199,6 +190,7 @@    ppPrefixName n @ Name { .. } = optParens (isInfixIdent nIdent) (ppName n) + -- | Pretty-print a name with its source location information. ppLocName :: Name -> Doc ppLocName n = pp Located { srcRange = nameLoc n, thing = n }@@ -209,6 +201,9 @@ nameIdent :: Name -> Ident nameIdent  = nIdent +nameNamespace :: Name -> Namespace+nameNamespace = nNamespace+ nameInfo :: Name -> NameInfo nameInfo  = nInfo @@ -218,23 +213,33 @@ nameFixity :: Name -> Maybe Fixity nameFixity = nFixity -+-- | Primtiives must be in a top level module, at least for now. asPrim :: Name -> Maybe PrimIdent asPrim Name { .. } =   case nInfo of-    Declared p _ -> Just $ PrimIdent p $ identText nIdent-    _            -> Nothing+    Declared (TopModule m) _ -> Just $ PrimIdent m $ identText nIdent+    _                        -> Nothing  toParamInstName :: Name -> Name toParamInstName n =   case nInfo n of-    Declared m s -> n { nInfo = Declared (paramInstModName m) s }+    Declared m s -> n { nInfo = Declared (apPathRoot paramInstModName m) s }     Parameter   -> n  asParamName :: Name -> Name asParamName n = n { nInfo = Parameter } +asOrigName :: Name -> Maybe OrigName+asOrigName nm =+  case nInfo nm of+    Declared p _ ->+      Just OrigName { ogModule    = apPathRoot notParamInstModName  p+                    , ogNamespace = nNamespace nm+                    , ogName      = nIdent nm+                    }+    Parameter    -> Nothing + -- Name Supply -----------------------------------------------------------------  class Monad m => FreshM m where@@ -321,15 +326,17 @@ -- Name Construction -----------------------------------------------------------  -- | Make a new name for a declaration.-mkDeclared :: ModName -> NameSource -> Ident -> Maybe Fixity -> Range -> Supply -> (Name,Supply)-mkDeclared m sys nIdent nFixity nLoc s =+mkDeclared ::+  Namespace -> ModPath -> NameSource -> Ident -> Maybe Fixity -> Range ->+  Supply -> (Name,Supply)+mkDeclared nNamespace m sys nIdent nFixity nLoc s =   let (nUnique,s') = nextUnique s       nInfo        = Declared m sys    in (Name { .. }, s')  -- | Make a new parameter name.-mkParameter :: Ident -> Range -> Supply -> (Name,Supply)-mkParameter nIdent nLoc s =+mkParameter :: Namespace -> Ident -> Range -> Supply -> (Name,Supply)+mkParameter nNamespace nIdent nLoc s =   let (nUnique,s') = nextUnique s       nFixity      = Nothing    in (Name { nInfo = Parameter, .. }, s')@@ -340,6 +347,7 @@                         , nIdent  = packIdent "$modParams"                         , nLoc    = emptyRange                         , nUnique = 0x01+                        , nNamespace = NSValue                         }  -- Prim Maps -------------------------------------------------------------------
src/Cryptol/ModuleSystem/NamingEnv.hs view
@@ -15,23 +15,18 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE OverloadedStrings #-} module Cryptol.ModuleSystem.NamingEnv where -import Cryptol.ModuleSystem.Interface-import Cryptol.ModuleSystem.Name-import Cryptol.Parser.AST-import Cryptol.Parser.Name(isGeneratedName)-import Cryptol.Parser.Position-import qualified Cryptol.TypeCheck.AST as T-import Cryptol.Utils.PP-import Cryptol.Utils.Panic (panic)- import Data.List (nub)-import Data.Maybe (fromMaybe)+import Data.Maybe (fromMaybe,mapMaybe,maybeToList)+import           Data.Map.Strict (Map) import qualified Data.Map.Strict as Map+import           Data.Set (Set) import qualified Data.Set as Set import Data.Semigroup-import MonadLib (runId,Id)+import MonadLib (runId,Id,StateT,runStateT,lift,sets_,forM_)  import GHC.Generics (Generic) import Control.DeepSeq@@ -39,46 +34,71 @@ import Prelude () import Prelude.Compat +import Cryptol.Utils.PP+import Cryptol.Utils.Panic (panic)+import Cryptol.Parser.AST+import Cryptol.Parser.Name(isGeneratedName)+import Cryptol.Parser.Position+import qualified Cryptol.TypeCheck.AST as T+import Cryptol.ModuleSystem.Interface+import Cryptol.ModuleSystem.Name + -- Naming Environment ----------------------------------------------------------  -- | The 'NamingEnv' is used by the renamer to determine what -- identifiers refer to.-data NamingEnv = NamingEnv { neExprs :: !(Map.Map PName [Name])-                             -- ^ Expr renaming environment-                           , neTypes :: !(Map.Map PName [Name])-                             -- ^ Type renaming environment-                           } deriving (Show, Generic, NFData)+newtype NamingEnv = NamingEnv (Map Namespace (Map PName [Name]))+  deriving (Show,Generic,NFData) +-- | All names mentioned in the environment+namingEnvNames :: NamingEnv -> Set Name+namingEnvNames (NamingEnv xs) =+  Set.fromList $ concatMap (concat . Map.elems) $ Map.elems xs+++-- | Get the names in a given namespace+namespaceMap :: Namespace -> NamingEnv -> Map PName [Name]+namespaceMap ns (NamingEnv env) = Map.findWithDefault Map.empty ns env++-- | Resolve a name in the given namespace.+lookupNS :: Namespace -> PName -> NamingEnv -> [Name]+lookupNS ns x = Map.findWithDefault [] x . namespaceMap ns+ -- | Return a list of value-level names to which this parsed name may refer. lookupValNames :: PName -> NamingEnv -> [Name]-lookupValNames qn ro = Map.findWithDefault [] qn (neExprs ro)+lookupValNames = lookupNS NSValue  -- | Return a list of type-level names to which this parsed name may refer. lookupTypeNames :: PName -> NamingEnv -> [Name]-lookupTypeNames qn ro = Map.findWithDefault [] qn (neTypes ro)+lookupTypeNames = lookupNS NSType +-- | Singleton renaming environment for the given namespace.+singletonNS :: Namespace -> PName -> Name -> NamingEnv+singletonNS ns pn n = NamingEnv (Map.singleton ns (Map.singleton pn [n])) +-- | Singleton expression renaming environment.+singletonE :: PName -> Name -> NamingEnv+singletonE = singletonNS NSValue -instance Semigroup NamingEnv where-  l <> r   =-    NamingEnv { neExprs  = Map.unionWith merge (neExprs  l) (neExprs  r)-              , neTypes  = Map.unionWith merge (neTypes  l) (neTypes  r) }+-- | Singleton type renaming environment.+singletonT :: PName -> Name -> NamingEnv+singletonT = singletonNS NSType -instance Monoid NamingEnv where-  mempty        =-    NamingEnv { neExprs  = Map.empty-              , neTypes  = Map.empty } -  mappend l r   = l <> r+namingEnvRename :: (Name -> Name) -> NamingEnv -> NamingEnv+namingEnvRename f (NamingEnv mp) = NamingEnv (ren <$> mp)+  where+  ren nsm = map f <$> nsm -  mconcat envs  =-    NamingEnv { neExprs  = Map.unionsWith merge (map neExprs  envs)-              , neTypes  = Map.unionsWith merge (map neTypes  envs) } +instance Semigroup NamingEnv where+  NamingEnv l <> NamingEnv r =+      NamingEnv (Map.unionWith (Map.unionWith merge) l r)++instance Monoid NamingEnv where+  mempty = NamingEnv Map.empty   {-# INLINE mempty #-}-  {-# INLINE mappend #-}-  {-# INLINE mconcat #-}   -- | Merge two name maps, collapsing cases where the entries are the same, and@@ -87,62 +107,61 @@ merge xs ys | xs == ys  = xs             | otherwise = nub (xs ++ ys) +instance PP NamingEnv where+  ppPrec _ (NamingEnv mps)   = vcat $ map ppNS $ Map.toList mps+    where ppNS (ns,xs) = pp ns $$ nest 2 (vcat (map ppNm (Map.toList xs)))+          ppNm (x,as)  = pp x <+> "->" <+> commaSep (map pp as)+ -- | Generate a mapping from 'PrimIdent' to 'Name' for a -- given naming environment. toPrimMap :: NamingEnv -> PrimMap-toPrimMap NamingEnv { .. } = PrimMap { .. }+toPrimMap env =+  PrimMap+    { primDecls = fromNS NSValue+    , primTypes = fromNS NSType+    }   where+  fromNS ns = Map.fromList+                [ entry x | xs <- Map.elems (namespaceMap ns env), x <- xs ]+   entry n = case asPrim n of               Just p  -> (p,n)               Nothing -> panic "toPrimMap" [ "Not a declared name?"                                            , show n                                            ] -  primDecls = Map.fromList [ entry n | ns <- Map.elems neExprs, n  <- ns ]-  primTypes = Map.fromList [ entry n | ns <- Map.elems neTypes, n  <- ns ]  -- | Generate a display format based on a naming environment. toNameDisp :: NamingEnv -> NameDisp-toNameDisp NamingEnv { .. } = NameDisp display+toNameDisp env = NameDisp (`Map.lookup` names)   where-  display mn ident = Map.lookup (mn,ident) names--  -- only format declared names, as parameters don't need any special-  -- formatting.   names = Map.fromList-     $ [ mkEntry (mn, nameIdent n) pn | (pn,ns)       <- Map.toList neExprs-                                      , n             <- ns-                                      , Declared mn _ <- [nameInfo n] ]--    ++ [ mkEntry (mn, nameIdent n) pn | (pn,ns)       <- Map.toList neTypes-                                      , n             <- ns-                                      , Declared mn _ <- [nameInfo n] ]--  mkEntry key pn = (key,fmt)-    where fmt = case getModName pn of-                  Just ns -> Qualified ns-                  Nothing -> UnQualified+            [ (og, qn)+              | ns            <- [ NSValue, NSType, NSModule ]+              , (pn,xs)       <- Map.toList (namespaceMap ns env)+              , x             <- xs+              , og            <- maybeToList (asOrigName x)+              , let qn = case getModName pn of+                          Just q  -> Qualified q+                          Nothing -> UnQualified+            ]   -- | Produce sets of visible names for types and declarations. ----- NOTE: if entries in the NamingEnv would have produced a name clash, they will--- be omitted from the resulting sets.-visibleNames :: NamingEnv -> ({- types -} Set.Set Name-                             ,{- decls -} Set.Set Name)--visibleNames NamingEnv { .. } = (types,decls)+-- NOTE: if entries in the NamingEnv would have produced a name clash,+-- they will be omitted from the resulting sets.+visibleNames :: NamingEnv -> Map Namespace (Set Name)+visibleNames (NamingEnv env) = Set.fromList . mapMaybe check . Map.elems <$> env   where-  types = Set.fromList [ n | [n] <- Map.elems neTypes ]-  decls = Set.fromList [ n | [n] <- Map.elems neExprs ]+  check names =+    case names of+      [name] -> Just name+      _      -> Nothing  -- | Qualify all symbols in a 'NamingEnv' with the given prefix. qualify :: ModName -> NamingEnv -> NamingEnv-qualify pfx NamingEnv { .. } =-  NamingEnv { neExprs = Map.mapKeys toQual neExprs-            , neTypes = Map.mapKeys toQual neTypes-            }-+qualify pfx (NamingEnv env) = NamingEnv (Map.mapKeys toQual <$> env)   where   -- XXX we don't currently qualify fresh names   toQual (Qual _ n)  = Qual pfx n@@ -150,53 +169,87 @@   toQual n@NewName{} = n  filterNames :: (PName -> Bool) -> NamingEnv -> NamingEnv-filterNames p NamingEnv { .. } =-  NamingEnv { neExprs = Map.filterWithKey check neExprs-            , neTypes = Map.filterWithKey check neTypes-            }-  where-  check :: PName -> a -> Bool-  check n _ = p n+filterNames p (NamingEnv env) = NamingEnv (Map.filterWithKey check <$> env)+  where check n _ = p n  --- | Singleton type renaming environment.-singletonT :: PName -> Name -> NamingEnv-singletonT qn tn = mempty { neTypes = Map.singleton qn [tn] }---- | Singleton expression renaming environment.-singletonE :: PName -> Name -> NamingEnv-singletonE qn en = mempty { neExprs = Map.singleton qn [en] }- -- | Like mappend, but when merging, prefer values on the lhs. shadowing :: NamingEnv -> NamingEnv -> NamingEnv-shadowing l r = NamingEnv-  { neExprs  = Map.union (neExprs  l) (neExprs  r)-  , neTypes  = Map.union (neTypes  l) (neTypes  r) }+shadowing (NamingEnv l) (NamingEnv r) = NamingEnv (Map.unionWith Map.union l r)  travNamingEnv :: Applicative f => (Name -> f Name) -> NamingEnv -> f NamingEnv-travNamingEnv f ne = NamingEnv <$> neExprs' <*> neTypes'-  where-    neExprs' = traverse (traverse f) (neExprs ne)-    neTypes' = traverse (traverse f) (neTypes ne)+travNamingEnv f (NamingEnv mp) =+  NamingEnv <$> traverse (traverse (traverse f)) mp  -data InModule a = InModule !ModName a+{- | Do somethign in context.  If `Nothing` than we are working with+a local declaration. Otherwise we are at the top-level of the+given module. -}+data InModule a = InModule (Maybe ModPath) a                   deriving (Functor,Traversable,Foldable,Show)  --- | Generate a 'NamingEnv' using an explicit supply.-namingEnv' :: BindsNames a => a -> Supply -> (NamingEnv,Supply)-namingEnv' a supply = runId (runSupplyT supply (runBuild (namingEnv a)))--newTop :: FreshM m => ModName -> PName -> Maybe Fixity -> Range -> m Name-newTop ns thing fx rng = liftSupply (mkDeclared ns src (getIdent thing) fx rng)+newTop ::+  FreshM m => Namespace -> ModPath -> PName -> Maybe Fixity -> Range -> m Name+newTop ns m thing fx rng =+  liftSupply (mkDeclared ns m src (getIdent thing) fx rng)   where src = if isGeneratedName thing then SystemName else UserName -newLocal :: FreshM m => PName -> Range -> m Name-newLocal thing rng = liftSupply (mkParameter (getIdent thing) rng)+newLocal :: FreshM m => Namespace -> PName -> Range -> m Name+newLocal ns thing rng = liftSupply (mkParameter ns (getIdent thing) rng)  newtype BuildNamingEnv = BuildNamingEnv { runBuild :: SupplyT Id NamingEnv } ++buildNamingEnv :: BuildNamingEnv -> Supply -> (NamingEnv,Supply)+buildNamingEnv b supply = runId $ runSupplyT supply $ runBuild b++-- | Generate a 'NamingEnv' using an explicit supply.+defsOf :: BindsNames a => a -> Supply -> (NamingEnv,Supply)+defsOf = buildNamingEnv . namingEnv+++--------------------------------------------------------------------------------+-- Collect definitions of nested modules++type NestedMods = Map Name NamingEnv+type CollectM   = StateT NestedMods (SupplyT Id)++collectNestedModules ::+  NamingEnv -> Module PName -> Supply -> (NestedMods, Supply)+collectNestedModules env m =+  collectNestedModulesDecls env (thing (mName m)) (mDecls m)++collectNestedModulesDecls ::+  NamingEnv -> ModName -> [TopDecl PName] -> Supply -> (NestedMods, Supply)+collectNestedModulesDecls env m ds sup = (mp,newS)+  where+  s0            = Map.empty+  mpath         = TopModule m+  ((_,mp),newS) = runId $ runSupplyT sup $ runStateT s0 $+                  collectNestedModulesDs mpath env ds++collectNestedModulesDs :: ModPath -> NamingEnv -> [TopDecl PName] -> CollectM ()+collectNestedModulesDs mpath env ds =+  forM_ [ tlValue nm | DModule nm <- ds ] \(NestedModule nested) ->+    do let pname = thing (mName nested)+           name  = case lookupNS NSModule pname env of+                     n : _ -> n -- if a name is ambiguous we may get+                                -- multiple answers, but we just pick one.+                                -- This should be OK, as the error should be+                                -- caught during actual renaming.+                     _   -> panic "collectedNestedModulesDs"+                             [ "Missing definition for " ++ show pname ]+       newEnv <- lift (runBuild (moduleDefs (Nested mpath (nameIdent name)) nested))+       sets_ (Map.insert name newEnv)+       let newMPath = Nested mpath (nameIdent name)+       collectNestedModulesDs newMPath newEnv (mDecls nested)++--------------------------------------------------------------------------------++++ instance Semigroup BuildNamingEnv where   BuildNamingEnv a <> BuildNamingEnv b = BuildNamingEnv $     do x <- a@@ -212,6 +265,10 @@     do ns <- sequence (map runBuild bs)        return (mconcat ns) +--------------------------------------------------------------------------------+++ -- | Things that define exported names. class BindsNames a where   namingEnv :: a -> BuildNamingEnv@@ -235,12 +292,12 @@   {-# INLINE namingEnv #-}  --- | Interpret an import in the context of an interface, to produce a name--- environment for the renamer, and a 'NameDisp' for pretty-printing.-interpImport :: Import     {- ^ The import declarations -} ->-                IfaceDecls {- ^ Declarations of imported module -} ->++-- | Adapt the things exported by something to the specific import/open.+interpImportEnv :: ImportG name  {- ^ The import declarations -} ->+                NamingEnv     {- ^ All public things coming in -} ->                 NamingEnv-interpImport imp publicDecls = qualified+interpImportEnv imp public = qualified   where    -- optionally qualify names based on the import@@ -257,16 +314,21 @@      | otherwise = public -  -- generate the initial environment from the public interface, where no names-  -- are qualified-  public = unqualifiedEnv publicDecls  +-- | Interpret an import in the context of an interface, to produce a name+-- environment for the renamer, and a 'NameDisp' for pretty-printing.+interpImportIface :: Import     {- ^ The import declarations -} ->+                IfaceDecls {- ^ Declarations of imported module -} ->+                NamingEnv+interpImportIface imp = interpImportEnv imp . unqualifiedEnv++ -- | Generate a naming environment from a declaration interface, where none of -- the names are qualified. unqualifiedEnv :: IfaceDecls -> NamingEnv unqualifiedEnv IfaceDecls { .. } =-  mconcat [ exprs, tySyns, ntTypes, absTys, ntExprs ]+  mconcat [ exprs, tySyns, ntTypes, absTys, ntExprs, mods ]   where   toPName n = mkUnqual (nameIdent n) @@ -275,16 +337,17 @@   ntTypes = mconcat [ singletonT (toPName n) n | n <- Map.keys ifNewtypes ]   absTys  = mconcat [ singletonT (toPName n) n | n <- Map.keys ifAbstractTypes ]   ntExprs = mconcat [ singletonE (toPName n) n | n <- Map.keys ifNewtypes ]-+  mods    = mconcat [ singletonNS NSModule (toPName n) n+                                                | n <- Map.keys ifModules ]  -- | Compute an unqualified naming environment, containing the various module -- parameters. modParamsNamingEnv :: IfaceParams -> NamingEnv modParamsNamingEnv IfaceParams { .. } =-  NamingEnv { neExprs = Map.fromList $ map fromFu $ Map.keys ifParamFuns-            , neTypes = Map.fromList $ map fromTy $ Map.elems ifParamTypes-            }-+  NamingEnv $ Map.fromList+    [ (NSValue, Map.fromList $ map fromFu $ Map.keys ifParamFuns)+    , (NSType,  Map.fromList $ map fromTy $ Map.elems ifParamTypes)+    ]   where   toPName n = mkUnqual (nameIdent n) @@ -301,14 +364,16 @@ -- mapping only from unqualified names to qualified ones. instance BindsNames ImportIface where   namingEnv (ImportIface imp Iface { .. }) = BuildNamingEnv $-    return (interpImport imp ifPublic)+    return (interpImportIface imp ifPublic)   {-# INLINE namingEnv #-}  -- | Introduce the name instance BindsNames (InModule (Bind PName)) where-  namingEnv (InModule ns b) = BuildNamingEnv $+  namingEnv (InModule mb b) = BuildNamingEnv $     do let Located { .. } = bName b-       n <- newTop ns thing (bFixity b) srcRange+       n <- case mb of+              Just m  -> newTop NSValue m thing (bFixity b) srcRange+              Nothing -> newLocal NSValue thing srcRange -- local fixitiies?         return (singletonE thing n) @@ -316,16 +381,19 @@ instance BindsNames (TParam PName) where   namingEnv TParam { .. } = BuildNamingEnv $     do let range = fromMaybe emptyRange tpRange-       n <- newLocal tpName range+       n <- newLocal NSType tpName range        return (singletonT tpName n)  -- | The naming environment for a single module.  This is the mapping from -- unqualified names to fully qualified names with uniques. instance BindsNames (Module PName) where-  namingEnv Module { .. } = foldMap (namingEnv . InModule ns) mDecls-    where-    ns = thing mName+  namingEnv m = moduleDefs (TopModule (thing (mName m))) m ++moduleDefs :: ModPath -> ModuleG mname PName -> BuildNamingEnv+moduleDefs m Module { .. } = foldMap (namingEnv . InModule (Just m)) mDecls++ instance BindsNames (InModule (TopDecl PName)) where   namingEnv (InModule ns td) =     case td of@@ -335,60 +403,70 @@       DParameterType d -> namingEnv (InModule ns d)       DParameterConstraint {} -> mempty       DParameterFun  d -> namingEnv (InModule ns d)-      Include _   -> mempty+      Include _        -> mempty+      DImport {}       -> mempty -- see 'openLoop' in the renamer+      DModule m        -> namingEnv (InModule ns (tlValue m)) ++instance BindsNames (InModule (NestedModule PName)) where+  namingEnv (InModule ~(Just m) (NestedModule mdef)) = BuildNamingEnv $+    do let pnmame = mName mdef+       nm   <- newTop NSModule m (thing pnmame) Nothing (srcRange pnmame)+       pure (singletonNS NSModule (thing pnmame) nm)+ instance BindsNames (InModule (PrimType PName)) where-  namingEnv (InModule ns PrimType { .. }) =+  namingEnv (InModule ~(Just m) PrimType { .. }) =     BuildNamingEnv $       do let Located { .. } = primTName-         nm <- newTop ns thing primTFixity srcRange+         nm <- newTop NSType m thing primTFixity srcRange          pure (singletonT thing nm)  instance BindsNames (InModule (ParameterFun PName)) where-  namingEnv (InModule ns ParameterFun { .. }) = BuildNamingEnv $+  namingEnv (InModule ~(Just ns) ParameterFun { .. }) = BuildNamingEnv $     do let Located { .. } = pfName-       ntName <- newTop ns thing pfFixity srcRange+       ntName <- newTop NSValue ns thing pfFixity srcRange        return (singletonE thing ntName)  instance BindsNames (InModule (ParameterType PName)) where-  namingEnv (InModule ns ParameterType { .. }) = BuildNamingEnv $+  namingEnv (InModule ~(Just ns) ParameterType { .. }) = BuildNamingEnv $     -- XXX: we don't seem to have a fixity environment at the type level     do let Located { .. } = ptName-       ntName <- newTop ns thing Nothing srcRange+       ntName <- newTop NSType ns thing Nothing srcRange        return (singletonT thing ntName)  -- NOTE: we use the same name at the type and expression level, as there's only -- ever one name introduced in the declaration. The names are only ever used in -- different namespaces, so there's no ambiguity. instance BindsNames (InModule (Newtype PName)) where-  namingEnv (InModule ns Newtype { .. }) = BuildNamingEnv $+  namingEnv (InModule ~(Just ns) Newtype { .. }) = BuildNamingEnv $     do let Located { .. } = nName-       ntName <- newTop ns thing Nothing srcRange+       ntName <- newTop NSType ns thing Nothing srcRange+       -- XXX: the name reuse here is sketchy        return (singletonT thing ntName `mappend` singletonE thing ntName)  -- | The naming environment for a single declaration. instance BindsNames (InModule (Decl PName)) where   namingEnv (InModule pfx d) = case d of-    DBind b -> BuildNamingEnv $-      do n <- mkName (bName b) (bFixity b)-         return (singletonE (thing (bName b)) n)-+    DBind b                 -> namingEnv (InModule pfx b)     DSignature ns _sig      -> foldMap qualBind ns     DPragma ns _p           -> foldMap qualBind ns     DType syn               -> qualType (tsName syn) (tsFixity syn)     DProp syn               -> qualType (psName syn) (psFixity syn)     DLocated d' _           -> namingEnv (InModule pfx d')-    DPatBind _pat _e        -> panic "ModuleSystem" ["Unexpected pattern binding"]-    DFixity{}               -> panic "ModuleSystem" ["Unexpected fixity declaration"]+    DRec {}                 -> panic "namingEnv" [ "DRec" ]+    DPatBind _pat _e        -> panic "namingEnv" ["Unexpected pattern binding"]+    DFixity{}               -> panic "namingEnv" ["Unexpected fixity declaration"]      where -    mkName ln fx = newTop pfx (thing ln) fx (srcRange ln)+    mkName ns ln fx = case pfx of+                        Just m  -> newTop ns m (thing ln) fx (srcRange ln)+                        Nothing -> newLocal ns (thing ln) (srcRange ln)      qualBind ln = BuildNamingEnv $-      do n <- mkName ln Nothing+      do n <- mkName NSValue ln Nothing          return (singletonE (thing ln) n)      qualType ln f = BuildNamingEnv $-      do n <- mkName ln f+      do n <- mkName NSType ln f          return (singletonT (thing ln) n)
src/Cryptol/ModuleSystem/Renamer.hs view
@@ -6,19 +6,13 @@ -- Stability   :  provisional -- Portability :  portable -{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE PatternGuards #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE OverloadedStrings #-}+{-# Language RecordWildCards #-}+{-# Language FlexibleInstances #-}+{-# Language FlexibleContexts #-}+{-# Language BlockArguments #-} module Cryptol.ModuleSystem.Renamer (     NamingEnv(), shadowing-  , BindsNames(..), InModule(..), namingEnv'-  , checkNamingEnv+  , BindsNames(..), InModule(..)   , shadowNames   , Rename(..), runRenamer, RenameM()   , RenamerError(..)@@ -26,429 +20,449 @@   , renameVar   , renameType   , renameModule+  , renameTopDecls+  , RenamerInfo(..)+  , NameType(..)+  , RenamedModule(..)   ) where +import Prelude ()+import Prelude.Compat++import Data.Either(partitionEithers)+import Data.Maybe(fromJust)+import Data.List(find,foldl')+import Data.Foldable(toList)+import Data.Map.Strict(Map)+import qualified Data.Map.Strict as Map+import qualified Data.Set as Set+import Data.Graph(SCC(..))+import Data.Graph.SCC(stronglyConnComp)+import           MonadLib hiding (mapM, mapM_)++ import Cryptol.ModuleSystem.Name import Cryptol.ModuleSystem.NamingEnv import Cryptol.ModuleSystem.Exports+import Cryptol.Parser.Position(getLoc) import Cryptol.Parser.AST-import Cryptol.Parser.Position-import Cryptol.Parser.Selector(ppNestedSels,selName)+import Cryptol.Parser.Selector(selName) import Cryptol.Utils.Panic (panic)-import Cryptol.Utils.PP import Cryptol.Utils.RecordMap+import Cryptol.Utils.Ident(allNamespaces,packModName) -import Data.List(find)-import qualified Data.Foldable as F-import           Data.Map.Strict ( Map )-import qualified Data.Map.Strict as Map-import qualified Data.Sequence as Seq-import qualified Data.Semigroup as S-import           Data.Set (Set)-import qualified Data.Set as Set-import           MonadLib hiding (mapM, mapM_)+import Cryptol.ModuleSystem.Interface+import Cryptol.ModuleSystem.Renamer.Error+import Cryptol.ModuleSystem.Renamer.Monad -import GHC.Generics (Generic)-import Control.DeepSeq -import Prelude ()-import Prelude.Compat+data RenamedModule = RenamedModule+  { rmModule   :: Module Name     -- ^ The renamed module+  , rmDefines  :: NamingEnv       -- ^ What this module defines+  , rmInScope  :: NamingEnv       -- ^ What's in scope in this module+  , rmImported :: IfaceDecls      -- ^ Imported declarations+  } --- Errors ----------------------------------------------------------------------+renameModule :: Module PName -> RenameM RenamedModule+renameModule m0 =+  do let m = m0 { mDecls = snd (addImplicitNestedImports (mDecls m0)) }+     env      <- liftSupply (defsOf m)+     nested   <- liftSupply (collectNestedModules env m)+     setNestedModule (nestedModuleNames nested)+       do (ifs,(inScope,m1)) <- collectIfaceDeps+                 $ renameModule' nested env (TopModule (thing (mName m))) m+          pure RenamedModule+                 { rmModule = m1+                 , rmDefines = env+                 , rmInScope = inScope+                 , rmImported = ifs+                -- XXX: maybe we should keep the nested defines too?+                 } -data RenamerError-  = MultipleSyms (Located PName) [Name] NameDisp-    -- ^ Multiple imported symbols contain this name+renameTopDecls ::+  ModName -> [TopDecl PName] -> RenameM (NamingEnv,[TopDecl Name])+renameTopDecls m ds0 =+  do let ds = snd (addImplicitNestedImports ds0)+     let mpath = TopModule m+     env    <- liftSupply (defsOf (map (InModule (Just mpath)) ds))+     nested <- liftSupply (collectNestedModulesDecls env m ds) -  | UnboundExpr (Located PName) NameDisp-    -- ^ Expression name is not bound to any definition+     setNestedModule (nestedModuleNames nested)+       do ds1 <- shadowNames' CheckOverlap env+                                        (renameTopDecls' (nested,mpath) ds)+          -- record a use of top-level names to avoid+          -- unused name warnings+          let exports = concatMap exportedNames ds1+          mapM_ recordUse (foldMap (exported NSType) exports) -  | UnboundType (Located PName) NameDisp-    -- ^ Type name is not bound to any definition+          pure (env,ds1) -  | OverlappingSyms [Name] NameDisp-    -- ^ An environment has produced multiple overlapping symbols+-- | Returns declarations with additional imports and the public module names+-- of this module and its children+addImplicitNestedImports ::+  [TopDecl PName] -> ([[Ident]], [TopDecl PName])+addImplicitNestedImports decls = (concat exportedMods, concat newDecls ++ other)+  where+  (mods,other)            = foldr classify ([], []) decls+  (newDecls,exportedMods) = unzip (map processModule mods)+  processModule m =+    let NestedModule m1 = tlValue m+        (childExs, ds1) = addImplicitNestedImports (mDecls m1)+        mname           = getIdent (thing (mName m1))+        imps            = map (mname :) ([] : childExs)+        isToName is     = case is of+                            [i] -> mkUnqual i+                            _   -> mkQual (isToQual (init is)) (last is)+        isToQual is     = packModName (map identText is)+        mkImp xs        = DImport+                          Located+                            { srcRange = srcRange (mName m1)+                            , thing = Import+                                        { iModule = ImpNested (isToName xs)+                                        , iAs     = Just (isToQual xs)+                                        , iSpec   = Nothing+                                        }+                            }+    in ( DModule m { tlValue = NestedModule m1 { mDecls = ds1 } }+       : map mkImp imps+       , case tlExport m of+           Public  -> imps+           Private -> []+       ) -  | ExpectedValue (Located PName) NameDisp-    -- ^ When a value is expected from the naming environment, but one or more-    -- types exist instead. -  | ExpectedType (Located PName) NameDisp-    -- ^ When a type is missing from the naming environment, but one or more-    -- values exist with the same name.+  classify d (ms,ds) =+    case d of+      DModule tl -> (tl : ms, ds)+      _          -> (ms, d : ds) -  | FixityError (Located Name) Fixity (Located Name) Fixity NameDisp-    -- ^ When the fixity of two operators conflict -  | InvalidConstraint (Type PName) NameDisp-    -- ^ When it's not possible to produce a Prop from a Type.+nestedModuleNames :: NestedMods -> Map ModPath Name+nestedModuleNames mp = Map.fromList (map entry (Map.keys mp))+  where+  entry n = case nameInfo n of+              Declared p _ -> (Nested p (nameIdent n),n)+              _ -> panic "nestedModuleName" [ "Not a top-level name" ] -  | MalformedBuiltin (Type PName) PName NameDisp-    -- ^ When a builtin type/type-function is used incorrectly. -  | BoundReservedType PName (Maybe Range) Doc NameDisp-    -- ^ When a builtin type is named in a binder.+class Rename f where+  rename :: f PName -> RenameM (f Name) -  | OverlappingRecordUpdate (Located [Selector]) (Located [Selector]) NameDisp-    -- ^ When record updates overlap (e.g., @{ r | x = e1, x.y = e2 }@)-    deriving (Show, Generic, NFData) -instance PP RenamerError where-  ppPrec _ e = case e of+-- | Returns:+--+--    * Interfaces for imported things,+--    * Things defines in the module+--    * Renamed module+renameModule' ::+  NestedMods -> NamingEnv -> ModPath -> ModuleG mname PName ->+  RenameM (NamingEnv, ModuleG mname Name)+renameModule' thisNested env mpath m =+  setCurMod mpath+  do (moreNested,imps) <- mconcat <$> mapM doImport (mImports m)+     let allNested = Map.union moreNested thisNested+         openDs    = map thing (mSubmoduleImports m)+         allImps   = openLoop allNested env openDs imps -    MultipleSyms lqn qns disp -> fixNameDisp disp $-      hang (text "[error] at" <+> pp (srcRange lqn))-         4 $ (text "Multiple definitions for symbol:" <+> pp (thing lqn))-          $$ vcat (map ppLocName qns)+     (inScope,decls') <-+        shadowNames' CheckNone allImps $+        shadowNames' CheckOverlap env $+                          -- maybe we should allow for a warning+                          -- if a local name shadows an imported one?+        do inScope <- getNamingEnv+           ds      <- renameTopDecls' (allNested,mpath) (mDecls m)+           pure (inScope, ds)+     let m1      = m { mDecls = decls' }+         exports = modExports m1+     mapM_ recordUse (exported NSType exports)+     return (inScope, m1) -    UnboundExpr lqn disp -> fixNameDisp disp $-      hang (text "[error] at" <+> pp (srcRange lqn))-         4 (text "Value not in scope:" <+> pp (thing lqn)) -    UnboundType lqn disp -> fixNameDisp disp $-      hang (text "[error] at" <+> pp (srcRange lqn))-         4 (text "Type not in scope:" <+> pp (thing lqn))+renameDecls :: [Decl PName] -> RenameM [Decl Name]+renameDecls ds =+  do (ds1,deps) <- depGroup (traverse rename ds)+     let toNode d = let x = NamedThing (declName d)+                    in ((d,x), x, map NamedThing+                            $ Set.toList+                            $ Map.findWithDefault Set.empty x deps)+         ordered = toList (stronglyConnComp (map toNode ds1))+         fromSCC x =+           case x of+             AcyclicSCC (d,_) -> pure [d]+             CyclicSCC ds_xs ->+               let (rds,xs) = unzip ds_xs+               in case mapM validRecursiveD rds of+                    Nothing -> do record (InvalidDependency xs)+                                  pure rds+                    Just bs ->+                      do checkSameModule xs+                         pure [DRec bs]+     concat <$> mapM fromSCC ordered -    OverlappingSyms qns disp -> fixNameDisp disp $-      hang (text "[error]")-         4 $ text "Overlapping symbols defined:"-          $$ vcat (map ppLocName qns) -    ExpectedValue lqn disp -> fixNameDisp disp $-      hang (text "[error] at" <+> pp (srcRange lqn))-         4 (fsep [ text "Expected a value named", quotes (pp (thing lqn))-                 , text "but found a type instead"-                 , text "Did you mean `(" <.> pp (thing lqn) <.> text")?" ])+validRecursiveD :: Decl name -> Maybe (Bind name)+validRecursiveD d =+  case d of+    DBind b       -> Just b+    DLocated d' _ -> validRecursiveD d'+    _             -> Nothing -    ExpectedType lqn disp -> fixNameDisp disp $-      hang (text "[error] at" <+> pp (srcRange lqn))-         4 (fsep [ text "Expected a type named", quotes (pp (thing lqn))-                 , text "but found a value instead" ])+checkSameModule :: [DepName] -> RenameM ()+checkSameModule xs =+  case ms of+    a : as | let bad = [ fst b | b <- as, snd a /= snd b ]+           , not (null bad) ->+              record $ InvalidDependency $ map NamedThing $ fst a : bad+    _ -> pure ()+  where+  ms = [ (x,p) | NamedThing x <- xs, Declared p _ <- [ nameInfo x ] ] -    FixityError o1 f1 o2 f2 disp -> fixNameDisp disp $-      hang (text "[error] at" <+> pp (srcRange o1) <+> text "and" <+> pp (srcRange o2))-         4 (fsep [ text "The fixities of"-                 , nest 2 $ vcat-                   [ "•" <+> pp (thing o1) <+> parens (pp f1)-                   , "•" <+> pp (thing o2) <+> parens (pp f2) ]-                 , text "are not compatible."-                 , text "You may use explicit parentheses to disambiguate." ]) -    InvalidConstraint ty disp -> fixNameDisp disp $-      hang (text "[error]" <+> maybe empty (\r -> text "at" <+> pp r) (getLoc ty))-         4 (fsep [ pp ty, text "is not a valid constraint" ])--    MalformedBuiltin ty pn disp -> fixNameDisp disp $-      hang (text "[error]" <+> maybe empty (\r -> text "at" <+> pp r) (getLoc ty))-         4 (fsep [ text "invalid use of built-in type", pp pn-                 , text "in type", pp ty ])--    BoundReservedType n loc src disp -> fixNameDisp disp $-      hang (text "[error]" <+> maybe empty (\r -> text "at" <+> pp r) loc)-         4 (fsep [ text "built-in type", quotes (pp n), text "shadowed in", src ])--    OverlappingRecordUpdate xs ys disp -> fixNameDisp disp $-      hang "[error] Overlapping record updates:"-         4 (vcat [ ppLab xs, ppLab ys ])-      where-      ppLab as = ppNestedSels (thing as) <+> "at" <+> pp (srcRange as)---- Warnings ----------------------------------------------------------------------data RenamerWarning-  = SymbolShadowed Name [Name] NameDisp--  | UnusedName Name NameDisp-    deriving (Show, Generic, NFData)--instance PP RenamerWarning where-  ppPrec _ (SymbolShadowed new originals disp) = fixNameDisp disp $-    hang (text "[warning] at" <+> loc)-       4 $ fsep [ text "This binding for" <+> backticks sym-                , text "shadows the existing binding" <.> plural <+>-                  text "at" ]-        $$ vcat (map (pp . nameLoc) originals)--    where-    plural | length originals > 1 = char 's'-           | otherwise            = empty--    loc = pp (nameLoc new)-    sym = pp new--  ppPrec _ (UnusedName x disp) = fixNameDisp disp $-    hang (text "[warning] at" <+> pp (nameLoc x))-       4 (text "Unused name:" <+> pp x)+renameTopDecls' ::+  (NestedMods,ModPath) -> [TopDecl PName] -> RenameM [TopDecl Name]+renameTopDecls' info ds =+  do (ds1,deps) <- depGroup (traverse (renameWithMods info) ds)  -data RenamerWarnings = RenamerWarnings-  { renWarnNameDisp :: !NameDisp-  , renWarnShadow   :: Map Name (Set Name)-  , renWarnUnused   :: Set Name-  }--noRenamerWarnings :: RenamerWarnings-noRenamerWarnings = RenamerWarnings-  { renWarnNameDisp = mempty-  , renWarnShadow   = Map.empty-  , renWarnUnused   = Set.empty-  }--addRenamerWarning :: RenamerWarning -> RenamerWarnings -> RenamerWarnings-addRenamerWarning w ws =-  case w of-    SymbolShadowed x xs d ->-      ws { renWarnNameDisp = renWarnNameDisp ws <> d-         , renWarnShadow   = Map.insertWith Set.union x (Set.fromList xs)-                                                        (renWarnShadow ws)-         }-    UnusedName x d ->-      ws { renWarnNameDisp = renWarnNameDisp ws <> d-         , renWarnUnused   = Set.insert x (renWarnUnused ws)-         }--listRenamerWarnings :: RenamerWarnings -> [RenamerWarning]-listRenamerWarnings ws =-  [ mk (UnusedName x) | x      <- Set.toList (renWarnUnused ws) ] ++-  [ mk (SymbolShadowed x (Set.toList xs))-          | (x,xs) <- Map.toList (renWarnShadow ws) ]+     let (noNameDs,nameDs) = partitionEithers (map topDeclName ds1)+         ctrs = [ nm | (_,nm@(ConstratintAt {})) <- nameDs ]+         toNode (d,x) = ((d,x),x, (if usesCtrs d then ctrs else []) +++                               map NamedThing+                             ( Set.toList+                             ( Map.findWithDefault Set.empty x deps) ))+         ordered = stronglyConnComp (map toNode nameDs)+         fromSCC x =+            case x of+              AcyclicSCC (d,_) -> pure [d]+              CyclicSCC ds_xs ->+                let (rds,xs) = unzip ds_xs+                in case mapM valid rds of+                     Nothing -> do record (InvalidDependency xs)+                                   pure rds+                     Just bs ->+                       do checkSameModule xs+                          pure [Decl TopLevel+                                       { tlDoc = Nothing+                                       , tlExport = Public+                                       , tlValue = DRec bs+                                       }]+                where+                valid d = case d of+                            Decl tl -> validRecursiveD (tlValue tl)+                            _       -> Nothing+     rds <- mapM fromSCC ordered+     pure (concat (noNameDs:rds))   where-  mk f = f (renWarnNameDisp ws)+  usesCtrs td =+    case td of+      Decl tl                 -> isValDecl (tlValue tl)+      DPrimType {}            -> False+      TDNewtype {}            -> False+      DParameterType {}       -> False+      DParameterConstraint {} -> False +      DParameterFun {}        -> True+      -- Here we may need the constraints to validate the type+      -- (e.g., if the parameter is of type `Z a`) --- Renaming Monad -------------------------------------------------------------- -data RO = RO-  { roLoc   :: Range-  , roMod   :: !ModName-  , roNames :: NamingEnv-  , roDisp  :: !NameDisp-  }+      DModule tl              -> any usesCtrs (mDecls m)+        where NestedModule m = tlValue tl+      DImport {}              -> False+      Include {}              -> bad "Include" -data RW = RW-  { rwWarnings      :: !RenamerWarnings-  , rwErrors        :: !(Seq.Seq RenamerError)-  , rwSupply        :: !Supply-  , rwNameUseCount  :: !(Map Name Int)-    -- ^ How many times did we refer to each name.-    -- Used to generate warnings for unused definitions.-  }+  isValDecl d =+    case d of+      DLocated d' _ -> isValDecl d'+      DBind {}      -> True+      DType {}      -> False+      DProp {}      -> False+      DRec {}       -> True+      DSignature {} -> bad "DSignature"+      DFixity {}    -> bad "DFixity"+      DPragma {}    -> bad "DPragma"+      DPatBind {}   -> bad "DPatBind" +  bad msg = panic "renameTopDecls'" [msg]  -newtype RenameM a = RenameM-  { unRenameM :: ReaderT RO (StateT RW Lift) a }--instance S.Semigroup a => S.Semigroup (RenameM a) where-  {-# INLINE (<>) #-}-  a <> b =-    do x <- a-       y <- b-       return (x S.<> y)--instance (S.Semigroup a, Monoid a) => Monoid (RenameM a) where-  {-# INLINE mempty #-}-  mempty = return mempty--  {-# INLINE mappend #-}-  mappend = (S.<>)--instance Functor RenameM where-  {-# INLINE fmap #-}-  fmap f m      = RenameM (fmap f (unRenameM m))--instance Applicative RenameM where-  {-# INLINE pure #-}-  pure x        = RenameM (pure x)--  {-# INLINE (<*>) #-}-  l <*> r       = RenameM (unRenameM l <*> unRenameM r)+declName :: Decl Name -> Name+declName decl =+  case decl of+    DLocated d _            -> declName d+    DBind b                 -> thing (bName b)+    DType (TySyn x _ _ _)   -> thing x+    DProp (PropSyn x _ _ _) -> thing x -instance Monad RenameM where-  {-# INLINE return #-}-  return x      = RenameM (return x)+    DSignature {}           -> bad "DSignature"+    DFixity {}              -> bad "DFixity"+    DPragma {}              -> bad "DPragma"+    DPatBind {}             -> bad "DPatBind"+    DRec {}                 -> bad "DRec"+  where+  bad x = panic "declName" [x] -  {-# INLINE (>>=) #-}-  m >>= k       = RenameM (unRenameM m >>= unRenameM . k)+topDeclName :: TopDecl Name -> Either (TopDecl Name) (TopDecl Name, DepName)+topDeclName topDecl =+  case topDecl of+    Decl d                  -> hasName (declName (tlValue d))+    DPrimType d             -> hasName (thing (primTName (tlValue d)))+    TDNewtype d             -> hasName (thing (nName (tlValue d)))+    DParameterType d        -> hasName (thing (ptName d))+    DParameterFun d         -> hasName (thing (pfName d))+    DModule d               -> hasName (thing (mName m))+      where NestedModule m = tlValue d -instance FreshM RenameM where-  liftSupply f = RenameM $ sets $ \ RW { .. } ->-    let (a,s') = f rwSupply-        rw'    = RW { rwSupply = s', .. }-     in a `seq` rw' `seq` (a, rw')+    DParameterConstraint ds ->+      case ds of+        []  -> noName+        _   -> Right (topDecl, ConstratintAt (fromJust (getLoc ds)))+    DImport {}              -> noName -runRenamer :: Supply -> ModName -> NamingEnv -> RenameM a-           -> (Either [RenamerError] (a,Supply),[RenamerWarning])-runRenamer s ns env m = (res, listRenamerWarnings warns)+    Include {}              -> bad "Include"   where-  warns = foldr addRenamerWarning (rwWarnings rw)-                                  (warnUnused ns env ro rw)+  noName    = Left topDecl+  hasName n = Right (topDecl, NamedThing n)+  bad x     = panic "topDeclName" [x] -  (a,rw) = runM (unRenameM m) ro-                              RW { rwErrors   = Seq.empty-                                 , rwWarnings = noRenamerWarnings-                                 , rwSupply   = s-                                 , rwNameUseCount = Map.empty-                                 } -  ro = RO { roLoc = emptyRange-          , roNames = env-          , roMod = ns-          , roDisp = neverQualifyMod ns `mappend` toNameDisp env-          }+-- | Returns:+--  * The public interface of the imported module+--  * Infromation about nested modules in this module+--  * New names introduced through this import+doImport :: Located Import -> RenameM (NestedMods, NamingEnv)+doImport li =+  do let i = thing li+     decls <- lookupImport i+     let declsOf = unqualifiedEnv . ifPublic+         nested  = declsOf <$> ifModules decls+     pure (nested, interpImportIface i decls) -  res | Seq.null (rwErrors rw) = Right (a,rwSupply rw)-      | otherwise              = Left (F.toList (rwErrors rw)) --- | Record an error.  XXX: use a better name-record :: (NameDisp -> RenamerError) -> RenameM ()-record f = RenameM $-  do RO { .. } <- ask-     RW { .. } <- get-     set RW { rwErrors = rwErrors Seq.|> f roDisp, .. } --- | Get the source range for wahtever we are currently renaming.-curLoc :: RenameM Range-curLoc  = RenameM (roLoc `fmap` ask)---- | Annotate something with the current range.-located :: a -> RenameM (Located a)-located thing =-  do srcRange <- curLoc-     return Located { .. }---- | Do the given computation using the source code range from `loc` if any.-withLoc :: HasLoc loc => loc -> RenameM a -> RenameM a-withLoc loc m = RenameM $ case getLoc loc of--  Just range -> do-    ro <- ask-    local ro { roLoc = range } (unRenameM m)--  Nothing -> unRenameM m---- | Retrieve the name of the current module.-getNS :: RenameM ModName-getNS  = RenameM (roMod `fmap` ask)---- | Shadow the current naming environment with some more names.-shadowNames :: BindsNames env => env -> RenameM a -> RenameM a-shadowNames  = shadowNames' CheckAll--data EnvCheck = CheckAll     -- ^ Check for overlap and shadowing-              | CheckOverlap -- ^ Only check for overlap-              | CheckNone    -- ^ Don't check the environment-                deriving (Eq,Show)---- | Shadow the current naming environment with some more names.-shadowNames' :: BindsNames env => EnvCheck -> env -> RenameM a -> RenameM a-shadowNames' check names m = do-  do env <- liftSupply (namingEnv' names)-     RenameM $-       do ro  <- ask-          env' <- sets (checkEnv (roDisp ro) check env (roNames ro))-          let ro' = ro { roNames = env' `shadowing` roNames ro }-          local ro' (unRenameM m)--shadowNamesNS :: BindsNames (InModule env) => env -> RenameM a -> RenameM a-shadowNamesNS names m =-  do ns <- getNS-     shadowNames (InModule ns names) m+--------------------------------------------------------------------------------+-- Compute names coming through `open` statements. +data OpenLoopState = OpenLoopState+  { unresolvedOpen  :: [ImportG PName]+  , scopeImports    :: NamingEnv    -- names from open/impot+  , scopeDefs       :: NamingEnv    -- names defined in this module+  , scopingRel      :: NamingEnv    -- defs + imports with shadowing+                                    -- (just a cache)+  , openLoopChange  :: Bool+  } --- | Generate warnings when the left environment shadows things defined in--- the right.  Additionally, generate errors when two names overlap in the--- left environment.-checkEnv :: NameDisp -> EnvCheck -> NamingEnv -> NamingEnv -> RW -> (NamingEnv,RW)-checkEnv disp check l r rw-  | check == CheckNone = (l',rw)-  | otherwise          = (l',rw'')+-- | Processing of a single @open@ declaration+processOpen :: NestedMods -> OpenLoopState -> ImportG PName -> OpenLoopState+processOpen modEnvs s o =+  case lookupNS NSModule (iModule o) (scopingRel s) of+    []  -> s { unresolvedOpen = o : unresolvedOpen s }+    [n] ->+      case Map.lookup n modEnvs of+        Nothing  -> panic "openLoop" [ "Missing defintion for module", show n ]+        Just def ->+          let new = interpImportEnv o def+              newImps = new <> scopeImports s+          in s { scopeImports   = newImps+               , scopingRel     = scopeDefs s `shadowing` newImps+               , openLoopChange = True+               }+    _ -> s+    {- Notes:+       * ambiguity will be reported later when we do the renaming+       * assumes scoping only grows, which should be true+       * we are not adding the names from *either* of the imports+         so this may give rise to undefined names, so we may want to+         suppress reporing undefined names if there ambiguities for+         module names.  Alternatively we could add the defitions from+         *all* options, but that might lead to spurious ambiguity errors.+    -} +{- | Complete the set of import using @open@ declarations.+This should terminate because on each iteration either @unresolvedOpen@+decreases or @openLoopChange@ remians @False@. We don't report errors+here, as they will be reported during renaming anyway. -}+openLoop ::+  NestedMods      {- ^ Definitions of all known nested modules  -} ->+  NamingEnv       {- ^ Definitions of the module (these shadow) -} ->+  [ImportG PName] {- ^ Open declarations                        -} ->+  NamingEnv       {- ^ Imported declarations                    -} ->+  NamingEnv       {- ^ Completed imports                        -}+openLoop modEnvs defs os imps =+  scopingRel $ loop OpenLoopState+                      { unresolvedOpen = os+                      , scopeImports   = imps+                      , scopeDefs      = defs+                      , scopingRel     = defs `shadowing` imps+                      , openLoopChange = True+                      }   where+  loop s+    | openLoopChange s =+      loop $ foldl' (processOpen modEnvs)+                    s { unresolvedOpen = [], openLoopChange = False }+                    (unresolvedOpen s)+    | otherwise = s -  l' = l { neExprs = es, neTypes = ts } -  (rw',es)  = Map.mapAccumWithKey (step neExprs) rw  (neExprs l)-  (rw'',ts) = Map.mapAccumWithKey (step neTypes) rw' (neTypes l)+-------------------------------------------------------------------------------- -  step prj acc k ns = (acc', [head ns])-    where-    acc' = acc-      { rwWarnings =-          if check == CheckAll-             then case Map.lookup k (prj r) of-                    Nothing -> rwWarnings acc-                    Just os -> addRenamerWarning -                                    (SymbolShadowed (head ns) os disp)-                                    (rwWarnings acc) -             else rwWarnings acc-      , rwErrors   = rwErrors acc Seq.>< containsOverlap disp ns-      }+data WithMods f n = WithMods (NestedMods,ModPath) (f n) --- | Check the RHS of a single name rewrite for conflicting sources.-containsOverlap :: NameDisp -> [Name] -> Seq.Seq RenamerError-containsOverlap _    [_] = Seq.empty-containsOverlap _    []  = panic "Renamer" ["Invalid naming environment"]-containsOverlap disp ns  = Seq.singleton (OverlappingSyms ns disp)+forgetMods :: WithMods f n -> f n+forgetMods (WithMods _ td) = td --- | Throw errors for any names that overlap in a rewrite environment.-checkNamingEnv :: NamingEnv -> ([RenamerError],[RenamerWarning])-checkNamingEnv env = (F.toList out, [])-  where-  out    = Map.foldr check outTys (neExprs env)-  outTys = Map.foldr check mempty (neTypes env)+renameWithMods ::+  Rename (WithMods f) => (NestedMods,ModPath) -> f PName -> RenameM (f Name)+renameWithMods info m = forgetMods <$> rename (WithMods info m) -  disp   = toNameDisp env -  check ns acc = containsOverlap disp ns Seq.>< acc+instance Rename (WithMods TopDecl) where+  rename (WithMods info td) = WithMods info <$>+    case td of+      Decl d      -> Decl      <$> traverse rename d+      DPrimType d -> DPrimType <$> traverse rename d+      TDNewtype n -> TDNewtype <$> traverse rename n+      Include n   -> return (Include n)+      DParameterFun f  -> DParameterFun  <$> rename f+      DParameterType f -> DParameterType <$> rename f -recordUse :: Name -> RenameM ()-recordUse x = RenameM $ sets_ $ \rw ->-  rw { rwNameUseCount = Map.insertWith (+) x 1 (rwNameUseCount rw) }+      DParameterConstraint ds ->+        case ds of+          [] -> pure (DParameterConstraint [])+          _  -> depsOf (ConstratintAt (fromJust (getLoc ds)))+              $ DParameterConstraint <$> mapM renameLocated ds+      DModule m -> DModule <$> traverse (renameWithMods info) m+      DImport li -> DImport <$> traverse renI li+        where+        renI i = do m <- rename (iModule i)+                    pure i { iModule = m } +instance Rename ImpName where+  rename i =+    case i of+      ImpTop m -> pure (ImpTop m)+      ImpNested m -> ImpNested <$> resolveName NameUse NSModule m -warnUnused :: ModName -> NamingEnv -> RO -> RW -> [RenamerWarning]-warnUnused m0 env ro rw =-  map warn-  $ Map.keys-  $ Map.filterWithKey keep-  $ rwNameUseCount rw-  where-  warn x   = UnusedName x (roDisp ro)-  keep k n = n == 1 && isLocal k-  oldNames = fst (visibleNames env)-  isLocal nm = case nameInfo nm of-                 Declared m sys -> sys == UserName &&-                                   m == m0 && nm `Set.notMember` oldNames-                 Parameter  -> True+instance Rename (WithMods NestedModule) where+  rename (WithMods info (NestedModule m)) = WithMods info <$>+    do let (nested,mpath) = info+           lnm            = mName m+           nm             = thing lnm+           newMPath       = Nested mpath (getIdent nm)+       n   <- resolveName NameBind NSModule nm+       depsOf (NamedThing n)+         do let env = case Map.lookup n (fst info) of+                        Just defs -> defs+                        Nothing -> panic "rename"+                           [ "Missing environment for nested module", show n ]+            -- XXX: we should store in scope somehwere if we want to browse+            -- nested modules properly+            (_inScope,m1) <- renameModule' nested env newMPath m+            pure (NestedModule m1 { mName = lnm { thing = n } }) --- Renaming -------------------------------------------------------------------- -class Rename f where-  rename :: f PName -> RenameM (f Name)--renameModule :: Module PName -> RenameM (NamingEnv,Module Name)-renameModule m =-  do env    <- liftSupply (namingEnv' m)-     -- NOTE: we explicitly hide shadowing errors here, by using shadowNames'-     decls' <-  shadowNames' CheckOverlap env (traverse rename (mDecls m))-     let m1 = m { mDecls = decls' }-         exports = modExports m1-     mapM_ recordUse (eTypes exports)-     return (env,m1)--instance Rename TopDecl where-  rename td     = case td of-    Decl d      -> Decl      <$> traverse rename d-    DPrimType d -> DPrimType <$> traverse rename d-    TDNewtype n -> TDNewtype <$> traverse rename n-    Include n   -> return (Include n)-    DParameterFun f  -> DParameterFun  <$> rename f-    DParameterType f -> DParameterType <$> rename f--    DParameterConstraint d -> DParameterConstraint <$> mapM renameLocated d- renameLocated :: Rename f => Located (f PName) -> RenameM (Located (f Name)) renameLocated x =   do y <- rename (thing x)@@ -456,21 +470,30 @@  instance Rename PrimType where   rename pt =-    do x <- rnLocated renameType (primTName pt)-       let (as,ps) = primTCts pt-       (_,cts) <- renameQual as ps $ \as' ps' -> pure (as',ps')-       pure pt { primTCts = cts, primTName = x }+    do x <- rnLocated (renameType NameBind) (primTName pt)+       depsOf (NamedThing (thing x))+         do let (as,ps) = primTCts pt+            (_,cts) <- renameQual as ps $ \as' ps' -> pure (as',ps') +            -- Record an additional use for each parameter since we checked+            -- earlier that all the parameters are used exactly once in the+            -- body of the signature.  This prevents incorret warnings+            -- about unused names.+            mapM_ (recordUse . tpName) (fst cts)++            pure pt { primTCts = cts, primTName = x }+ instance Rename ParameterType where   rename a =-    do n' <- rnLocated renameType (ptName a)+    do n' <- rnLocated (renameType NameBind) (ptName a)        return a { ptName = n' }  instance Rename ParameterFun where   rename a =-    do n'   <- rnLocated renameVar (pfName a)-       sig' <- renameSchema (pfSchema a)-       return a { pfName = n', pfSchema = snd sig' }+    do n'   <- rnLocated (renameVar NameBind) (pfName a)+       depsOf (NamedThing (thing n'))+         do sig' <- renameSchema (pfSchema a)+            return a { pfName = n', pfSchema = snd sig' }  rnLocated :: (a -> RenameM b) -> Located a -> RenameM (Located b) rnLocated f loc = withLoc loc $@@ -479,101 +502,95 @@  instance Rename Decl where   rename d      = case d of-    DSignature ns sig -> DSignature    <$> traverse (rnLocated renameVar) ns-                                       <*> rename sig-    DPragma ns p      -> DPragma       <$> traverse (rnLocated renameVar) ns-                                       <*> pure p-    DBind b           -> DBind         <$> rename b--    -- XXX we probably shouldn't see these at this point...-    DPatBind pat e    -> do (pe,pat') <- renamePat pat-                            shadowNames pe (DPatBind pat' <$> rename e)+    DBind b           -> DBind <$> rename b      DType syn         -> DType         <$> rename syn     DProp syn         -> DProp         <$> rename syn     DLocated d' r     -> withLoc r                        $ DLocated      <$> rename d'  <*> pure r-    DFixity{}         -> panic "Renamer" ["Unexpected fixity declaration"-                                         , show d] -instance Rename Newtype where-  rename n      = do-    name' <- rnLocated renameType (nName n)-    shadowNames (nParams n) $-      do ps'   <- traverse rename (nParams n)-         body' <- traverse (traverse rename) (nBody n)-         return Newtype { nName   = name'-                        , nParams = ps'-                        , nBody   = body' }+    DFixity{}         -> panic "renaem" [ "DFixity" ]+    DSignature {}     -> panic "rename" [ "DSignature" ]+    DPragma  {}       -> panic "rename" [ "DPragma" ]+    DPatBind {}       -> panic "rename" [ "DPatBind " ]+    DRec {}           -> panic "rename" [ "DRec" ] -renameVar :: PName -> RenameM Name-renameVar qn = do-  ro <- RenameM ask-  case Map.lookup qn (neExprs (roNames ro)) of-    Just [n]  -> return n-    Just []   -> panic "Renamer" ["Invalid expression renaming environment"]-    Just syms ->-      do n <- located qn-         record (MultipleSyms n syms)-         return (head syms) -    -- This is an unbound value. Record an error and invent a bogus real name-    -- for it.-    Nothing ->-      do n <- located qn -         case Map.lookup qn (neTypes (roNames ro)) of-           -- types existed with the name of the value expected-           Just _ -> record (ExpectedValue n)+instance Rename Newtype where+  rename n      =+    shadowNames (nParams n) $+    do name' <- rnLocated (renameType NameBind) (nName n)+       depsOf (NamedThing (thing name')) $+         do ps'   <- traverse rename (nParams n)+            body' <- traverse (traverse rename) (nBody n)+            return Newtype { nName   = name'+                           , nParams = ps'+                           , nBody   = body' } -           -- the value is just missing-           Nothing -> record (UnboundExpr n) -         mkFakeName qn --- | Produce a name if one exists. Note that this includes situations where--- overlap exists, as it's just a query about anything being in scope. In the--- event that overlap does exist, an error will be recorded.-typeExists :: PName -> RenameM (Maybe Name)-typeExists pn =+-- | Try to resolve a name+resolveNameMaybe :: NameType -> Namespace -> PName -> RenameM (Maybe Name)+resolveNameMaybe nt expected qn =   do ro <- RenameM ask-     case Map.lookup pn (neTypes (roNames ro)) of-       Just [n]  -> recordUse n >> return (Just n)-       Just []   -> panic "Renamer" ["Invalid type renaming environment"]-       Just syms -> do n <- located pn-                       mapM_ recordUse syms-                       record (MultipleSyms n syms)-                       return (Just (head syms))-       Nothing -> return Nothing+     let lkpIn here = Map.lookup qn (namespaceMap here (roNames ro))+         use = case expected of+                 NSType -> recordUse+                 _      -> const (pure ())+     case lkpIn expected of+       Just [n]  ->+          do case nt of+               NameBind -> pure ()+               NameUse  -> addDep n+             use n    -- for warning+             return (Just n)+       Just []   -> panic "Renamer" ["Invalid expression renaming environment"]+       Just syms ->+         do mapM_ use syms    -- mark as used to avoid unused warnings+            n <- located qn+            record (MultipleSyms n syms)+            return (Just (head syms)) -renameType :: PName -> RenameM Name-renameType pn =-  do mb <- typeExists pn-     case mb of-       Just n -> return n+       Nothing -> pure Nothing -       -- This is an unbound value. Record an error and invent a bogus real name-       -- for it.+-- | Resolve a name, and report error on failure+resolveName :: NameType -> Namespace -> PName -> RenameM Name+resolveName nt expected qn =+  do mb <- resolveNameMaybe nt expected qn+     case mb of+       Just n -> pure n        Nothing ->          do ro <- RenameM ask-            let n = Located { srcRange = roLoc ro, thing = pn }+            let lkpIn here = Map.lookup qn (namespaceMap here (roNames ro))+                others     = [ ns | ns <- allNamespaces+                                  , ns /= expected+                                  , Just _ <- [lkpIn ns] ]+            nm <- located qn+            case others of+              -- name exists in a different namespace+              actual : _ -> record (WrongNamespace expected actual nm) -            case Map.lookup pn (neExprs (roNames ro)) of+              -- the value is just missing+              [] -> record (UnboundName expected nm) -              -- values exist with the same name, so throw a different error-              Just _ -> record (ExpectedType n)+            mkFakeName expected qn -              -- no terms with the same name, so the type is just unbound-              Nothing -> record (UnboundType n) -            mkFakeName pn+renameVar :: NameType -> PName -> RenameM Name+renameVar nt = resolveName nt NSValue +renameType :: NameType -> PName -> RenameM Name+renameType nt = resolveName nt NSType+++ -- | Assuming an error has been recorded already, construct a fake name that's -- not expected to make it out of the renamer.-mkFakeName :: PName -> RenameM Name-mkFakeName pn =+mkFakeName :: Namespace -> PName -> RenameM Name+mkFakeName ns pn =   do ro <- RenameM ask-     liftSupply (mkParameter (getIdent pn) (roLoc ro))+     liftSupply (mkParameter ns (getIdent pn) (roLoc ro))  -- | Rename a schema, assuming that none of its type variables are already in -- scope.@@ -593,7 +610,7 @@               ([TParam Name] -> [Prop Name] -> RenameM a) ->               RenameM (NamingEnv, a) renameQual as ps k =-  do env <- liftSupply (namingEnv' as)+  do env <- liftSupply (defsOf as)      res <- shadowNames env $ do as' <- traverse rename as                                  ps' <- traverse rename ps                                  k as' ps'@@ -601,7 +618,7 @@  instance Rename TParam where   rename TParam { .. } =-    do n <- renameType tpName+    do n <- renameType NameBind tpName        return TParam { tpName = n, .. }  instance Rename Prop where@@ -616,7 +633,7 @@       TBit           -> return TBit       TNum c         -> return (TNum c)       TChar c        -> return (TChar c)-      TUser qn ps    -> TUser    <$> renameType qn <*> traverse rename ps+      TUser qn ps    -> TUser <$> renameType NameUse qn <*> traverse rename ps       TTyApp fs      -> TTyApp   <$> traverse (traverse rename) fs       TRecord fs     -> TRecord  <$> traverse (traverse rename) fs       TTuple fs      -> TTuple   <$> traverse rename fs@@ -628,7 +645,8 @@                            b' <- rename b                            mkTInfix a' o' b' -mkTInfix :: Type Name -> (Located Name, Fixity) -> Type Name -> RenameM (Type Name)+mkTInfix ::+  Type Name -> (Located Name, Fixity) -> Type Name -> RenameM (Type Name)  mkTInfix t@(TInfix x o1 f1 y) op@(o2,f2) z =   case compareFixity f1 f2 of@@ -647,20 +665,21 @@  -- | Rename a binding. instance Rename Bind where-  rename b      = do-    n'    <- rnLocated renameVar (bName b)-    mbSig <- traverse renameSchema (bSignature b)-    shadowNames (fst `fmap` mbSig) $-      do (patEnv,pats') <- renamePats (bParams b)-         -- NOTE: renamePats will generate warnings, so we don't need to trigger-         -- them again here.-         e'             <- shadowNames' CheckNone patEnv (rnLocated rename (bDef b))-         return b { bName      = n'-                  , bParams    = pats'-                  , bDef       = e'-                  , bSignature = snd `fmap` mbSig-                  , bPragmas   = bPragmas b-                  }+  rename b =+    do n'    <- rnLocated (renameVar NameBind) (bName b)+       depsOf (NamedThing (thing n'))+         do mbSig <- traverse renameSchema (bSignature b)+            shadowNames (fst `fmap` mbSig) $+              do (patEnv,pats') <- renamePats (bParams b)+                 -- NOTE: renamePats will generate warnings,+                 -- so we don't need to trigger them again here.+                 e' <- shadowNames' CheckNone patEnv (rnLocated rename (bDef b))+                 return b { bName      = n'+                          , bParams    = pats'+                          , bDef       = e'+                          , bSignature = snd `fmap` mbSig+                          , bPragmas   = bPragmas b+                          }  instance Rename BindDef where   rename DPrim     = return DPrim@@ -669,7 +688,7 @@ -- NOTE: this only renames types within the pattern. instance Rename Pattern where   rename p      = case p of-    PVar lv         -> PVar <$> rnLocated renameVar lv+    PVar lv         -> PVar <$> rnLocated (renameVar NameBind) lv     PWild           -> pure PWild     PTuple ps       -> PTuple   <$> traverse rename ps     PRecord nps     -> PRecord  <$> traverse (traverse rename) nps@@ -702,12 +721,12 @@  instance Rename FunDesc where   rename (FunDesc nm offset) =-    do nm' <- traverse renameVar nm+    do nm' <- traverse (renameVar NameBind)  nm        pure (FunDesc nm' offset)  instance Rename Expr where   rename expr = case expr of-    EVar n          -> EVar <$> renameVar n+    EVar n          -> EVar <$> renameVar NameUse n     ELit l          -> return (ELit l)     ENeg e          -> ENeg    <$> rename e     EComplement e   -> EComplement@@ -724,6 +743,18 @@                                <*> traverse rename n                                <*> rename e                                <*> traverse rename t+    EFromToBy isStrict s e b t ->+                       EFromToBy isStrict+                                 <$> rename s+                                 <*> rename e+                                 <*> rename b+                                 <*> traverse rename t+    EFromToDownBy isStrict s e b t ->+                       EFromToDownBy isStrict+                                 <$> rename s+                                 <*> rename e+                                 <*> rename b+                                 <*> traverse rename t     EFromToLessThan s e t ->                        EFromToLessThan <$> rename s                                        <*> rename e@@ -737,9 +768,8 @@     EApp f x        -> EApp    <$> rename f  <*> rename x     EAppT f ti      -> EAppT   <$> rename f  <*> traverse rename ti     EIf b t f       -> EIf     <$> rename b  <*> rename t  <*> rename f-    EWhere e' ds    -> do ns <- getNS-                          shadowNames (map (InModule ns) ds) $-                            EWhere <$> rename e' <*> traverse rename ds+    EWhere e' ds    -> shadowNames (map (InModule Nothing) ds) $+                          EWhere <$> rename e' <*> renameDecls ds     ETyped e' ty    -> ETyped  <$> rename e' <*> rename ty     ETypeVal ty     -> ETypeVal<$> rename ty     EFun desc ps e' -> do desc' <- rename desc@@ -810,14 +840,14 @@ renameOp :: Located PName -> RenameM (Located Name, Fixity) renameOp ln =   withLoc ln $-  do n <- renameVar (thing ln)+  do n <- renameVar NameUse (thing ln)      fixity <- lookupFixity n      return (ln { thing = n }, fixity)  renameTypeOp :: Located PName -> RenameM (Located Name, Fixity) renameTypeOp ln =   withLoc ln $-  do n <- renameType (thing ln)+  do n <- renameType NameUse (thing ln)      fixity <- lookupFixity n      return (ln { thing = n }, fixity) @@ -859,8 +889,7 @@      return (pe,Match p' e')  renameMatch (MatchLet b) =-  do ns <- getNS-     be <- liftSupply (namingEnv' (InModule ns b))+  do be <- liftSupply (defsOf (InModule Nothing b))      b' <- shadowNames be (rename b)      return (be,MatchLet b') @@ -892,7 +921,8 @@ patternEnv  = go   where   go (PVar Located { .. }) =-    do n <- liftSupply (mkParameter (getIdent thing) srcRange)+    do n <- liftSupply (mkParameter NSValue (getIdent thing) srcRange)+       -- XXX: for deps, we should record a use        return (singletonE thing n)    go PWild            = return mempty@@ -919,7 +949,7 @@   typeEnv TChar{}    = return mempty    typeEnv (TUser pn ps) =-    do mb <- typeExists pn+    do mb <- resolveNameMaybe NameUse NSType pn        case mb of           -- The type is already bound, don't introduce anything.@@ -931,15 +961,15 @@            -- of the type of the pattern.            | null ps ->              do loc <- curLoc-                n   <- liftSupply (mkParameter (getIdent pn) loc)+                n   <- liftSupply (mkParameter NSType (getIdent pn) loc)                 return (singletonT pn n)             -- This references a type synonym that's not in scope. Record an            -- error and continue with a made up name.            | otherwise ->              do loc <- curLoc-                record (UnboundType (Located loc pn))-                n   <- liftSupply (mkParameter (getIdent pn) loc)+                record (UnboundName NSType (Located loc pn))+                n   <- liftSupply (mkParameter NSType (getIdent pn) loc)                 return (singletonT pn n)    typeEnv (TRecord fs)      = bindTypes (map snd (recordElements fs))@@ -961,18 +991,17 @@ instance Rename Match where   rename m = case m of     Match p e  ->                  Match    <$> rename p <*> rename e-    MatchLet b -> shadowNamesNS b (MatchLet <$> rename b)+    MatchLet b -> shadowNames (InModule Nothing b) (MatchLet <$> rename b)  instance Rename TySyn where   rename (TySyn n f ps ty) =-    shadowNames ps $ TySyn <$> rnLocated renameType n-                           <*> pure f-                           <*> traverse rename ps-                           <*> rename ty+    shadowNames ps+    do n' <- rnLocated (renameType NameBind) n+       depsOf (NamedThing (thing n')) $+         TySyn n' <$> pure f <*> traverse rename ps <*> rename ty  instance Rename PropSyn where   rename (PropSyn n f ps cs) =-    shadowNames ps $ PropSyn <$> rnLocated renameType n-                             <*> pure f-                             <*> traverse rename ps-                             <*> traverse rename cs+    shadowNames ps+    do n' <- rnLocated (renameType NameBind) n+       PropSyn n' <$> pure f <*> traverse rename ps <*> traverse rename cs
+ src/Cryptol/ModuleSystem/Renamer/Error.hs view
@@ -0,0 +1,205 @@+-- |+-- Module      :  Cryptol.ModuleSystem.Renamer+-- Copyright   :  (c) 2013-2016 Galois, Inc.+-- License     :  BSD3+-- Maintainer  :  cryptol@galois.com+-- Stability   :  provisional+-- Portability :  portable++{-# Language DeriveGeneric, DeriveAnyClass #-}+{-# Language OverloadedStrings #-}+module Cryptol.ModuleSystem.Renamer.Error where++import Cryptol.ModuleSystem.Name+import Cryptol.Parser.AST+import Cryptol.Parser.Position+import Cryptol.Parser.Selector(ppNestedSels)+import Cryptol.Utils.PP++import GHC.Generics (Generic)+import Control.DeepSeq++import Prelude ()+import Prelude.Compat++-- Errors ----------------------------------------------------------------------++data RenamerError+  = MultipleSyms (Located PName) [Name]+    -- ^ Multiple imported symbols contain this name++  | UnboundName Namespace (Located PName)+    -- ^ Some name not bound to any definition++  | OverlappingSyms [Name]+    -- ^ An environment has produced multiple overlapping symbols++  | WrongNamespace Namespace Namespace (Located PName)+    -- ^ expected, actual.+    -- When a name is missing from the expected namespace, but exists in another++  | FixityError (Located Name) Fixity (Located Name) Fixity+    -- ^ When the fixity of two operators conflict++  | InvalidConstraint (Type PName)+    -- ^ When it's not possible to produce a Prop from a Type.++  | MalformedBuiltin (Type PName) PName+    -- ^ When a builtin type/type-function is used incorrectly.++  | BoundReservedType PName (Maybe Range) Doc+    -- ^ When a builtin type is named in a binder.++  | OverlappingRecordUpdate (Located [Selector]) (Located [Selector])+    -- ^ When record updates overlap (e.g., @{ r | x = e1, x.y = e2 }@)++  | InvalidDependency [DepName]+    deriving (Show, Generic, NFData)+++-- We use this because parameter constrstaints have no names+data DepName = NamedThing Name+             | ConstratintAt Range -- ^ identifed by location in source+               deriving (Eq,Ord,Show,Generic,NFData)++depNameLoc :: DepName -> Range+depNameLoc x =+  case x of+    NamedThing n -> nameLoc n+    ConstratintAt r -> r+  +++instance PP RenamerError where+  ppPrec _ e = case e of++    MultipleSyms lqn qns ->+      hang (text "[error] at" <+> pp (srcRange lqn))+         4 $ (text "Multiple definitions for symbol:" <+> pp (thing lqn))+          $$ vcat (map ppLocName qns)++    UnboundName ns lqn ->+      hang (text "[error] at" <+> pp (srcRange lqn))+         4 (something <+> "not in scope:" <+> pp (thing lqn))+      where+      something = case ns of+                    NSValue   -> "Value"+                    NSType    -> "Type"+                    NSModule  -> "Module"++    OverlappingSyms qns ->+      hang (text "[error]")+         4 $ text "Overlapping symbols defined:"+          $$ vcat (map ppLocName qns)++    WrongNamespace expected actual lqn ->+      hang ("[error] at" <+> pp (srcRange lqn ))+         4 (fsep $+            [ "Expected a", sayNS expected, "named", quotes (pp (thing lqn))+            , "but found a", sayNS actual, "instead"+            ] ++ suggestion)+        where+        sayNS ns = case ns of+                     NSValue  -> "value"+                     NSType   -> "type"+                     NSModule -> "module"+        suggestion =+          case (expected,actual) of++            (NSValue,NSType) ->+                ["Did you mean `(" <.> pp (thing lqn) <.> text")?"]+            _ -> []++    FixityError o1 f1 o2 f2 ->+      hang (text "[error] at" <+> pp (srcRange o1) <+> text "and" <+> pp (srcRange o2))+         4 (vsep [ text "The fixities of"+                 , indent 2 $ vcat+                   [ "•" <+> pp (thing o1) <+> parens (pp f1)+                   , "•" <+> pp (thing o2) <+> parens (pp f2) ]+                 , text "are not compatible."+                 , text "You may use explicit parentheses to disambiguate." ])++    InvalidConstraint ty ->+      hang (hsep $ [text "[error]"] ++ maybe [] (\r -> [text "at" <+> pp r]) (getLoc ty))+         4 (fsep [ pp ty, text "is not a valid constraint" ])++    MalformedBuiltin ty pn ->+      hang (hsep $ [text "[error]"] ++ maybe [] (\r -> [text "at" <+> pp r]) (getLoc ty))+         4 (fsep [ text "invalid use of built-in type", pp pn+                 , text "in type", pp ty ])++    BoundReservedType n loc src ->+      hang (hsep $ [text "[error]"] ++ maybe [] (\r -> [text "at" <+> pp r]) loc)+         4 (fsep [ text "built-in type", quotes (pp n), text "shadowed in", src ])++    OverlappingRecordUpdate xs ys ->+      hang "[error] Overlapping record updates:"+         4 (vcat [ ppLab xs, ppLab ys ])+      where+      ppLab as = ppNestedSels (thing as) <+> "at" <+> pp (srcRange as)++    InvalidDependency ds ->+      hang "[error] Invalid recursive dependency:"+         4 (vcat [ "•" <+> pp x <.> ", defined at" <+> ppR (depNameLoc x)+                 | x <- ds ])+      where ppR r = pp (from r) <.> "--" <.> pp (to r)++instance PP DepName where+  ppPrec _ d =+    case d of+      ConstratintAt r -> "constraint at" <+> pp r+      NamedThing n ->+        case nameNamespace n of+          NSModule -> "submodule" <+> pp n+          NSType   -> "type" <+> pp n+          NSValue  -> pp n++++-- Warnings --------------------------------------------------------------------++data RenamerWarning+  = SymbolShadowed PName Name [Name]+  | UnusedName Name+    deriving (Show, Generic, NFData)++instance Eq RenamerWarning where+  x == y = compare x y == EQ++-- used to determine in what order ot show things+instance Ord RenamerWarning where+  compare w1 w2 =+    case w1 of+      SymbolShadowed x y _ ->+        case w2 of+          SymbolShadowed x' y' _ -> compare (byStart y,x) (byStart y',x')+          _                      -> LT+      UnusedName x ->+        case w2 of+          UnusedName y -> compare (byStart x) (byStart y)+          _            -> GT++      where+      byStart = from . nameLoc+++instance PP RenamerWarning where+  ppPrec _ (SymbolShadowed k x os) =+    hang (text "[warning] at" <+> loc)+       4 $ fsep [ "This binding for" <+> backticks (pp k)+                , "shadows the existing binding" <.> plural+                , text "at" ]+        $$ vcat (map (pp . nameLoc) os)++    where+    plural | length os > 1 = char 's'+           | otherwise     = mempty++    loc = pp (nameLoc x)++  ppPrec _ (UnusedName x) =+    hang (text "[warning] at" <+> pp (nameLoc x))+       4 (text "Unused name:" <+> pp x)+++
+ src/Cryptol/ModuleSystem/Renamer/Monad.hs view
@@ -0,0 +1,342 @@+-- |+-- Module      :  Cryptol.ModuleSystem.Renamer+-- Copyright   :  (c) 2013-2016 Galois, Inc.+-- License     :  BSD3+-- Maintainer  :  cryptol@galois.com+-- Stability   :  provisional+-- Portability :  portable++{-# Language RecordWildCards #-}+{-# Language FlexibleContexts #-}+{-# Language BlockArguments #-}+module Cryptol.ModuleSystem.Renamer.Monad where++import Data.List(sort)+import           Data.Set(Set)+import qualified Data.Set as Set+import qualified Data.Foldable as F+import           Data.Map.Strict ( Map )+import qualified Data.Map.Strict as Map+import qualified Data.Sequence as Seq+import qualified Data.Semigroup as S+import           MonadLib hiding (mapM, mapM_)++import Prelude ()+import Prelude.Compat++import Cryptol.ModuleSystem.Name+import Cryptol.ModuleSystem.NamingEnv+import Cryptol.ModuleSystem.Interface+import Cryptol.Parser.AST+import Cryptol.Parser.Position+import Cryptol.Utils.Panic (panic)+import Cryptol.Utils.Ident(modPathCommon)++import Cryptol.ModuleSystem.Renamer.Error++-- | Indicates if a name is in a binding poisition or a use site+data NameType = NameBind | NameUse++-- | Information needed to do some renaming.+data RenamerInfo = RenamerInfo+  { renSupply   :: Supply     -- ^ Use to make new names+  , renContext  :: ModPath    -- ^ We are renaming things in here+  , renEnv      :: NamingEnv  -- ^ This is what's in scope+  , renIfaces   :: ModName -> Iface+  }++newtype RenameM a = RenameM { unRenameM :: ReaderT RO (StateT RW Lift) a }++data RO = RO+  { roLoc    :: Range+  , roNames  :: NamingEnv+  , roIfaces :: ModName -> Iface+  , roCurMod :: ModPath           -- ^ Current module we are working on+  , roNestedMods :: Map ModPath Name+  }++data RW = RW+  { rwWarnings      :: ![RenamerWarning]+  , rwErrors        :: !(Seq.Seq RenamerError)+  , rwSupply        :: !Supply+  , rwNameUseCount  :: !(Map Name Int)+    -- ^ How many times did we refer to each name.+    -- Used to generate warnings for unused definitions.++  , rwCurrentDeps     :: Set Name+    -- ^ keeps track of names *used* by something.+    -- see 'depsOf'++  , rwDepGraph        :: Map DepName (Set Name)+    -- ^ keeps track of the dependencies for things.+    -- see 'depsOf'++  , rwExternalDeps  :: !IfaceDecls+    -- ^ Info about imported things+  }++++instance S.Semigroup a => S.Semigroup (RenameM a) where+  {-# INLINE (<>) #-}+  a <> b =+    do x <- a+       y <- b+       return (x S.<> y)++instance (S.Semigroup a, Monoid a) => Monoid (RenameM a) where+  {-# INLINE mempty #-}+  mempty = return mempty++  {-# INLINE mappend #-}+  mappend = (S.<>)++instance Functor RenameM where+  {-# INLINE fmap #-}+  fmap f m      = RenameM (fmap f (unRenameM m))++instance Applicative RenameM where+  {-# INLINE pure #-}+  pure x        = RenameM (pure x)++  {-# INLINE (<*>) #-}+  l <*> r       = RenameM (unRenameM l <*> unRenameM r)++instance Monad RenameM where+  {-# INLINE return #-}+  return x      = RenameM (return x)++  {-# INLINE (>>=) #-}+  m >>= k       = RenameM (unRenameM m >>= unRenameM . k)++instance FreshM RenameM where+  liftSupply f = RenameM $ sets $ \ RW { .. } ->+    let (a,s') = f rwSupply+        rw'    = RW { rwSupply = s', .. }+     in a `seq` rw' `seq` (a, rw')+++runRenamer :: RenamerInfo -> RenameM a+           -> ( Either [RenamerError] (a,Supply)+              , [RenamerWarning]+              )+runRenamer info m = (res, warns)+  where+  warns = sort (rwWarnings rw ++ warnUnused (renContext info) (renEnv info) rw)++  (a,rw) = runM (unRenameM m) ro+                              RW { rwErrors   = Seq.empty+                                 , rwWarnings = []+                                 , rwSupply   = renSupply info+                                 , rwNameUseCount = Map.empty+                                 , rwExternalDeps = mempty+                                 , rwCurrentDeps = Set.empty+                                 , rwDepGraph = Map.empty+                                 }++  ro = RO { roLoc   = emptyRange+          , roNames = renEnv info+          , roIfaces = renIfaces info+          , roCurMod = renContext info+          , roNestedMods = Map.empty+          }++  res | Seq.null (rwErrors rw) = Right (a,rwSupply rw)+      | otherwise              = Left (F.toList (rwErrors rw))+++setCurMod :: ModPath -> RenameM a -> RenameM a+setCurMod mpath (RenameM m) =+  RenameM $ mapReader (\ro -> ro { roCurMod = mpath }) m++getCurMod :: RenameM ModPath+getCurMod = RenameM $ asks roCurMod++getNamingEnv :: RenameM NamingEnv+getNamingEnv = RenameM (asks roNames)+++setNestedModule :: Map ModPath Name -> RenameM a -> RenameM a+setNestedModule mp (RenameM m) =+  RenameM $ mapReader (\ro -> ro { roNestedMods = mp }) m++nestedModuleOrig :: ModPath -> RenameM (Maybe Name)+nestedModuleOrig x = RenameM (asks (Map.lookup x . roNestedMods))+++-- | Record an error.  XXX: use a better name+record :: RenamerError -> RenameM ()+record f = RenameM $+  do RW { .. } <- get+     set RW { rwErrors = rwErrors Seq.|> f, .. }++collectIfaceDeps :: RenameM a -> RenameM (IfaceDecls,a)+collectIfaceDeps (RenameM m) =+  RenameM+  do ds  <- sets \s -> (rwExternalDeps s, s { rwExternalDeps = mempty })+     a   <- m+     ds' <- sets \s -> (rwExternalDeps s, s { rwExternalDeps = ds })+     pure (ds',a)++-- |  Rename something.  All name uses in the sub-computation are assumed+-- to be dependenices of the thing.+depsOf :: DepName -> RenameM a -> RenameM a+depsOf x (RenameM m) = RenameM+  do ds <- sets \rw -> (rwCurrentDeps rw, rw { rwCurrentDeps = Set.empty })+     a  <- m+     sets_ \rw ->+        rw { rwCurrentDeps = Set.union (rwCurrentDeps rw) ds+           , rwDepGraph = Map.insert x (rwCurrentDeps rw) (rwDepGraph rw)+           }+     pure a++-- | This is used when renaming a group of things.  The result contains+-- dependencies between names defines and the group, and is intended to+-- be used to order the group members in dependency order.+depGroup :: RenameM a -> RenameM (a, Map DepName (Set Name))+depGroup (RenameM m) = RenameM+  do ds  <- sets \rw -> (rwDepGraph rw, rw { rwDepGraph = Map.empty })+     a   <- m+     ds1 <- sets \rw -> (rwDepGraph rw, rw { rwDepGraph = ds })+     pure (a,ds1)++-- | Get the source range for wahtever we are currently renaming.+curLoc :: RenameM Range+curLoc  = RenameM (roLoc `fmap` ask)++-- | Annotate something with the current range.+located :: a -> RenameM (Located a)+located thing =+  do srcRange <- curLoc+     return Located { .. }++-- | Do the given computation using the source code range from `loc` if any.+withLoc :: HasLoc loc => loc -> RenameM a -> RenameM a+withLoc loc m = RenameM $ case getLoc loc of++  Just range -> do+    ro <- ask+    local ro { roLoc = range } (unRenameM m)++  Nothing -> unRenameM m+++-- | Shadow the current naming environment with some more names.+shadowNames :: BindsNames env => env -> RenameM a -> RenameM a+shadowNames  = shadowNames' CheckAll++data EnvCheck = CheckAll     -- ^ Check for overlap and shadowing+              | CheckOverlap -- ^ Only check for overlap+              | CheckNone    -- ^ Don't check the environment+                deriving (Eq,Show)++-- | Shadow the current naming environment with some more names.+shadowNames' :: BindsNames env => EnvCheck -> env -> RenameM a -> RenameM a+shadowNames' check names m = do+  do env <- liftSupply (defsOf names)+     RenameM $+       do ro  <- ask+          env' <- sets (checkEnv check env (roNames ro))+          let ro' = ro { roNames = env' `shadowing` roNames ro }+          local ro' (unRenameM m)++-- | Generate warnings when the left environment shadows things defined in+-- the right.  Additionally, generate errors when two names overlap in the+-- left environment.+checkEnv :: EnvCheck -> NamingEnv -> NamingEnv -> RW -> (NamingEnv,RW)+checkEnv check (NamingEnv lenv) r rw0+  | check == CheckNone = (newEnv,rw0)+  | otherwise          = (newEnv,rwFin)++  where+  newEnv         = NamingEnv newMap+  (rwFin,newMap) = Map.mapAccumWithKey doNS rw0 lenv  -- lenv 1 ns at a time+  doNS rw ns     = Map.mapAccumWithKey (step ns) rw++  -- namespace, current state, k : parse name, xs : possible entities for k+  step ns acc k xs = (acc', case check of+                              CheckNone -> xs+                              _         -> [head xs]+                              -- we've already reported an overlap error,+                              -- so resolve arbitrarily to  the first entry+                      )+    where+    acc' = acc+      { rwWarnings =+          if check == CheckAll+             then case Map.lookup k (namespaceMap ns r) of+                    Just os | [x] <- xs+                            , let os' = filter (/=x) os+                            , not (null os') ->+                              SymbolShadowed k x os' : rwWarnings acc+                    _ -> rwWarnings acc++             else rwWarnings acc+      , rwErrors   = rwErrors acc Seq.>< containsOverlap xs+      }++-- | Check the RHS of a single name rewrite for conflicting sources.+containsOverlap :: [Name] -> Seq.Seq RenamerError+containsOverlap [_] = Seq.empty+containsOverlap []  = panic "Renamer" ["Invalid naming environment"]+containsOverlap ns  = Seq.singleton (OverlappingSyms ns)+++recordUse :: Name -> RenameM ()+recordUse x = RenameM $ sets_ $ \rw ->+  rw { rwNameUseCount = Map.insertWith (+) x 1 (rwNameUseCount rw) }+  {- NOTE: we don't distinguish between bindings and uses here, because+  the situation is complicated by the pattern signatures where the first+  "use" site is actually the binding site.  Instead we just count them all, and+  something is considered unused if it is used only once (i.e, just the+  binding site) -}++-- | Mark something as a dependency. This is similar but different from+-- `recordUse`, in particular:+--    * We only record use sites, not bindings+--    * We record all namespaces, not just types+--    * We only keep track of actual uses mentioned in the code.+--      Otoh, `recordUse` also considers exported entities to be used.+--    * If we depend on a name from a sibling submodule we add a dependency on+--      the module in our common ancestor.  Examples:+--      - @A::B::x@ depends on @A::B::C::D::y@, @x@ depends on @A::B::C@+--      - @A::B::x@ depends on @A::P::Q::y@@,   @x@ depends on @A::P@++addDep :: Name -> RenameM ()+addDep x =+  do cur  <- getCurMod+     deps <- case nameInfo x of+               Declared m _ | Just (c,_,i:_) <- modPathCommon cur m ->+                 do mb <- nestedModuleOrig (Nested c i)+                    pure case mb of+                           Just y  -> Set.fromList [x,y]+                           Nothing -> Set.singleton x+               _ -> pure (Set.singleton x)+     RenameM $+       sets_ \rw -> rw { rwCurrentDeps = Set.union deps (rwCurrentDeps rw) }+++warnUnused :: ModPath -> NamingEnv -> RW -> [RenamerWarning]+warnUnused m0 env rw =+  map warn+  $ Map.keys+  $ Map.filterWithKey keep+  $ rwNameUseCount rw+  where+  warn x   = UnusedName x+  keep nm count = count == 1 && isLocal nm+  oldNames = Map.findWithDefault Set.empty NSType (visibleNames env)+  isLocal nm = case nameInfo nm of+                 Declared m sys -> sys == UserName &&+                                   m == m0 && nm `Set.notMember` oldNames+                 Parameter  -> True++-- | Get the exported declarations in a module+lookupImport :: Import -> RenameM IfaceDecls+lookupImport imp = RenameM $+  do getIf <- roIfaces <$> ask+     let ifs = ifPublic (getIf (iModule imp))+     sets_ \s -> s { rwExternalDeps = ifs <> rwExternalDeps s }+     pure ifs++
src/Cryptol/Parser.y view
@@ -35,6 +35,7 @@ import Cryptol.Parser.AST import Cryptol.Parser.Position import Cryptol.Parser.LexerUtils hiding (mkIdent)+import Cryptol.Parser.Token import Cryptol.Parser.ParserUtils import Cryptol.Parser.Unlit(PreProc(..), guessPreProc) import Cryptol.Utils.Ident(paramInstModName)@@ -43,7 +44,7 @@ import Paths_cryptol } -{- state 196 contains 1 shift/reduce conflicts.+{- state 202 contains 1 shift/reduce conflicts.      `_` identifier conflicts with `_` in record update.     We have `_` as an identifier for the cases where we parse types as     expressions, for example `[ 12 .. _ ]`.@@ -77,12 +78,15 @@   'type'      { Located $$ (Token (KW KW_type   ) _)}   'newtype'   { Located $$ (Token (KW KW_newtype) _)}   'module'    { Located $$ (Token (KW KW_module ) _)}+  'submodule' { Located $$ (Token (KW KW_submodule ) _)}   'where'     { Located $$ (Token (KW KW_where  ) _)}   'let'       { Located $$ (Token (KW KW_let    ) _)}   'if'        { Located $$ (Token (KW KW_if     ) _)}   'then'      { Located $$ (Token (KW KW_then   ) _)}   'else'      { Located $$ (Token (KW KW_else   ) _)}   'x'         { Located $$ (Token (KW KW_x)       _)}+  'down'      { Located $$ (Token (KW KW_down)    _)}+  'by'        { Located $$ (Token (KW KW_by)      _)}    'primitive' { Located $$ (Token (KW KW_primitive) _)}   'constraint'{ Located $$ (Token (KW KW_constraint) _)}@@ -94,8 +98,10 @@   '..'        { Located $$ (Token (Sym DotDot  ) _)}   '...'       { Located $$ (Token (Sym DotDotDot) _)}   '..<'       { Located $$ (Token (Sym DotDotLt) _)}+  '..>'       { Located $$ (Token (Sym DotDotGt) _)}   '|'         { Located $$ (Token (Sym Bar     ) _)}   '<'         { Located $$ (Token (Sym Lt      ) _)}+  '>'         { Located $$ (Token (Sym Gt      ) _)}    '('         { Located $$ (Token (Sym ParenL  ) _)}   ')'         { Located $$ (Token (Sym ParenR  ) _)}@@ -158,27 +164,27 @@ %%  -vmodule                    :: { Module PName }-  : 'module' modName 'where' 'v{' vmod_body 'v}' { mkModule $2 $5 }-  | 'module' modName '=' modName 'where' 'v{' vmod_body 'v}'-                                                 { mkModuleInstance $2 $4 $7 }-  | 'v{' vmod_body 'v}'                          { mkAnonymousModule $2 }+vmodule :: { Module PName }+  : 'module' module_def       { $2 }+  | 'v{' vmod_body 'v}'       { mkAnonymousModule $2 } -vmod_body                  :: { ([Located Import], [TopDecl PName]) }-  : vimports 'v;' vtop_decls  { (reverse $1, reverse $3) }-  | vimports ';'  vtop_decls  { (reverse $1, reverse $3) }-  | vimports                  { (reverse $1, [])         }-  | vtop_decls                { ([], reverse $1)         }-  | {- empty -}               { ([], [])                 } -vimports                   :: { [Located Import] }-  : vimports 'v;' import      { $3 : $1 }-  | vimports ';'  import      { $3 : $1 }-  | import                    { [$1]    }+module_def :: { Module PName } +  : modName 'where'+      'v{' vmod_body 'v}'                 { mkModule $1 $4 }++  | modName '=' modName 'where'+      'v{' vmod_body 'v}'                 { mkModuleInstance $1 $3 $6 }++vmod_body                  :: { [TopDecl PName] }+  : vtop_decls                { reverse $1 }+  | {- empty -}               { [] }++ -- XXX replace rComb with uses of at-import                     :: { Located Import }-  : 'import' modName mbAs mbImportSpec+import                          :: { Located (ImportG (ImpName PName)) }+  : 'import' impName mbAs mbImportSpec                               { Located { srcRange = rComb $1                                                    $ fromMaybe (srcRange $2)                                                    $ msum [ fmap srcRange $4@@ -191,6 +197,11 @@                                           }                                         } } +impName                    :: { Located (ImpName PName) }+  : 'submodule' qname         { ImpNested `fmap` $2 }+  | modName                   { ImpTop `fmap` $1 }++ mbAs                       :: { Maybe (Located ModName) }   : 'as' modName              { Just $2 }   | {- empty -}               { Nothing }@@ -242,6 +253,9 @@   | prim_bind              { $1                                               }   | private_decls          { $1                                               }   | parameter_decls        { $1                                               }+  | mbDoc 'submodule'+    module_def             {% ((:[]) . exportModule $1) `fmap` mkNested $3 }+  | import                 { [DImport $1] }  top_decl                :: { [TopDecl PName] }   : decl                   { [Decl (TopLevel {tlExport = Public, tlValue = $1 })] }@@ -303,6 +317,7 @@                                           , bInfix     = True                                           , bFixity    = Nothing                                           , bDoc       = Nothing+                                          , bExport    = Public                                           } }    | 'type' name '=' type   {% at ($1,$4) `fmap` mkTySyn $2 [] $4 }@@ -323,10 +338,49 @@   | 'infix'  NUM ops       {% mkFixity NonAssoc   $2 (reverse $3) }   | error                  {% expected "a declaration" } +let_decls               :: { [Decl PName] }+  : let_decl               { [$1] }+  | let_decl ';'           { [$1] }+  | let_decl ';' let_decls { ($1:$3) }+ let_decl                :: { Decl PName }-  : 'let' ipat '=' expr          { at ($2,$4) $ DPatBind $2 $4                    }-  | 'let' name apats_indices '=' expr    { at ($2,$5) $ mkIndexedDecl $2 $3 $5 }+  : 'let' ipat '=' expr               { at ($2,$4) $ DPatBind $2 $4                    }+  | 'let' var apats_indices '=' expr  { at ($2,$5) $ mkIndexedDecl $2 $3 $5 }+  | 'let' '(' op ')' '=' expr         { at ($2,$6) $ DPatBind (PVar $3) $6             }+  | 'let' apat pat_op apat '=' expr+                           { at ($2,$6) $+                             DBind $ Bind { bName      = $3+                                          , bParams    = [$2,$4]+                                          , bDef       = at $6 (Located emptyRange (DExpr $6))+                                          , bSignature = Nothing+                                          , bPragmas   = []+                                          , bMono      = False+                                          , bInfix     = True+                                          , bFixity    = Nothing+                                          , bDoc       = Nothing+                                          , bExport    = Public+                                          } } +  | 'let' vars_comma ':' schema  { at (head $2,$4) $ DSignature (reverse $2) $4   }++  | 'type' name '=' type   {% at ($1,$4) `fmap` mkTySyn $2 [] $4 }+  | 'type' name tysyn_params '=' type+                           {% at ($1,$5) `fmap` mkTySyn $2 (reverse $3) $5  }+  | 'type' tysyn_param op tysyn_param '=' type+                           {% at ($1,$6) `fmap` mkTySyn $3 [$2, $4] $6 }++  | 'type' 'constraint' name '=' type+                           {% at ($2,$5) `fmap` mkPropSyn $3 [] $5 }+  | 'type' 'constraint' name tysyn_params '=' type+                           {% at ($2,$6) `fmap` mkPropSyn $3 (reverse $4) $6 }+  | 'type' 'constraint' tysyn_param op tysyn_param '=' type+                           {% at ($2,$7) `fmap` mkPropSyn $4 [$3, $5] $7 }++  | 'infixl' NUM ops       {% mkFixity LeftAssoc  $2 (reverse $3) }+  | 'infixr' NUM ops       {% mkFixity RightAssoc $2 (reverse $3) }+  | 'infix'  NUM ops       {% mkFixity NonAssoc   $2 (reverse $3) }++ newtype                 :: { Newtype PName }   : 'newtype' qname '=' newtype_body                            { Newtype $2 [] (thing $4) }@@ -380,7 +434,7 @@  repl                    :: { ReplInput PName }   : expr                   { ExprInput $1 }-  | let_decl               { LetInput $1 }+  | let_decls              { LetInput $1 }   | {- empty -}            { EmptyInput }  @@ -407,7 +461,7 @@   | '~'                             { Located $1 $ mkUnqual $ mkInfix "~" }   | '^^'                            { Located $1 $ mkUnqual $ mkInfix "^^" }   | '<'                             { Located $1 $ mkUnqual $ mkInfix "<" }-+  | '>'                             { Located $1 $ mkUnqual $ mkInfix ">" }  other_op                         :: { LPName }   : OP                              { let Token (Op (Other [] str)) _ = thing $1@@ -576,6 +630,14 @@   | expr '..' '<' expr            {% eFromToLessThan $2 $1 $4   }   | expr '..<'    expr            {% eFromToLessThan $2 $1 $3   } +  | expr '..' expr 'by' expr      {% eFromToBy $2 $1 $3 $5 False }+  | expr '..' '<' expr 'by' expr  {% eFromToBy $2 $1 $4 $6 True }+  | expr '..<' expr 'by' expr     {% eFromToBy $2 $1 $3 $5 True }++  | expr '..' expr 'down' 'by' expr     {% eFromToDownBy $2 $1 $3 $6 False }+  | expr '..' '>' expr 'down' 'by' expr {% eFromToDownBy $2 $1 $4 $7 True }+  | expr '..>' expr 'down' 'by' expr    {% eFromToDownBy $2 $1 $3 $6 True }+   | expr '...'                    { EInfFrom $1 Nothing         }   | expr ',' expr '...'           { EInfFrom $1 (Just $3)       } @@ -720,7 +782,6 @@   | 'private'         { Located { srcRange = $1, thing = mkIdent "private" } }   | 'as'              { Located { srcRange = $1, thing = mkIdent "as" } }   | 'hiding'          { Located { srcRange = $1, thing = mkIdent "hiding" } }-  name               :: { LPName }   : ident             { fmap mkUnqual $1 }
src/Cryptol/Parser/AST.hs view
@@ -37,7 +37,10 @@   , psFixity      -- * Declarations-  , Module(..)+  , Module+  , ModuleG(..)+  , mImports+  , mSubmoduleImports   , Program(..)   , TopDecl(..)   , Decl(..)@@ -50,11 +53,12 @@   , Pragma(..)   , ExportType(..)   , TopLevel(..)-  , Import(..), ImportSpec(..)+  , Import, ImportG(..), ImportSpec(..), ImpName(..)   , Newtype(..)   , PrimType(..)   , ParameterType(..)   , ParameterFun(..)+  , NestedModule(..)      -- * Interactive   , ReplInput(..)@@ -119,15 +123,39 @@                        deriving (Show)  -- | A parsed module.-data Module name = Module-  { mName     :: Located ModName            -- ^ Name of the module+data ModuleG mname name = Module+  { mName     :: Located mname              -- ^ Name of the module   , mInstance :: !(Maybe (Located ModName)) -- ^ Functor to instantiate                                             -- (if this is a functor instnaces)-  , mImports  :: [Located Import]           -- ^ Imports for the module+  -- , mImports  :: [Located Import]           -- ^ Imports for the module   , mDecls    :: [TopDecl name]             -- ^ Declartions for the module   } deriving (Show, Generic, NFData) +mImports :: ModuleG mname name -> [ Located Import ]+mImports m =+  [ li { thing = i { iModule = n } }+  | DImport li <- mDecls m+  , let i = thing li+  , ImpTop n  <- [iModule i]+  ] +mSubmoduleImports :: ModuleG mname name -> [ Located (ImportG name) ]+mSubmoduleImports m =+  [ li { thing = i { iModule = n } }+  | DImport li <- mDecls m+  , let i = thing li+  , ImpNested n  <- [iModule i]+  ]++++type Module = ModuleG ModName+++newtype NestedModule name = NestedModule (ModuleG name name)+  deriving (Show,Generic,NFData)++ modRange :: Module name -> Range modRange m = rCombs $ catMaybes     [ getLoc (mName m)@@ -146,12 +174,21 @@   | DParameterConstraint [Located (Prop name)]                                         -- ^ @parameter type constraint (fin T)@   | DParameterFun  (ParameterFun name)  -- ^ @parameter someVal : [256]@+  | DModule (TopLevel (NestedModule name))  -- ^ Nested module+  | DImport (Located (ImportG (ImpName name)))  -- ^ An import declaration                     deriving (Show, Generic, NFData) +data ImpName name =+    ImpTop    ModName+  | ImpNested name+    deriving (Show, Generic, NFData)+ data Decl name = DSignature [Located name] (Schema name)                | DFixity !Fixity [Located name]                | DPragma [Located name] Pragma                | DBind (Bind name)+               | DRec [Bind name]+                 -- ^ A group of recursive bindings, introduced by the renamer.                | DPatBind (Pattern name) (Expr name)                | DType (TySyn name)                | DProp (PropSyn name)@@ -178,16 +215,15 @@   -- | An import declaration.-data Import = Import { iModule    :: !ModName-                     , iAs        :: Maybe ModName-                     , iSpec      :: Maybe ImportSpec-                     } deriving (Eq, Show, Generic, NFData)+data ImportG mname = Import+  { iModule    :: !mname+  , iAs        :: Maybe ModName+  , iSpec      :: Maybe ImportSpec+  } deriving (Eq, Show, Generic, NFData) +type Import = ImportG ModName+ -- | The list of names following an import.------ INVARIANT: All of the 'Name' entries in the list are expected to be--- unqualified names; the 'QName' or 'NewName' constructors should not be--- present. data ImportSpec = Hiding [Ident]                 | Only   [Ident]                   deriving (Eq, Show, Generic, NFData)@@ -234,6 +270,7 @@   , bPragmas   :: [Pragma]                -- ^ Optional pragmas   , bMono      :: Bool                    -- ^ Is this a monomorphic binding   , bDoc       :: Maybe Text              -- ^ Optional doc string+  , bExport    :: !ExportType   } deriving (Eq, Generic, NFData, Functor, Show)  type LBindDef = Located (BindDef PName)@@ -263,7 +300,7 @@ -- | Input at the REPL, which can be an expression, a @let@ -- statement, or empty (possibly a comment). data ReplInput name = ExprInput (Expr name)-                    | LetInput (Decl name)+                    | LetInput [Decl name]                     | EmptyInput                       deriving (Eq, Show) @@ -314,6 +351,11 @@               | EList [Expr n]                  -- ^ @ [1,2,3] @               | EFromTo (Type n) (Maybe (Type n)) (Type n) (Maybe (Type n))                                                 -- ^ @ [1, 5 .. 117 : t] @+              | EFromToBy Bool (Type n) (Type n) (Type n) (Maybe (Type n))+                                                -- ^ @ [1 .. 10 by 2 : t ] @++              | EFromToDownBy Bool (Type n) (Type n) (Type n) (Maybe (Type n))+                                                -- ^ @ [10 .. 1 down by 2 : t ] @               | EFromToLessThan (Type n) (Type n) (Maybe (Type n))                                                 -- ^ @ [ 1 .. < 10 : t ] @ @@ -482,14 +524,17 @@   getLoc = getLoc . tlValue  instance HasLoc (TopDecl name) where-  getLoc td = case td of-    Decl tld    -> getLoc tld-    DPrimType pt -> getLoc pt-    TDNewtype n -> getLoc n-    Include lfp -> getLoc lfp-    DParameterType d -> getLoc d-    DParameterFun d  -> getLoc d-    DParameterConstraint d -> getLoc d+  getLoc td =+    case td of+      Decl tld    -> getLoc tld+      DPrimType pt -> getLoc pt+      TDNewtype n -> getLoc n+      Include lfp -> getLoc lfp+      DParameterType d -> getLoc d+      DParameterFun d  -> getLoc d+      DParameterConstraint d -> getLoc d+      DModule d -> getLoc d+      DImport d -> getLoc d  instance HasLoc (PrimType name) where   getLoc pt = Just (rComb (srcRange (primTName pt)) (srcRange (primTKind pt)))@@ -500,7 +545,7 @@ instance HasLoc (ParameterFun name) where   getLoc a = getLoc (pfName a) -instance HasLoc (Module name) where+instance HasLoc (ModuleG mname name) where   getLoc m     | null locs = Nothing     | otherwise = Just (rCombs locs)@@ -510,6 +555,9 @@                      , getLoc (mDecls m)                      ] +instance HasLoc (NestedModule name) where+  getLoc (NestedModule m) = getLoc m+ instance HasLoc (Newtype name) where   getLoc n     | null locs = Nothing@@ -537,11 +585,25 @@ ppNamed' :: PP a => String -> (Ident, (Range, a)) -> Doc ppNamed' s (i,(_,v)) = pp i <+> text s <+> pp v -instance (Show name, PPName name) => PP (Module name) where-  ppPrec _ m = text "module" <+> ppL (mName m) <+> text "where"-            $$ vcat (map ppL (mImports m))-            $$ vcat (map pp (mDecls m)) ++instance (Show name, PPName mname, PPName name) => PP (ModuleG mname name) where+  ppPrec _ = ppModule 0++ppModule :: (Show name, PPName mname, PPName name) =>+  Int -> ModuleG mname name -> Doc+ppModule n m =+  text "module" <+> ppL (mName m) <+> text "where" $$ nest n body+  where+  body = vcat (map ppL (mImports m))+      $$ vcat (map pp (mDecls m))++++instance (Show name, PPName name) => PP (NestedModule name) where+  ppPrec _ (NestedModule m) = ppModule 2 m++ instance (Show name, PPName name) => PP (Program name) where   ppPrec _ (Program ds) = vcat (map pp ds) @@ -556,10 +618,12 @@       DParameterType d -> pp d       DParameterConstraint d ->         "parameter" <+> "type" <+> "constraint" <+> prop-        where prop = case map pp d of+        where prop = case map (pp . thing) d of                        [x] -> x                        []  -> "()"-                       xs  -> parens (hsep (punctuate comma xs))+                       xs  -> nest 1 (parens (commaSepFill xs))+      DModule d -> pp d+      DImport i -> pp (thing i)  instance (Show name, PPName name) => PP (PrimType name) where   ppPrec _ pt =@@ -580,6 +644,7 @@       DSignature xs s -> commaSep (map ppL xs) <+> text ":" <+> pp s       DPatBind p e    -> pp p <+> text "=" <+> pp e       DBind b         -> ppPrec n b+      DRec bs         -> nest 2 (vcat ("recursive" : map (ppPrec n) bs))       DFixity f ns    -> ppFixity f ns       DPragma xs p    -> ppPragma xs p       DType ts        -> ppPrec n ts@@ -592,16 +657,22 @@ ppFixity (Fixity NonAssoc   i) ns = text "infix"  <+> int i <+> commaSep (map pp ns)  instance PPName name => PP (Newtype name) where-  ppPrec _ nt = hsep-    [ text "newtype", ppL (nName nt), hsep (map pp (nParams nt)), char '='-    , braces (commaSep (map (ppNamed' ":") (displayFields (nBody nt)))) ]+  ppPrec _ nt = nest 2 $ sep+    [ fsep $ [text "newtype", ppL (nName nt)] ++ map pp (nParams nt) ++ [char '=']+    , ppRecord (map (ppNamed' ":") (displayFields (nBody nt)))+    ] -instance PP Import where-  ppPrec _ d = text "import" <+> sep [ pp (iModule d), mbAs, mbSpec ]+instance PP mname => PP (ImportG mname) where+  ppPrec _ d = text "import" <+> sep ([pp (iModule d)] ++ mbAs ++ mbSpec)     where-    mbAs = maybe empty (\ name -> text "as" <+> pp name ) (iAs d)+    mbAs   = maybe [] (\ name -> [text "as" <+> pp name]) (iAs d)+    mbSpec = maybe [] (\x -> [pp x]) (iSpec d) -    mbSpec = maybe empty pp (iSpec d)+instance PP name => PP (ImpName name) where+  ppPrec _ nm =+    case nm of+      ImpTop x    -> pp x+      ImpNested x -> "submodule" <+> pp x  instance PP ImportSpec where   ppPrec _ s = case s of@@ -623,16 +694,16 @@   <+> text "*/"  instance (Show name, PPName name) => PP (Bind name) where-  ppPrec _ b = sig $$ vcat [ ppPragma [f] p | p <- bPragmas b ] $$-               hang (def <+> eq) 4 (pp (thing (bDef b)))+  ppPrec _ b = vcat (sig ++ [ ppPragma [f] p | p <- bPragmas b ] +++                     [hang (def <+> eq) 4 (pp (thing (bDef b)))])     where def | bInfix b  = lhsOp               | otherwise = lhs           f = bName b           sig = case bSignature b of-                  Nothing -> empty-                  Just s  -> pp (DSignature [f] s)+                  Nothing -> []+                  Just s  -> [pp (DSignature [f] s)]           eq  = if bMono b then text ":=" else text "="-          lhs = ppL f <+> fsep (map (ppPrec 3) (bParams b))+          lhs = fsep (ppL f : (map (ppPrec 3) (bParams b)))            lhsOp = case bParams b of                     [x,y] -> pp x <+> ppL f <+> pp y@@ -647,13 +718,17 @@  instance PPName name => PP (TySyn name) where   ppPrec _ (TySyn x _ xs t) =-    text "type" <+> ppL x <+> fsep (map (ppPrec 1) xs)-                <+> text "=" <+> pp t+    nest 2 $ sep $+      [ fsep $ [text "type", ppL x] ++ map (ppPrec 1) xs ++ [text "="]+      , pp t+      ]  instance PPName name => PP (PropSyn name) where   ppPrec _ (PropSyn x _ xs ps) =-    text "constraint" <+> ppL x <+> fsep (map (ppPrec 1) xs)-                      <+> text "=" <+> parens (commaSep (map pp ps))+    nest 2 $ sep $+      [ fsep $ [text "constraint", ppL x] ++ map (ppPrec 1) xs ++ [text "="]+      , parens (commaSep (map pp ps))+      ]  instance PP Literal where   ppPrec _ lit =@@ -710,7 +785,7 @@     | otherwise = bits (Just p) (p : res) (p + 1) (num `shiftR` 1)  wrap :: Int -> Int -> Doc -> Doc-wrap contextPrec myPrec doc = if myPrec < contextPrec then parens doc else doc+wrap contextPrec myPrec doc = optParens (myPrec < contextPrec) doc  isEApp :: Expr n -> Maybe (Expr n, Expr n) isEApp (ELocated e _)     = isEApp e@@ -749,15 +824,23 @@       ERecord fs    -> braces (commaSep (map (ppNamed' "=") (displayFields fs)))       EList es      -> brackets (commaSep (map pp es))       EFromTo e1 e2 e3 t1 -> brackets (pp e1 <.> step <+> text ".." <+> end)-        where step = maybe empty (\e -> comma <+> pp e) e2+        where step = maybe mempty (\e -> comma <+> pp e) e2               end = maybe (pp e3) (\t -> pp e3 <+> colon <+> pp t) t1+      EFromToBy isStrict e1 e2 e3 t1 -> brackets (pp e1 <+> dots <+> pp e2 <+> text "by" <+> end)+        where end = maybe (pp e3) (\t -> pp e3 <+> colon <+> pp t) t1+              dots | isStrict  = text ".. <"+                   | otherwise = text ".."+      EFromToDownBy isStrict e1 e2 e3 t1 -> brackets (pp e1 <+> dots <+> pp e2 <+> text "down by" <+> end)+        where end = maybe (pp e3) (\t -> pp e3 <+> colon <+> pp t) t1+              dots | isStrict  = text ".. >"+                   | otherwise = text ".."       EFromToLessThan e1 e2 t1 -> brackets (strt <+> text ".. <" <+> end)         where strt = maybe (pp e1) (\t -> pp e1 <+> colon <+> pp t) t1               end  = pp e2       EInfFrom e1 e2 -> brackets (pp e1 <.> step <+> text "...")-        where step = maybe empty (\e -> comma <+> pp e) e2-      EComp e mss   -> brackets (pp e <+> vcat (map arm mss))-        where arm ms = text "|" <+> commaSep (map pp ms)+        where step = maybe mempty (\e -> comma <+> pp e) e2+      EComp e mss   -> brackets (pp e <> align (vcat (map arm mss)))+        where arm ms = text " |" <+> commaSep (map pp ms)       EUpd mb fs    -> braces (hd <+> "|" <+> commaSep (map pp fs))         where hd = maybe "_" pp mb @@ -775,10 +858,10 @@        ETyped e t    -> wrap n 0 (ppPrec 2 e <+> text ":" <+> pp t) -      EWhere  e ds  -> wrap n 0 (pp e-                                $$ text "where"-                                $$ nest 2 (vcat (map pp ds))-                                $$ text "")+      EWhere  e ds  -> wrap n 0 $ align $ vsep+                         [ pp e+                         , hang "where" 2 (vcat (map pp ds))+                         ]        -- infix applications       _ | Just ifix <- isInfix expr ->@@ -814,9 +897,9 @@     case pat of       PVar x        -> pp (thing x)       PWild         -> char '_'-      PTuple ps     -> parens   (commaSep (map pp ps))-      PRecord fs    -> braces   (commaSep (map (ppNamed' "=") (displayFields fs)))-      PList ps      -> brackets (commaSep (map pp ps))+      PTuple ps     -> ppTuple (map pp ps)+      PRecord fs    -> ppRecord (map (ppNamed' "=") (displayFields fs))+      PList ps      -> ppList (map pp ps)       PTyped p t    -> wrap n 0 (ppPrec 1 p  <+> text ":" <+> pp t)       PSplit p1 p2  -> wrap n 1 (ppPrec 1 p1 <+> text "#" <+> ppPrec 1 p2)       PLocated p _  -> ppPrec n p@@ -827,13 +910,13 @@   instance PPName name => PP (Schema name) where-  ppPrec _ (Forall xs ps t _) = sep [vars <+> preds, pp t]+  ppPrec _ (Forall xs ps t _) = sep (vars ++ preds ++ [pp t])     where vars = case xs of-                   [] -> empty-                   _  -> braces (commaSep (map pp xs))+                   [] -> []+                   _  -> [nest 1 (braces (commaSepFill (map pp xs)))]           preds = case ps of-                    [] -> empty-                    _  -> parens (commaSep (map pp ps)) <+> text "=>"+                    [] -> []+                    _  -> [nest 1 (parens (commaSepFill (map pp ps))) <+> text "=>"]  instance PP Kind where   ppPrec _ KType  = text "*"@@ -915,13 +998,15 @@ instance NoPos (Program name) where   noPos (Program x) = Program (noPos x) -instance NoPos (Module name) where+instance NoPos (ModuleG mname name) where   noPos m = Module { mName      = mName m                    , mInstance  = mInstance m-                   , mImports   = noPos (mImports m)                    , mDecls     = noPos (mDecls m)                    } +instance NoPos (NestedModule name) where+  noPos (NestedModule m) = NestedModule (noPos m)+ instance NoPos (TopDecl name) where   noPos decl =     case decl of@@ -932,7 +1017,10 @@       DParameterFun d  -> DParameterFun (noPos d)       DParameterType d -> DParameterType (noPos d)       DParameterConstraint d -> DParameterConstraint (noPos d)+      DModule d -> DModule (noPos d)+      DImport d -> DImport (noPos d) + instance NoPos (PrimType name) where   noPos x = x @@ -953,6 +1041,7 @@       DPatBind   x y   -> DPatBind   (noPos x) (noPos y)       DFixity f ns     -> DFixity f (noPos ns)       DBind      x     -> DBind      (noPos x)+      DRec       bs    -> DRec       (map noPos bs)       DType      x     -> DType      (noPos x)       DProp      x     -> DProp      (noPos x)       DLocated   x _   -> noPos x@@ -973,6 +1062,7 @@                  , bPragmas   = noPos (bPragmas   x)                  , bMono      = bMono x                  , bDoc       = bDoc x+                 , bExport    = bExport x                  }  instance NoPos Pragma where@@ -1001,6 +1091,10 @@       EUpd x y        -> EUpd     (noPos x) (noPos y)       EList x         -> EList    (noPos x)       EFromTo x y z t -> EFromTo  (noPos x) (noPos y) (noPos z) (noPos t)+      EFromToBy isStrict x y z t+                      -> EFromToBy isStrict (noPos x) (noPos y) (noPos z) (noPos t)+      EFromToDownBy isStrict x y z t+                      -> EFromToDownBy isStrict (noPos x) (noPos y) (noPos z) (noPos t)       EFromToLessThan x y t -> EFromToLessThan (noPos x) (noPos y) (noPos t)       EInfFrom x y    -> EInfFrom (noPos x) (noPos y)       EComp x y       -> EComp    (noPos x) (noPos y)
+ src/Cryptol/Parser/Layout.hs view
@@ -0,0 +1,237 @@+{-# Language BlockArguments #-}+{-# Language OverloadedStrings #-}+module Cryptol.Parser.Layout where++import Cryptol.Utils.Panic(panic)+import Cryptol.Parser.Position+import Cryptol.Parser.Token++{-++We assume the existence of an explicit EOF token at the end of the input.  This token is *less* indented+than all other tokens (i.e., it is at column 0)++Explicit Layout Blocks++  * The symbols `(`, `{`, and `[` start an explicit layout block.+  * While in an explicit layout block we pass through tokens, except:+      - We may start new implicit or explicit layout blocks+      - A `,` terminates any *nested* layout blocks+      - We terminate the current layout block if we encounter the matching+        closing symbol `)`, `}`, `]`++Implicit Layout Blocks++  * The keywords `where`, `private`, and `parameter` start an implicit+    layout block.+  * The layout block starts at the column of the *following* token and we+    insert "virtual start block" between the current and the following tokens.+  * While in an implicit layout block:+    - We may start new implicit or explicit layout blocks+    - We insert a "virtual separator" before tokens starting at the same+      column as the layout block, EXCEPT:+        * we do not insert a separator if the previous token was a+          "documentation comment"+        * we do not insert a separator before the first token in the block++    - The implicit layout block is ended by:+          * a token than is less indented that the block, or+          * `)`, `}`, `]`, or +          * ',' but only if there is an outer paren block+          block's column.+    - When an implicit layout block ends, we insert a "virtual end block"+      token just before the token that caused the block to end.++Examples:++f = x where x = 0x1         -- end implicit layout by layout+g = 0x3                     -- (`g` is less indented than `x`)++f (x where x = 2)           -- end implicit layout by `)`++[ x where x = 2, 3 ]        -- end implicit layout by `,`++module A where              -- two implicit layout blocks with the+private                     -- *same* indentation (`where` and `private`)+x = 0x2+-}+++layout :: Bool -> [Located Token] -> [Located Token]+layout isMod ts0++  -- Star an implicit layout block at the top of the module+  | let t         = head ts0+        rng       = srcRange t+        blockCol  = max 1 (col (from rng)) -- see startImplicitBlock+  , isMod && tokenType (thing t) /= KW KW_module =+    virt rng VCurlyL : go [ Virtual blockCol ] blockCol True ts0++  | otherwise =+    go [] 0 False ts0++  where++  {- State parameters for `go`:++       stack:+          The stack of implicit and explicit blocks++       lastVirt:+          The indentation of the outer most implicit block, or 0 if none.+          This can be computed from the stack but we cache+          it here as we need to check it on each token.++       noVirtSep:+          Do not emit a virtual separator even if token matches block alignment.+          This is enabled at the beginning of a block, or after a doc string,+          or if we just emitted a separtor, but have not yet consumed the+          next token.++       tokens:+          remaining tokens to process+  -}++  go stack lastVirt noVirtSep tokens++    -- End implicit layout due to indentation.  If the outermost block+    -- is a lyout block we just end it.   If the outermost block is an+    -- explicit layout block we report a lexical error.+    | col curLoc < lastVirt =+      endImplictBlock++    -- End implicit layout block due to a symbol+    | Just (Virtual {}) <- curBlock, endsLayout curTokTy =+      endImplictBlock++    -- End implicit layout block due to a comma+    | Just (Virtual {}) <- curBlock+    , Sym Comma <- curTokTy+    , not (null [ () | Explicit _ <- popStack ]) =+      endImplictBlock++    -- Insert a virtual separator+    | Just (Virtual {}) <- curBlock+    , col curLoc == lastVirt && not noVirtSep =+      virt curRange VSemi : go stack lastVirt True tokens++    -- Start a new implicit layout. Advances token position.+    | startsLayout curTokTy = startImplicitBlock++    -- Start a paren block.  Advances token position+    | Just close <- startsParenBlock curTokTy =+      curTok : go (Explicit close : stack) lastVirt False advanceTokens++    -- End a paren block. Advances token position+    | Just (Explicit close) <- curBlock, close == curTokTy =+      curTok : go popStack lastVirt False advanceTokens++    -- Disable virtual separator after doc string. Advances token position+    | White DocStr <- curTokTy =+      curTok : go stack lastVirt True advanceTokens++    -- Check to see if we are done.  Note that if we got here, implicit layout+    -- blocks should have already been closed, as `EOF` is less indented than+    -- all other tokens+    | EOF <- curTokTy =+      [curTok]++    -- Any other token, just emit.  Advances token position+    | otherwise =+      curTok : go stack lastVirt False advanceTokens++    where+    curTok : advanceTokens = tokens+    curTokTy               = tokenType (thing curTok)+    curRange               = srcRange curTok+    curLoc                 = from curRange++    (curBlock,popStack) =+      case stack of+        a : b -> (Just a,b)+        []    -> (Nothing, panic "layout" ["pop empty stack"])+++    startImplicitBlock =+      let nextRng  = srcRange (head advanceTokens)+          nextLoc  = from nextRng+          blockCol = max 1 (col nextLoc)+          -- the `max` ensuraes that indentation is always at least 1,+          -- in case we are starting a block at the very end of the input++      in curTok+       : virt nextRng VCurlyL+       : go (Virtual blockCol : stack) blockCol True advanceTokens+++    endImplictBlock =+      case curBlock of+        Just (Virtual {}) ->+           virt curRange VCurlyR+           : go popStack newVirt False tokens+          where newVirt = case [ n | Virtual n <- popStack ] of+                            n : _ -> n+                            _     -> 0++        Just (Explicit c) ->+          errTok curRange (InvalidIndentation c) : advanceTokens++        Nothing -> panic "layout" ["endImplictBlock with empty stack"]+++--------------------------------------------------------------------------------++data Block =+    Virtual Int     -- ^ Virtual layout block+  | Explicit TokenT -- ^ An explicit layout block, expecting this ending token.+    deriving (Show)++-- | These tokens start an implicit layout block+startsLayout :: TokenT -> Bool+startsLayout ty =+  case ty of+    KW KW_where       -> True+    KW KW_private     -> True+    KW KW_parameter   -> True+    _                 -> False++-- | These tokens end an implicit layout block+endsLayout :: TokenT -> Bool+endsLayout ty =+  case ty of+    Sym BracketR -> True+    Sym ParenR   -> True+    Sym CurlyR   -> True+    _            -> False++-- | These tokens start an explicit "paren" layout block.+-- If so, the result contains the corresponding closing paren.+startsParenBlock :: TokenT -> Maybe TokenT+startsParenBlock ty =+  case ty of+    Sym BracketL -> Just (Sym BracketR)+    Sym ParenL   -> Just (Sym ParenR)+    Sym CurlyL   -> Just (Sym CurlyR)+    _            -> Nothing+++--------------------------------------------------------------------------------++-- | Make a virtual token of the given type+virt :: Range -> TokenV -> Located Token+virt rng x = Located { srcRange = rng { to = from rng }, thing = t }+  where+  t = Token (Virt x)+      case x of+        VCurlyL -> "beginning of layout block"+        VCurlyR -> "end of layout block"+        VSemi   -> "layout block separator"++errTok :: Range -> TokenErr -> Located Token+errTok rng x = Located { srcRange = rng { to = from rng }, thing = t }+  where+  t = Token { tokenType = Err x, tokenText = "" }++++
src/Cryptol/Parser/Lexer.x view
@@ -18,10 +18,13 @@   , Located(..)   , Config(..)   , defaultConfig+  , dbgLex   ) where  import Cryptol.Parser.Position+import Cryptol.Parser.Token import Cryptol.Parser.LexerUtils+import qualified Cryptol.Parser.Layout as L import Cryptol.Parser.Unlit(unLit) import Data.Text (Text) import qualified Data.Text as Text@@ -100,6 +103,7 @@ "private"                 { emit $ KW KW_private } "include"                 { emit $ KW KW_include } "module"                  { emit $ KW KW_module }+"submodule"               { emit $ KW KW_submodule } "newtype"                 { emit $ KW KW_newtype } "pragma"                  { emit $ KW KW_pragma } "property"                { emit $ KW KW_property }@@ -112,6 +116,8 @@ "as"                      { emit $ KW KW_as } "hiding"                  { emit $ KW KW_hiding } "newtype"                 { emit $ KW KW_newtype }+"down"                    { emit $ KW KW_down }+"by"                      { emit $ KW KW_by }  "infixl"                  { emit $ KW KW_infixl } "infixr"                  { emit $ KW KW_infixr }@@ -143,6 +149,7 @@ ".."                      { emit $ Sym DotDot } "..."                     { emit $ Sym DotDotDot } "..<"                     { emit $ Sym DotDotLt  }+"..>"                     { emit $ Sym DotDotGt  } "|"                       { emit $ Sym Bar } "("                       { emit $ Sym ParenL } ")"                       { emit $ Sym ParenR }@@ -165,6 +172,9 @@ -- < can appear in the enumeration syntax `[ x .. < y ] "<"                       { emit $ Sym Lt } +-- > can appear in the enumeration syntax `[ x .. > y down by n ]+">"                       { emit $ Sym Gt }+ -- hash is used as a kind, and as a pattern "#"                       { emit  (Op   Hash ) } @@ -194,7 +204,7 @@ -- This stream is fed to the parser. lexer :: Config -> Text -> ([Located Token], Position) lexer cfg cs = ( case cfgLayout cfg of-                   Layout   -> layout cfg lexemes+                   Layout   -> L.layout (cfgModuleScope cfg) lexemes                    NoLayout -> lexemes                , finalPos                )@@ -251,6 +261,11 @@             (mtok,s')   = act cfg (alexPos i) txt s             (rest,pos)  = run i' $! s'         in (mtok ++ rest, pos)++dbgLex file =+  do txt <- readFile file+     let (ts,_) = lexer defaultConfig (Text.pack txt)+     mapM_ (print . thing) ts  -- vim: ft=haskell }
src/Cryptol/Parser/LexerUtils.hs view
@@ -5,19 +5,9 @@ -- Maintainer  :  cryptol@galois.com -- Stability   :  provisional -- Portability :  portable--{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE PatternGuards #-}-{-# LANGUAGE BlockArguments #-} module Cryptol.Parser.LexerUtils where -import Cryptol.Parser.Position-import Cryptol.Parser.Unlit(PreProc(None))-import Cryptol.Utils.PP-import Cryptol.Utils.Panic- import           Control.Monad(guard) import           Data.Char(toLower,generalCategory,isAscii,ord,isSpace,                                                             isAlphaNum,isAlpha)@@ -27,9 +17,13 @@ import qualified Data.Text.Read as T import           Data.Word(Word8) -import GHC.Generics (Generic)-import Control.DeepSeq+import Cryptol.Utils.Panic+import Cryptol.Parser.Position+import Cryptol.Parser.Token+import Cryptol.Parser.Unlit(PreProc(None)) ++ data Config = Config   { cfgSource      :: !FilePath     -- ^ File that we are working on   , cfgStart       :: !Position     -- ^ Starting position for the parser@@ -362,209 +356,6 @@         notWhite _         = True  -data Block = Virtual Int     -- ^ Virtual layout block-           | Explicit TokenT -- ^ An explicit layout block, expecting this ending-                             -- token.-             deriving (Show)--isExplicit :: Block -> Bool-isExplicit Explicit{} = True-isExplicit Virtual{}  = False--startsLayout :: TokenT -> Bool-startsLayout (KW KW_where)    = True-startsLayout (KW KW_private)  = True-startsLayout (KW KW_parameter) = True-startsLayout _                = False---- Add separators computed from layout-layout :: Config -> [Located Token] -> [Located Token]-layout cfg ts0 = loop False implicitScope [] ts0-  where--  (_pos0,implicitScope) = case ts0 of-    t : _ -> (from (srcRange t), cfgModuleScope cfg && tokenType (thing t) /= KW KW_module)-    _     -> (start,False)---  loop :: Bool -> Bool -> [Block] -> [Located Token] -> [Located Token]-  loop afterDoc startBlock stack (t : ts)-    | startsLayout ty    = toks ++ loop False True                             stack'  ts--    -- We don't do layout within these delimeters-    | Sym ParenL   <- ty = toks ++ loop False False (Explicit (Sym ParenR)   : stack') ts-    | Sym CurlyL   <- ty = toks ++ loop False False (Explicit (Sym CurlyR)   : stack') ts-    | Sym BracketL <- ty = toks ++ loop False False (Explicit (Sym BracketR) : stack') ts--    | EOF          <- ty = toks-    | White DocStr <- ty = toks ++ loop True  False                            stack'  ts-    | otherwise          = toks ++ loop False False                            stack'  ts--    where-    ty  = tokenType (thing t)-    pos = srcRange t--    (toks,offStack)-      | afterDoc  = ([t], stack)-      | otherwise = offsides startToks t stack--    -- add any block start tokens, and push a level on the stack-    (startToks,stack')-      | startBlock && ty == EOF = ( [ virt cfg (to pos) VCurlyR-                                    , virt cfg (to pos) VCurlyL ]-                                  , offStack )-      | startBlock = ( [ virt cfg (to pos) VCurlyL ], Virtual (col (from pos)) : offStack )-      | otherwise  = ( [], offStack )--  loop _ _ _ [] = panic "[Lexer] layout" ["Missing EOF token"]---  offsides :: [Located Token] -> Located Token -> [Block] -> ([Located Token], [Block])-  offsides startToks t = go startToks-    where-    go virts stack = case stack of--      -- delimit or close a layout block-      Virtual c : rest-          -- commas only close to an explicit marker, so if there is none, the-          -- comma doesn't close anything-        | Sym Comma == ty     ->-                         if any isExplicit rest-                            then go   (virt cfg (to pos) VCurlyR : virts) rest-                            else done                              virts  stack--        | closingToken        -> go   (virt cfg (to pos) VCurlyR : virts) rest-        | col (from pos) == c -> done (virt cfg (to pos) VSemi   : virts) stack-        | col (from pos) <  c -> go   (virt cfg (to pos) VCurlyR : virts) rest--      -- close an explicit block-      Explicit close : rest | close     == ty -> done virts rest-                            | Sym Comma == ty -> done virts stack--      _ -> done virts stack--    ty  = tokenType (thing t)-    pos = srcRange t--    done ts s = (reverse (t:ts), s)--    closingToken = ty `elem` [ Sym ParenR, Sym BracketR, Sym CurlyR ]--virt :: Config -> Position -> TokenV -> Located Token-virt cfg pos x = Located { srcRange = Range-                             { from = pos-                             , to = pos-                             , source = cfgSource cfg-                             }-                         , thing = t }-  where t = Token (Virt x) $ case x of-                               VCurlyL -> "beginning of layout block"-                               VCurlyR -> "end of layout block"-                               VSemi   -> "layout block separator"------------------------------------------------------------------------------------data Token    = Token { tokenType :: !TokenT, tokenText :: !Text }-                deriving (Show, Generic, NFData)---- | Virtual tokens, inserted by layout processing.-data TokenV   = VCurlyL| VCurlyR | VSemi-                deriving (Eq, Show, Generic, NFData)--data TokenW   = BlockComment | LineComment | Space | DocStr-                deriving (Eq, Show, Generic, NFData)--data TokenKW  = KW_else-              | KW_extern-              | KW_fin-              | KW_if-              | KW_private-              | KW_include-              | KW_inf-              | KW_lg2-              | KW_lengthFromThen-              | KW_lengthFromThenTo-              | KW_max-              | KW_min-              | KW_module-              | KW_newtype-              | KW_pragma-              | KW_property-              | KW_then-              | KW_type-              | KW_where-              | KW_let-              | KW_x-              | KW_import-              | KW_as-              | KW_hiding-              | KW_infixl-              | KW_infixr-              | KW_infix-              | KW_primitive-              | KW_parameter-              | KW_constraint-              | KW_Prop-                deriving (Eq, Show, Generic, NFData)---- | The named operators are a special case for parsing types, and 'Other' is--- used for all other cases that lexed as an operator.-data TokenOp  = Plus | Minus | Mul | Div | Exp | Mod-              | Equal | LEQ | GEQ-              | Complement | Hash | At-              | Other [T.Text] T.Text-                deriving (Eq, Show, Generic, NFData)--data TokenSym = Bar-              | ArrL | ArrR | FatArrR-              | Lambda-              | EqDef-              | Comma-              | Semi-              | Dot-              | DotDot-              | DotDotDot-              | DotDotLt-              | Colon-              | BackTick-              | ParenL   | ParenR-              | BracketL | BracketR-              | CurlyL   | CurlyR-              | TriL     | TriR-              | Lt-              | Underscore-                deriving (Eq, Show, Generic, NFData)--data TokenErr = UnterminatedComment-              | UnterminatedString-              | UnterminatedChar-              | InvalidString-              | InvalidChar-              | LexicalError-              | MalformedLiteral-              | MalformedSelector-                deriving (Eq, Show, Generic, NFData)--data SelectorType = RecordSelectorTok Text | TupleSelectorTok Int-                deriving (Eq, Show, Generic, NFData)--data TokenT   = Num !Integer !Int !Int   -- ^ value, base, number of digits-              | Frac !Rational !Int      -- ^ value, base.-              | ChrLit  !Char         -- ^ character literal-              | Ident ![T.Text] !T.Text -- ^ (qualified) identifier-              | StrLit !String         -- ^ string literal-              | Selector !SelectorType  -- ^ .hello or .123-              | KW    !TokenKW         -- ^ keyword-              | Op    !TokenOp         -- ^ operator-              | Sym   !TokenSym        -- ^ symbol-              | Virt  !TokenV          -- ^ virtual token (for layout)-              | White !TokenW          -- ^ white space token-              | Err   !TokenErr        -- ^ error token-              | EOF-                deriving (Eq, Show, Generic, NFData)--instance PP Token where-  ppPrec _ (Token _ s) = text (T.unpack s)  -- | Collapse characters into a single Word8, identifying ASCII, and classes of -- unicode.  This came from:
src/Cryptol/Parser/Name.hs view
@@ -78,7 +78,7 @@     i   = getIdent n     pfx = case getModName n of             Just ns -> pp ns <.> text "::"-            Nothing -> empty+            Nothing -> mempty    ppInfixName n     | isInfixIdent i = pfx <.> pp i@@ -87,4 +87,4 @@     i   = getIdent n     pfx = case getModName n of             Just ns -> pp ns <.> text "::"-            Nothing -> empty+            Nothing -> mempty
src/Cryptol/Parser/Names.hs view
@@ -9,15 +9,26 @@ -- This module defines the scoping rules for value- and type-level -- names in Cryptol. -module Cryptol.Parser.Names where+module Cryptol.Parser.Names+  ( tnamesNT+  , tnamesT+  , tnamesC +  , namesD+  , tnamesD+  , namesB+  , namesP++  , boundNames+  , boundNamesSet+  ) where+ import Cryptol.Parser.AST import Cryptol.Utils.RecordMap  import           Data.Set (Set) import qualified Data.Set as Set - -- | The names defined by a newtype. tnamesNT :: Newtype name -> ([Located name], ()) tnamesNT x = ([ nName x ], ())@@ -34,6 +45,8 @@ namesD decl =   case decl of     DBind b       -> namesB b+    DRec bs       -> let (xs,ys) = unzip (map namesB bs)+                     in (concat xs, Set.unions ys)  -- remove binders?     DPatBind p e  -> (namesP p, namesE e)     DSignature {} -> ([],Set.empty)     DFixity{}     -> ([],Set.empty)@@ -42,25 +55,10 @@     DProp {}      -> ([],Set.empty)     DLocated d _  -> namesD d --- | The names defined and used by a single declarations in such a way--- that they cannot be duplicated in a file. For example, it is fine--- to use @x@ on the RHS of two bindings, but not on the LHS of two--- type signatures.-allNamesD :: Ord name => Decl name -> [Located name]-allNamesD decl =-  case decl of-    DBind b         -> fst (namesB b)-    DPatBind p _    -> namesP p-    DSignature ns _ -> ns-    DFixity _ ns    -> ns-    DPragma ns _    -> ns-    DType ts        -> [tsName ts]-    DProp ps        -> [psName ps]-    DLocated d _    -> allNamesD d- -- | The names defined and used by a single binding. namesB :: Ord name => Bind name -> ([Located name], Set name)-namesB b = ([bName b], boundLNames (namesPs (bParams b)) (namesDef (thing (bDef b))))+namesB b =+  ([bName b], boundLNames (namesPs (bParams b)) (namesDef (thing (bDef b))))   namesDef :: Ord name => BindDef name -> Set name@@ -84,6 +82,8 @@                      in Set.unions (e : map namesUF fs)     EList es      -> Set.unions (map namesE es)     EFromTo{}     -> Set.empty+    EFromToBy{}   -> Set.empty+    EFromToDownBy{} -> Set.empty     EFromToLessThan{} -> Set.empty     EInfFrom e e' -> Set.union (namesE e) (maybe Set.empty namesE e')     EComp e arms  -> let (dss,uss) = unzip (map namesArm arms)@@ -164,6 +164,7 @@     DFixity {}           -> ([], Set.empty)     DPragma {}           -> ([], Set.empty)     DBind b              -> ([], tnamesB b)+    DRec bs              -> ([], Set.unions (map tnamesB bs))     DPatBind _ e         -> ([], tnamesE e)     DLocated d _         -> tnamesD d     DType (TySyn n _ ps t)@@ -204,6 +205,8 @@                        `Set.union` maybe Set.empty tnamesT b                        `Set.union` tnamesT c                        `Set.union` maybe Set.empty tnamesT t+    EFromToBy _ a b c t -> Set.unions [ tnamesT a, tnamesT b, tnamesT c, maybe Set.empty tnamesT t ]+    EFromToDownBy _ a b c t -> Set.unions [ tnamesT a, tnamesT b, tnamesT c, maybe Set.empty tnamesT t ]     EFromToLessThan a b t -> tnamesT a `Set.union` tnamesT b                                        `Set.union` maybe Set.empty tnamesT t     EInfFrom e e'   -> Set.union (tnamesE e) (maybe Set.empty tnamesE e')
src/Cryptol/Parser/NoInclude.hs view
@@ -34,7 +34,7 @@ import Cryptol.Parser.LexerUtils (Config(..),defaultConfig) import Cryptol.Parser.ParserUtils import Cryptol.Parser.Unlit (guessPreProc)-import Cryptol.Utils.PP+import Cryptol.Utils.PP hiding ((</>))  removeIncludesModule ::   (FilePath -> IO ByteString) ->@@ -160,7 +160,7 @@   return rs  -- | Remove includes from a module.-noIncludeModule :: Module PName -> NoIncM (Module PName)+noIncludeModule :: ModuleG mname PName -> NoIncM (ModuleG mname PName) noIncludeModule m = update `fmap` collectErrors noIncTopDecl (mDecls m)   where   update tds = m { mDecls = concat tds }@@ -174,13 +174,19 @@ -- reference. noIncTopDecl :: TopDecl PName -> NoIncM [TopDecl PName] noIncTopDecl td = case td of-  Decl _     -> return [td]+  Decl _     -> pure [td]   DPrimType {} -> pure [td]-  TDNewtype _-> return [td]-  DParameterType {} -> return [td]-  DParameterConstraint {} -> return [td]-  DParameterFun {} -> return [td]+  TDNewtype _-> pure [td]+  DParameterType {} -> pure [td]+  DParameterConstraint {} -> pure [td]+  DParameterFun {} -> pure [td]   Include lf -> resolveInclude lf+  DModule tl ->+    case tlValue tl of+      NestedModule m ->+        do m1 <- noIncludeModule m+           pure [ DModule tl { tlValue = NestedModule m1 } ]+  DImport {} -> pure [td]  -- | Resolve the file referenced by a include into a list of top-level -- declarations.
src/Cryptol/Parser/NoPat.hs view
@@ -44,18 +44,23 @@ instance RemovePatterns (Expr PName) where   removePatterns e = runNoPatM (noPatE e) -instance RemovePatterns (Module PName) where+instance RemovePatterns (ModuleG mname PName) where   removePatterns m = runNoPatM (noPatModule m)  instance RemovePatterns [Decl PName] where   removePatterns ds = runNoPatM (noPatDs ds) +instance RemovePatterns (NestedModule PName) where+  removePatterns (NestedModule m) = (NestedModule m1,errs)+    where (m1,errs) = removePatterns m+ simpleBind :: Located PName -> Expr PName -> Bind PName simpleBind x e = Bind { bName = x, bParams = []                       , bDef = at e (Located emptyRange (DExpr e))                       , bSignature = Nothing, bPragmas = []                       , bMono = True, bInfix = False, bFixity = Nothing                       , bDoc = Nothing+                      , bExport = Public                       }  sel :: Pattern PName -> PName -> Selector -> Bind PName@@ -154,6 +159,8 @@     EUpd mb fs    -> EUpd    <$> traverse noPatE mb <*> traverse noPatUF fs     EList es      -> EList   <$> mapM noPatE es     EFromTo {}    -> return expr+    EFromToBy {}  -> return expr+    EFromToDownBy {} -> return expr     EFromToLessThan{} -> return expr     EInfFrom e e' -> EInfFrom <$> noPatE e <*> traverse noPatE e'     EComp e mss   -> EComp  <$> noPatE e <*> mapM noPatArm mss@@ -226,6 +233,7 @@      DBind b         -> do b1 <- noMatchB b                           return [DBind b1]+    DRec {}         -> panic "noMatchD" [ "DRec" ]      DPatBind p e    -> do (p',bs) <- noPat p                           let (x,ts) = splitSimpleP p'@@ -240,6 +248,7 @@                                               , bInfix = False                                               , bFixity = Nothing                                               , bDoc = Nothing+                                              , bExport = Public                                               } : map DBind bs     DType {}        -> return [decl]     DProp {}        -> return [decl]@@ -323,7 +332,7 @@ noPatProg :: Program PName -> NoPatM (Program PName) noPatProg (Program topDs) = Program <$> noPatTopDs topDs -noPatModule :: Module PName -> NoPatM (Module PName)+noPatModule :: ModuleG mname PName -> NoPatM (ModuleG mname PName) noPatModule m =   do ds1 <- noPatTopDs (mDecls m)      return m { mDecls = ds1 }@@ -385,6 +394,13 @@         TDNewtype {} -> (d :) <$> annotTopDs ds         Include {}   -> (d :) <$> annotTopDs ds +        DModule m ->+          case removePatterns (tlValue m) of+            (m1,errs) -> do lift (mapM_ recordError errs)+                            (DModule m { tlValue = m1 } :) <$> annotTopDs ds++        DImport {} -> (d :) <$> annotTopDs ds+     [] -> return []  @@ -403,6 +419,7 @@ annotD decl =   case decl of     DBind b       -> DBind <$> lift (annotB b)+    DRec {}       -> panic "annotD" [ "DRec" ]     DSignature {} -> raise ()     DFixity{}     -> raise ()     DPragma {}    -> raise ()@@ -524,6 +541,7 @@       DSignature ns _ -> [ (thing n, [txt]) | n <- ns ]       DFixity _ ns    -> [ (thing n, [txt]) | n <- ns ]       DBind b         -> [ (thing (bName b), [txt]) ]+      DRec {}         -> panic "toDocs" [ "DRec" ]       DLocated d _    -> go txt d       DPatBind p _    -> [ (thing n, [txt]) | n <- namesP p ] 
src/Cryptol/Parser/ParserUtils.hs view
@@ -35,10 +35,10 @@  import Cryptol.Parser.AST import Cryptol.Parser.Lexer-import Cryptol.Parser.LexerUtils(SelectorType(..))+import Cryptol.Parser.Token(SelectorType(..)) import Cryptol.Parser.Position import Cryptol.Parser.Utils (translateExprToNumT,widthIdent)-import Cryptol.Utils.Ident(packModName)+import Cryptol.Utils.Ident(packModName,packIdent,modNameChunks) import Cryptol.Utils.PP import Cryptol.Utils.Panic import Cryptol.Utils.RecordMap@@ -81,6 +81,12 @@                                     T.unpack (tokenText it)            MalformedSelector   -> "malformed selector: " ++                                     T.unpack (tokenText it)+           InvalidIndentation c -> "invalid indentation, unmatched " +++              case c of+                Sym CurlyR    -> "{ ... } "+                Sym ParenR    -> "( ... )"+                Sym BracketR  -> "[ ... ]"+                _             -> show c -- basically panic         ]       where it = thing t @@ -111,13 +117,13 @@   | White DocStr <- tokenType tok =     "Unexpected documentation (/**) comment at" <+>     text path <.> char ':' <.> pp pos <.> colon $$-    nest 2+    indent 2       "Documentation comments need to be followed by something to document."    | otherwise =     text "Parse error at" <+>     text path <.> char ':' <.> pp pos <.> comma $$-    nest 2 (text "unexpected:" <+> pp tok)+    indent 2 (text "unexpected:" <+> pp tok)   where   pos = from (srcRange ltok)   tok = thing ltok@@ -126,18 +132,18 @@   text "Unexpected end of file at:" <+>     text path <.> char ':' <.> pp pos -ppError (HappyErrorMsg p xs)  = text "Parse error at" <+> pp p $$ nest 2 (vcat (map text xs))+ppError (HappyErrorMsg p xs)  = text "Parse error at" <+> pp p $$ indent 2 (vcat (map text xs))  ppError (HappyUnexpected path ltok e) =-  text "Parse error at" <+>-   text path <.> char ':' <.> pp pos <.> comma $$-   nest 2 unexp $$-   nest 2 ("expected:" <+> text e)+  nest 2 $ vcat $+   [ text "Parse error at" <+> text path <.> char ':' <.> pp pos <.> comma ]+   ++ unexp+   ++ ["expected:" <+> text e]   where   (unexp,pos) =     case ltok of-      Nothing -> (empty,start)-      Just t  -> ( "unexpected:" <+> text (T.unpack (tokenText (thing t)))+      Nothing -> ( [] ,start)+      Just t  -> ( ["unexpected:" <+> text (T.unpack (tokenText (thing t)))]                  , from (srcRange t)                  ) @@ -372,6 +378,43 @@     (Nothing, Nothing, Nothing) -> eFromToType r e1 e2 e3 Nothing     _ -> errorMessage r ["A sequence enumeration may have at most one element type annotation."] +eFromToBy :: Range -> Expr PName -> Expr PName -> Expr PName -> Bool -> ParseM (Expr PName)+eFromToBy r e1 e2 e3 isStrictBound =+  case (asETyped e1, asETyped e2, asETyped e3) of+    (Just (e1', t), Nothing, Nothing) -> eFromToByTyped r e1' e2 e3 (Just t) isStrictBound+    (Nothing, Just (e2', t), Nothing) -> eFromToByTyped r e1 e2' e3 (Just t) isStrictBound   +    (Nothing, Nothing, Just (e3', t)) -> eFromToByTyped r e1 e2 e3' (Just t) isStrictBound+    (Nothing, Nothing, Nothing)       -> eFromToByTyped r e1 e2 e3 Nothing isStrictBound+    _ -> errorMessage r ["A sequence enumeration may have at most one element type annotation."]++eFromToByTyped :: Range -> Expr PName -> Expr PName -> Expr PName -> Maybe (Type PName) -> Bool -> ParseM (Expr PName)+eFromToByTyped r e1 e2 e3 t isStrictBound =+  EFromToBy isStrictBound+      <$> exprToNumT r e1+      <*> exprToNumT r e2+      <*> exprToNumT r e3+      <*> pure t++eFromToDownBy ::+  Range -> Expr PName -> Expr PName -> Expr PName -> Bool -> ParseM (Expr PName)+eFromToDownBy r e1 e2 e3 isStrictBound =+  case (asETyped e1, asETyped e2, asETyped e3) of+    (Just (e1', t), Nothing, Nothing) -> eFromToDownByTyped r e1' e2 e3 (Just t) isStrictBound+    (Nothing, Just (e2', t), Nothing) -> eFromToDownByTyped r e1 e2' e3 (Just t) isStrictBound   +    (Nothing, Nothing, Just (e3', t)) -> eFromToDownByTyped r e1 e2 e3' (Just t) isStrictBound+    (Nothing, Nothing, Nothing)       -> eFromToDownByTyped r e1 e2 e3 Nothing isStrictBound+    _ -> errorMessage r ["A sequence enumeration may have at most one element type annotation."]++eFromToDownByTyped ::+  Range -> Expr PName -> Expr PName -> Expr PName -> Maybe (Type PName) -> Bool -> ParseM (Expr PName)+eFromToDownByTyped r e1 e2 e3 t isStrictBound =+  EFromToDownBy isStrictBound+      <$> exprToNumT r e1+      <*> exprToNumT r e2+      <*> exprToNumT r e3+      <*> pure t++ asETyped :: Expr n -> Maybe (Expr n, Type n) asETyped (ELocated e _) = asETyped e asETyped (ETyped e t) = Just (e, t)@@ -433,6 +476,11 @@                                          , tlDoc    = d                                          , tlValue  = n } +exportModule :: Maybe (Located Text) -> NestedModule PName -> TopDecl PName+exportModule mbDoc m = DModule TopLevel { tlExport = Public+                                        , tlDoc    = mbDoc+                                        , tlValue  = m }+ mkParFun :: Maybe (Located Text) ->             Located PName ->             Schema PName ->@@ -464,7 +512,9 @@   change (Decl d)      = Decl      d { tlExport = e }   change (DPrimType t) = DPrimType t { tlExport = e }   change (TDNewtype n) = TDNewtype n { tlExport = e }+  change (DModule m)   = DModule   m { tlExport = e }   change td@Include{}  = td+  change td@DImport{}  = td   change (DParameterType {}) = panic "changeExport" ["private type parameter?"]   change (DParameterFun {})  = panic "changeExport" ["private value parameter?"]   change (DParameterConstraint {}) =@@ -534,6 +584,7 @@                                , bInfix      = False                                , bFixity     = Nothing                                , bDoc        = Nothing+                               , bExport     = Public                                }  -- NOTE: The lists of patterns are reversed!@@ -549,6 +600,7 @@              , bInfix      = False              , bFixity     = Nothing              , bDoc        = Nothing+             , bExport     = Public              }   where     rhs :: Expr PName@@ -588,6 +640,7 @@                  , bInfix     = isInfixIdent (getIdent (thing ln))                  , bFixity    = Nothing                  , bDoc       = Nothing+                 , bExport    = Public                  }   , exportDecl Nothing Public     $ DSignature [ln] sig@@ -737,18 +790,24 @@     err = errorMessage r ["Invalid constraint"]  -- | Make an ordinary module-mkModule :: Located ModName ->-            ([Located Import], [TopDecl PName]) ->-            Module PName-mkModule nm (is,ds) = Module { mName = nm-                             , mInstance = Nothing-                             , mImports = is-                             , mDecls = ds-                             }+mkModule :: Located ModName -> [TopDecl PName] -> Module PName+mkModule nm ds = Module { mName = nm+                        , mInstance = Nothing+                        , mDecls = ds+                        } +mkNested :: Module PName -> ParseM (NestedModule PName)+mkNested m =+  case modNameChunks (thing nm) of+    [c] -> pure (NestedModule m { mName = nm { thing = mkUnqual (packIdent c)}})+    _   -> errorMessage r+                ["Nested modules names should be a simple identifier."]+  where+  nm = mName m+  r = srcRange nm+ -- | Make an unnamed module---gets the name @Main@.-mkAnonymousModule :: ([Located Import], [TopDecl PName]) ->-                     Module PName+mkAnonymousModule :: [TopDecl PName] -> Module PName mkAnonymousModule = mkModule Located { srcRange = emptyRange                                      , thing    = mkModName [T.pack "Main"]                                      }@@ -756,12 +815,11 @@ -- | Make a module which defines a functor instance. mkModuleInstance :: Located ModName ->                     Located ModName ->-                    ([Located Import], [TopDecl PName]) ->+                    [TopDecl PName] ->                     Module PName-mkModuleInstance nm fun (is,ds) =+mkModuleInstance nm fun ds =   Module { mName     = nm          , mInstance = Just fun-         , mImports  = is          , mDecls    = ds          } 
src/Cryptol/Parser/Position.hs view
@@ -10,6 +10,9 @@  {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE RecordWildCards #-} module Cryptol.Parser.Position where @@ -22,7 +25,8 @@ import Cryptol.Utils.PP  data Located a  = Located { srcRange :: !Range, thing :: !a }-                  deriving (Eq, Ord, Show, Generic, NFData)+                  deriving (Eq, Ord, Show, Generic, NFData+                           , Functor, Foldable, Traversable )   data Position   = Position { line :: !Int, col :: !Int }@@ -65,8 +69,6 @@ rCombs :: [Range] -> Range rCombs  = foldl1 rComb -instance Functor Located where-  fmap f l = l { thing = f (thing l) }  -------------------------------------------------------------------------------- 
src/Cryptol/Parser/Selector.hs view
@@ -48,16 +48,16 @@ instance PP Selector where   ppPrec _ sel =     case sel of-      TupleSel x sig    -> int x <+> ppSig tupleSig sig-      RecordSel x sig  -> pp x  <+> ppSig recordSig sig-      ListSel x sig    -> int x <+> ppSig listSig sig+      TupleSel x sig   -> sep (int x : ppSig tupleSig sig)+      RecordSel x sig  -> sep (pp x  : ppSig recordSig sig)+      ListSel x sig    -> sep (int x : ppSig listSig sig)      where     tupleSig n   = int n-    recordSig xs = braces $ fsep $ punctuate comma $ map pp xs+    recordSig xs = ppRecord $ map pp xs     listSig n    = int n -    ppSig f = maybe empty (\x -> text "/* of" <+> f x <+> text "*/")+    ppSig f = maybe [] (\x -> [text "/* of" <+> f x <+> text "*/"])   -- | Display the thing selected by the selector, nicely.
+ src/Cryptol/Parser/Token.hs view
@@ -0,0 +1,119 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+module Cryptol.Parser.Token where++import Data.Text(Text)+import qualified Data.Text as Text+import Control.DeepSeq+import GHC.Generics++import Cryptol.Utils.PP++data Token    = Token { tokenType :: !TokenT, tokenText :: !Text }+                deriving (Show, Generic, NFData)++-- | Virtual tokens, inserted by layout processing.+data TokenV   = VCurlyL| VCurlyR | VSemi+                deriving (Eq, Show, Generic, NFData)++data TokenW   = BlockComment | LineComment | Space | DocStr+                deriving (Eq, Show, Generic, NFData)++data TokenKW  = KW_else+              | KW_extern+              | KW_fin+              | KW_if+              | KW_private+              | KW_include+              | KW_inf+              | KW_lg2+              | KW_lengthFromThen+              | KW_lengthFromThenTo+              | KW_max+              | KW_min+              | KW_module+              | KW_submodule+              | KW_newtype+              | KW_pragma+              | KW_property+              | KW_then+              | KW_type+              | KW_where+              | KW_let+              | KW_x+              | KW_import+              | KW_as+              | KW_hiding+              | KW_infixl+              | KW_infixr+              | KW_infix+              | KW_primitive+              | KW_parameter+              | KW_constraint+              | KW_Prop+              | KW_by+              | KW_down+                deriving (Eq, Show, Generic, NFData)++-- | The named operators are a special case for parsing types, and 'Other' is+-- used for all other cases that lexed as an operator.+data TokenOp  = Plus | Minus | Mul | Div | Exp | Mod+              | Equal | LEQ | GEQ+              | Complement | Hash | At+              | Other [Text] Text+                deriving (Eq, Show, Generic, NFData)++data TokenSym = Bar+              | ArrL | ArrR | FatArrR+              | Lambda+              | EqDef+              | Comma+              | Semi+              | Dot+              | DotDot+              | DotDotDot+              | DotDotLt+              | DotDotGt+              | Colon+              | BackTick+              | ParenL   | ParenR+              | BracketL | BracketR+              | CurlyL   | CurlyR+              | TriL     | TriR+              | Lt | Gt+              | Underscore+                deriving (Eq, Show, Generic, NFData)++data TokenErr = UnterminatedComment+              | UnterminatedString+              | UnterminatedChar+              | InvalidString+              | InvalidChar+              | LexicalError+              | MalformedLiteral+              | MalformedSelector+              | InvalidIndentation TokenT -- expected closing paren+                deriving (Eq, Show, Generic, NFData)++data SelectorType = RecordSelectorTok Text | TupleSelectorTok Int+                deriving (Eq, Show, Generic, NFData)++data TokenT   = Num !Integer !Int !Int    -- ^ value, base, number of digits+              | Frac !Rational !Int       -- ^ value, base.+              | ChrLit  !Char             -- ^ character literal+              | Ident ![Text] !Text       -- ^ (qualified) identifier+              | StrLit !String            -- ^ string literal+              | Selector !SelectorType    -- ^ .hello or .123+              | KW    !TokenKW            -- ^ keyword+              | Op    !TokenOp            -- ^ operator+              | Sym   !TokenSym           -- ^ symbol+              | Virt  !TokenV             -- ^ virtual token (for layout)+              | White !TokenW             -- ^ white space token+              | Err   !TokenErr           -- ^ error token+              | EOF+                deriving (Eq, Show, Generic, NFData)++instance PP Token where+  ppPrec _ (Token _ s) = text (Text.unpack s)++
+ src/Cryptol/REPL/Browse.hs view
@@ -0,0 +1,155 @@+{-# Language OverloadedStrings, BlockArguments #-}+module Cryptol.REPL.Browse (BrowseHow(..), browseModContext) where++import qualified Data.Set as Set+import Data.Map (Map)+import qualified Data.Map as Map+import Data.Maybe(mapMaybe)+import Data.List(sortBy)+import Data.Void (Void)+import qualified Prettyprinter as PP++import Cryptol.Parser.AST(Pragma(..))+import qualified Cryptol.TypeCheck.Type as T++import Cryptol.Utils.PP+import Cryptol.ModuleSystem.Env(ModContext(..))+import Cryptol.ModuleSystem.NamingEnv(namingEnvNames)+import Cryptol.ModuleSystem.Name+import Cryptol.ModuleSystem.Interface++data BrowseHow = BrowseExported | BrowseInScope++browseModContext :: BrowseHow -> ModContext -> PP.Doc Void+browseModContext how mc = runDoc (env disp) (vcat sections)+  where+  sections = concat+    [ browseMParams (env disp) (mctxParams mc)+    , browseMods disp decls+    , browseTSyns disp decls+    , browsePrimTys disp decls+    , browseNewtypes disp decls+    , browseVars disp decls+    ]++  disp     = DispInfo { dispHow = how, env = mctxNameDisp mc }+  decls    = filterIfaceDecls (`Set.member` visNames) (mctxDecls mc)+  allNames = namingEnvNames (mctxNames mc)+  visNames = case how of+               BrowseInScope  -> allNames+               BrowseExported -> mctxExported mc++data DispInfo = DispInfo { dispHow :: BrowseHow, env :: NameDisp }++--------------------------------------------------------------------------------+++browseMParams :: NameDisp -> IfaceParams -> [Doc]+browseMParams disp params =+  ppSectionHeading "Module Parameters"+  $ addEmpty+  $ map ppParamTy (sortByName disp (Map.toList (ifParamTypes params))) +++    map ppParamFu (sortByName disp (Map.toList (ifParamFuns  params)))+  where+  ppParamTy p = nest 2 (sep ["type", pp (T.mtpName p) <+> ":", pp (T.mtpKind p)])+  ppParamFu p = nest 2 (sep [pp (T.mvpName p) <+> ":", pp (T.mvpType p)])+  -- XXX: should we print the constraints somewhere too?++  addEmpty xs = case xs of+                  [] -> []+                  _  -> xs ++ ["    "]+++browseMods :: DispInfo -> IfaceDecls -> [Doc]+browseMods disp decls =+  ppSection disp "Modules" ppM (ifModules decls)+  where+  ppM m = "submodule" <+> pp (ifModName m)+  -- XXX: can print a lot more information about the moduels, but+  -- might be better to do that with a separate command+++++browseTSyns :: DispInfo -> IfaceDecls -> [Doc]+browseTSyns disp decls =+     ppSection disp "Type Synonyms" pp tss+  ++ ppSection disp "Constraint Synonyms" pp cts+  where+  (cts,tss)  = Map.partition isCtrait (ifTySyns decls)+  isCtrait t = T.kindResult (T.kindOf (T.tsDef t)) == T.KProp++browsePrimTys :: DispInfo -> IfaceDecls -> [Doc]+browsePrimTys disp decls =+  ppSection disp "Primitive Types" ppA (ifAbstractTypes decls)+  where+  ppA a = nest 2 (sep [pp (T.atName a) <+> ":", pp (T.atKind a)])++browseNewtypes :: DispInfo -> IfaceDecls -> [Doc]+browseNewtypes disp decls =+  ppSection disp "Newtypes" T.ppNewtypeShort (ifNewtypes decls)++browseVars :: DispInfo -> IfaceDecls -> [Doc]+browseVars disp decls =+     ppSection disp "Properties" ppVar props+  ++ ppSection disp "Symbols"    ppVar syms+  where+  isProp p     = PragmaProperty `elem` ifDeclPragmas p+  (props,syms) = Map.partition isProp (ifDecls decls)++  ppVar d      = nest 2 (sep [pp (ifDeclName d) <+> ":", pp (ifDeclSig d)])++--------------------------------------------------------------------------------++ppSection :: DispInfo -> String -> (a -> Doc) -> Map Name a -> [Doc]+ppSection disp heading ppThing mp =+  ppSectionHeading heading +  case dispHow disp of+    BrowseExported | [(_,xs)] <- grouped -> ppThings xs+    _ -> concatMap ppMod grouped+  where+  grouped = groupDecls (env disp) mp++  ppThings xs = map ppThing xs ++ [" "]++  ppMod (nm,things) =+    [ "From" <+> pp nm+    , "-----" <.> text (map (const '-') (show (runDoc (env disp) (pp nm))))+    , "     "+    , indent 2 (vcat (ppThings things))+    ]++ppSectionHeading :: String -> [Doc] -> [Doc]+ppSectionHeading heading body+  | null body = []+  | otherwise = +     [ text heading+     , text (map (const '=') heading)+     , "    "+     , indent 2 (vcat body)+     ]+++++-- | Organize by module where defined, then sort by name.+groupDecls :: NameDisp -> Map Name a -> [(ModPath,[a])]+groupDecls disp = Map.toList+                . fmap (sortByName disp)+                . Map.fromListWith (++)+                . mapMaybe toEntry+                . Map.toList+  where+  toEntry (n,a) =+    case nameInfo n of+      Declared m _ -> Just (m,[(n,a)])+      _            -> Nothing+++sortByName :: NameDisp -> [(Name,a)] -> [a]+sortByName disp = map snd . sortBy cmpByDispName+  where+  cmpByDispName (x,_) (y,_) =  cmpNameDisplay disp x y+++
src/Cryptol/REPL/Command.hs view
@@ -46,6 +46,7 @@     -- Misc utilities   , handleCtrlC   , sanitize+  , withRWTempFile      -- To support Notebook interface (might need to refactor)   , replParse@@ -55,6 +56,7 @@  import Cryptol.REPL.Monad import Cryptol.REPL.Trie+import Cryptol.REPL.Browse  import qualified Cryptol.ModuleSystem as M import qualified Cryptol.ModuleSystem.Name as M@@ -64,6 +66,7 @@ import qualified Cryptol.ModuleSystem.Env as M  import qualified Cryptol.Backend.Monad as E+import qualified Cryptol.Backend.SeqMap as E import           Cryptol.Eval.Concrete( Concrete(..) ) import qualified Cryptol.Eval.Concrete as Concrete import qualified Cryptol.Eval.Env as E@@ -81,9 +84,8 @@ import qualified Cryptol.TypeCheck.Parseable as T import qualified Cryptol.TypeCheck.Subst as T import           Cryptol.TypeCheck.Solve(defaultReplExpr)-import qualified Cryptol.TypeCheck.Solver.SMT as SMT import           Cryptol.TypeCheck.PP (dump,ppWithNames,emptyNameMap)-import           Cryptol.Utils.PP+import           Cryptol.Utils.PP hiding ((</>)) import           Cryptol.Utils.Panic(panic) import           Cryptol.Utils.RecordMap import qualified Cryptol.Parser.AST as P@@ -106,8 +108,7 @@ import Data.Bits (shiftL, (.&.), (.|.)) import Data.Char (isSpace,isPunctuation,isSymbol,isAlphaNum,isAscii) import Data.Function (on)-import Data.List (intercalate, nub, sortBy, groupBy,-                                        partition, isPrefixOf,intersperse)+import Data.List (intercalate, nub, isPrefixOf,intersperse) import Data.Maybe (fromMaybe,mapMaybe,isNothing) import System.Environment (lookupEnv) import System.Exit (ExitCode(ExitSuccess))@@ -117,7 +118,6 @@ import System.Directory(getHomeDirectory,setCurrentDirectory,doesDirectoryExist                        ,getTemporaryDirectory,setPermissions,removeFile                        ,emptyPermissions,setOwnerReadable)-import Data.Map (Map) import qualified Data.Map as Map import qualified Data.Set as Set import System.IO@@ -200,8 +200,12 @@     "Check the type of an expression."     ""   , CommandDescr [ ":b", ":browse" ] ["[ MODULE ]"] (ModNameArg browseCmd)-    "Display environment for all loaded modules, or for a specific module."-    ""+    "Display information about loaded modules."+    (unlines+       [ "With no arguent, :browse shows information about the names in scope."+       , "With an argument M, shows information about the names exported from M"+       ]+    )   , CommandDescr [ ":version"] [] (NoArg versionCmd)     "Display the version of this Cryptol executable"     ""@@ -332,10 +336,10 @@       --          $ return $!! show $ pp $ E.WithBase ppOpts val        rPutStrLn (show valDoc)-    P.LetInput decl -> do+    P.LetInput ds -> do       -- explicitly make this a top-level declaration, so that it will       -- be generalized if mono-binds is enabled-      replEvalDecl decl+      replEvalDecls ds     P.EmptyInput ->       -- comment or empty input does nothing       pure ()@@ -344,16 +348,16 @@ printCounterexample cexTy exprDoc vs =   do ppOpts <- getPPValOpts      docs <- mapM (rEval . E.ppValue Concrete ppOpts) vs-     rPrint $ hang exprDoc 2 (sep docs) <+>-       case cexTy of-         SafetyViolation -> text "~> ERROR"-         PredicateFalsified -> text "= False"+     let cexRes = case cexTy of+           SafetyViolation    -> [text "~> ERROR"]+           PredicateFalsified -> [text "= False"]+     rPrint $ nest 2 (sep ([exprDoc] ++ docs ++ cexRes))  printSatisfyingModel :: Doc -> [Concrete.Value] -> REPL () printSatisfyingModel exprDoc vs =   do ppOpts <- getPPValOpts      docs <- mapM (rEval . E.ppValue Concrete ppOpts) vs-     rPrint $ hang exprDoc 2 (sep docs) <+> text ("= True")+     rPrint $ nest 2 (sep ([exprDoc] ++ docs ++ [text "= True"]))   dumpTestsCmd :: FilePath -> String -> (Int,Int) -> Maybe FilePath -> REPL ()@@ -781,6 +785,9 @@             ~(EnvBool yes) <- getUser "showExamples"             when yes $ forM_ vss (printSatisfyingModel exprDoc) +            let numModels = length tevss+            when (numModels > 1) (rPutStrLn ("Models found: " ++ show numModels))+             case exprs of               [e] -> void $ bindItVariable ty e               _   -> bindItVariables ty exprs@@ -881,10 +888,10 @@                Just path -> io $ writeFile path smtlib                Nothing -> rPutStr smtlib -    Right w4Cfg ->+    Right _w4Cfg ->       do ~(EnvBool hashConsing) <- getUser "hashConsing"          ~(EnvBool warnUninterp) <- getUser "warnUninterp"-         result <- liftModuleCmd $ W4.satProveOffline w4Cfg hashConsing warnUninterp cmd $ \f ->+         result <- liftModuleCmd $ W4.satProveOffline hashConsing warnUninterp cmd $ \f ->                      do displayMsg                         case mfile of                           Just path ->@@ -977,7 +984,8 @@   whenDebug (rPutStrLn (dump def))   fDisp <- M.mctxNameDisp <$> getFocusedEnv   -- type annotation ':' has precedence 2-  rPrint $ runDoc fDisp $ ppPrec 2 expr <+> text ":" <+> pp sig+  rPrint $ runDoc fDisp $ group $ hang+    (ppPrec 2 expr <+> text ":") 2 (pp sig)  readFileCmd :: FilePath -> REPL () readFileCmd fp = do@@ -1156,212 +1164,18 @@ quitCmd  = stop  browseCmd :: String -> REPL ()-browseCmd input = do-  let mnames = map (M.textToModName . T.pack) (words input)-  validModNames <- (:) M.interactiveName <$> getModNames-  let checkModName m =-        unless (m `elem` validModNames) $-        rPutStrLn ("error: " ++ show m ++ " is not a loaded module.")-  mapM_ checkModName mnames--  fe <- getFocusedEnv--  let params = M.mctxParams fe-      iface  = M.mctxDecls fe-      names  = M.mctxNames fe-      disp   = M.mctxNameDisp fe-      provV  = M.mctxValueProvenance fe-      provT  = M.mctxTypeProvenace fe---  let f &&& g = \x -> f x && g x-      isUser x = case M.nameInfo x of-                   M.Declared _ M.SystemName -> False-                   _ -> True-      inSet s x = x `Set.member` s--  let (visibleTypes,visibleDecls) = M.visibleNames names--      restricted = if null mnames then const True else hasAnyModName mnames--      visibleType  = isUser &&& restricted &&& inSet visibleTypes-      visibleDecl  = isUser &&& restricted &&& inSet visibleDecls--  browseMParams  visibleType visibleDecl params disp-  browseTSyns    visibleType provT       iface disp-  browsePrimTys  visibleType provT       iface disp-  browseNewtypes visibleType provT       iface disp-  browseVars     visibleDecl provV       iface disp---browseMParams :: (M.Name -> Bool) -> (M.Name -> Bool) ->-                 M.IfaceParams -> NameDisp -> REPL ()-browseMParams visT visD M.IfaceParams { .. } names =-  do ppBlock names ppParamTy "Type Parameters"-                              (sorted visT T.mtpName ifParamTypes)-     ppBlock names ppParamFu "Value Parameters"-                              (sorted visD T.mvpName ifParamFuns)--  where-  ppParamTy T.ModTParam { .. } = hang ("type" <+> pp mtpName <+> ":")-                                                           2 (pp mtpKind)-  ppParamFu T.ModVParam { .. } = hang (pp mvpName <+> ":") 2 (pp mvpType)--  sorted vis nm mp = sortBy (M.cmpNameDisplay names `on` nm)-               $ filter (vis . nm) $ Map.elems mp--type Prov = Map M.Name M.DeclProvenance--browsePrimTys :: (M.Name -> Bool) -> Prov -> M.IfaceDecls -> NameDisp -> REPL ()-browsePrimTys isVisible prov M.IfaceDecls { .. } names =-  ppSection (Map.elems ifAbstractTypes)-    Section { secName = "Primitive Types"-            , secEntryName = T.atName-            , secProvenance = prov-            , secDisp = names-            , secPP = ppA-            , secVisible = isVisible-            }-  where-  ppA a = pp (T.atName a) <+> ":" <+> pp (T.atKind a)---browseTSyns :: (M.Name -> Bool) -> Prov -> M.IfaceDecls -> NameDisp -> REPL ()-browseTSyns isVisible prov M.IfaceDecls { .. } names =-  do ppSection tss-       Section { secName = "Type Synonyms"-               , secEntryName = T.tsName-               , secProvenance = prov-               , secDisp = names-               , secVisible = isVisible-               , secPP = pp-               }-     ppSection cts-       Section { secName = "Constraint Synonyms"-               , secEntryName = T.tsName-               , secProvenance = prov-               , secDisp = names-               , secVisible = isVisible-               , secPP = pp-               }-  where-  (cts,tss) = partition isCtrait (Map.elems ifTySyns)-  isCtrait t = T.kindResult (T.kindOf (T.tsDef t)) == T.KProp--browseNewtypes ::-  (M.Name -> Bool) -> Prov -> M.IfaceDecls -> NameDisp -> REPL ()-browseNewtypes isVisible prov M.IfaceDecls { .. } names =-  ppSection (Map.elems ifNewtypes)-    Section { secName = "Newtypes"-            , secEntryName = T.ntName-            , secVisible = isVisible-            , secProvenance = prov-            , secDisp = names-            , secPP = T.ppNewtypeShort-            }--browseVars :: (M.Name -> Bool) -> Prov -> M.IfaceDecls -> NameDisp -> REPL ()-browseVars isVisible prov M.IfaceDecls { .. } names =-  do ppSection props Section { secName = "Properties"-                             , secEntryName = M.ifDeclName-                             , secVisible = isVisible-                             , secProvenance = prov-                             , secDisp = names-                             , secPP = ppVar-                             }-     ppSection syms  Section { secName = "Symbols"-                             , secEntryName = M.ifDeclName-                             , secVisible = isVisible-                             , secProvenance = prov-                             , secDisp = names-                             , secPP = ppVar-                             }--  where-  isProp p     = T.PragmaProperty `elem` (M.ifDeclPragmas p)-  (props,syms) = partition isProp (Map.elems ifDecls)--  ppVar M.IfaceDecl { .. } = hang (pp ifDeclName <+> char ':') 2 (pp ifDeclSig)----data Section a = Section-  { secName       :: String-  , secEntryName  :: a -> M.Name-  , secVisible    :: M.Name -> Bool-  , secProvenance :: Map M.Name M.DeclProvenance-  , secDisp       :: NameDisp-  , secPP         :: a -> Doc-  }--ppSection :: [a] -> Section a -> REPL ()-ppSection things s-  | null grouped = pure ()+browseCmd input+  | null input =+    do fe <- getFocusedEnv+       rPrint (browseModContext BrowseInScope fe)   | otherwise =-    do let heading = secName s-       rPutStrLn heading-       rPutStrLn (map (const '=') heading)-       rPutStrLn ""-       mapM_ ppSub grouped--  where-  ppSub (p,ts) =-    do let heading = provHeading p-       rPutStrLn ("  " ++ heading)-       rPutStrLn ("  " ++ map (const '-') heading)-       rPutStrLn ""-       rPutStrLn $ show $ runDoc (secDisp s) $ nest 4 $ vcat $ map (secPP s) ts-       rPutStrLn ""--  grouped = map rearrange $-            groupBy sameProv $-            sortBy cmpThings-            [ (n,p,t) | t <- things,-                        let n = secEntryName s t,-                        secVisible s n,-                        let p = case Map.lookup n (secProvenance s) of-                                  Just i -> i-                                  Nothing -> panic "ppSection"-                                               [ "Name with no provenance"-                                               , show n ]-           ]--  rearrange xs = (p, [ a | (_,_,a) <- xs ])-    where (_,p,_) : _ = xs--  cmpThings (n1, p1, _) (n2, p2, _) =-    case cmpProv p1 p2 of-      EQ -> M.cmpNameDisplay (secDisp s) n1 n2-      r  -> r--  sameProv (_,p1,_) (_,p2,_) = provOrd p1 == provOrd p2--  provOrd p =-    case p of-      M.NameIsParameter      -> Left 1 :: Either Int P.ModName-      M.NameIsDynamicDecl    -> Left 2-      M.NameIsLocalPublic    -> Left 3-      M.NameIsLocalPrivate   -> Left 4-      M.NameIsImportedFrom x -> Right x--  cmpProv p1 p2 = compare (provOrd p1) (provOrd p2)--  provHeading p =-    case p of-      M.NameIsParameter      -> "Parameters"-      M.NameIsDynamicDecl    -> "REPL"-      M.NameIsLocalPublic    -> "Public"-      M.NameIsLocalPrivate   -> "Private"-      M.NameIsImportedFrom m -> "From " ++ show (pp m)----ppBlock :: NameDisp -> (a -> Doc) -> String -> [a] -> REPL ()-ppBlock names ppFun name xs = unless (null xs) $-    do rPutStrLn name-       rPutStrLn (replicate (length name) '=')-       rPrint (runDoc names (nest 4 (vcat (map ppFun xs))))-       rPutStrLn ""+    case parseModName input of+      Nothing -> rPutStrLn "Invalid module name"+      Just m ->+        do mb <- M.modContextOf m <$> getModuleEnv+           case mb of+             Nothing -> rPutStrLn ("Module " ++ show input ++ " is not loaded")+             Just fe -> rPrint (browseModContext BrowseExported fe)   setOptionCmd :: String -> REPL ()@@ -1414,14 +1228,16 @@                 vNames = M.lookupValNames  qname rnEnv                tNames = M.lookupTypeNames qname rnEnv+               mNames = M.lookupNS M.NSModule qname rnEnv             let helps = map (showTypeHelp params env disp) tNames ++-                       map (showValHelp params env disp qname) vNames+                       map (showValHelp params env disp qname) vNames +++                       map (showModHelp env disp) mNames                 separ = rPutStrLn "            ---------"            sequence_ (intersperse separ helps) -           when (null (vNames ++ tNames)) $+           when (null (vNames ++ tNames ++ mNames)) $              rPrint $ "Undefined name:" <+> pp qname       Nothing ->            rPutStrLn ("Unable to parse name: " ++ cmd)@@ -1434,6 +1250,9 @@       M.Parameter  -> rPutStrLn "// No documentation is available."  +  showModHelp _env disp x =+    rPrint $ runDoc disp $ vcat [ "`" <> pp x <> "` is a module." ]+    -- XXX: show doc. if any    showTypeHelp params env nameEnv name =     fromMaybe (noInfo nameEnv name) $@@ -1463,9 +1282,9 @@                             ns = T.addTNames vs emptyNameMap                             rs = [ "•" <+> ppWithNames ns c | c <- cs ]                         rPutStrLn ""-                        rPrint $ runDoc nameEnv $ nest 4 $+                        rPrint $ runDoc nameEnv $ indent 4 $                                     backticks (ppWithNames ns example) <+>-                                    "requires:" $$ nest 2 (vcat rs)+                                    "requires:" $$ indent 2 (vcat rs)                     doShowFix (T.atFixitiy a)                    doShowDocString (T.atDoc a)@@ -1475,12 +1294,13 @@          let uses c = T.TVBound (T.mtpParam p) `Set.member` T.fvs c              ctrs = filter uses (map P.thing (M.ifParamConstraints params))              ctrDoc = case ctrs of-                        [] -> empty-                        [x] -> pp x-                        xs  -> parens $ hsep $ punctuate comma $ map pp xs-             decl = text "parameter" <+> pp name <+> text ":"-                      <+> pp (T.mtpKind p)-                   $$ ctrDoc+                        []  -> []+                        [x] -> [pp x]+                        xs  -> [parens $ commaSep $ map pp xs]+             decl = vcat $+                      [ text "parameter" <+> pp name <+> text ":"+                        <+> pp (T.mtpKind p) ]+                      ++ ctrDoc          return $ doShowTyHelp nameEnv decl (T.mtpDoc p)    doShowTyHelp nameEnv decl doc =@@ -1510,16 +1330,15 @@          return $            do rPutStrLn "" -              let property-                    | P.PragmaProperty `elem` ifDeclPragmas = text "property"-                    | otherwise                             = empty+              let property +                    | P.PragmaProperty `elem` ifDeclPragmas = [text "property"]+                    | otherwise                             = []               rPrint $ runDoc nameEnv-                     $ nest 4-                     $ property-                       <+> pp qname-                       <+> colon-                       <+> pp (ifDeclSig)+                     $ indent 4+                     $ hsep +                     $ property ++ [pp qname, colon, pp (ifDeclSig)]+               doShowFix $ ifDeclFixity `mplus`                           (guard ifDeclInfix >> return P.defaultFixity) @@ -1534,7 +1353,7 @@          return $            do rPutStrLn ""               rPrint $ runDoc nameEnv-                     $ nest 4+                     $ indent 4                      $ text "parameter" <+> pp qname                                         <+> colon                                         <+> pp (T.mvpType p)@@ -1591,18 +1410,11 @@ -- XXX this should probably do something a bit more specific. handleCtrlC :: a -> REPL a handleCtrlC a = do rPutStrLn "Ctrl-C"+                   resetTCSolver                    return a - -- Utilities ------------------------------------------------------------------- -hasAnyModName :: [M.ModName] -> M.Name -> Bool-hasAnyModName mnames n =-  case M.nameInfo n of-    M.Declared m _ -> m `elem` mnames-    M.Parameter  -> False-- -- | Lift a parsing action into the REPL monad. replParse :: (String -> Either ParseError a) -> String -> REPL a replParse parse str = case parse str of@@ -1648,16 +1460,16 @@   do evo <- getEvalOptsAction      env <- getModuleEnv      callStacks <- getCallStacks-     let cfg = M.meSolverConfig env-     let minp s =+     tcSolver <- getTCSolver+     let minp =              M.ModuleInput                 { minpCallStacks = callStacks                 , minpEvalOpts   = evo                 , minpByteReader = BS.readFile                 , minpModuleEnv  = env-                , minpTCSolver   = s+                , minpTCSolver   = tcSolver                 }-     moduleCmdResult =<< io (SMT.withSolver cfg (cmd . minp))+     moduleCmdResult =<< io (cmd minp)  moduleCmdResult :: M.ModuleRes a -> REPL a moduleCmdResult (res,ws0) = do@@ -1714,12 +1526,13 @@   let mkTop d = P.Decl P.TopLevel { P.tlExport = P.Public                                   , P.tlDoc    = Nothing                                   , P.tlValue  = d }-  (names,ds') <- liftModuleCmd (M.checkDecls (map mkTop npds))+  (names,ds',tyMap) <- liftModuleCmd (M.checkDecls (map mkTop npds)) -  -- extend the naming env+  -- extend the naming env and type synonym maps   denv        <- getDynEnv-  setDynEnv denv { M.deNames = names `M.shadowing` M.deNames denv }-+  setDynEnv denv { M.deNames  = names `M.shadowing` M.deNames denv+                 , M.deTySyns = tyMap <> M.deTySyns denv+                 }   return ds'  replSpecExpr :: T.Expr -> REPL T.Expr@@ -1735,9 +1548,8 @@   do validEvalContext def      validEvalContext sig -     me <- getModuleEnv-     let cfg = M.meSolverConfig me-     mbDef <- io $ SMT.withSolver cfg (\s -> defaultReplExpr s def sig)+     s <- getTCSolver+     mbDef <- io (defaultReplExpr s def sig)       (def1,ty) <-         case mbDef of@@ -1834,9 +1646,9 @@     seqTy = E.TVSeq (toInteger len) ty     seqExpr = T.EList exprs (E.tValTy ty) -replEvalDecl :: P.Decl P.PName -> REPL ()-replEvalDecl decl = do-  dgs <- replCheckDecls [decl]+replEvalDecls :: [P.Decl P.PName] -> REPL ()+replEvalDecls ds = do+  dgs <- replCheckDecls ds   validEvalContext dgs   whenDebug (mapM_ (\dg -> (rPutStrLn (dump dg))) dgs)   liftModuleCmd (M.evalDecls dgs)
src/Cryptol/REPL/Monad.hs view
@@ -6,6 +6,7 @@ -- Stability   :  provisional -- Portability :  portable +{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-}@@ -36,6 +37,8 @@   , getModuleEnv, setModuleEnv   , getDynEnv, setDynEnv   , getCallStacks+  , getTCSolver+  , resetTCSolver   , uniqify, freshName   , whenDebug   , getEvalOptsAction@@ -65,7 +68,9 @@   , getUserShowProverStats   , getUserProverValidate   , parsePPFloatFormat+  , parseFieldOrder   , getProverConfig+  , parseSearchPath      -- ** Configurable Output   , getPutStr@@ -91,6 +96,7 @@ import Cryptol.Parser.Position (emptyRange, Range(from)) import qualified Cryptol.TypeCheck.AST as T import qualified Cryptol.TypeCheck as T+import qualified Cryptol.TypeCheck.Solver.SMT as SMT import qualified Cryptol.IR.FreeVars as T import qualified Cryptol.Utils.Ident as I import Cryptol.Utils.PP@@ -103,6 +109,8 @@ import qualified Cryptol.Symbolic.SBV as SBV (proverNames, setupProver, defaultProver, SBVProverConfig) import qualified Cryptol.Symbolic.What4 as W4 (proverNames, setupProver, W4ProverConfig) ++ import Control.Monad (ap,unless,when) import Control.Monad.Base import qualified Control.Monad.Catch as Ex@@ -110,12 +118,13 @@ import Control.Monad.Trans.Control import Data.Char (isSpace, toLower) import Data.IORef-    (IORef,newIORef,readIORef,modifyIORef,atomicModifyIORef)+    (IORef,newIORef,readIORef,atomicModifyIORef) import Data.List (intercalate, isPrefixOf, unfoldr, sortBy) import Data.Maybe (catMaybes) import Data.Ord (comparing) import Data.Typeable (Typeable) import System.Directory (findExecutable)+import System.FilePath (splitSearchPath, searchPathSeparator) import qualified Control.Exception as X import qualified Data.Map as Map import qualified Data.Set as Set@@ -165,12 +174,27 @@     -- This is used to change the title of terminal when loading a module.    , eProverConfig :: Either SBV.SBVProverConfig W4.W4ProverConfig++  , eTCConfig :: T.SolverConfig+    -- ^ Solver configuration to be used for typechecking++  , eTCSolver :: Maybe SMT.Solver+    -- ^ Solver instance to be used for typechecking++  , eTCSolverRestarts :: !Int+    -- ^ Counts how many times we've restarted the solver.+    -- Used as a kind of id for the current solver, which helps avoid+    -- a race condition where the callback of a dead solver runs after+    -- a new one has been started.   } + -- | Initial, empty environment.-defaultRW :: Bool -> Bool ->Logger -> IO RW+defaultRW :: Bool -> Bool -> Logger -> IO RW defaultRW isBatch callStacks l = do   env <- M.initialModuleEnv+  let searchPath = M.meSearchPath env+  let solverConfig = T.defaultSolverConfig searchPath   return RW     { eLoadedMod   = Nothing     , eEditFile    = Nothing@@ -182,6 +206,9 @@     , eCallStacks  = callStacks     , eUpdateTitle = return ()     , eProverConfig = Left SBV.defaultProver+    , eTCConfig    = solverConfig+    , eTCSolver    = Nothing+    , eTCSolverRestarts = 0     }  -- | Build up the prompt for the REPL.@@ -228,8 +255,10 @@ -- | Run a REPL action with a fresh environment. runREPL :: Bool -> Bool -> Logger -> REPL a -> IO a runREPL isBatch callStacks l m = do-  ref <- newIORef =<< defaultRW isBatch callStacks l-  unREPL m ref+  Ex.bracket+    (newIORef =<< defaultRW isBatch callStacks l)+    (unREPL resetTCSolver)+    (unREPL m)  instance Functor REPL where   {-# INLINE fmap #-}@@ -331,9 +360,9 @@                          $$ text "Type:" <+> pp s     TypeNotTestable t    -> text "The expression is not of a testable type."                          $$ text "Type:" <+> pp t-    EvalInParamModule xs ->-      text "Expression depends on definitions from a parameterized module:"-        $$ nest 2 (vcat (map pp xs))+    EvalInParamModule xs -> nest 2 $ vsep $+      [ text "Expression depends on definitions from a parameterized module:" ]+      ++ map pp xs     SBVError s           -> text "SBV error:" $$ text s     SBVException e       -> text "SBV exception:" $$ text (show e)     SBVPortfolioException e -> text "SBV exception:" $$ text (show e)@@ -384,7 +413,7 @@ modifyRW f = REPL (\ ref -> atomicModifyIORef ref f)  modifyRW_ :: (RW -> RW) -> REPL ()-modifyRW_ f = REPL (\ ref -> modifyIORef ref f)+modifyRW_ f = REPL (\ ref -> atomicModifyIORef ref (\x -> (f x, ())))  -- | Construct the prompt for the current environment. getPrompt :: REPL String@@ -393,25 +422,56 @@ getCallStacks :: REPL Bool getCallStacks = eCallStacks <$> getRW +-- This assumes that we are not starting solvers in parallel, otherwise+-- there are a bunch of race conditions here.+getTCSolver :: REPL SMT.Solver+getTCSolver =+  do rw <- getRW+     case eTCSolver rw of+       Just s -> return s+       Nothing ->+         do ref <- REPL (\ref -> pure ref)+            let now = eTCSolverRestarts rw + 1+                upd new = if eTCSolverRestarts new == now+                             then new { eTCSolver = Nothing }+                             else new+                onExit = atomicModifyIORef ref (\s -> (upd s, ()))+            s <- io (SMT.startSolver onExit (eTCConfig rw))+            modifyRW_ (\rw' -> rw'{ eTCSolver = Just s+                                  , eTCSolverRestarts = now })+            return s+++resetTCSolver :: REPL ()+resetTCSolver =+  do mtc <- eTCSolver <$> getRW+     case mtc of+       Nothing -> return ()+       Just s  ->+         do io (SMT.stopSolver s)+            modifyRW_ (\rw -> rw{ eTCSolver = Nothing })+ -- Get the setting we should use for displaying values. getPPValOpts :: REPL PPOpts getPPValOpts =-  do base      <- getKnownUser "base"-     ascii     <- getKnownUser "ascii"-     infLength <- getKnownUser "infLength"+  do base       <- getKnownUser "base"+     ascii      <- getKnownUser "ascii"+     infLength  <- getKnownUser "infLength" -     fpBase    <- getKnownUser "fpBase"-     fpFmtTxt  <- getKnownUser "fpFormat"+     fpBase     <- getKnownUser "fpBase"+     fpFmtTxt   <- getKnownUser "fpFormat"+     fieldOrder <- getKnownUser "fieldOrder"      let fpFmt = case parsePPFloatFormat fpFmtTxt of                    Just f  -> f                    Nothing -> panic "getPPOpts"                                       [ "Failed to parse fp-format" ] -     return PPOpts { useBase      = base-                   , useAscii     = ascii-                   , useInfLength = infLength-                   , useFPBase    = fpBase-                   , useFPFormat  = fpFmt+     return PPOpts { useBase       = base+                   , useAscii      = ascii+                   , useInfLength  = infLength+                   , useFPBase     = fpBase+                   , useFPFormat   = fpFmt+                   , useFieldOrder = fieldOrder                    }  getEvalOptsAction :: REPL (IO EvalOpts)@@ -451,11 +511,14 @@ setSearchPath path = do   me <- getModuleEnv   setModuleEnv $ me { M.meSearchPath = path }+  setUserDirect "path" (EnvString (renderSearchPath path))  prependSearchPath :: [FilePath] -> REPL () prependSearchPath path = do   me <- getModuleEnv-  setModuleEnv $ me { M.meSearchPath = path ++ M.meSearchPath me }+  let path' = path ++ M.meSearchPath me+  setModuleEnv $ me { M.meSearchPath = path' }+  setUserDirect "path" (EnvString (renderSearchPath path'))  getProverConfig :: REPL (Either SBV.SBVProverConfig W4.W4ProverConfig) getProverConfig = eProverConfig <$> getRW@@ -492,7 +555,7 @@           badName nm bs =            case M.nameInfo nm of-             M.Declared m _+             M.Declared (M.TopModule m) _   -- XXX: can we focus nested modules?                | M.isLoadedParamMod m (M.meLoadedModules me) -> Set.insert nm bs              _ -> bs @@ -547,14 +610,14 @@ getExprNames :: REPL [String] getExprNames =   do fNames <- M.mctxNames <$> getFocusedEnv-     return (map (show . pp) (Map.keys (M.neExprs fNames)))+     return (map (show . pp) (Map.keys (M.namespaceMap M.NSValue fNames)))  -- | Get visible type signature names. -- This is used for command line completition. getTypeNames :: REPL [String] getTypeNames  =   do fNames <- M.mctxNames <$> getFocusedEnv-     return (map (show . pp) (Map.keys (M.neTypes fNames)))+     return (map (show . pp) (Map.keys (M.namespaceMap M.NSType fNames)))  -- | Return a list of property names, sorted by position in the file. getPropertyNames :: REPL ([(M.Name,M.IfaceDecl)],NameDisp)@@ -595,7 +658,8 @@ uniqify name =   case M.nameInfo name of     M.Declared ns s ->-      M.liftSupply (M.mkDeclared ns s (M.nameIdent name) (M.nameFixity name) (M.nameLoc name))+      M.liftSupply (M.mkDeclared (M.nameNamespace name)+                  ns s (M.nameIdent name) (M.nameFixity name) (M.nameLoc name))      M.Parameter ->       panic "[REPL] uniqify" ["tried to uniqify a parameter: " ++ pretty name]@@ -615,9 +679,28 @@ -- the "<interactive>" namespace. freshName :: I.Ident -> M.NameSource -> REPL M.Name freshName i sys =-  M.liftSupply (M.mkDeclared I.interactiveName sys i Nothing emptyRange)+  M.liftSupply (M.mkDeclared I.NSValue mpath sys i Nothing emptyRange)+  where mpath = M.TopModule I.interactiveName  +parseSearchPath :: String -> [String]+parseSearchPath path = path'+#if defined(mingw32_HOST_OS) || defined(__MINGW32__)+      -- Windows paths search from end to beginning+      where path' = reverse (splitSearchPath path)+#else+      where path' = splitSearchPath path+#endif++renderSearchPath :: [String] -> String+renderSearchPath pathSegs = path+#if defined(mingw32_HOST_OS) || defined(__MINGW32__)+      -- Windows paths search from end to beginning+      where path = intercalate [searchPathSeparator] (reverse pathSegs)+#else+      where path = intercalate [searchPathSeparator] pathSegs+#endif+ -- User Environment Interaction ------------------------------------------------  -- | User modifiable environment, for things like numeric base.@@ -710,6 +793,10 @@     Just ev -> return ev     Nothing -> panic "[REPL] getUser" ["option `" ++ name ++ "` does not exist"] +setUserDirect :: String -> EnvVal -> REPL ()+setUserDirect optName val = do+  modifyRW_ (\rw -> rw { eUserEnv = Map.insert optName val (eUserEnv rw) })+ getKnownUser :: IsEnvVal a => String -> REPL a getKnownUser x = fromEnvVal <$> getUser x @@ -736,6 +823,12 @@                    EnvString b -> b                    _           -> badIsEnv "String" +instance IsEnvVal FieldOrder where+  fromEnvVal x = case x of+                   EnvString s | Just o <- parseFieldOrder s+                     -> o+                   _ -> badIsEnv "display` or `canonical"+ badIsEnv :: String -> a badIsEnv x = panic "fromEnvVal" [ "[REPL] Expected a `" ++ x ++ "` value." ] @@ -806,6 +899,14 @@     "Choose whether to issue a warning when uninterpreted functions are used to implement primitives in the symbolic simulator."   , simpleOpt "smtFile" ["smt-file"] (EnvString "-") noCheck     "The file to use for SMT-Lib scripts (for debugging or offline proving).\nUse \"-\" for stdout."+  , OptionDescr "path" [] (EnvString "") noCheck+    "The search path for finding named Cryptol modules." $+    \case EnvString path ->+            do let segs = parseSearchPath path+               me <- getModuleEnv+               setModuleEnv me { M.meSearchPath = segs }+          _ -> return ()+   , OptionDescr "monoBinds" ["mono-binds"] (EnvBool True) noCheck     "Whether or not to generalize bindings in a 'where' clause." $     \case EnvBool b -> do me <- getModuleEnv@@ -815,11 +916,11 @@   , OptionDescr "tcSolver" ["tc-solver"] (EnvProg "z3" [ "-smt2", "-in" ])     noCheck  -- TODO: check for the program in the path     "The solver that will be used by the type checker." $-    \case EnvProg prog args -> do me <- getModuleEnv-                                  let cfg = M.meSolverConfig me-                                  setModuleEnv me { M.meSolverConfig =-                                                      cfg { T.solverPath = prog-                                                          , T.solverArgs = args } }+    \case EnvProg prog args -> do modifyRW_ (\rw -> rw { eTCConfig = (eTCConfig rw)+                                                                      { T.solverPath = prog+                                                                      , T.solverArgs = args+                                                                      }})+                                  resetTCSolver           _                 -> return ()    , OptionDescr "tcDebug" ["tc-debug"] (EnvNum 0)@@ -829,9 +930,10 @@       , "  *  0  no debug output"       , "  *  1  show type-checker debug info"       , "  * >1  show type-checker debug info and interactions with SMT solver"]) $-    \case EnvNum n -> do me <- getModuleEnv-                         let cfg = M.meSolverConfig me-                         setModuleEnv me { M.meSolverConfig = cfg{ T.solverVerbose = n } }+    \case EnvNum n -> do changed <- modifyRW (\rw -> ( rw{ eTCConfig = (eTCConfig rw){ T.solverVerbose = n } }+                                                     , n /= T.solverVerbose (eTCConfig rw)+                                                     ))+                         when changed resetTCSolver           _        -> return ()   , OptionDescr "coreLint" ["core-lint"] (EnvBool False)     noCheck@@ -869,6 +971,13 @@    , simpleOpt "ignoreSafety" ["ignore-safety"] (EnvBool False) noCheck     "Ignore safety predicates when performing :sat or :prove checks"++  , simpleOpt "fieldOrder" ["field-order"] (EnvString "display") checkFieldOrder+    $ unlines+    [ "The order that record fields are displayed in."+    , "  * display      try to match the order they were written in the source code"+    , "  * canonical    use a predictable, canonical order"+    ]   ]  @@ -893,7 +1002,16 @@     EnvString s | Just _ <- parsePPFloatFormat s -> noWarns Nothing     _ -> noWarns $ Just "Failed to parse `fp-format`" +parseFieldOrder :: String -> Maybe FieldOrder+parseFieldOrder "canonical" = Just CanonicalOrder+parseFieldOrder "display" = Just DisplayOrder+parseFieldOrder _ = Nothing +checkFieldOrder :: Checker+checkFieldOrder val =+  case val of+    EnvString s | Just _ <- parseFieldOrder s -> noWarns Nothing+    _ -> noWarns $ Just "Failed to parse field-order (expected one of \"canonical\" or \"display\")"  -- | Check the value to the `base` option. checkBase :: Checker
src/Cryptol/Symbolic.hs view
@@ -38,6 +38,8 @@  , modelPred  , varModelPred  , varToExpr+ , flattenShape+ , flattenShapes  ) where  @@ -50,6 +52,8 @@  import           Cryptol.Backend import           Cryptol.Backend.FloatHelpers(bfValue)+import           Cryptol.Backend.SeqMap (finiteSeqMap)+import           Cryptol.Backend.WordValue (wordVal)  import qualified Cryptol.Eval.Concrete as Concrete import           Cryptol.Eval.Value@@ -211,24 +215,42 @@ ppVarShape _sym (VarRational _n _d) = text "<rational>" ppVarShape sym (VarWord w) = text "<word:" <> integer (wordLen sym w) <> text ">" ppVarShape sym (VarFinSeq _ xs) =-  brackets (fsep (punctuate comma (map (ppVarShape sym) xs)))+  ppList (map (ppVarShape sym) xs) ppVarShape sym (VarTuple xs) =-  parens (sep (punctuate comma (map (ppVarShape sym) xs)))+  ppTuple (map (ppVarShape sym) xs) ppVarShape sym (VarRecord fs) =-  braces (sep (punctuate comma (map ppField (displayFields fs))))+  ppRecord (map ppField (displayFields fs))  where   ppField (f,v) = pp f <+> char '=' <+> ppVarShape sym v  +-- | Flatten structured shapes (like tuples and sequences), leaving only+--   a sequence of variable shapes of base type.+flattenShapes :: [VarShape sym] -> [VarShape sym] -> [VarShape sym]+flattenShapes []     tl = tl+flattenShapes (x:xs) tl = flattenShape x (flattenShapes xs tl)++flattenShape :: VarShape sym -> [VarShape sym] -> [VarShape sym]+flattenShape x tl =+  case x of+    VarBit{}       -> x : tl+    VarInteger{}   -> x : tl+    VarRational{}  -> x : tl+    VarWord{}      -> x : tl+    VarFloat{}     -> x : tl+    VarFinSeq _ vs -> flattenShapes vs tl+    VarTuple vs    -> flattenShapes vs tl+    VarRecord fs   -> flattenShapes (recordElements fs) tl+ varShapeToValue :: Backend sym => sym -> VarShape sym -> GenValue sym varShapeToValue sym var =   case var of     VarBit b     -> VBit b     VarInteger i -> VInteger i     VarRational n d -> VRational (SRational n d)-    VarWord w    -> VWord (wordLen sym w) (return (WordVal w))+    VarWord w    -> VWord (wordLen sym w) (wordVal w)     VarFloat f   -> VFloat f-    VarFinSeq n vs -> VSeq n (finiteSeqMap (map (pure . varShapeToValue sym) vs))+    VarFinSeq n vs -> VSeq n (finiteSeqMap sym (map (pure . varShapeToValue sym) vs))     VarTuple vs  -> VTuple (map (pure . varShapeToValue sym) vs)     VarRecord fs -> VRecord (fmap (pure . varShapeToValue sym) fs) 
src/Cryptol/Symbolic/What4.hs view
@@ -8,8 +8,10 @@  {-# LANGUAGE BlockArguments #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-} {-# LANGUAGE ImplicitParams #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE ParallelListComp #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-}@@ -33,13 +35,14 @@ import Control.Concurrent.Async import Control.Concurrent.MVar import Control.Monad.IO.Class-import Control.Monad (when, foldM, forM_)+import Control.Monad (when, foldM, forM_, void) import qualified Control.Exception as X import System.IO (Handle) import Data.Time import Data.IORef-import Data.List (intercalate)+import Data.List (intercalate, tails, inits) import Data.List.NonEmpty (NonEmpty(..))+import Data.Proxy import qualified Data.Map as Map import           Data.Set (Set) import qualified Data.Set as Set@@ -60,7 +63,9 @@ import qualified Cryptol.Eval as Eval import qualified Cryptol.Eval.Concrete as Concrete import qualified Cryptol.Eval.Value as Eval+import           Cryptol.Eval.Type (TValue) import           Cryptol.Eval.What4+ import           Cryptol.Parser.Position (emptyRange) import           Cryptol.Symbolic import           Cryptol.TypeCheck.AST@@ -75,7 +80,15 @@ import qualified What4.SFloat as W4 import qualified What4.SWord as SW import           What4.Solver+import qualified What4.Solver.Boolector as W4+import qualified What4.Solver.CVC4 as W4+import qualified What4.Solver.ExternalABC as W4+import qualified What4.Solver.Yices as W4+import qualified What4.Solver.Z3 as W4 import qualified What4.Solver.Adapter as W4+import qualified What4.Protocol.Online as W4+import qualified What4.Protocol.SMTLib2 as W4+import qualified What4.ProblemFeatures as W4  import qualified Data.BitVector.Sized as BV import           Data.Parameterized.Nonce@@ -130,32 +143,64 @@        W4Result p x -> pure (p,x)  -data AnAdapter = AnAdapter (forall st. SolverAdapter st)+data AnAdapter+  = AnAdapter (forall st. SolverAdapter st)+  | forall s. W4.OnlineSolver s =>+     AnOnlineAdapter+       String+       W4.ProblemFeatures+       [W4.ConfigDesc]+       (Proxy s)  data W4ProverConfig   = W4ProverConfig AnAdapter+  | W4OfflineConfig   | W4Portfolio (NonEmpty AnAdapter)  proverConfigs :: [(String, W4ProverConfig)] proverConfigs =-  [ ("w4-cvc4"     , W4ProverConfig (AnAdapter cvc4Adapter) )-  , ("w4-yices"    , W4ProverConfig (AnAdapter yicesAdapter) )-  , ("w4-z3"       , W4ProverConfig (AnAdapter z3Adapter) )-  , ("w4-boolector", W4ProverConfig (AnAdapter boolectorAdapter) )-  , ("w4-offline"  , W4ProverConfig (AnAdapter z3Adapter) )-  , ("w4-any"      , allSolvers)+  [ ("w4-cvc4"      , W4ProverConfig cvc4OnlineAdapter)+  , ("w4-yices"     , W4ProverConfig yicesOnlineAdapter)+  , ("w4-z3"        , W4ProverConfig z3OnlineAdapter)+  , ("w4-boolector" , W4ProverConfig boolectorOnlineAdapter)++  , ("w4-abc"       , W4ProverConfig (AnAdapter W4.externalABCAdapter))++  , ("w4-offline"   , W4OfflineConfig )+  , ("w4-any"       , allSolvers)   ] +z3OnlineAdapter :: AnAdapter+z3OnlineAdapter =+  AnOnlineAdapter "Z3" W4.z3Features W4.z3Options+         (Proxy :: Proxy (W4.Writer W4.Z3))++yicesOnlineAdapter :: AnAdapter+yicesOnlineAdapter =+  AnOnlineAdapter "Yices" W4.yicesDefaultFeatures W4.yicesOptions+         (Proxy :: Proxy W4.Connection)++cvc4OnlineAdapter :: AnAdapter+cvc4OnlineAdapter =+  AnOnlineAdapter "CVC4" W4.cvc4Features W4.cvc4Options+         (Proxy :: Proxy (W4.Writer W4.CVC4))++boolectorOnlineAdapter :: AnAdapter+boolectorOnlineAdapter =+  AnOnlineAdapter "Boolector" W4.boolectorFeatures W4.boolectorOptions+         (Proxy :: Proxy (W4.Writer W4.Boolector))+ allSolvers :: W4ProverConfig allSolvers = W4Portfolio-  $ AnAdapter z3Adapter :|-  [ AnAdapter cvc4Adapter-  , AnAdapter boolectorAdapter-  , AnAdapter yicesAdapter+  $ z3OnlineAdapter :|+  [ cvc4OnlineAdapter+  , boolectorOnlineAdapter+  , yicesOnlineAdapter+  , AnAdapter W4.externalABCAdapter   ]  defaultProver :: W4ProverConfig-defaultProver = W4ProverConfig (AnAdapter z3Adapter)+defaultProver = W4ProverConfig z3OnlineAdapter  proverNames :: [String] proverNames = map fst proverConfigs@@ -178,12 +223,16 @@            let msg = "What4 found the following solvers: " ++ show (adapterNames (p:ps')) in            pure (Right ([msg], W4Portfolio (p:|ps'))) +    Just W4OfflineConfig -> pure (Right ([], W4OfflineConfig))+     Nothing -> pure (Left ("unknown solver name: " ++ nm))    where   adapterNames [] = []   adapterNames (AnAdapter adpt : ps) =     solver_adapter_name adpt : adapterNames ps+  adapterNames (AnOnlineAdapter n _ _ _ : ps) =+    n : adapterNames ps    filterAdapters [] = pure []   filterAdapters (p:ps) =@@ -191,12 +240,25 @@       Just _err -> filterAdapters ps       Nothing   -> (p:) <$> filterAdapters ps +  tryAdapter :: AnAdapter -> IO (Maybe X.SomeException)+   tryAdapter (AnAdapter adpt) =      do sym <- W4.newExprBuilder W4.FloatIEEERepr CryptolState globalNonceGenerator         W4.extendConfig (W4.solver_adapter_config_options adpt) (W4.getConfiguration sym)         W4.smokeTest sym adpt -+  tryAdapter (AnOnlineAdapter _ fs opts (_ :: Proxy s)) = test `X.catch` (pure . Just)+   where+    test =+      do sym <- W4.newExprBuilder W4.FloatIEEERepr CryptolState globalNonceGenerator+         W4.extendConfig opts (W4.getConfiguration sym)+         (proc :: W4.SolverProcess GlobalNonceGenerator s) <- W4.startSolverProcess fs Nothing sym+         res <- W4.checkSatisfiable proc "smoke test" (W4.falsePred sym)+         case res of+           W4.Unsat () -> return ()+           _ -> fail "smoke test failed, expected UNSAT!"+         void (W4.shutdownSolverProcess proc)+         return Nothing  proverError :: String -> M.ModuleCmd (Maybe String, ProverResult) proverError msg minp =@@ -211,11 +273,13 @@    case cfg of      W4ProverConfig p -> setupAnAdapter p      W4Portfolio ps -> mapM_ setupAnAdapter ps+     W4OfflineConfig -> return ()    where   setupAnAdapter (AnAdapter adpt) =     W4.extendConfig (W4.solver_adapter_config_options adpt) (W4.getConfiguration sym)-+  setupAnAdapter (AnOnlineAdapter _n _fs opts _p) =+    W4.extendConfig opts (W4.getConfiguration sym)  what4FreshFns :: W4.IsSymExprBuilder sym => sym -> FreshVarFns (What4 sym) what4FreshFns sym =@@ -350,16 +414,13 @@       Right (ts,args,safety,query) ->         case pcQueryType of           ProveQuery ->-            singleQuery sym solverCfg primMap logData ts args-                                                          (Just safety) query+            singleQuery sym solverCfg primMap logData ts args (Just safety) query            SafetyQuery ->-            singleQuery sym solverCfg primMap logData ts args-                                                          (Just safety) query+            singleQuery sym solverCfg primMap logData ts args (Just safety) query            SatQuery num ->-            multiSATQuery sym solverCfg primMap logData ts args-                                                            query num+            multiSATQuery sym solverCfg primMap logData ts args query num  printUninterpWarn :: Logger -> Set Text -> IO () printUninterpWarn lg uninterpWarns =@@ -371,17 +432,14 @@              , "  " ++ intercalate ", " (map Text.unpack xs) ]  satProveOffline ::-  W4ProverConfig ->   Bool {- ^ hash consing -} ->   Bool {- ^ warn on uninterpreted functions -} ->   ProverCommand ->   ((Handle -> IO ()) -> IO ()) ->   M.ModuleCmd (Maybe String) -satProveOffline (W4Portfolio (p:|_)) hashConsing warnUninterp cmd outputContinuation =-  satProveOffline (W4ProverConfig p) hashConsing warnUninterp cmd outputContinuation+satProveOffline hashConsing warnUninterp ProverCommand{ .. } outputContinuation = -satProveOffline (W4ProverConfig (AnAdapter adpt)) hashConsing warnUninterp ProverCommand {..} outputContinuation =   protectStack onError \modIn ->   M.runModuleM modIn    do w4sym <- liftIO makeSym@@ -396,27 +454,26 @@         case ok of           Left msg -> return (Just msg)           Right (_ts,_args,_safety,query) ->-            do outputContinuation-                  (\hdl -> solver_adapter_write_smt2 adpt w4sym hdl [query])+            do outputContinuation (\hdl -> W4.writeZ3SMT2File w4sym hdl [query])                return Nothing   where   makeSym =-    do sym <- W4.newExprBuilder W4.FloatIEEERepr CryptolState-                                                    globalNonceGenerator-       W4.extendConfig (W4.solver_adapter_config_options adpt)-                       (W4.getConfiguration sym)+    do sym <- W4.newExprBuilder W4.FloatIEEERepr CryptolState globalNonceGenerator+       W4.extendConfig W4.z3Options (W4.getConfiguration sym)        when hashConsing  (W4.startCaching sym)        pure sym    onError msg minp = pure (Right (Just msg, M.minpModuleEnv minp), [])  +{- decSatNum :: SatNum -> SatNum decSatNum (SomeSat n) | n > 0 = SomeSat (n-1) decSatNum n = n+-}  -multiSATQuery ::+multiSATQuery :: forall sym t fm.   sym ~ W4.ExprBuilder t CryptolState fm =>   What4 sym ->   W4ProverConfig ->@@ -427,58 +484,145 @@   W4.Pred sym ->   SatNum ->   IO (Maybe String, ProverResult)+ multiSATQuery sym solverCfg primMap logData ts args query (SomeSat n) | n <= 1 =   singleQuery sym solverCfg primMap logData ts args Nothing query +multiSATQuery _sym W4OfflineConfig _primMap _logData _ts _args _query _satNum =+  fail "What4 offline solver cannot be used for multi-SAT queries"+ multiSATQuery _sym (W4Portfolio _) _primMap _logData _ts _args _query _satNum =-  fail "What4 portfolio solver cannot be used for multi SAT queries"+  fail "What4 portfolio solver cannot be used for multi-SAT queries" -multiSATQuery sym (W4ProverConfig (AnAdapter adpt)) primMap logData ts args query satNum0 =-  do pres <- W4.solver_adapter_check_sat adpt (w4 sym) logData [query] $ \res ->-         case res of-           W4.Unknown -> return (Left (ProverError "Solver returned UNKNOWN"))-           W4.Unsat _ -> return (Left (ThmResult (map unFinType ts)))-           W4.Sat (evalFn,_) ->-             do xs <- mapM (varShapeToConcrete evalFn) args-                let model = computeModel primMap ts xs-                blockingPred <- computeBlockingPred sym args xs-                return (Right (model, blockingPred))+multiSATQuery _sym (W4ProverConfig (AnAdapter adpt)) _primMap _logData _ts _args _query _satNum =+  fail ("Solver " ++ solver_adapter_name adpt ++ " does not support incremental solving and " +++        "cannot be used for multi-SAT queries.") -     case pres of-       Left res -> pure (Just (solver_adapter_name adpt), res)-       Right (mdl,block) ->-         do mdls <- (mdl:) <$> computeMoreModels [block,query] (decSatNum satNum0)-            return (Just (solver_adapter_name adpt), AllSatResult mdls)+multiSATQuery sym (W4ProverConfig (AnOnlineAdapter nm fs _opts (_ :: Proxy s)))+               primMap _logData ts args query satNum0 =+    X.bracket+      (W4.startSolverProcess fs Nothing (w4 sym))+      (void . W4.shutdownSolverProcess)+      (\ (proc :: W4.SolverProcess t s) ->+        do W4.assume (W4.solverConn proc) query+           res <- W4.checkAndGetModel proc "query"+           case res of+             W4.Unknown -> return (Just nm, ProverError "Solver returned UNKNOWN")+             W4.Unsat _ -> return (Just nm, ThmResult (map unFinType ts))+             W4.Sat evalFn ->+               do xs <- mapM (varShapeToConcrete evalFn) args+                  let mdl = computeModel primMap ts xs+                  -- NB, we flatten these shapes to make sure that we can split+                  -- our search across all of the atomic variables+                  let vs = flattenShapes args []+                  let cs = flattenShapes xs []+                  mdls <- runMultiSat satNum0 $+                            do yield mdl+                               computeMoreModels proc vs cs+                  return (Just nm, AllSatResult mdls))    where+  -- This search procedure uses incremental solving and push/pop to split on the concrete+  -- values of variables, while also helping to prevent the accumulation of unhelpful+  -- lemmas in the solver state.  This algorithm is basically taken from:+  --   http://theory.stanford.edu/%7Enikolaj/programmingz3.html#sec-blocking-evaluations+  computeMoreModels ::+    W4.SolverProcess t s ->+    [VarShape (What4 sym)] ->+    [VarShape Concrete.Concrete] ->+    MultiSat ()+  computeMoreModels proc vs cs =+    -- Enumerate all the ways to split up the current model+    forM_ (computeSplits vs cs) $ \ (prefix, vi, ci, suffix) ->+      do -- open a new solver frame+         liftIO $ W4.push proc+         -- force the selected pair to be different+         liftIO $ W4.assume (W4.solverConn proc) =<< W4.notPred (w4 sym) =<< computeModelPred sym vi ci+         -- force the prefix values to be the same+         liftIO $ forM_ prefix $ \(v,c) ->+           W4.assume (W4.solverConn proc) =<< computeModelPred sym v c+         -- under these assumptions, find all the remaining models+         findMoreModels proc (vi:suffix)+         -- pop the current assumption frame+         liftIO $ W4.pop proc -  computeMoreModels _qs (SomeSat n) | n <= 0 = return [] -- should never happen...-  computeMoreModels qs (SomeSat n) | n <= 1 = -- final model-    W4.solver_adapter_check_sat adpt (w4 sym) logData qs $ \res ->-         case res of-           W4.Unknown -> return []-           W4.Unsat _ -> return []-           W4.Sat (evalFn,_) ->-             do xs <- mapM (varShapeToConcrete evalFn) args-                let model = computeModel primMap ts xs-                return [model]+  findMoreModels ::+    W4.SolverProcess t s ->+    [VarShape (What4 sym)] ->+    MultiSat ()+  findMoreModels proc vs =+    -- see if our current assumptions are consistent+    do res <- liftIO (W4.checkAndGetModel proc "find model")+       case res of+         -- if the solver gets stuck, drop all the way out and stop search+         W4.Unknown -> done+         -- if our assumptions are already unsatisfiable, stop search and return+         W4.Unsat _ -> return ()+         W4.Sat evalFn ->+           -- We found a model.  Record it and then use it to split the remaining+           -- search variables some more.+           do xs <- liftIO (mapM (varShapeToConcrete evalFn) args)+              yield (computeModel primMap ts xs)+              cs <- liftIO (mapM (varShapeToConcrete evalFn) vs)+              computeMoreModels proc vs cs -  computeMoreModels qs satNum =-    do pres <- W4.solver_adapter_check_sat adpt (w4 sym) logData qs $ \res ->-         case res of-           W4.Unknown -> return Nothing-           W4.Unsat _ -> return Nothing-           W4.Sat (evalFn,_) ->-             do xs <- mapM (varShapeToConcrete evalFn) args-                let model = computeModel primMap ts xs-                blockingPred <- computeBlockingPred sym args xs-                return (Just (model, blockingPred))+-- == Support operations for multi-SAT ==+type Models = [[(TValue, Expr, Concrete.Value)]] -       case pres of-         Nothing -> return []-         Just (mdl, block) ->-           (mdl:) <$> computeMoreModels (block:qs) (decSatNum satNum)+newtype MultiSat a =+  MultiSat { unMultiSat ::  Models -> SatNum -> (a -> Models -> SatNum -> IO Models) -> IO Models } +instance Functor MultiSat where+  fmap f m = MultiSat (\ms satNum k -> unMultiSat m ms satNum (k . f))++instance Applicative MultiSat where+  pure x = MultiSat (\ms satNum k -> k x ms satNum)+  mf <*> mx = mf >>= \f -> fmap f mx++instance Monad MultiSat where+  m >>= f = MultiSat (\ms satNum k -> unMultiSat m ms satNum (\x ms' satNum' -> unMultiSat (f x) ms' satNum' k))++instance MonadIO MultiSat where+  liftIO m = MultiSat (\ms satNum k -> do x <- m; k x ms satNum)++runMultiSat :: SatNum -> MultiSat a -> IO Models+runMultiSat satNum m = reverse <$> unMultiSat m [] satNum (\_ ms _ -> return ms)++done :: MultiSat a+done = MultiSat (\ms _satNum _k -> return ms)++yield :: [(TValue, Expr, Concrete.Value)] -> MultiSat ()+yield mdl = MultiSat (\ms satNum k ->+  case satNum of+    SomeSat n+      | n > 1 -> k () (mdl:ms) (SomeSat (n-1))+      | otherwise -> return (mdl:ms)+    _ -> k () (mdl:ms) satNum)++-- Compute all the ways to split a sequences of variables+-- and concrete values for those variables.  Each element+-- of the list consists of a prefix of (varaible,value)+-- pairs whose values we will fix, a single (varaible,value)+-- pair that we will force to be different, and a list of+-- additional unconstrained variables.+computeSplits ::+  [VarShape (What4 sym)] ->+  [VarShape Concrete.Concrete] ->+  [ ( [(VarShape (What4 sym), VarShape Concrete.Concrete)]+    , VarShape (What4 sym)+    , VarShape Concrete.Concrete+    , [VarShape (What4 sym)]+    )+  ]+computeSplits vs cs = reverse+  [ (prefix, v, c, tl)+  | prefix <- inits (zip vs cs)+  | v      <- vs+  | c      <- cs+  | tl     <- tail (tails vs)+  ]+-- == END Support operations for multi-SAT ==+ singleQuery ::   sym ~ W4.ExprBuilder t CryptolState fm =>   What4 sym ->@@ -491,6 +635,10 @@   W4.Pred sym ->   IO (Maybe String, ProverResult) +singleQuery _ W4OfflineConfig _primMap _logData _ts _args _msafe _query =+  -- this shouldn't happen...+  fail "What4 offline solver cannot be used for direct queries"+ singleQuery sym (W4Portfolio ps) primMap logData ts args msafe query =   do as <- mapM async [ singleQuery sym (W4ProverConfig p) primMap logData ts args msafe query                       | p <- NE.toList ps@@ -528,16 +676,37 @@       return (Just (W4.solver_adapter_name adpt), pres) +singleQuery sym (W4ProverConfig (AnOnlineAdapter nm fs _opts (_ :: Proxy s)))+              primMap _logData ts args msafe query =+  X.bracket+    (W4.startSolverProcess fs Nothing (w4 sym))+    (void . W4.shutdownSolverProcess)+    (\ (proc :: W4.SolverProcess t s) ->+        do W4.assume (W4.solverConn proc) query+           res <- W4.checkAndGetModel proc "query"+           case res of+             W4.Unknown -> return (Just nm, ProverError "Solver returned UNKNOWN")+             W4.Unsat _ -> return (Just nm, ThmResult (map unFinType ts))+             W4.Sat evalFn ->+               do xs <- mapM (varShapeToConcrete evalFn) args+                  let model = computeModel primMap ts xs+                  case msafe of+                    Just s ->+                      do s' <- W4.groundEval evalFn s+                         let cexType = if s' then PredicateFalsified else SafetyViolation+                         return (Just nm, CounterExample cexType model)+                    Nothing -> return (Just nm, AllSatResult [ model ])+    ) -computeBlockingPred ::++computeModelPred ::   sym ~ W4.ExprBuilder t CryptolState fm =>   What4 sym ->-  [VarShape (What4 sym)] ->-  [VarShape Concrete.Concrete] ->+  VarShape (What4 sym) ->+  VarShape Concrete.Concrete ->   IO (W4.Pred sym)-computeBlockingPred sym vs xs =-  do res <- doW4Eval (w4 sym) (modelPred sym vs xs)-     W4.notPred (w4 sym) (snd res)+computeModelPred sym v c =+  snd <$> doW4Eval (w4 sym) (varModelPred sym (v, c))  varShapeToConcrete ::   W4.GroundEvalFn t ->
src/Cryptol/Testing/Random.hs view
@@ -34,16 +34,18 @@ import Data.List              (unfoldr, genericTake, genericIndex, genericReplicate) import qualified Data.Sequence as Seq -import System.Random          (RandomGen, split, random, randomR)+import System.Random.TF.Gen+import System.Random.TF.Instances  import Cryptol.Backend        (Backend(..), SRational(..)) import Cryptol.Backend.FloatHelpers (floatFromBits) import Cryptol.Backend.Monad  (runEval,Eval,EvalErrorEx(..)) import Cryptol.Backend.Concrete+import Cryptol.Backend.SeqMap (indexSeqMap, finiteSeqMap)+import Cryptol.Backend.WordValue (wordVal)  import Cryptol.Eval.Type      (TValue(..))-import Cryptol.Eval.Value     (GenValue(..),SeqMap(..), WordValue(..),-                               ppValue, defaultPPOpts, finiteSeqMap, fromVFun)+import Cryptol.Eval.Value     (GenValue(..), ppValue, defaultPPOpts, fromVFun) import Cryptol.TypeCheck.Solver.InfNat (widthInteger) import Cryptol.Utils.Ident    (Ident) import Cryptol.Utils.Panic    (panic)@@ -212,7 +214,7 @@ randomWord :: (Backend sym, RandomGen g) => sym -> Integer -> Gen g sym randomWord sym w _sz g =    let (val, g1) = randomR (0,2^w-1) g-   in (return $ VWord w (WordVal <$> wordLit sym w val), g1)+   in (VWord w . wordVal <$> wordLit sym w val, g1)  {-# INLINE randomStream #-} @@ -220,7 +222,7 @@ randomStream :: (Backend sym, RandomGen g) => Gen g sym -> Gen g sym randomStream mkElem sz g =   let (g1,g2) = split g-  in (pure $ VStream $ IndexSeqMap $ genericIndex (unfoldr (Just . mkElem sz) g1), g2)+  in (pure $ VStream $ indexSeqMap $ genericIndex (unfoldr (Just . mkElem sz) g1), g2)  {-# INLINE randomSequence #-} @@ -232,7 +234,7 @@   let f g = let (x,g') = mkElem sz g              in seq x (Just (x, g'))   let xs = Seq.fromList $ genericTake w $ unfoldr f g1-  let v  = VSeq w $ IndexSeqMap $ \i -> Seq.index xs (fromInteger i)+  let v  = VSeq w $ indexSeqMap $ \i -> Seq.index xs (fromInteger i)   seq xs (pure v, g2)  {-# INLINE randomTuple #-}@@ -401,11 +403,11 @@     TVArray{}   -> []     TVStream{}  -> []     TVSeq n TVBit ->-      [ VWord n (pure (WordVal (BV n x)))+      [ VWord n (wordVal (BV n x))       | x <- [ 0 .. 2^n - 1 ]       ]     TVSeq n el ->-      [ VSeq n (finiteSeqMap (map pure xs))+      [ VSeq n (finiteSeqMap Concrete (map pure xs))       | xs <- sequence (genericReplicate n (typeValues el))       ]     TVTuple ts ->
src/Cryptol/Transform/MonoValues.hs view
@@ -79,11 +79,11 @@ module Cryptol.Transform.MonoValues (rewModule) where  import Cryptol.ModuleSystem.Name-        (SupplyT,liftSupply,Supply,mkDeclared,NameSource(..))+        (SupplyT,liftSupply,Supply,mkDeclared,NameSource(..),ModPath(..)) import Cryptol.Parser.Position (emptyRange) import Cryptol.TypeCheck.AST hiding (splitTApp) -- XXX: just use this one import Cryptol.TypeCheck.TypeMap-import Cryptol.Utils.Ident (ModName)+import Cryptol.Utils.Ident(Namespace(..)) import Data.List(sortBy,groupBy) import Data.Either(partitionEithers) import Data.Map (Map)@@ -132,7 +132,7 @@ -- | Note that this assumes that this pass will be run only once for each -- module, otherwise we will get name collisions. rewModule :: Supply -> Module -> (Module,Supply)-rewModule s m = runM body (mName m) s+rewModule s m = runM body (TopModule (mName m)) s   where   body = do ds <- mapM (rewDeclGroup emptyTM) (mDecls m)             return m { mDecls = ds }@@ -140,13 +140,13 @@ --------------------------------------------------------------------------------  type M  = ReaderT RO (SupplyT Id)-type RO = ModName+type RO = ModPath  -- | Produce a fresh top-level name. newName :: M Name newName  =   do ns <- ask-     liftSupply (mkDeclared ns SystemName "$mono" Nothing emptyRange)+     liftSupply (mkDeclared NSValue ns SystemName "$mono" Nothing emptyRange)  newTopOrLocalName :: M Name newTopOrLocalName  = newName
src/Cryptol/Transform/Specialize.hs view
@@ -242,9 +242,10 @@ freshName :: Name -> [Type] -> SpecM Name freshName n _ =   case nameInfo n of-    Declared ns s -> liftSupply (mkDeclared ns s ident fx loc)-    Parameter     -> liftSupply (mkParameter ident loc)+    Declared m s  -> liftSupply (mkDeclared ns m s ident fx loc)+    Parameter     -> liftSupply (mkParameter ns ident loc)   where+  ns    = nameNamespace n   fx    = nameFixity n   ident = nameIdent n   loc   = nameLoc n
src/Cryptol/TypeCheck.hs view
@@ -15,6 +15,7 @@   , InferInput(..)   , InferOutput(..)   , SolverConfig(..)+  , defaultSolverConfig   , NameSeeds   , nameSeeds   , Error(..)@@ -27,12 +28,15 @@   , ppNamedError   ) where +import Data.IORef(IORef,modifyIORef')+import Data.Map(Map)+ import           Cryptol.ModuleSystem.Name-                    (liftSupply,mkDeclared,NameSource(..))+                    (liftSupply,mkDeclared,NameSource(..),ModPath(..))+import Cryptol.ModuleSystem.NamingEnv(NamingEnv,namingEnvRename) import qualified Cryptol.Parser.AST as P import           Cryptol.Parser.Position(Range,emptyRange) import           Cryptol.TypeCheck.AST-import           Cryptol.TypeCheck.Depends (FromDecl) import           Cryptol.TypeCheck.Error import           Cryptol.TypeCheck.Monad                    ( runInferM@@ -41,16 +45,20 @@                    , NameSeeds                    , nameSeeds                    , lookupVar+                   , newLocalScope, endLocalScope+                   , newModuleScope, addParamType, addParameterConstraints+                   , endModuleInstance+                   , io                    )-import           Cryptol.TypeCheck.Infer (inferModule, inferBinds, inferDs)-import           Cryptol.TypeCheck.InferTypes(VarType(..), SolverConfig(..))-import           Cryptol.TypeCheck.Solve(proveModuleTopLevel)-import           Cryptol.TypeCheck.CheckModuleInstance(checkModuleInstance)-import           Cryptol.TypeCheck.Monad(withParamType,withParameterConstraints)-import           Cryptol.TypeCheck.PP(WithNames(..),NameMap)-import           Cryptol.Utils.Ident (exprModName,packIdent)-import           Cryptol.Utils.PP-import           Cryptol.Utils.Panic(panic)+import Cryptol.TypeCheck.Infer (inferModule, inferBinds, checkTopDecls)+import Cryptol.TypeCheck.InferTypes(VarType(..), SolverConfig(..), defaultSolverConfig)+import Cryptol.TypeCheck.Solve(proveModuleTopLevel)+import Cryptol.TypeCheck.CheckModuleInstance(checkModuleInstance)+-- import Cryptol.TypeCheck.Monad(withParamType,withParameterConstraints)+import Cryptol.TypeCheck.PP(WithNames(..),NameMap)+import Cryptol.Utils.Ident (exprModName,packIdent,Namespace(..))+import Cryptol.Utils.PP+import Cryptol.Utils.Panic(panic)   @@ -59,17 +67,22 @@  -- | Check a module instantiation, assuming that the functor has already -- been checked.-tcModuleInst :: Module                  {- ^ functor -} ->-                P.Module Name           {- params -} ->+-- XXX: This will change+tcModuleInst :: IORef NamingEnv {- ^ renaming environment of functor -} ->+                Module                  {- ^ functor -} ->+                P.Module Name           {- ^ params -} ->                 InferInput              {- ^ TC settings -} ->                 IO (InferOutput Module) {- ^ new version of instance -}-tcModuleInst func m inp = runInferM inp-                        $ do x <- inferModule m-                             flip (foldr withParamType) (mParamTypes x) $-                               withParameterConstraints (mParamConstraints x) $-                               do y <- checkModuleInstance func x-                                  proveModuleTopLevel-                                  pure y+tcModuleInst renThis func m inp = runInferM inp $+  do x <- inferModule m+     newModuleScope (mName func) [] mempty+     mapM_ addParamType (mParamTypes x)+     addParameterConstraints (mParamConstraints x)+     (ren,y) <- checkModuleInstance func x+     io $ modifyIORef' renThis (namingEnvRename ren)+     proveModuleTopLevel+     endModuleInstance+     pure y  tcExpr :: P.Expr Name -> InferInput -> IO (InferOutput (Expr,Schema)) tcExpr e0 inp = runInferM inp@@ -92,8 +105,9 @@                              , show e'                              , show t                              ]-      _ -> do fresh <- liftSupply (mkDeclared exprModName SystemName-                                      (packIdent "(expression)") Nothing loc)+      _ -> do fresh <- liftSupply $+                        mkDeclared NSValue (TopModule exprModName) SystemName+                                      (packIdent "(expression)") Nothing loc               res   <- inferBinds True False                 [ P.Bind                     { P.bName      = P.Located { P.srcRange = loc, P.thing = fresh }@@ -105,6 +119,7 @@                     , P.bInfix     = False                     , P.bFixity    = Nothing                     , P.bDoc       = Nothing+                    , P.bExport    = Public                     } ]                case res of@@ -119,24 +134,24 @@                           : map show res                           ) -tcDecls :: FromDecl d => [d] -> InferInput -> IO (InferOutput [DeclGroup])-tcDecls ds inp = runInferM inp $ inferDs ds $ \dgs -> do-                   proveModuleTopLevel-                   return dgs+tcDecls :: [P.TopDecl Name] -> InferInput -> IO (InferOutput ([DeclGroup],Map Name TySyn))+tcDecls ds inp = runInferM inp $+  do newLocalScope+     checkTopDecls ds+     proveModuleTopLevel+     endLocalScope  ppWarning :: (Range,Warning) -> Doc-ppWarning (r,w) = text "[warning] at" <+> pp r <.> colon $$ nest 2 (pp w)+ppWarning (r,w) = nest 2 (text "[warning] at" <+> pp r <.> colon $$ pp w)  ppError :: (Range,Error) -> Doc-ppError (r,w) = text "[error] at" <+> pp r <.> colon $$ nest 2 (pp w)-+ppError (r,w) = nest 2 (text "[error] at" <+> pp r <.> colon $$ pp w)  ppNamedWarning :: NameMap -> (Range,Warning) -> Doc ppNamedWarning nm (r,w) =-  text "[warning] at" <+> pp r <.> colon $$ nest 2 (pp (WithNames w nm))+  nest 2 (text "[warning] at" <+> pp r <.> colon $$ pp (WithNames w nm))  ppNamedError :: NameMap -> (Range,Error) -> Doc ppNamedError nm (r,e) =-  text "[error] at" <+> pp r <.> colon $$ nest 2 (pp (WithNames e nm))-+  nest 2 (text "[error] at" <+> pp r <.> colon $$ pp (WithNames e nm)) 
src/Cryptol/TypeCheck/AST.hs view
@@ -18,10 +18,10 @@   , Name()   , TFun(..)   , Selector(..)-  , Import(..)+  , Import, ImportG(..)   , ImportSpec(..)   , ExportType(..)-  , ExportSpec(..), isExportedBind, isExportedType+  , ExportSpec(..), isExportedBind, isExportedType, isExported   , Pragma(..)   , Fixity(..)   , PrimMap(..)@@ -30,10 +30,12 @@  import Cryptol.Parser.Position(Located,Range,HasLoc(..)) import Cryptol.ModuleSystem.Name+import Cryptol.ModuleSystem.Interface import Cryptol.ModuleSystem.Exports(ExportSpec(..)-                                   , isExportedBind, isExportedType)+                                   , isExportedBind, isExportedType, isExported) import Cryptol.Parser.AST ( Selector(..),Pragma(..)-                          , Import(..), ImportSpec(..), ExportType(..)+                          , Import+                          , ImportG(..), ImportSpec(..), ExportType(..)                           , Fixity(..)) import Cryptol.Utils.Ident (Ident,isInfixIdent,ModName,PrimIdent,prelPrim) import Cryptol.Utils.RecordMap@@ -50,58 +52,60 @@   -- | A Cryptol module.-data Module = Module { mName        :: !ModName-                     , mExports     :: ExportSpec Name-                     , mImports     :: [Import]+data ModuleG mname =+              Module { mName             :: !mname+                     , mExports          :: ExportSpec Name+                     , mImports          :: [Import] -                     , mTySyns      :: Map Name TySyn-                       -- ^ This is just the type-level type synonyms-                       -- of a module.+                       {-| Interfaces of submodules, including functors.+                           This is only the directly nested modules.+                           Info about more nested modules is in the+                           corresponding interface. -}+                     , mSubModules       :: Map Name (IfaceG Name) -                     , mNewtypes         :: Map Name Newtype-                     , mPrimTypes        :: Map Name AbstractType+                     -- params, if functor                      , mParamTypes       :: Map Name ModTParam                      , mParamConstraints :: [Located Prop]                      , mParamFuns        :: Map Name ModVParam+++                      -- Declarations, including everything from non-functor+                      -- submodules+                     , mTySyns           :: Map Name TySyn+                     , mNewtypes         :: Map Name Newtype+                     , mPrimTypes        :: Map Name AbstractType                      , mDecls            :: [DeclGroup]+                     , mFunctors         :: Map Name (ModuleG Name)                      } deriving (Show, Generic, NFData) +emptyModule :: mname -> ModuleG mname+emptyModule nm =+  Module+    { mName             = nm+    , mExports          = mempty+    , mImports          = []+    , mSubModules       = mempty++    , mParamTypes       = mempty+    , mParamConstraints = mempty+    , mParamFuns        = mempty++    , mTySyns           = mempty+    , mNewtypes         = mempty+    , mPrimTypes        = mempty+    , mDecls            = mempty+    , mFunctors         = mempty+    }++type Module = ModuleG ModName+ -- | Is this a parameterized module?-isParametrizedModule :: Module -> Bool+isParametrizedModule :: ModuleG mname -> Bool isParametrizedModule m = not (null (mParamTypes m) &&                               null (mParamConstraints m) &&                               null (mParamFuns m)) --- | A type parameter of a module.-data ModTParam = ModTParam-  { mtpName   :: Name-  , mtpKind   :: Kind-  , mtpNumber :: !Int -- ^ The number of the parameter in the module-                      -- This is used when we move parameters from the module-                      -- level to individual declarations-                      -- (type synonyms in particular)-  , mtpDoc    :: Maybe Text-  } deriving (Show,Generic,NFData) -mtpParam :: ModTParam -> TParam-mtpParam mtp = TParam { tpUnique = nameUnique (mtpName mtp)-                      , tpKind   = mtpKind mtp-                      , tpFlav   = TPModParam (mtpName mtp)-                      , tpInfo   = desc-                      }-  where desc = TVarInfo { tvarDesc   = TVFromModParam (mtpName mtp)-                        , tvarSource = nameLoc (mtpName mtp)-                        }---- | A value parameter of a module.-data ModVParam = ModVParam-  { mvpName   :: Name-  , mvpType   :: Schema-  , mvpDoc    :: Maybe Text-  , mvpFixity :: Maybe Fixity-  } deriving (Show,Generic,NFData)-- data Expr   = EList [Expr] Type         -- ^ List value (with type of elements)             | ETuple [Expr]             -- ^ Tuple value             | ERec (RecordMap Ident Expr) -- ^ Record value@@ -207,14 +211,14 @@       EList [] t    -> optParens (prec > 0)                     $ text "[]" <+> colon <+> ppWP prec t -      EList es _    -> brackets $ sep $ punctuate comma $ map ppW es+      EList es _    -> ppList $ map ppW es -      ETuple es     -> parens $ sep $ punctuate comma $ map ppW es+      ETuple es     -> ppTuple $ map ppW es -      ERec fs       -> braces $ sep $ punctuate comma+      ERec fs       -> ppRecord                         [ pp f <+> text "=" <+> ppW e | (f,e) <- displayFields fs ] -      ESel e sel    -> ppWP 4 e <+> text "." <.> pp sel+      ESel e sel    -> ppWP 4 e <.> text "." <.> pp sel        ESet _ty e sel v  -> braces (pp e <+> "|" <+> pp sel <+> "=" <+> pp v) @@ -224,7 +228,7 @@                           , text "else" <+> ppW e3 ]        EComp _ _ e mss -> let arm ms = text "|" <+> commaSep (map ppW ms)-                          in brackets $ ppW e <+> vcat (map arm mss)+                          in brackets $ ppW e <+> (align (vcat (map arm mss)))        EVar x        -> ppPrefixName x @@ -257,28 +261,29 @@       ETApp e t     -> optParens (prec > 3)                     $ ppWP 3 e <+> ppWP 5 t -      EWhere e ds   -> optParens (prec > 0)-                     ( ppW e $$ text "where"-                                     $$ nest 2 (vcat (map ppW ds))-                                     $$ text "" )+      EWhere e ds   -> optParens (prec > 0) $ align $ vsep $+                         [ ppW e+                         , hang "where" 2 (vcat (map ppW ds))+                         ]      where     ppW x   = ppWithNames nm x     ppWP x  = ppWithNamesPrec nm x  ppLam :: NameMap -> Int -> [TParam] -> [Prop] -> [(Name,Type)] -> Expr -> Doc-ppLam nm prec [] [] [] e = ppWithNamesPrec nm prec e+ppLam nm prec [] [] [] e = nest 2 (ppWithNamesPrec nm prec e) ppLam nm prec ts ps xs e =   optParens (prec > 0) $-  sep [ text "\\" <.> tsD <+> psD <+> xsD <+> text "->"-      , ppWithNames ns1 e-      ]+  nest 2 $ sep+    [ text "\\" <.> hsep (tsD ++ psD ++ xsD ++ [text "->"])+    , ppWithNames ns1 e+    ]   where   ns1 = addTNames ts nm -  tsD = if null ts then empty else braces $ sep $ punctuate comma $ map ppT ts-  psD = if null ps then empty else parens $ sep $ punctuate comma $ map ppP ps-  xsD = if null xs then empty else sep    $ map ppArg xs+  tsD = if null ts then [] else [braces $ commaSep $ map ppT ts]+  psD = if null ps then [] else [parens $ commaSep $ map ppP ps]+  xsD = if null xs then [] else [sep    $ map ppArg xs]    ppT = ppWithNames ns1   ppP = ppWithNames ns1@@ -355,12 +360,12 @@  instance PP (WithNames Decl) where   ppPrec _ (WithNames Decl { .. } nm) =-    pp dName <+> text ":" <+> ppWithNames nm dSignature  $$-    (if null dPragmas-        then empty-        else text "pragmas" <+> pp dName <+> sep (map pp dPragmas)-    ) $$-    pp dName <+> text "=" <+> ppWithNames nm dDefinition+    vcat $+      [ pp dName <+> text ":" <+> ppWithNames nm dSignature ]+      ++ (if null dPragmas+            then []+            else [text "pragmas" <+> pp dName <+> sep (map pp dPragmas)])+      ++ [ nest 2 (sep [pp dName <+> text "=", ppWithNames nm dDefinition]) ]  instance PP (WithNames DeclDef) where   ppPrec _ (WithNames DPrim _)      = text "<primitive>"@@ -369,10 +374,10 @@ instance PP Decl where   ppPrec = ppWithNamesPrec IntMap.empty -instance PP Module where+instance PP n => PP (ModuleG n) where   ppPrec = ppWithNamesPrec IntMap.empty -instance PP (WithNames Module) where+instance PP n => PP (WithNames (ModuleG n)) where   ppPrec _ (WithNames Module { .. } nm) =     text "module" <+> pp mName $$     -- XXX: Print exports?
src/Cryptol/TypeCheck/CheckModuleInstance.hs view
@@ -1,3 +1,4 @@+{-# Language OverloadedStrings #-} module Cryptol.TypeCheck.CheckModuleInstance (checkModuleInstance) where  import           Data.Map ( Map )@@ -19,17 +20,24 @@ -- | Check that the instance provides what the functor needs. checkModuleInstance :: Module {- ^ type-checked functor -} ->                        Module {- ^ type-checked instance -} ->-                       InferM Module -- ^ Instantiated module-checkModuleInstance func inst =+                       InferM (Name->Name,Module)+                       -- ^ Renaming,Instantiated module+checkModuleInstance func inst+  | not (null (mSubModules func) && null (mSubModules inst)) =+    do recordError $ TemporaryError+         "Cannot combine nested modules with old-style parameterized modules"+       pure (id,func) -- doesn't matter?+  | otherwise =   do tMap <- checkTyParams func inst      vMap <- checkValParams func tMap inst-     (ctrs, m) <- instantiateModule func (mName inst) tMap vMap+     (ren, ctrs, m) <- instantiateModule func (mName inst) tMap vMap      let toG p = Goal { goal = thing p                       , goalRange = srcRange p                       , goalSource = CtModuleInstance (mName inst)                       }      addGoals (map toG ctrs)-     return Module { mName = mName m+     return ( ren+            , Module { mName = mName m                    , mExports = mExports m                    , mImports = mImports inst ++ mImports m                                 -- Note that this is just here to record@@ -43,7 +51,11 @@                    , mParamConstraints = mParamConstraints inst                    , mParamFuns        = mParamFuns inst                    , mDecls            = mDecls inst ++ mDecls m++                   , mSubModules = mempty+                   , mFunctors   = mempty                    }+              )  -- | Check that the type parameters of the functors all have appropriate -- definitions.@@ -179,6 +191,7 @@                , P.bPragmas   = []                , P.bMono      = False                , P.bDoc       = Nothing+               , P.bExport    = Public                }   loc a = P.Located { P.srcRange = nameLoc x, P.thing = a } 
− src/Cryptol/TypeCheck/Depends.hs
@@ -1,214 +0,0 @@--- |--- Module      :  Cryptol.TypeCheck.Depends--- Copyright   :  (c) 2013-2016 Galois, Inc.--- License     :  BSD3--- Maintainer  :  cryptol@galois.com--- Stability   :  provisional--- Portability :  portable--{-# LANGUAGE Safe #-}-{-# LANGUAGE FlexibleInstances #-}-module Cryptol.TypeCheck.Depends where--import           Cryptol.ModuleSystem.Name (Name)-import qualified Cryptol.Parser.AST as P-import           Cryptol.Parser.Position(Range, Located(..), thing)-import           Cryptol.Parser.Names (namesB, tnamesT, tnamesC,-                                      boundNamesSet, boundNames)-import           Cryptol.TypeCheck.Monad( InferM, getTVars )-import           Cryptol.TypeCheck.Error(Error(..))-import           Cryptol.Utils.Panic(panic)-import           Cryptol.Utils.RecordMap(recordElements)--import           Data.List(sortBy, groupBy)-import           Data.Function(on)-import           Data.Maybe(mapMaybe)-import           Data.Graph.SCC(stronglyConnComp)-import           Data.Graph (SCC(..))-import           Data.Map (Map)-import qualified Data.Map as Map-import qualified Data.Set as Set-import           Data.Text (Text)-import           MonadLib (ExceptionT, runExceptionT, raise)--data TyDecl =-    TS (P.TySyn Name) (Maybe Text)          -- ^ Type synonym-  | NT (P.Newtype Name) (Maybe Text)        -- ^ Newtype-  | AT (P.ParameterType Name) (Maybe Text)  -- ^ Parameter type-  | PS (P.PropSyn Name) (Maybe Text)        -- ^ Property synonym-  | PT (P.PrimType Name) (Maybe Text)       -- ^ A primitive/abstract typee-    deriving Show--setDocString :: Maybe Text -> TyDecl -> TyDecl-setDocString x d =-  case d of-    TS a _ -> TS a x-    PS a _ -> PS a x-    NT a _ -> NT a x-    AT a _ -> AT a x-    PT a _ -> PT a x---- | Check for duplicate and recursive type synonyms.--- Returns the type-synonyms in dependency order.-orderTyDecls :: [TyDecl] -> InferM (Either Error [TyDecl])-orderTyDecls ts =-  do vs <- getTVars-     ds <- combine $ map (toMap vs) ts-     let ordered = mkScc [ (t,[x],deps)-                              | (x,(t,deps)) <- Map.toList (Map.map thing ds) ]-     runExceptionT (concat `fmap` mapM check ordered)--  where-  toMap vs ty@(PT p _) =-    let x       = P.primTName p-        (as,cs) = P.primTCts p-    in  ( thing x-        , x { thing = (ty, Set.toList $-                           boundNamesSet vs $-                           boundNames (map P.tpName as) $-                           Set.unions $-                           map tnamesC cs-                      )-             }-        )---  toMap _ ty@(AT a _) =-    let x = P.ptName a-    in ( thing x, x { thing = (ty, []) } )--  toMap vs ty@(NT (P.Newtype x as fs) _) =-    ( thing x-    , x { thing = (ty, Set.toList $-                       boundNamesSet vs $-                       boundNames (map P.tpName as) $-                       Set.unions $-                       map (tnamesT . snd) (recordElements fs)-                  )-        }-    )--  toMap vs ty@(TS (P.TySyn x _ as t) _) =-        (thing x-        , x { thing = (ty, Set.toList $-                           boundNamesSet vs $-                           boundNames (map P.tpName as) $-                           tnamesT t-                      )-             }-        )--  toMap vs ty@(PS (P.PropSyn x _ as ps) _) =-        (thing x-        , x { thing = (ty, Set.toList $-                           boundNamesSet vs $-                           boundNames (map P.tpName as) $-                           Set.unions $-                           map tnamesC ps-                      )-             }-        )-  getN (TS x _) = thing (P.tsName x)-  getN (PS x _) = thing (P.psName x)-  getN (NT x _) = thing (P.nName x)-  getN (AT x _) = thing (P.ptName x)-  getN (PT x _) = thing (P.primTName x)--  check :: SCC TyDecl -> ExceptionT Error InferM [TyDecl]-  check (AcyclicSCC x) = return [x]--  -- We don't support any recursion, for now.-  -- We could support recursion between newtypes, or newtypes and tysysn.-  check (CyclicSCC xs) = raise (RecursiveTypeDecls (map getN xs))---- | Associate type signatures with bindings and order bindings by dependency.-orderBinds :: [P.Bind Name] -> [SCC (P.Bind Name)]-orderBinds bs = mkScc [ (b, map thing defs, Set.toList uses)-                      | b <- bs-                      , let (defs,uses) = namesB b-                      ]--class FromDecl d where-  toBind             :: d -> Maybe (P.Bind Name)-  toParamFun         :: d -> Maybe (P.ParameterFun Name)-  toParamConstraints :: d -> [P.Located (P.Prop Name)]-  toTyDecl           :: d -> Maybe TyDecl-  isTopDecl          :: d -> Bool--instance FromDecl (P.TopDecl Name) where-  toBind (P.Decl x)         = toBind (P.tlValue x)-  toBind _                  = Nothing--  toParamFun (P.DParameterFun d)  = Just d-  toParamFun _                    = Nothing--  toParamConstraints (P.DParameterConstraint xs) = xs-  toParamConstraints _                           = []--  toTyDecl (P.DPrimType p)      = Just (PT (P.tlValue p) (thing <$> P.tlDoc p))-  toTyDecl (P.DParameterType d) = Just (AT d (P.ptDoc d))-  toTyDecl (P.TDNewtype d)      = Just (NT (P.tlValue d) (thing <$> P.tlDoc d))-  toTyDecl (P.Decl x)           = setDocString (thing <$> P.tlDoc x)-                                  <$> toTyDecl (P.tlValue x)-  toTyDecl _                    = Nothing--  isTopDecl _               = True--instance FromDecl (P.Decl Name) where-  toBind (P.DLocated d _) = toBind d-  toBind (P.DBind b)      = return b-  toBind _                = Nothing--  toParamFun _ = Nothing-  toParamConstraints _ = []--  toTyDecl (P.DLocated d _) = toTyDecl d-  toTyDecl (P.DType x)      = Just (TS x Nothing)-  toTyDecl (P.DProp x)      = Just (PS x Nothing)-  toTyDecl _                = Nothing--  isTopDecl _               = False--{- | Given a list of declarations, annoted with (i) the names that they-define, and (ii) the names that they use, we compute a list of strongly-connected components of the declarations.  The SCCs are in dependency order. -}-mkScc :: [(a,[Name],[Name])] -> [SCC a]-mkScc ents = stronglyConnComp $ zipWith mkGr keys ents-  where-  keys                    = [ 0 :: Integer .. ]--  mkGr i (x,_,uses)       = (x,i,mapMaybe (`Map.lookup` nodeMap) uses)--  -- Maps names to node ids.-  nodeMap                 = Map.fromList $ concat $ zipWith mkNode keys ents-  mkNode i (_,defs,_)     = [ (d,i) | d <- defs ]--{- | Combine a bunch of definitions into a single map.  Here we check-that each name is defined only onces. -}-combineMaps :: [Map Name (Located a)] -> InferM (Map Name (Located a))-combineMaps ms = if null bad then return (Map.unions ms)-                             else panic "combineMaps" $ "Multiple definitions"-                                                      : map show bad-  where-  bad = do m <- ms-           duplicates [ a { thing = x } | (x,a) <- Map.toList m ]--{- | Combine a bunch of definitions into a single map.  Here we check-that each name is defined only onces. -}-combine :: [(Name, Located a)] -> InferM (Map Name (Located a))-combine m = if null bad then return (Map.fromList m)-                        else panic "combine" $ "Multiple definitions"-                                             : map show bad-  where-  bad = duplicates [ a { thing = x } | (x,a) <- m ]---- | Identify multiple occurances of something.-duplicates :: Ord a => [Located a] -> [(a,[Range])]-duplicates = mapMaybe multiple-           . groupBy ((==) `on` thing)-           . sortBy (compare `on` thing)-  where-  multiple xs@(x : _ : _) = Just (thing x, map srcRange xs)-  multiple _              = Nothing--
src/Cryptol/TypeCheck/Error.hs view
@@ -139,6 +139,12 @@               | TypeShadowing String Name String               | MissingModTParam (Located Ident)               | MissingModVParam (Located Ident)++              | TemporaryError Doc+                -- ^ This is for errors that don't fit other cateogories.+                -- We should not use it much, and is generally to be used+                -- for transient errors, which are due to incomplete+                -- implementation.                 deriving (Show, Generic, NFData)  -- | When we have multiple errors on the same location, we show only the@@ -147,6 +153,10 @@ errorImportance err =   case err of     BareTypeApp                                      -> 11 -- basically a parse error+    TemporaryError {}                                -> 11+    -- show these as usually means the user used something that doesn't work++     KindMismatch {}                                  -> 10     TyVarWithParams {}                               -> 9     TypeMismatch {}                                  -> 8@@ -236,7 +246,9 @@       MissingModTParam {}  -> err       MissingModVParam {}  -> err +      TemporaryError {} -> err + instance FVS Error where   fvs err =     case err of@@ -269,6 +281,8 @@       MissingModTParam {}  -> Set.empty       MissingModVParam {}  -> Set.empty +      TemporaryError {} -> Set.empty+ instance PP Warning where   ppPrec = ppWithNamesPrec IntMap.empty @@ -310,11 +324,11 @@       KindMismatch mbsrc k1 k2 ->         addTVarsDescsAfter names err $         nested "Incorrect type form." $-         vcat [ "Expected:" <+> cppKind k1-              , "Inferred:" <+> cppKind k2-              , kindMismatchHint k1 k2-              , maybe empty (\src -> "When checking" <+> pp src) mbsrc-              ]+         vcat $+           [ "Expected:" <+> cppKind k1+           , "Inferred:" <+> cppKind k2+           ] ++ kindMismatchHint k1 k2+             ++ maybe [] (\src -> ["When checking" <+> pp src]) mbsrc        TooManyTypeParams extra k ->         addTVarsDescsAfter names err $@@ -341,16 +355,16 @@       RecursiveTypeDecls ts ->         addTVarsDescsAfter names err $         nested "Recursive type declarations:"-               (fsep $ punctuate comma $ map nm ts)+               (commaSep $ map nm ts)        TypeMismatch src t1 t2 ->         addTVarsDescsAfter names err $         nested "Type mismatch:" $-        vcat [ "Expected type:" <+> ppWithNames names t1-             , "Inferred type:" <+> ppWithNames names t2-             , mismatchHint t1 t2-             , "When checking" <+> pp src-             ]+        vcat $+          [ "Expected type:" <+> ppWithNames names t1+          , "Inferred type:" <+> ppWithNames names t2+          ] ++ mismatchHint t1 t2+            ++ ["When checking" <+> pp src]        UnsolvableGoals gs -> explainUnsolvable names gs @@ -380,7 +394,7 @@         nested ("The type" <+> ppWithNames names t <+>                                         "is not sufficiently polymorphic.") $           vcat [ "It cannot depend on quantified variables:" <+>-                          sep (punctuate comma (map (ppWithNames names) xs))+                     (commaSep (map (ppWithNames names) xs))                , "When checking" <+> pp src                ] @@ -412,16 +426,17 @@           $$ "See" <+> pp (srcRange x)        RepeatedTypeParameter x rs ->-        addTVarsDescsAfter names err $-        "Multiple definitions for type parameter `" <.> pp x <.> "`:"-          $$ nest 2 (bullets (map pp rs))+        addTVarsDescsAfter names err $ nest 2 $+          "Multiple definitions for type parameter `" <.> pp x <.> "`:"+          $$ bullets (map pp rs)        AmbiguousSize x t ->         let sizeMsg =                case t of-                 Just t' -> "Must be at least:" <+> ppWithNames names t'-                 Nothing -> empty-         in addTVarsDescsAfter names err ("Ambiguous numeric type:" <+> pp (tvarDesc x) $$ sizeMsg)+                 Just t' -> ["Must be at least:" <+> ppWithNames names t']+                 Nothing -> []+         in addTVarsDescsAfter names err+              (vcat (["Ambiguous numeric type:" <+> pp (tvarDesc x)] ++ sizeMsg))        BareTypeApp ->         "Unexpected bare type application." $$@@ -436,13 +451,11 @@       MissingModVParam x ->         "Missing definition for value parameter" <+> quotes (pp (thing x)) ---+      TemporaryError doc -> doc     where     bullets xs = vcat [ "•" <+> d | d <- xs ] -    nested x y = x $$ nest 2 y+    nested x y = nest 2 (x $$ y)      pl 1 x     = text "1" <+> text x     pl n x     = text (show n) <+> text x <.> text "s"@@ -451,18 +464,18 @@      kindMismatchHint k1 k2 =       case (k1,k2) of-        (KType,KProp) -> "Possibly due to a missing `=>`"-        _ -> empty+        (KType,KProp) -> [text "Possibly due to a missing `=>`"]+        _ -> []      mismatchHint (TRec fs1) (TRec fs2) =-      hint "Missing" missing $$ hint "Unexpected" extra+      hint "Missing" missing ++ hint "Unexpected" extra       where         missing = displayOrder fs1 \\ displayOrder fs2         extra   = displayOrder fs2 \\ displayOrder fs1-        hint _ []  = mempty-        hint s [x] = text s <+> text "field" <+> pp x-        hint s xs  = text s <+> text "fields" <+> commaSep (map pp xs)-    mismatchHint _ _ = mempty+        hint _ []  = []+        hint s [x] = [text s <+> text "field" <+> pp x]+        hint s xs  = [text s <+> text "fields" <+> commaSep (map pp xs)]+    mismatchHint _ _ = []      noUni = Set.null (Set.filter isFreeTV (fvs err)) @@ -478,18 +491,17 @@     explain g =-    let useCtr = "Unsolvable constraint:" $$-                  nest 2 (ppWithNames names g)+    let useCtr = hang "Unsolvable constraint:" 2 (ppWithNames names g)      in     case tNoUser (goal g) of       TCon (PC pc) ts ->         let tys = [ backticks (ppWithNames names t) | t <- ts ]             doc1 : _ = tys-            custom msg = msg $$-                         nest 2 (text "arising from" $$-                                 pp (goalSource g)   $$-                                 text "at" <+> pp (goalRange g))+            custom msg = hang msg+                            2 (text "arising from" $$+                               pp (goalSource g)   $$+                               text "at" <+> pp (goalRange g))         in         case pc of           PEqual      -> useCtr@@ -499,7 +511,7 @@           PPrime      -> useCtr            PHas sel ->-            custom ("Type" <+> doc1 <+> "does not have field" <+> f+            custom ("Type" <+> doc1 </> "does not have field" <+> f                     <+> "of type" <+> (tys !! 1))             where f = case sel of                         P.TupleSel n _ -> int n@@ -507,39 +519,39 @@                         P.ListSel n _ -> int n            PZero  ->-            custom ("Type" <+> doc1 <+> "does not have `zero`")+            custom ("Type" <+> doc1 </> "does not have `zero`")            PLogic ->-            custom ("Type" <+> doc1 <+> "does not support logical operations.")+            custom ("Type" <+> doc1 </> "does not support logical operations.")            PRing ->-            custom ("Type" <+> doc1 <+> "does not support ring operations.")+            custom ("Type" <+> doc1 </> "does not support ring operations.")            PIntegral ->-            custom (doc1 <+> "is not an integral type.")+            custom (doc1 </> "is not an integral type.")            PField ->-            custom ("Type" <+> doc1 <+> "does not support field operations.")+            custom ("Type" <+> doc1 </> "does not support field operations.")            PRound ->-            custom ("Type" <+> doc1 <+> "does not support rounding operations.")+            custom ("Type" <+> doc1 </> "does not support rounding operations.")            PEq ->-            custom ("Type" <+> doc1 <+> "does not support equality.")+            custom ("Type" <+> doc1 </> "does not support equality.")            PCmp        ->-            custom ("Type" <+> doc1 <+> "does not support comparisons.")+            custom ("Type" <+> doc1 </> "does not support comparisons.")            PSignedCmp  ->-            custom ("Type" <+> doc1 <+> "does not support signed comparisons.")+            custom ("Type" <+> doc1 </> "does not support signed comparisons.")            PLiteral ->             let doc2 = tys !! 1-            in custom (doc1 <+> "is not a valid literal of type" <+> doc2)+            in custom (doc1 </> "is not a valid literal of type" <+> doc2)            PLiteralLessThan ->             let doc2 = tys !! 1-            in custom ("Type" <+> doc2 <+> "does not contain all literals below" <+> (doc1 <> "."))+            in custom ("Type" <+> doc2 </> "does not contain all literals below" <+> (doc1 <> "."))            PFLiteral ->             case ts of@@ -547,14 +559,14 @@                  let frac = backticks (ppWithNamesPrec names 4 m <> "/" <>                                        ppWithNamesPrec names 4 n)                      ty   = tys !! 3-                 in custom (frac <+> "is not a valid literal of type" <+> ty)+                 in custom (frac </> "is not a valid literal of type" </> ty)            PValidFloat ->             case ts of-              ~[e,p] ->-                custom ("Unsupported floating point parameters:" $$-                     nest 2 ("exponent =" <+> ppWithNames names e $$-                             "precision =" <+> ppWithNames names p))+              ~[e,p] -> +                custom (hang "Unsupported floating point parameters:"+                           2 ("exponent =" <+> ppWithNames names e $$+                              "precision =" <+> ppWithNames names p))             PAnd        -> useCtr
src/Cryptol/TypeCheck/Infer.hs view
@@ -13,16 +13,18 @@ {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BlockArguments #-} {-# LANGUAGE Safe #-} module Cryptol.TypeCheck.Infer   ( checkE   , checkSigB   , inferModule   , inferBinds-  , inferDs+  , checkTopDecls   ) where +import Data.Text(Text) import qualified Data.Text as Text  @@ -41,7 +43,6 @@                                         checkPrimType,                                         checkParameterConstraints) import           Cryptol.TypeCheck.Instantiate-import           Cryptol.TypeCheck.Depends import           Cryptol.TypeCheck.Subst (listSubst,apSubst,(@@),isEmptySubst) import           Cryptol.Utils.Ident import           Cryptol.Utils.Panic(panic)@@ -50,43 +51,24 @@ import qualified Data.Map as Map import           Data.Map (Map) import qualified Data.Set as Set-import           Data.List(foldl',sortBy)+import           Data.List(foldl',sortBy,groupBy) import           Data.Either(partitionEithers)-import           Data.Maybe(mapMaybe,isJust, fromMaybe)+import           Data.Maybe(isJust, fromMaybe, mapMaybe) import           Data.List(partition)-import           Data.Graph(SCC(..)) import           Data.Ratio(numerator,denominator) import           Data.Traversable(forM)-import           Control.Monad(zipWithM,unless,foldM)+import           Data.Function(on)+import           Control.Monad(zipWithM,unless,foldM,forM_)    inferModule :: P.Module Name -> InferM Module inferModule m =-  inferDs (P.mDecls m) $ \ds1 ->-    do proveModuleTopLevel-       ts <- getTSyns-       nts <- getNewtypes-       ats <- getAbstractTypes-       pTs <- getParamTypes-       pCs <- getParamConstraints-       pFuns <- getParamFuns-       return Module { mName      = thing (P.mName m)-                     , mExports   = P.modExports m-                     , mImports   = map thing (P.mImports m)-                     , mTySyns    = Map.mapMaybe onlyLocal ts-                     , mNewtypes  = Map.mapMaybe onlyLocal nts-                     , mPrimTypes = Map.mapMaybe onlyLocal ats-                     , mParamTypes = pTs-                     , mParamConstraints = pCs-                     , mParamFuns = pFuns-                     , mDecls     = ds1-                     }-  where-  onlyLocal (IsLocal, x)    = Just x-  onlyLocal (IsExternal, _) = Nothing--+  do newModuleScope (thing (P.mName m)) (map thing (P.mImports m))+                                        (P.modExports m)+     checkTopDecls (P.mDecls m)+     proveModuleTopLevel+     endModule  -- | Construct a Prelude primitive in the parsed AST. mkPrim :: String -> InferM (P.Expr Name)@@ -164,9 +146,8 @@     -- Here is an example of why this might be useful:     -- f ` { x = T } where type T = ...     P.EWhere e ds ->-      inferDs ds $ \ds1 -> do e1 <- appTys e ts tGoal-                              return (EWhere e1 ds1)-         -- XXX: Is there a scoping issue here?  I think not, but check.+      do (e1,ds1) <- checkLocalDecls ds (appTys e ts tGoal)+         pure (EWhere e1 ds1)      P.ELocated e r ->       do e' <- inRange r (appTys e ts tGoal)@@ -183,6 +164,8 @@     P.ESel      {} -> mono     P.EList     {} -> mono     P.EFromTo   {} -> mono+    P.EFromToBy {} -> mono+    P.EFromToDownBy {} -> mono     P.EFromToLessThan {} -> mono     P.EInfFrom  {} -> mono     P.EComp     {} -> mono@@ -295,6 +278,58 @@          es' <- mapM checkElem es          return (EList es' a) +    P.EFromToBy isStrict t1 t2 t3 mety+      | isStrict ->+        do l <- curRange+           let fs = [("first",t1),("bound",t2),("stride",t3)] +++                    case mety of+                      Just ety -> [("a",ety)]+                      Nothing  -> []+           prim <- mkPrim "fromToByLessThan"+           let e' = P.EAppT prim+                    [ P.NamedInst P.Named{ name = Located l (packIdent x), value = y }+                    | (x,y) <- fs+                    ]+           checkE e' tGoal+      | otherwise ->+        do l <- curRange+           let fs = [("first",t1),("last",t2),("stride",t3)] +++                    case mety of+                      Just ety -> [("a",ety)]+                      Nothing  -> []+           prim <- mkPrim "fromToBy"+           let e' = P.EAppT prim+                    [ P.NamedInst P.Named{ name = Located l (packIdent x), value = y }+                    | (x,y) <- fs+                    ]+           checkE e' tGoal++    P.EFromToDownBy isStrict t1 t2 t3 mety+      | isStrict ->+        do l <- curRange+           let fs = [("first",t1),("bound",t2),("stride",t3)] +++                    case mety of+                      Just ety -> [("a",ety)]+                      Nothing  -> []+           prim <- mkPrim "fromToDownByGreaterThan"+           let e' = P.EAppT prim+                    [ P.NamedInst P.Named{ name = Located l (packIdent x), value = y }+                    | (x,y) <- fs+                    ]+           checkE e' tGoal+      | otherwise ->+        do l <- curRange+           let fs = [("first",t1),("last",t2),("stride",t3)] +++                    case mety of+                      Just ety -> [("a",ety)]+                      Nothing  -> []+           prim <- mkPrim "fromToDownBy"+           let e' = P.EAppT prim+                    [ P.NamedInst P.Named{ name = Located l (packIdent x), value = y }+                    | (x,y) <- fs+                    ]+           checkE e' tGoal+     P.EFromToLessThan t1 t2 mety ->       do l <- curRange          let fs0 =@@ -349,7 +384,24 @@          ds     <- combineMaps dss          e'     <- withMonoTypes ds (checkE e (WithSource a TypeOfSeqElement))          return (EComp len a e' mss')+      where+      -- the renamer should have made these checks already?+      combineMaps ms = if null bad+                          then return (Map.unions ms)+                          else panic "combineMaps" $ "Multiple definitions"+                                                      : map show bad+          where+          bad = do m <- ms+                   duplicates [ a { thing = x } | (x,a) <- Map.toList m ]+          duplicates = mapMaybe multiple+                     . groupBy ((==) `on` thing)+                     . sortBy (compare `on` thing)+            where+            multiple xs@(x : _ : _) = Just (thing x, map srcRange xs)+            multiple _              = Nothing ++     P.EAppT e fs -> appTys e (map uncheckedTypeArg fs) tGoal      P.EApp e1 e2 ->@@ -366,8 +418,8 @@          return (EIf e1' e2' e3')      P.EWhere e ds ->-      inferDs ds $ \ds1 -> do e1 <- checkE e tGoal-                              return (EWhere e1 ds1)+      do (e1,ds1) <- checkLocalDecls ds (checkE e tGoal)+         pure (EWhere e1 ds1)      P.ETyped e t ->       do tSig <- checkTypeOfKind t KType@@ -406,7 +458,7 @@      -- { _ | fs } ~~>  \r -> { r | fs }     Nothing ->-      do r <- newParamName (packIdent "r")+      do r <- newParamName NSValue (packIdent "r")          let p  = P.PVar Located { srcRange = nameLoc r, thing = r }              fe = P.EFun P.emptyFunDesc [p] (P.EUpd (Just (P.EVar r)) fs)          checkE fe tGoal@@ -432,7 +484,7 @@                 v1 <- checkE v (WithSource (tFun ft ft) src)                 -- XXX: ^ may be used a different src?                 d  <- newHasGoal s (twsType tGoal) ft-                tmp <- newParamName (packIdent "rf")+                tmp <- newParamName NSValue (packIdent "rf")                 let e' = EVar tmp                 pure $ hasDoSet d e' (EApp v1 (hasDoSelect d e'))                        `EWhere`@@ -581,10 +633,11 @@   checkFun ::-  P.FunDesc Name -> [P.Pattern Name] -> P.Expr Name -> TypeWithSource -> InferM Expr+  P.FunDesc Name -> [P.Pattern Name] ->+  P.Expr Name -> TypeWithSource -> InferM Expr checkFun _    [] e tGoal = checkE e tGoal checkFun (P.FunDesc fun offset) ps e tGoal =-  inNewScope $+  inNewScope   do let descs = [ TypeOfArg (ArgDescr fun (Just n)) | n <- [ 1 + offset .. ] ]       (tys,tRes) <- expectFun fun (length ps) tGoal@@ -965,68 +1018,104 @@         , dDoc        = P.bDoc b         } -inferDs :: FromDecl d => [d] -> ([DeclGroup] -> InferM a) -> InferM a-inferDs ds continue = either onErr checkTyDecls =<< orderTyDecls (mapMaybe toTyDecl ds)++--------------------------------------------------------------------------------+--------------------------------------------------------------------------------++checkLocalDecls :: [P.Decl Name] -> InferM a -> InferM (a,[DeclGroup])+checkLocalDecls ds0 k =+  do newLocalScope+     forM_ ds0 \d -> checkDecl False d Nothing+     a <- k+     (ds,_tySyns) <- endLocalScope+     pure (a,ds)++++checkTopDecls :: [P.TopDecl Name] -> InferM ()+checkTopDecls = mapM_ checkTopDecl   where-  onErr err = recordError err >> continue []+  checkTopDecl decl =+    case decl of+      P.Decl tl -> checkDecl True (P.tlValue tl) (thing <$> P.tlDoc tl) -  isTopLevel = isTopDecl (head ds)+      P.TDNewtype tl ->+        do t <- checkNewtype (P.tlValue tl) (thing <$> P.tlDoc tl)+           addNewtype t -  checkTyDecls (AT t mbD : ts) =-    do t1 <- checkParameterType t mbD-       withParamType t1 (checkTyDecls ts)+      P.DPrimType tl ->+        do t <- checkPrimType (P.tlValue tl) (thing <$> P.tlDoc tl)+           addPrimType t -  checkTyDecls (TS t mbD : ts) =-    do t1 <- checkTySyn t mbD-       withTySyn t1 (checkTyDecls ts)+      P.DParameterType ty ->+        do t <- checkParameterType ty (P.ptDoc ty)+           addParamType t -  checkTyDecls (PS t mbD : ts) =-    do t1 <- checkPropSyn t mbD-       withTySyn t1 (checkTyDecls ts)+      P.DParameterConstraint cs ->+        do cs1 <- checkParameterConstraints cs+           addParameterConstraints cs1 -  checkTyDecls (NT t mbD : ts) =-    do t1 <- checkNewtype t mbD-       withNewtype t1 (checkTyDecls ts)+      P.DParameterFun pf ->+        do x <- checkParameterFun pf+           addParamFun x -  checkTyDecls (PT p mbD : ts) =-    do p1 <- checkPrimType p mbD-       withPrimType p1 (checkTyDecls ts)+      P.DModule tl ->+         do let P.NestedModule m = P.tlValue tl+            newSubmoduleScope (thing (P.mName m)) (map thing (P.mImports m))+                                                  (P.modExports m)+            checkTopDecls (P.mDecls m)+            endSubmodule -  -- We checked all type synonyms, now continue with value-level definitions:-  checkTyDecls [] =-    do cs <- checkParameterConstraints (concatMap toParamConstraints ds)-       withParameterConstraints cs $-         do xs <- mapM checkParameterFun (mapMaybe toParamFun ds)-            withParamFuns xs $ checkBinds [] $ orderBinds $ mapMaybe toBind ds+      P.DImport {} -> pure ()+      P.Include {} -> panic "checkTopDecl" [ "Unexpected `inlude`" ]  -  checkParameterFun x =-    do (s,gs) <- checkSchema NoWildCards (P.pfSchema x)-       su <- proveImplication (Just (thing (P.pfName x)))-                              (sVars s) (sProps s) gs-       unless (isEmptySubst su) $-         panic "checkParameterFun" ["Subst not empty??"]-       let n = thing (P.pfName x)-       return ModVParam { mvpName = n-                        , mvpType = s-                        , mvpDoc  = P.pfDoc x-                        , mvpFixity = P.pfFixity x-                        }+checkDecl :: Bool -> P.Decl Name -> Maybe Text -> InferM ()+checkDecl isTopLevel d mbDoc =+  case d of -  checkBinds decls (CyclicSCC bs : more) =-     do bs1 <- inferBinds isTopLevel True bs-        foldr (\b m -> withVar (dName b) (dSignature b) m)-              (checkBinds (Recursive bs1 : decls) more)-              bs1+    P.DBind c ->+      do ~[b] <- inferBinds isTopLevel False [c]+         addDecls (NonRecursive b) -  checkBinds decls (AcyclicSCC c : more) =-    do ~[b] <- inferBinds isTopLevel False [c]-       withVar (dName b) (dSignature b) $-         checkBinds (NonRecursive b : decls) more+    P.DRec bs ->+      do bs1 <- inferBinds isTopLevel True bs+         addDecls (Recursive bs1) -  -- We are done with all value-level definitions.-  -- Now continue with anything that's in scope of the declarations.-  checkBinds decls [] = continue (reverse decls)+    P.DType t ->+      do t1 <- checkTySyn t mbDoc+         addTySyn t1++    P.DProp t ->+      do t1 <- checkPropSyn t mbDoc+         addTySyn t1++    P.DLocated d' r -> inRange r (checkDecl isTopLevel d' mbDoc)++    P.DSignature {} -> bad "DSignature"+    P.DFixity {}    -> bad "DFixity"+    P.DPragma {}    -> bad "DPragma"+    P.DPatBind {}   -> bad "DPatBind"++  where+  bad x = panic "checkDecl" [x]+++checkParameterFun :: P.ParameterFun Name -> InferM ModVParam+checkParameterFun x =+  do (s,gs) <- checkSchema NoWildCards (P.pfSchema x)+     su <- proveImplication (Just (thing (P.pfName x)))+                            (sVars s) (sProps s) gs+     unless (isEmptySubst su) $+       panic "checkParameterFun" ["Subst not empty??"]+     let n = thing (P.pfName x)+     return ModVParam { mvpName = n+                      , mvpType = s+                      , mvpDoc  = P.pfDoc x+                      , mvpFixity = P.pfFixity x+                      }++  tcPanic :: String -> [String] -> a tcPanic l msg = panic ("[TypeCheck] " ++ l) msg
src/Cryptol/TypeCheck/InferTypes.hs view
@@ -48,6 +48,18 @@   } deriving (Show, Generic, NFData)  +-- | A default configuration for using Z3, where+--   the solver prelude is expected to be found+--   in the given search path.+defaultSolverConfig :: [FilePath] -> SolverConfig+defaultSolverConfig searchPath =+  SolverConfig+  { solverPath = "z3"+  , solverArgs = [ "-smt2", "-in" ]+  , solverVerbose = 0+  , solverPreludePath = searchPath+  }+ -- | The types of variables in the environment. data VarType = ExtVar Schema                -- ^ Known type@@ -303,24 +315,25 @@ addTVarsDescsAfter :: FVS t => NameMap -> t -> Doc -> Doc addTVarsDescsAfter nm t d   | Set.null vs = d+-- TODO? use `hang` here instead to indent things after "where"   | otherwise   = d $$ text "where" $$ vcat (map desc (Set.toList vs))   where   vs     = fvs t   desc v = ppWithNames nm v <+> text "is" <+> pp (tvInfo v)  addTVarsDescsBefore :: FVS t => NameMap -> t -> Doc -> Doc-addTVarsDescsBefore nm t d = frontMsg $$ d $$ backMsg+addTVarsDescsBefore nm t d = vcat (frontMsg ++ [d] ++ backMsg)   where   (vs1,vs2)  = Set.partition isFreeTV (fvs t) -  frontMsg | null vs1  = empty-           | otherwise = "Failed to infer the following types:"-                         $$ nest 2 (vcat (map desc1 (Set.toList vs1)))+  frontMsg | null vs1  = []+           | otherwise = [hang "Failed to infer the following types:"+                             2 (vcat (map desc1 (Set.toList vs1)))]   desc1 v    = "•" <+> ppWithNames nm v <.> comma <+> pp (tvInfo v) -  backMsg  | null vs2  = empty-           | otherwise = "where"-                         $$ nest 2 (vcat (map desc2 (Set.toList vs2)))+  backMsg  | null vs2  = []+           | otherwise = [hang "where"+                             2 (vcat (map desc2 (Set.toList vs2)))]   desc2 v    = ppWithNames nm v <+> text "is" <+> pp (tvInfo v)  @@ -351,7 +364,7 @@       | prim == "infFromThen"  -> "infinite enumeration (with step)"       | prim == "fromTo"       -> "finite enumeration"       | prim == "fromThenTo"   -> "finite enumeration"-    _                                    -> "expression" <+> pp expr+    _                          -> "expression" <+> pp expr   where   isPrelPrim x = do PrimIdent p i <- asPrim x                     guard (p == preludeName)@@ -359,19 +372,21 @@  instance PP (WithNames Goal) where   ppPrec _ (WithNames g names) =-      (ppWithNames names (goal g)) $$-               nest 2 (text "arising from" $$-                       pp (goalSource g)   $$-                       text "at" <+> pp (goalRange g))+      hang (ppWithNames names (goal g))+         2 (text "arising from" $$+            pp (goalSource g)   $$+            text "at" <+> pp (goalRange g))  instance PP (WithNames DelayedCt) where   ppPrec _ (WithNames d names) =-    sig $$ "we need to show that" $$-    nest 2 (vcat [ vars, asmps, "the following constraints hold:"-                 , nest 2 $ vcat-                          $ bullets-                          $ map (ppWithNames ns1)-                          $ dctGoals d ])+    sig $$+    hang "we need to show that"+       2 (vcat ( vars ++ asmps ++ +               [ hang "the following constraints hold:"+                    2 (vcat+                       $ bullets+                       $ map (ppWithNames ns1)+                       $ dctGoals d )]))     where     bullets xs = [ "•" <+> x | x <- xs ] @@ -382,12 +397,11 @@      name  = dctSource d     vars = case dctForall d of-             [] -> empty-             xs -> "for any type" <+>-                      fsep (punctuate comma (map (ppWithNames ns1 ) xs))+             [] -> []+             xs -> ["for any type" <+> commaSep (map (ppWithNames ns1) xs)]     asmps = case dctAsmps d of-              [] -> empty-              xs -> "assuming" $$-                    nest 2 (vcat (bullets (map (ppWithNames ns1) xs)))+              [] -> []+              xs -> [hang "assuming"+                       2 (vcat (bullets (map (ppWithNames ns1) xs)))]      ns1 = addTNames (dctForall d) names
+ src/Cryptol/TypeCheck/Interface.hs view
@@ -0,0 +1,73 @@+module Cryptol.TypeCheck.Interface where++import qualified Data.Map as Map++import Cryptol.Utils.Ident(Namespace(..))+import Cryptol.ModuleSystem.Interface+import Cryptol.TypeCheck.AST+++mkIfaceDecl :: Decl -> IfaceDecl+mkIfaceDecl d = IfaceDecl+  { ifDeclName    = dName d+  , ifDeclSig     = dSignature d+  , ifDeclPragmas = dPragmas d+  , ifDeclInfix   = dInfix d+  , ifDeclFixity  = dFixity d+  , ifDeclDoc     = dDoc d+  }++-- | Generate an Iface from a typechecked module.+genIface :: ModuleG mname -> IfaceG mname+genIface m = Iface+  { ifModName = mName m++  , ifPublic      = IfaceDecls+    { ifTySyns    = tsPub+    , ifNewtypes  = ntPub+    , ifAbstractTypes = atPub+    , ifDecls     = dPub+    , ifModules   = mPub+    }++  , ifPrivate = IfaceDecls+    { ifTySyns    = tsPriv+    , ifNewtypes  = ntPriv+    , ifAbstractTypes = atPriv+    , ifDecls     = dPriv+    , ifModules   = mPriv+    }++  , ifParams = IfaceParams+    { ifParamTypes = mParamTypes m+    , ifParamConstraints = mParamConstraints m+    , ifParamFuns  = mParamFuns m+    }+  }+  where++  (tsPub,tsPriv) =+      Map.partitionWithKey (\ qn _ -> qn `isExportedType` mExports m )+                          (mTySyns m)+  (ntPub,ntPriv) =+      Map.partitionWithKey (\ qn _ -> qn `isExportedType` mExports m )+                           (mNewtypes m)++  (atPub,atPriv) =+    Map.partitionWithKey (\qn _ -> qn `isExportedType` mExports m)+                         (mPrimTypes m)++  (dPub,dPriv) =+      Map.partitionWithKey (\ qn _ -> qn `isExportedBind` mExports m)+      $ Map.fromList [ (qn,mkIfaceDecl d) | dg <- mDecls m+                                          , d  <- groupDecls dg+                                          , let qn = dName d+                                          ]++  (mPub,mPriv) =+      Map.partitionWithKey (\ qn _ -> isExported NSModule qn (mExports m))+      $ mSubModules m++++
src/Cryptol/TypeCheck/Monad.hs view
@@ -13,11 +13,30 @@ {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE BlockArguments #-} module Cryptol.TypeCheck.Monad   ( module Cryptol.TypeCheck.Monad   , module Cryptol.TypeCheck.InferTypes   ) where +import qualified Control.Applicative as A+import qualified Control.Monad.Fail as Fail+import           Control.Monad.Fix(MonadFix(..))+import qualified Data.Map as Map+import qualified Data.Set as Set+import           Data.Map (Map)+import           Data.Set (Set)+import           Data.List(find, foldl')+import           Data.List.NonEmpty(NonEmpty((:|)))+import           Data.Semigroup(sconcat)+import           Data.Maybe(mapMaybe,fromMaybe)+import           Data.IORef++import           GHC.Generics (Generic)+import           Control.DeepSeq++import           MonadLib hiding (mapM)+ import           Cryptol.ModuleSystem.Name                     (FreshM(..),Supply,mkParameter                     , nameInfo, NameInfo(..),NameSource(..))@@ -25,6 +44,7 @@ import qualified Cryptol.Parser.AST as P import           Cryptol.TypeCheck.AST import           Cryptol.TypeCheck.Subst+import           Cryptol.TypeCheck.Interface(genIface) import           Cryptol.TypeCheck.Unify(mgu, runResult, UnificationError(..)) import           Cryptol.TypeCheck.InferTypes import           Cryptol.TypeCheck.Error( Warning(..),Error(..)@@ -34,26 +54,9 @@ import qualified Cryptol.TypeCheck.Solver.SMT as SMT import           Cryptol.TypeCheck.PP(NameMap) import           Cryptol.Utils.PP(pp, (<+>), text,commaSep,brackets)-import           Cryptol.Utils.Ident(Ident)+import           Cryptol.Utils.Ident(Ident,Namespace(..)) import           Cryptol.Utils.Panic(panic) -import qualified Control.Applicative as A-import qualified Control.Monad.Fail as Fail-import           Control.Monad.Fix(MonadFix(..))-import qualified Data.Map as Map-import qualified Data.Set as Set-import           Data.Map (Map)-import           Data.Set (Set)-import           Data.List(find, foldl')-import           Data.Maybe(mapMaybe,fromMaybe)-import           MonadLib hiding (mapM)--import           Data.IORef---import GHC.Generics (Generic)-import Control.DeepSeq- -- | Information needed for type inference. data InferInput = InferInput   { inpRange     :: Range             -- ^ Location of program source@@ -76,7 +79,6 @@    , inpCallStacks :: Bool             -- ^ Are we tracking call stacks? -  , inpSolverConfig :: SolverConfig   -- ^ Options for the constraint solver   , inpSearchPath :: [FilePath]     -- ^ Where to look for Cryptol theory file. @@ -119,16 +121,21 @@ runInferM :: TVars a => InferInput -> InferM a -> IO (InferOutput a) runInferM info (IM m) =   do counter <- newIORef 0+     let env = Map.map ExtVar (inpVars info)+            <> Map.map (ExtVar . newtypeConType) (inpNewtypes info)+      rec ro <- return RO { iRange     = inpRange info-                         , iVars          = Map.map ExtVar (inpVars info)-                         , iTVars         = []-                         , iTSyns         = fmap mkExternal (inpTSyns info)-                         , iNewtypes      = fmap mkExternal (inpNewtypes info)-                         , iAbstractTypes = mkExternal <$> inpAbstractTypes info-                         , iParamTypes    = inpParamTypes info-                         , iParamFuns     = inpParamFuns info-                         , iParamConstraints = inpParamConstraints info+                         , iVars      = env+                         , iExtScope = (emptyModule ExternalScope)+                             { mTySyns           = inpTSyns info+                             , mNewtypes         = inpNewtypes info+                             , mPrimTypes        = inpAbstractTypes info+                             , mParamTypes       = inpParamTypes info+                             , mParamFuns        = inpParamFuns info+                             , mParamConstraints = inpParamConstraints info+                             } +                         , iTVars         = []                          , iSolvedHasLazy = iSolvedHas finalRW     -- RECURSION                          , iMonoBinds     = inpMonoBinds info                          , iCallStacks    = inpCallStacks info@@ -168,7 +175,6 @@     in pure (InferFailed (computeFreeVarNames ws es1) ws es1)  -  mkExternal x = (IsExternal, x)   rw = RW { iErrors     = []           , iWarnings   = []           , iSubst      = emptySubst@@ -181,6 +187,9 @@           , iSolvedHas  = Map.empty            , iSupply     = inpSupply info++          , iScope      = []+          , iBindTypes  = mempty           }  @@ -191,38 +200,28 @@  newtype InferM a = IM { unIM :: ReaderT RO (StateT RW IO) a } -data DefLoc = IsLocal | IsExternal +data ScopeName = ExternalScope+               | LocalScope+               | SubModule Name+               | MTopModule P.ModName+ -- | Read-only component of the monad. data RO = RO-  { iRange    :: Range                  -- ^ Source code being analysed-  , iVars     :: Map Name VarType      -- ^ Type of variable that are in scope+  { iRange    :: Range       -- ^ Source code being analysed+  , iVars     :: Map Name VarType+    -- ^ Type of variable that are in scope+    -- These are only parameters vars that are in recursive component we+    -- are checking at the moment.  If a var is not there, keep looking in+    -- the 'iScope' -  {- NOTE: We assume no shadowing between these two, so it does not matter-  where we look first. Similarly, we assume no shadowing with-  the existential type variable (in RW).  See 'checkTShadowing'. -} -  , iTVars    :: [TParam]                  -- ^ Type variable that are in scope-  , iTSyns    :: Map Name (DefLoc, TySyn) -- ^ Type synonyms that are in scope-  , iNewtypes :: Map Name (DefLoc, Newtype)-   -- ^ Newtype declarations in scope-   ---   -- NOTE: type synonyms take precedence over newtype.  The reason is-   -- that we can define local type synonyms, but not local newtypes.-   -- So, either a type-synonym shadows a newtype, or it was declared-   -- at the top-level, but then there can't be a newtype with the-   -- same name (this should be caught by the renamer).-  , iAbstractTypes :: Map Name (DefLoc, AbstractType)--  , iParamTypes :: Map Name ModTParam-    -- ^ Parameter types--  , iParamConstraints :: [Located Prop]-    -- ^ Constraints on the type parameters--  , iParamFuns :: Map Name ModVParam-    -- ^ Parameter functions+  , iTVars    :: [TParam]    -- ^ Type variable that are in scope +  , iExtScope :: ModuleG ScopeName+    -- ^ These are things we know about, but are not part of the+    -- modules we are currently constructing.+    -- XXX: this sould probably be an interface    , iSolvedHasLazy :: Map Int HasGoalSln     -- ^ NOTE: This field is lazy in an important way!  It is the@@ -278,9 +277,17 @@     {- ^ Tuple/record projection constraints.  The 'Int' is the "name"          of the constraint, used so that we can name its solution properly. -} +  , iScope :: ![ModuleG ScopeName]+    -- ^ Nested scopes we are currently checking, most nested first.++  , iBindTypes :: !(Map Name Schema)+    -- ^ Types of variables that we know about.  We don't worry about scoping+    -- here because we assume the bindings all have different names.+   , iSupply :: !Supply   } + instance Functor InferM where   fmap f (IM m) = IM (fmap f m) @@ -452,10 +459,10 @@ --------------------------------------------------------------------------------  -- | Generate a fresh variable name to be used in a local binding.-newParamName :: Ident -> InferM Name-newParamName x =+newParamName :: Namespace -> Ident -> InferM Name+newParamName ns x =   do r <- curRange-     liftSupply (mkParameter x r)+     liftSupply (mkParameter ns x r)  newName :: (NameSeeds -> (a , NameSeeds)) -> InferM a newName upd = IM $ sets $ \s -> let (x,seeds) = upd (iNameSeeds s)@@ -634,17 +641,13 @@ lookupVar x =   do mb <- IM $ asks $ Map.lookup x . iVars      case mb of-       Just t  -> return t+       Just a  -> pure a        Nothing ->-         do mbNT <- lookupNewtype x-            case mbNT of-              Just nt -> return (ExtVar (newtypeConType nt))-              Nothing ->-                do mbParamFun <- lookupParamFun x-                   case mbParamFun of-                     Just pf -> return (ExtVar (mvpType pf))-                     Nothing -> panic "lookupVar" [ "Undefined type variable"-                                                  , show x]+         do mb1 <- Map.lookup x . iBindTypes <$> IM get+            case mb1 of+              Just a -> pure (ExtVar a)+              Nothing -> panic "lookupVar" [ "Undefined vairable"+                                           , show x ]  -- | Lookup a type variable.  Return `Nothing` if there is no such variable -- in scope, in which case we must be dealing with a type constant.@@ -654,14 +657,14 @@  -- | Lookup the definition of a type synonym. lookupTSyn :: Name -> InferM (Maybe TySyn)-lookupTSyn x = fmap (fmap snd . Map.lookup x) getTSyns+lookupTSyn x = Map.lookup x <$> getTSyns  -- | Lookup the definition of a newtype lookupNewtype :: Name -> InferM (Maybe Newtype)-lookupNewtype x = fmap (fmap snd . Map.lookup x) getNewtypes+lookupNewtype x = Map.lookup x <$> getNewtypes  lookupAbstractType :: Name -> InferM (Maybe AbstractType)-lookupAbstractType x = fmap (fmap snd . Map.lookup x) getAbstractTypes+lookupAbstractType x = Map.lookup x <$> getAbstractTypes  -- | Lookup the kind of a parameter type lookupParamType :: Name -> InferM (Maybe ModTParam)@@ -693,28 +696,28 @@   -- | Returns the type synonyms that are currently in scope.-getTSyns :: InferM (Map Name (DefLoc,TySyn))-getTSyns = IM $ asks iTSyns+getTSyns :: InferM (Map Name TySyn)+getTSyns = getScope mTySyns  -- | Returns the newtype declarations that are in scope.-getNewtypes :: InferM (Map Name (DefLoc,Newtype))-getNewtypes = IM $ asks iNewtypes+getNewtypes :: InferM (Map Name Newtype)+getNewtypes = getScope mNewtypes  -- | Returns the abstract type declarations that are in scope.-getAbstractTypes :: InferM (Map Name (DefLoc,AbstractType))-getAbstractTypes = IM $ asks iAbstractTypes+getAbstractTypes :: InferM (Map Name AbstractType)+getAbstractTypes = getScope mPrimTypes  -- | Returns the parameter functions declarations getParamFuns :: InferM (Map Name ModVParam)-getParamFuns = IM $ asks iParamFuns+getParamFuns = getScope mParamFuns  -- | Returns the abstract function declarations getParamTypes :: InferM (Map Name ModTParam)-getParamTypes = IM $ asks iParamTypes+getParamTypes = getScope mParamTypes  -- | Constraints on the module's parameters. getParamConstraints :: InferM [Located Prop]-getParamConstraints = IM $ asks iParamConstraints+getParamConstraints = getScope mParamConstraints  -- | Get the set of bound type variables that are in scope. getTVars :: InferM (Set Name)@@ -724,8 +727,8 @@ getBoundInScope :: InferM (Set TParam) getBoundInScope =   do ro <- IM ask-     let params = Set.fromList (map mtpParam (Map.elems (iParamTypes ro)))-         bound  = Set.fromList (iTVars ro)+     params <- Set.fromList . map mtpParam . Map.elems <$> getParamTypes+     let bound  = Set.fromList (iTVars ro)      return $! Set.union params bound  -- | Retrieve the value of the `mono-binds` option.@@ -740,12 +743,14 @@ need to worry about where we lookup things (i.e., in the variable or type synonym environment. -} +-- XXX: this should be done in renamer checkTShadowing :: String -> Name -> InferM () checkTShadowing this new =-  do ro <- IM ask+  do tsyns <- getTSyns+     ro <- IM ask      rw <- IM get      let shadowed =-           do _ <- Map.lookup new (iTSyns ro)+           do _ <- Map.lookup new tsyns               return "type synonym"            `mplus`            do guard (new `elem` mapMaybe tpName (iTVars ro))@@ -760,7 +765,6 @@           recordError (TypeShadowing this new that)  - -- | The sub-computation is performed with the given type parameter in scope. withTParam :: TParam -> InferM a -> InferM a withTParam p (IM m) =@@ -772,32 +776,148 @@ withTParams :: [TParam] -> InferM a -> InferM a withTParams ps m = foldr withTParam m ps ++-- | Execute the given computation in a new top scope.+-- The sub-computation would typically be validating a module.+newScope :: ScopeName -> InferM ()+newScope nm = IM $ sets_ \rw -> rw { iScope = emptyModule nm : iScope rw }++newLocalScope :: InferM ()+newLocalScope = newScope LocalScope++newSubmoduleScope :: Name -> [Import] -> ExportSpec Name -> InferM ()+newSubmoduleScope x is e =+  do newScope (SubModule x)+     updScope \m -> m { mImports = is, mExports = e }++newModuleScope :: P.ModName -> [Import] -> ExportSpec Name -> InferM ()+newModuleScope x is e =+  do newScope (MTopModule x)+     updScope \m -> m { mImports = is, mExports = e }++-- | Update the current scope (first in the list). Assumes there is one.+updScope :: (ModuleG ScopeName -> ModuleG ScopeName) -> InferM ()+updScope f = IM $ sets_ \rw -> rw { iScope = upd (iScope rw) }+  where+  upd r =+    case r of+      []       -> panic "updTopScope" [ "No top scope" ]+      s : more -> f s : more++endLocalScope :: InferM ([DeclGroup], Map Name TySyn)+endLocalScope =+  IM $ sets \rw ->+       case iScope rw of+         x : xs | LocalScope <- mName x ->+                    ( (reverse (mDecls x), mTySyns x), rw { iScope = xs })++         _ -> panic "endLocalScope" ["Missing local scope"]++endSubmodule :: InferM ()+endSubmodule =+  IM $ sets_ \rw ->+       case iScope rw of+         x@Module { mName = SubModule m } : y : more -> rw { iScope = z : more }+           where+           x1    = x { mName = m }+           iface = genIface x1+           me = if isParametrizedModule x1 then Map.singleton m x1 else mempty+           z = y { mImports     = mImports x ++ mImports y -- just for deps+                 , mSubModules  = Map.insert m iface (mSubModules y)++                 , mTySyns      = mTySyns x <> mTySyns y+                 , mNewtypes    = mNewtypes x <> mNewtypes y+                 , mPrimTypes   = mPrimTypes x <> mPrimTypes y+                 , mDecls       = mDecls x <> mDecls y+                 , mFunctors    = me <> mFunctors x <> mFunctors y+                 }++         _ -> panic "endSubmodule" [ "Not a submodule" ]+++endModule :: InferM Module+endModule =+  IM $ sets \rw ->+    case iScope rw of+      [ x ] | MTopModule m <- mName x ->+        ( x { mName = m, mDecls = reverse (mDecls x) }+        , rw { iScope = [] }+        )+      _ -> panic "endModule" [ "Not a single top module" ]++endModuleInstance :: InferM ()+endModuleInstance =+  IM $ sets_ \rw ->+    case iScope rw of+      [ x ] | MTopModule _ <- mName x -> rw { iScope = [] }+      _ -> panic "endModuleInstance" [ "Not single top module" ]+++-- | Get an environment combining all nested scopes.+getScope :: Semigroup a => (ModuleG ScopeName -> a) -> InferM a+getScope f =+  do ro <- IM ask+     rw <- IM get+     pure (sconcat (f (iExtScope ro) :| map f (iScope rw)))++addDecls :: DeclGroup -> InferM ()+addDecls ds =+  do updScope \r -> r { mDecls = ds : mDecls r }+     IM $ sets_ \rw -> rw { iBindTypes = new rw }+  where+  add d   = Map.insert (dName d) (dSignature d)+  new rw  = foldr add (iBindTypes rw) (groupDecls ds)+ -- | The sub-computation is performed with the given type-synonym in scope.-withTySyn :: TySyn -> InferM a -> InferM a-withTySyn t (IM m) =+addTySyn :: TySyn -> InferM ()+addTySyn t =   do let x = tsName t      checkTShadowing "synonym" x-     IM $ mapReader (\r -> r { iTSyns = Map.insert x (IsLocal,t) (iTSyns r) }) m+     updScope \r -> r { mTySyns = Map.insert x t (mTySyns r) } -withNewtype :: Newtype -> InferM a -> InferM a-withNewtype t (IM m) =-  IM $ mapReader-        (\r -> r { iNewtypes = Map.insert (ntName t) (IsLocal,t)-                                                     (iNewtypes r) }) m+addNewtype :: Newtype -> InferM ()+addNewtype t =+  do updScope \r -> r { mNewtypes = Map.insert (ntName t) t (mNewtypes r) }+     IM $ sets_ \rw -> rw { iBindTypes = Map.insert (ntName t)+                                                    (newtypeConType t)+                                                    (iBindTypes rw) } -withPrimType :: AbstractType -> InferM a -> InferM a-withPrimType t (IM m) =-  IM $ mapReader-      (\r -> r { iAbstractTypes = Map.insert (atName t) (IsLocal,t)-                                                        (iAbstractTypes r) }) m+addPrimType :: AbstractType -> InferM ()+addPrimType t =+  updScope \r ->+    r { mPrimTypes = Map.insert (atName t) t (mPrimTypes r) } +addParamType :: ModTParam -> InferM ()+addParamType a =+  updScope \r -> r { mParamTypes = Map.insert (mtpName a) a (mParamTypes r) } -withParamType :: ModTParam -> InferM a -> InferM a-withParamType a (IM m) =-  IM $ mapReader-        (\r -> r { iParamTypes = Map.insert (mtpName a) a (iParamTypes r) })-        m+-- | The sub-computation is performed with the given abstract function in scope.+addParamFun :: ModVParam -> InferM ()+addParamFun x =+  do updScope \r -> r { mParamFuns = Map.insert (mvpName x) x (mParamFuns r) }+     IM $ sets_ \rw -> rw { iBindTypes = Map.insert (mvpName x) (mvpType x)+                                                    (iBindTypes rw) } +-- | Add some assumptions for an entire module+addParameterConstraints :: [Located Prop] -> InferM ()+addParameterConstraints ps =+  updScope \r -> r { mParamConstraints = ps ++ mParamConstraints r }+++++-- | Perform the given computation in a new scope (i.e., the subcomputation+-- may use existential type variables).  This is a different kind of scope+-- from the nested modules one.+inNewScope :: InferM a -> InferM a+inNewScope m =+  do curScopes <- iExistTVars <$> IM get+     IM $ sets_ $ \s -> s { iExistTVars = Map.empty : curScopes }+     a <- m+     IM $ sets_ $ \s -> s { iExistTVars = curScopes }+     return a++ -- | The sub-computation is performed with the given variable in scope. withVarType :: Name -> VarType -> InferM a -> InferM a withVarType x s (IM m) =@@ -809,19 +929,6 @@ withVar :: Name -> Schema -> InferM a -> InferM a withVar x s = withVarType x (ExtVar s) --- | The sub-computation is performed with the given abstract function in scope.-withParamFuns :: [ModVParam] -> InferM a -> InferM a-withParamFuns xs (IM m) =-  IM $ mapReader (\r -> r { iParamFuns = foldr add (iParamFuns r) xs }) m-  where-  add x = Map.insert (mvpName x) x---- | Add some assumptions for an entire module-withParameterConstraints :: [Located Prop] -> InferM a -> InferM a-withParameterConstraints ps (IM m) =-  IM $ mapReader (\r -> r { iParamConstraints = ps ++ iParamConstraints r }) m-- -- | The sub-computation is performed with the given variables in scope. withMonoType :: (Name,Located Type) -> InferM a -> InferM a withMonoType (x,lt) = withVar x (Forall [] [] (thing lt))@@ -829,25 +936,6 @@ -- | The sub-computation is performed with the given variables in scope. withMonoTypes :: Map Name (Located Type) -> InferM a -> InferM a withMonoTypes xs m = foldr withMonoType m (Map.toList xs)---- | The sub-computation is performed with the given type synonyms--- and variables in scope.-withDecls :: ([TySyn], Map Name Schema) -> InferM a -> InferM a-withDecls (ts,vs) m = foldr withTySyn (foldr add m (Map.toList vs)) ts-  where-  add (x,t) = withVar x t---- | Perform the given computation in a new scope (i.e., the subcomputation--- may use existential type variables).-inNewScope :: InferM a -> InferM a-inNewScope m =-  do curScopes <- iExistTVars <$> IM get-     IM $ sets_ $ \s -> s { iExistTVars = Map.empty : curScopes }-     a <- m-     IM $ sets_ $ \s -> s { iExistTVars = curScopes }-     return a--  -------------------------------------------------------------------------------- -- Kind checking
src/Cryptol/TypeCheck/Parseable.hs view
@@ -17,18 +17,30 @@   , ShowParseable(..)   ) where +import Data.Void+import Prettyprinter+ import Cryptol.TypeCheck.AST import Cryptol.Utils.Ident (Ident,unpackIdent) import Cryptol.Utils.RecordMap (canonicalFields) import Cryptol.Parser.AST ( Located(..)) import Cryptol.ModuleSystem.Name-import Text.PrettyPrint hiding ((<>))-import qualified Text.PrettyPrint as PP ((<>)) ++infixl 5 $$+($$) :: Doc a -> Doc a -> Doc a+($$) x y = sep [x, y]++text :: String -> Doc a+text = pretty++int :: Int -> Doc a+int = pretty+ -- ShowParseable prints out a cryptol program in a way that it's parseable by Coq (and likely other things) -- Used mainly for reasoning about the semantics of cryptol programs in Coq (https://github.com/GaloisInc/cryptol-semantics) class ShowParseable t where-  showParseable :: t -> Doc+  showParseable :: t -> Doc Void  instance ShowParseable Expr where   showParseable (ELocated _ e) = showParseable e -- TODO? emit range information@@ -53,7 +65,7 @@   showParseable (EProofApp e) = showParseable e --"(EProofApp " ++ showParseable e ++ ")"  instance (ShowParseable a, ShowParseable b) => ShowParseable (a,b) where-  showParseable (x,y) = parens (showParseable x PP.<> comma PP.<> showParseable y)+  showParseable (x,y) = parens (showParseable x <> comma <> showParseable y)  instance ShowParseable Int where   showParseable i = int i@@ -105,11 +117,11 @@   showParseable l = showParseable (thing l)  instance ShowParseable TParam where-  showParseable tp = parens (text (show (tpUnique tp)) PP.<> comma PP.<> maybeNameDoc (tpName tp))+  showParseable tp = parens (text (show (tpUnique tp)) <> comma <> maybeNameDoc (tpName tp)) -maybeNameDoc :: Maybe Name -> Doc-maybeNameDoc Nothing = doubleQuotes empty+maybeNameDoc :: Maybe Name -> Doc Void+maybeNameDoc Nothing = dquotes mempty maybeNameDoc (Just n) = showParseable (nameIdent n)  instance ShowParseable Name where-  showParseable n = parens (text (show (nameUnique n)) PP.<> comma PP.<> showParseable (nameIdent n))+  showParseable n = parens (text (show (nameUnique n)) <> comma <> showParseable (nameIdent n))
src/Cryptol/TypeCheck/SimpType.hs view
@@ -182,7 +182,6 @@ tCeilDiv :: Type -> Type -> Type tCeilDiv x y   | Just t <- tOp TCCeilDiv (op2 nCeilDiv) [x,y] = t-  | tIsInf x = bad   | tIsInf y = bad   | Just 0 <- tIsNum y = bad   | otherwise = tf2 TCCeilDiv x y@@ -191,7 +190,6 @@ tCeilMod :: Type -> Type -> Type tCeilMod x y   | Just t <- tOp TCCeilMod (op2 nCeilMod) [x,y] = t-  | tIsInf x = bad   | tIsInf y = bad   | Just 0 <- tIsNum x = bad   | otherwise = tf2 TCCeilMod x y@@ -264,6 +262,12 @@   maxK (Nat 0) t = t   maxK (Nat k) t +    -- max 1 t ~> t,   if t = a ^ b && a >= 1+    | k == 1+    , TCon (TF TCExp) [a,_] <- t'+    , Just base <- tIsNat' a+    , base >= Nat 1 = t+     | TCon (TF TCAdd) [a,b] <- t'     , Just n <- tIsNum a = if k <= n                              then t@@ -285,6 +289,13 @@ tWidth :: Type -> Type tWidth x   | Just t <- tOp TCWidth (total (op1 nWidth)) [x] = t++  -- width (2^n - 1) = n+  | TCon (TF TCSub) [a,b] <- tNoUser x+  , Just 1 <- tIsNum b+  , TCon (TF TCExp) [p,q] <- tNoUser a+  , Just 2 <- tIsNum p = q+   | otherwise = tf1 TCWidth x  tLenFromThenTo :: Type -> Type -> Type -> Type
src/Cryptol/TypeCheck/SimpleSolver.hs view
@@ -30,8 +30,7 @@     SolvedIf ps -> dbg msg $ pAnd (map (simplify ctxt) ps)      where msg = case ps of                     [] -> text "solved:" <+> pp p-                    _  -> pp p <+> text "~~~>" <+>-                          vcat (punctuate comma (map pp ps))+                    _  -> pp p <+> text "~~~>" <+> commaSep (map pp ps)    where   dbg msg x
src/Cryptol/TypeCheck/Solver/InfNat.hs view
@@ -122,23 +122,22 @@ nMod (Nat x) Inf      = Just (Nat x)          -- inf * 0 + x = 0 + x  -- | @nCeilDiv msgLen blockSize@ computes the least @n@ such that--- @msgLen <= blockSize * n@. It is undefined when @blockSize = 0@.--- It is also undefined when either input is infinite; perhaps this--- could be relaxed later.+-- @msgLen <= blockSize * n@. It is undefined when @blockSize = 0@,+-- or when @blockSize = inf@. @inf@ divided by any positive+-- finite value is @inf@. nCeilDiv :: Nat' -> Nat' -> Maybe Nat'+nCeilDiv _       Inf      = Nothing nCeilDiv _       (Nat 0)  = Nothing-nCeilDiv Inf     _        = Nothing-nCeilDiv (Nat _) Inf      = Nothing+nCeilDiv Inf     (Nat _)  = Just Inf nCeilDiv (Nat x) (Nat y)  = Just (Nat (- div (- x) y))  -- | @nCeilMod msgLen blockSize@ computes the least @k@ such that--- @blockSize@ divides @msgLen + k@. It is undefined when @blockSize = 0@.--- It is also undefined when either input is infinite; perhaps this--- could be relaxed later.+-- @blockSize@ divides @msgLen + k@. It is undefined when @blockSize = 0@+-- or @blockSize = inf@.  @inf@ modulus any positive finite value is @0@. nCeilMod :: Nat' -> Nat' -> Maybe Nat'+nCeilMod _       Inf      = Nothing nCeilMod _       (Nat 0)  = Nothing-nCeilMod Inf     _        = Nothing-nCeilMod (Nat _) Inf      = Nothing+nCeilMod Inf     (Nat _)  = Just (Nat 0) nCeilMod (Nat x) (Nat y)  = Just (Nat (mod (- x) y))  -- | Rounds up.
src/Cryptol/TypeCheck/Solver/Numeric/Fin.hs view
@@ -56,7 +56,7 @@           i2 = typeInterval varInfo t2  -        (TCDiv, [t1,_])  -> SolvedIf [ pFin t1 ]+        (TCDiv, [_,_])   -> SolvedIf []         (TCMod, [_,_])   -> SolvedIf []          -- fin (x ^ y)@@ -85,7 +85,7 @@          (TCMax, [t1,t2])          -> SolvedIf [ pFin t1, pFin t2 ]         (TCWidth, [t1])           -> SolvedIf [ pFin t1 ]-        (TCCeilDiv, [_,_])        -> SolvedIf []+        (TCCeilDiv, [t1,_])       -> SolvedIf [ pFin t1 ]         (TCCeilMod, [_,_])        -> SolvedIf []         (TCLenFromThenTo,[_,_,_]) -> SolvedIf [] 
src/Cryptol/TypeCheck/Solver/SMT.hs view
@@ -15,10 +15,12 @@ module Cryptol.TypeCheck.Solver.SMT   ( -- * Setup     Solver+  , SolverConfig   , withSolver   , startSolver   , stopSolver   , isNumeric+  , resetSolver      -- * Debugging   , debugBlock@@ -53,7 +55,7 @@ import Cryptol.TypeCheck.TypePat hiding ((~>),(~~>)) import Cryptol.TypeCheck.Subst(Subst) import Cryptol.Utils.Panic-import Cryptol.Utils.PP -- ( Doc )+import Cryptol.Utils.PP ( Doc, pp )   @@ -67,18 +69,22 @@     -- ^ For debugging   } +setupSolver :: Solver -> SolverConfig -> IO ()+setupSolver s cfg = do+  _ <- SMT.setOptionMaybe (solver s) ":global-decls" "false"+  loadTcPrelude s (solverPreludePath cfg)+ -- | Start a fresh solver instance-startSolver :: SolverConfig -> IO Solver-startSolver SolverConfig { .. } =-   do logger <- if solverVerbose > 0 then SMT.newLogger 0+startSolver :: IO () -> SolverConfig -> IO Solver+startSolver onExit sCfg =+   do logger <- if (solverVerbose sCfg) > 0 then SMT.newLogger 0                                       else return quietLogger-      let smtDbg = if solverVerbose > 1 then Just logger else Nothing-      solver <- SMT.newSolver solverPath solverArgs smtDbg-      _ <- SMT.setOptionMaybe solver ":global-decls" "false"-      -- SMT.setLogic solver "QF_LIA"-      let sol = Solver { .. }-      loadTcPrelude sol solverPreludePath+      let smtDbg = if (solverVerbose sCfg) > 1 then Just logger else Nothing+      solver <- SMT.newSolverNotify+                    (solverPath sCfg) (solverArgs sCfg) smtDbg (Just (const onExit))+      let sol = Solver solver logger+      setupSolver sol sCfg       return sol    where@@ -93,9 +99,14 @@ stopSolver :: Solver -> IO () stopSolver s = void $ SMT.stop (solver s) +resetSolver :: Solver -> SolverConfig -> IO ()+resetSolver s sCfg = do+  _ <- SMT.simpleCommand (solver s) ["reset"]+  setupSolver s sCfg+ -- | Execute a computation with a fresh solver instance.-withSolver :: SolverConfig -> (Solver -> IO a) -> IO a-withSolver cfg = bracket (startSolver cfg) stopSolver+withSolver :: IO () -> SolverConfig -> (Solver -> IO a) -> IO a+withSolver onExit cfg = bracket (startSolver onExit cfg) stopSolver  -- | Load the definitions used for type checking. loadTcPrelude :: Solver -> [FilePath] {- ^ Search in this paths -} -> IO ()
src/Cryptol/TypeCheck/Solver/Selector.hs view
@@ -15,7 +15,7 @@                               , newParamName                               ) import Cryptol.TypeCheck.Subst (listParamSubst, apSubst)-import Cryptol.Utils.Ident (Ident, packIdent)+import Cryptol.Utils.Ident (Ident, packIdent,Namespace(..)) import Cryptol.Utils.Panic(panic) import Cryptol.Utils.RecordMap @@ -163,9 +163,9 @@   -- xs.s             ~~> [ x.s           | x <- xs ]   -- { xs | s = ys }  ~~> [ { x | s = y } | x <- xs | y <- ys ]   liftSeq len el =-    do x1 <- newParamName (packIdent "x")-       x2 <- newParamName (packIdent "x")-       y2 <- newParamName (packIdent "y")+    do x1 <- newParamName NSValue (packIdent "x")+       x2 <- newParamName NSValue (packIdent "x")+       y2 <- newParamName NSValue (packIdent "y")        case tNoUser innerT of          TCon _ [_,eli] ->            do d <- mkSelSln s el eli@@ -187,8 +187,8 @@   -- f.s            ~~> \x -> (f x).s   -- { f | s = g }  ~~> \x -> { f x | s = g x }   liftFun t1 t2 =-    do x1 <- newParamName (packIdent "x")-       x2 <- newParamName (packIdent "x")+    do x1 <- newParamName NSValue (packIdent "x")+       x2 <- newParamName NSValue (packIdent "x")        case tNoUser innerT of          TCon _ [_,inT] ->            do d <- mkSelSln s t2 inT
src/Cryptol/TypeCheck/Subst.hs view
@@ -336,6 +336,14 @@                                      (cons k)                          } +instance TVars a => TVars (Map.Map k a) where+  -- NB, strict map+  apSubst su m = Map.map (apSubst su) m++instance TVars TySyn where+  apSubst su (TySyn nm params props t doc) =+    (\props' t' -> TySyn nm params props' t' doc)+      !$ apSubst su props !$ apSubst su t  {- | This instance does not need to worry about bound variable capture, because we rely on the 'Subst' datatype invariant to ensure
src/Cryptol/TypeCheck/TCon.hs view
@@ -41,9 +41,9 @@ builtInType nm =   case M.nameInfo nm of     M.Declared m _-      | m == preludeName -> Map.lookup (M.nameIdent nm) builtInTypes-      | m == floatName   -> Map.lookup (M.nameIdent nm) builtInFloat-      | m == arrayName   -> Map.lookup (M.nameIdent nm) builtInArray+      | m == M.TopModule preludeName -> Map.lookup (M.nameIdent nm) builtInTypes+      | m == M.TopModule floatName   -> Map.lookup (M.nameIdent nm) builtInFloat+      | m == M.TopModule arrayName   -> Map.lookup (M.nameIdent nm) builtInArray     _ -> Nothing    where
src/Cryptol/TypeCheck/Type.hs view
@@ -2,6 +2,11 @@ {-# Language FlexibleInstances, FlexibleContexts #-} {-# Language PatternGuards #-} {-# Language OverloadedStrings #-}+{-| This module contains types related to typechecking and the output of the+typechecker.  In particular, it should contain the types needed by+interface files (see 'Crytpol.ModuleSystem.Interface'), which are (kind of)+the output of the typechker.+-} module Cryptol.TypeCheck.Type   ( module Cryptol.TypeCheck.Type   , module Cryptol.TypeCheck.TCon@@ -32,8 +37,40 @@ infix  4 =#=, >== infixr 5 `tFun` +-- | A type parameter of a module.+data ModTParam = ModTParam+  { mtpName   :: Name+  , mtpKind   :: Kind+  , mtpNumber :: !Int -- ^ The number of the parameter in the module+                      -- This is used when we move parameters from the module+                      -- level to individual declarations+                      -- (type synonyms in particular)+  , mtpDoc    :: Maybe Text+  } deriving (Show,Generic,NFData)  +mtpParam :: ModTParam -> TParam+mtpParam mtp = TParam { tpUnique = nameUnique (mtpName mtp)+                      , tpKind   = mtpKind mtp+                      , tpFlav   = TPModParam (mtpName mtp)+                      , tpInfo   = desc+                      }+  where desc = TVarInfo { tvarDesc   = TVFromModParam (mtpName mtp)+                        , tvarSource = nameLoc (mtpName mtp)+                        }++-- | A value parameter of a module.+data ModVParam = ModVParam+  { mvpName   :: Name+  , mvpType   :: Schema+  , mvpDoc    :: Maybe Text+  , mvpFixity :: Maybe Fixity+  } deriving (Show,Generic,NFData)+++++ -- | The types of polymorphic values. data Schema = Forall { sVars :: [TParam], sProps :: [Prop], sType :: Type }               deriving (Eq, Show, Generic, NFData)@@ -893,17 +930,17 @@ instance PP (WithNames Schema) where   ppPrec _ (WithNames s ns)     | null (sVars s) && null (sProps s) = body-    | otherwise = hang (vars <+> props) 2 body+    | otherwise = nest 2 (sep (vars ++ props ++ [body]))     where     body = ppWithNames ns1 (sType s)      vars = case sVars s of-      [] -> empty-      vs -> braces $ commaSep $ map (ppWithNames ns1) vs+      [] -> []+      vs -> [nest 1 (braces (commaSepFill (map (ppWithNames ns1) vs)))]      props = case sProps s of-      [] -> empty-      ps -> parens (commaSep (map (ppWithNames ns1) ps)) <+> text "=>"+      [] -> []+      ps -> [nest 1 (parens (commaSepFill (map (ppWithNames ns1) ps))) <+> text "=>"]      ns1 = addTNames (sVars s) ns @@ -912,17 +949,20 @@  instance PP (WithNames TySyn) where   ppPrec _ (WithNames ts ns) =-    text "type" <+> ctr <+> lhs <+> char '=' <+> ppWithNames ns1 (tsDef ts)+    nest 2 $ sep+      [ fsep ([text "type"] ++ ctr ++ lhs ++ [char '='])+      , ppWithNames ns1 (tsDef ts)+      ]     where ns1 = addTNames (tsParams ts) ns           ctr = case kindResult (kindOf ts) of-                  KProp -> text "constraint"-                  _     -> empty+                  KProp -> [text "constraint"]+                  _     -> []           n = tsName ts           lhs = case (nameFixity n, tsParams ts) of                   (Just _, [x, y]) ->-                    ppWithNames ns1 x <+> pp (nameIdent n) <+> ppWithNames ns1 y+                    [ppWithNames ns1 x, pp (nameIdent n), ppWithNames ns1 y]                   (_, ps) ->-                    pp n <+> sep (map (ppWithNames ns1) ps)+                    [pp n] ++ map (ppWithNames ns1) ps  instance PP Newtype where   ppPrec = ppWithNamesPrec IntMap.empty@@ -948,8 +988,8 @@   ppPrec prec ty0@(WithNames ty nmMap) =     case ty of       TVar a  -> ppWithNames nmMap a-      TNewtype nt ts -> optParens (prec > 3) $ pp (ntName nt) <+> fsep (map (go 5) ts)-      TRec fs -> braces $ fsep $ punctuate comma+      TNewtype nt ts -> optParens (prec > 3) $ fsep (pp (ntName nt) : map (go 5) ts)+      TRec fs -> ppRecord                     [ pp l <+> text ":" <+> go 0 t | (l,t) <- displayFields fs ]        _ | Just tinf <- isTInfix ty0 -> optParens (prec > 2)@@ -957,14 +997,13 @@        TUser c ts t ->         withNameDisp $ \disp ->-        case nameInfo c of-          Declared m _-            | NotInScope <- getNameFormat m (nameIdent c) disp ->+        case asOrigName c of+          Just og | NotInScope <- getNameFormat og disp ->               go prec t -- unfold type synonym if not in scope           _ ->             case ts of               [] -> pp c-              _ -> optParens (prec > 3) $ pp c <+> fsep (map (go 5) ts)+              _ -> optParens (prec > 3) $ fsep (pp c : map (go 5) ts)        TCon (TC tc) ts ->         case (tc,ts) of@@ -983,9 +1022,9 @@           (TCFun,   [t1,t2])  -> optParens (prec > 1)                               $ go 2 t1 <+> text "->" <+> go 1 t2 -          (TCTuple _, fs)     -> parens $ fsep $ punctuate comma $ map (go 0) fs+          (TCTuple _, fs)     -> ppTuple $ map (go 0) fs -          (_, _)              -> optParens (prec > 3) $ pp tc <+> fsep (map (go 5) ts)+          (_, _)              -> optParens (prec > 3) $ fsep (pp tc : (map (go 5) ts))        TCon (PC pc) ts ->         case (pc,ts) of@@ -996,7 +1035,7 @@           (PPrime,  [t1])     -> optParens (prec > 3) $ text "prime" <+> (go 5 t1)           (PHas x, [t1,t2])   -> ppSelector x <+> text "of"                                <+> go 0 t1 <+> text "is" <+> go 0 t2-          (PAnd, [t1,t2])     -> parens (commaSep (map (go 0) (t1 : pSplitAnd t2)))+          (PAnd, [t1,t2])     -> nest 1 (parens (commaSepFill (map (go 0) (t1 : pSplitAnd t2))))            (PRing, [t1])       -> pp pc <+> go 5 t1           (PField, [t1])      -> pp pc <+> go 5 t1@@ -1008,10 +1047,9 @@           (PLiteral, [t1,t2]) -> pp pc <+> go 5 t1 <+> go 5 t2           (PLiteralLessThan, [t1,t2]) -> pp pc <+> go 5 t1 <+> go 5 t2 -          (_, _)              -> optParens (prec > 3) $ pp pc <+> fsep (map (go 5) ts)+          (_, _)              -> optParens (prec > 3) $ fsep (pp pc : map (go 5) ts) -      TCon f ts -> optParens (prec > 3)-                $ pp f <+> fsep (map (go 5) ts)+      TCon f ts -> optParens (prec > 3) $ fsep (pp f : map (go 5) ts)      where     go p t = ppWithNamesPrec nmMap p t@@ -1076,7 +1114,7 @@     TypeParamInstPos f n   -> mk (sh f ++ "_" ++ show n)     DefinitionOf x ->       case nameInfo x of-        Declared m SystemName | m == exprModName -> mk "it"+        Declared m SystemName | m == TopModule exprModName -> mk "it"         _ -> using x     LenOfCompGen           -> mk "n"     GeneratorOfListComp    -> "seq"@@ -1100,19 +1138,18 @@   ppPrec n t = ppWithNamesPrec IntMap.empty n t  instance PP TVarInfo where-  ppPrec _ tvinfo = pp (tvarDesc tvinfo) <+> loc+  ppPrec _ tvinfo = hsep $ [pp (tvarDesc tvinfo)] ++ loc     where-    loc = if rng == emptyRange then empty else "at" <+> pp rng+    loc = if rng == emptyRange then [] else ["at" <+> pp rng]     rng = tvarSource tvinfo  instance PP ArgDescr where-  ppPrec _ ad = which <+> "argument" <+> ofFun+  ppPrec _ ad = hsep ([which, "argument"] ++ ofFun)         where         which = maybe "function" ordinal (argDescrNumber ad)         ofFun = case argDescrFun ad of-                  Nothing -> empty-                  Just f  -> "of" <+> pp f-+                  Nothing -> []+                  Just f  -> ["of" <+> pp f]   instance PP TypeSource where
src/Cryptol/TypeCheck/TypeOf.hs view
@@ -54,8 +54,12 @@     polymorphic =       case fastSchemaOf tyenv expr of         Forall [] [] ty -> ty-        _ -> panic "Cryptol.TypeCheck.TypeOf.fastTypeOf"-               [ "unexpected polymorphic type" ]+        s@Forall {} -> panic "Cryptol.TypeCheck.TypeOf.fastTypeOf"+               [ "unexpected polymorphic type in expression:"+               , pretty expr+               , "with schema:"+               , pretty s+               ]  fastSchemaOf :: Map Name Schema -> Expr -> Schema fastSchemaOf tyenv expr =@@ -124,13 +128,32 @@  -- | Yields the return type of the selector on the given argument type. typeSelect :: Type -> Selector -> Type++-- Selectors push inside the definition of type aliases typeSelect (TUser _ _ ty) sel = typeSelect ty sel++-- Tuple selector applied to a tuple typeSelect (tIsTuple -> Just ts) (TupleSel i _)   | i < length ts = ts !! i++-- Record selector applied to a record typeSelect (TRec fields) (RecordSel n _)   | Just ty <- lookupField n fields = ty++-- Record selector applied to a newtype+typeSelect (TNewtype nt args) (RecordSel n _)+  | Just ty <- lookupField n (ntFields nt)+  = plainSubst (listParamSubst (zip (ntParams nt) args)) ty++-- List selector applied to a sequence typeSelect (tIsSeq -> Just (_, a)) ListSel{} = a++-- Tuple selectors and record selectors lift pointwise over sequences typeSelect (tIsSeq -> Just (n, a)) sel@TupleSel{} = tSeq n (typeSelect a sel) typeSelect (tIsSeq -> Just (n, a)) sel@RecordSel{} = tSeq n (typeSelect a sel)++-- Selectors lift pointwise over functions+typeSelect (tIsFun -> Just (a, b)) sel = tFun a (typeSelect b sel)+ typeSelect ty _ = panic "Cryptol.TypeCheck.TypeOf.typeSelect"-                    [ "cannot apply selector to value of type", render (pp ty) ]+                    [ "cannot apply selector to value of type", show (pp ty) ]
src/Cryptol/Utils/Ident.hs view
@@ -7,10 +7,17 @@ -- Portability :  portable  {-# LANGUAGE DeriveGeneric, OverloadedStrings #-}+{-# LANGUAGE DeriveAnyClass #-}  module Cryptol.Utils.Ident   ( -- * Module names-    ModName+    ModPath(..)+  , apPathRoot+  , modPathCommon+  , topModuleFor+  , modPathSplit++  , ModName   , modNameToText   , textToModName   , modNameChunks@@ -41,6 +48,13 @@   , identText   , modParamIdent +    -- * Namespaces+  , Namespace(..)+  , allNamespaces++    -- * Original names+  , OrigName(..)+     -- * Identifiers for primitives   , PrimIdent(..)   , prelPrim@@ -58,7 +72,64 @@ import           GHC.Generics (Generic)  --- | Module names are just text.+--------------------------------------------------------------------------------++-- | Namespaces for names+data Namespace = NSValue | NSType | NSModule+  deriving (Generic,Show,NFData,Eq,Ord,Enum,Bounded)++allNamespaces :: [Namespace]+allNamespaces = [ minBound .. maxBound ]++-- | Idnetifies a possibly nested module+data ModPath  = TopModule ModName+              | Nested ModPath Ident+                deriving (Eq,Ord,Show,Generic,NFData)++apPathRoot :: (ModName -> ModName) -> ModPath -> ModPath+apPathRoot f path =+  case path of+    TopModule m -> TopModule (f m)+    Nested p q  -> Nested (apPathRoot f p) q++topModuleFor :: ModPath -> ModName+topModuleFor m =+  case m of+    TopModule x -> x+    Nested p _ -> topModuleFor p++-- | Compute a common prefix between two module paths, if any.+-- This is basically "anti-unification" of the two paths, where we+-- compute the longest common prefix, and the remaining differences for+-- each module.+modPathCommon :: ModPath -> ModPath -> Maybe (ModPath, [Ident], [Ident])+modPathCommon p1 p2+  | top1 == top2 = Just (findCommon (TopModule top1) as bs)+  | otherwise    = Nothing+  where+  (top1,as) = modPathSplit p1+  (top2,bs) = modPathSplit p2++  findCommon com xs ys =+    case (xs,ys) of+      (x:xs',y:ys') | x == y -> findCommon (Nested com x) xs' ys'+      _                      -> (com, xs, ys)++modPathSplit :: ModPath -> (ModName, [Ident])+modPathSplit p0 = (top,reverse xs)+  where+  (top,xs) = go p0+  go p =+    case p of+      TopModule a -> (a, [])+      Nested b i  -> (a, i:bs)+        where (a,bs) = go b+++++--------------------------------------------------------------------------------+-- | Top-level Module names are just text. data ModName = ModName T.Text   deriving (Eq,Ord,Show,Generic) @@ -135,6 +206,15 @@  exprModName :: ModName exprModName = packModName ["<expr>"]+++--------------------------------------------------------------------------------+-- | Identifies an entitiy+data OrigName = OrigName+  { ogNamespace :: Namespace+  , ogModule    :: ModPath+  , ogName      :: Ident+  } deriving (Eq,Ord,Show,Generic,NFData)   --------------------------------------------------------------------------------
src/Cryptol/Utils/PP.hs view
@@ -18,23 +18,21 @@ import           Control.DeepSeq import           Control.Monad (mplus) import           Data.Maybe (fromMaybe)-import qualified Data.Semigroup as S import           Data.String (IsString(..)) import qualified Data.Text as T+import           Data.Void (Void) import           GHC.Generics (Generic)-import qualified Text.PrettyPrint as PJ--import Prelude ()-import Prelude.Compat-+import qualified Prettyprinter as PP+import qualified Prettyprinter.Render.String as PP  -- | How to pretty print things when evaluating data PPOpts = PPOpts-  { useAscii     :: Bool-  , useBase      :: Int-  , useInfLength :: Int-  , useFPBase    :: Int-  , useFPFormat  :: PPFloatFormat+  { useAscii      :: Bool+  , useBase       :: Int+  , useInfLength  :: Int+  , useFPBase     :: Int+  , useFPFormat   :: PPFloatFormat+  , useFieldOrder :: FieldOrder   }  deriving Show @@ -51,11 +49,14 @@                 | AutoExponent  -- ^ Only show exponent when needed  deriving Show +data FieldOrder = DisplayOrder | CanonicalOrder deriving (Bounded, Enum, Eq, Ord, Read, Show) + defaultPPOpts :: PPOpts defaultPPOpts = PPOpts { useAscii = False, useBase = 10, useInfLength = 5                        , useFPBase = 16                        , useFPFormat = FloatFree AutoExponent+                       , useFieldOrder = DisplayOrder                        }  @@ -66,21 +67,21 @@ that the display has no opinion on how this name should be displayed, and some other display should be tried out. -} data NameDisp = EmptyNameDisp-              | NameDisp (ModName -> Ident -> Maybe NameFormat)+              | NameDisp (OrigName -> Maybe NameFormat)                 deriving (Generic, NFData)  instance Show NameDisp where   show _ = "<NameDisp>" -instance S.Semigroup NameDisp where-  NameDisp f    <> NameDisp g    = NameDisp (\m n -> f m n `mplus` g m n)+instance Semigroup NameDisp where+  NameDisp f    <> NameDisp g    = NameDisp (\n -> f n `mplus` g n)   EmptyNameDisp <> EmptyNameDisp = EmptyNameDisp   EmptyNameDisp <> x             = x   x             <> _             = x  instance Monoid NameDisp where   mempty = EmptyNameDisp-  mappend = (S.<>)+  mappend = (<>)  data NameFormat = UnQualified                 | Qualified !ModName@@ -88,21 +89,13 @@                   deriving (Show)  -- | Never qualify names from this module.-neverQualifyMod :: ModName -> NameDisp-neverQualifyMod mn = NameDisp $ \ mn' _ ->-  if mn == mn' then Just UnQualified-               else Nothing--alwaysQualify :: NameDisp-alwaysQualify  = NameDisp $ \ mn _ -> Just (Qualified mn)+neverQualifyMod :: ModPath -> NameDisp+neverQualifyMod mn = NameDisp $ \n ->+  if ogModule n == mn then Just UnQualified else Nothing  neverQualify :: NameDisp-neverQualify  = NameDisp $ \ _ _ -> Just UnQualified+neverQualify  = NameDisp $ \ _ -> Just UnQualified -fmtModName :: ModName -> NameFormat -> T.Text-fmtModName _  UnQualified    = T.empty-fmtModName _  (Qualified mn) = modNameToText mn-fmtModName mn NotInScope     = modNameToText mn  -- | Compose two naming environments, preferring names from the left -- environment.@@ -111,9 +104,9 @@  -- | Get the format for a name. When 'Nothing' is returned, the name is not -- currently in scope.-getNameFormat :: ModName -> Ident -> NameDisp -> NameFormat-getNameFormat m i (NameDisp f)  = fromMaybe NotInScope (f m i)-getNameFormat _ _ EmptyNameDisp = NotInScope+getNameFormat :: OrigName -> NameDisp -> NameFormat+getNameFormat m (NameDisp f)  = fromMaybe NotInScope (f m)+getNameFormat _ EmptyNameDisp = NotInScope  -- | Produce a document in the context of the current 'NameDisp'. withNameDisp :: (NameDisp -> Doc) -> Doc@@ -126,29 +119,27 @@  -- Documents ------------------------------------------------------------------- -newtype Doc = Doc (NameDisp -> PJ.Doc) deriving (Generic, NFData)+newtype Doc = Doc (NameDisp -> PP.Doc Void) deriving (Generic, NFData) -instance S.Semigroup Doc where-  (<>) = liftPJ2 (PJ.<>)+instance Semigroup Doc where+  (<>) = liftPP2 (<>)  instance Monoid Doc where-  mempty = liftPJ PJ.empty-  mappend = (S.<>)+  mempty = liftPP mempty+  mappend = (<>) -runDoc :: NameDisp -> Doc -> PJ.Doc+runDoc :: NameDisp -> Doc -> PP.Doc Void runDoc names (Doc f) = f names  instance Show Doc where-  show d = show (runDoc mempty d)+  show d = PP.renderString (PP.layoutPretty opts (runDoc mempty d))+    where opts = PP.defaultLayoutOptions{ PP.layoutPageWidth = PP.AvailablePerLine 100 0.666 }  instance IsString Doc where   fromString = text -render :: Doc -> String-render d = PJ.render (runDoc mempty d)- renderOneLine :: Doc -> String-renderOneLine d = PJ.renderStyle (PJ.style { PJ.mode = PJ.OneLineMode }) (runDoc mempty d)+renderOneLine d = PP.renderString (PP.layoutCompact (runDoc mempty d))  class PP a where   ppPrec :: Int -> a -> Doc@@ -163,6 +154,11 @@   -- | Print a name as an infix operator: @a + b@   ppInfixName  :: a -> Doc +instance PPName ModName where+  ppNameFixity _ = Nothing+  ppPrefixName   = pp+  ppInfixName    = pp+ pp :: PP a => a -> Doc pp = ppPrec 0 @@ -170,7 +166,7 @@ pretty  = show . pp  optParens :: Bool -> Doc -> Doc-optParens b body | b         = parens body+optParens b body | b         = nest 1 (parens body)                  | otherwise = body  @@ -182,10 +178,6 @@   , ieFixity :: Fixity   -- ^ operator fixity   } -commaSep :: [Doc] -> Doc-commaSep = fsep . punctuate comma-- -- | Pretty print an infix expression of some sort. ppInfix :: (PP thing, PP op)         => Int            -- ^ Non-infix leaves are printed with this precedence@@ -227,94 +219,123 @@  -- Wrapped Combinators --------------------------------------------------------- -liftPJ :: PJ.Doc -> Doc-liftPJ d = Doc (const d)+liftPP :: PP.Doc Void -> Doc+liftPP d = Doc (const d) -liftPJ1 :: (PJ.Doc -> PJ.Doc) -> Doc -> Doc-liftPJ1 f (Doc d) = Doc (\env -> f (d env))+liftPP1 :: (PP.Doc Void -> PP.Doc Void) -> Doc -> Doc+liftPP1 f (Doc d) = Doc (\env -> f (d env)) -liftPJ2 :: (PJ.Doc -> PJ.Doc -> PJ.Doc) -> (Doc -> Doc -> Doc)-liftPJ2 f (Doc a) (Doc b) = Doc (\e -> f (a e) (b e))+liftPP2 :: (PP.Doc Void -> PP.Doc Void -> PP.Doc Void) -> (Doc -> Doc -> Doc)+liftPP2 f (Doc a) (Doc b) = Doc (\e -> f (a e) (b e)) -liftSep :: ([PJ.Doc] -> PJ.Doc) -> ([Doc] -> Doc)+liftSep :: ([PP.Doc Void] -> PP.Doc Void) -> ([Doc] -> Doc) liftSep f ds = Doc (\e -> f [ d e | Doc d <- ds ]) -infixl 6 <.>, <+>+infixl 6 <.>, <+>, </>  (<.>) :: Doc -> Doc -> Doc-(<.>)  = liftPJ2 (PJ.<>)+(<.>)  = liftPP2 (PP.<>)  (<+>) :: Doc -> Doc -> Doc-(<+>)  = liftPJ2 (PJ.<+>)+(<+>)  = liftPP2 (PP.<+>) +(</>) :: Doc -> Doc -> Doc+Doc x </> Doc y = Doc (\e -> x e <> PP.softline <> y e)+ infixl 5 $$  ($$) :: Doc -> Doc -> Doc-($$)  = liftPJ2 (PJ.$$)+($$) x y = vsep [x,y]  sep :: [Doc] -> Doc-sep  = liftSep PJ.sep+sep  = liftSep PP.sep  fsep :: [Doc] -> Doc-fsep  = liftSep PJ.fsep+fsep  = liftSep PP.fillSep  hsep :: [Doc] -> Doc-hsep  = liftSep PJ.hsep+hsep  = liftSep PP.hsep  hcat :: [Doc] -> Doc-hcat  = liftSep PJ.hcat+hcat  = liftSep PP.hcat  vcat :: [Doc] -> Doc-vcat  = liftSep PJ.vcat+vcat  = liftSep PP.vcat +vsep :: [Doc] -> Doc+vsep  = liftSep PP.vsep++group :: Doc -> Doc+group = liftPP1 PP.group++-- NB, this is the semantics of "hang" as defined+--  by the HugesPJ printer, not the "hang" from prettyprinter,+--  which is subtly different. hang :: Doc -> Int -> Doc -> Doc-hang (Doc p) i (Doc q) = Doc (\e -> PJ.hang (p e) i (q e))+hang (Doc p) i (Doc q) = Doc (\e -> PP.hang i (PP.vsep [p e, q e]))  nest :: Int -> Doc -> Doc-nest n = liftPJ1 (PJ.nest n)+nest n = liftPP1 (PP.nest n) +indent :: Int -> Doc -> Doc+indent n = liftPP1 (PP.indent n)++align :: Doc -> Doc+align = liftPP1 PP.align+ parens :: Doc -> Doc-parens  = liftPJ1 PJ.parens+parens  = liftPP1 PP.parens  braces :: Doc -> Doc-braces  = liftPJ1 PJ.braces+braces  = liftPP1 PP.braces  brackets :: Doc -> Doc-brackets  = liftPJ1 PJ.brackets+brackets  = liftPP1 PP.brackets  quotes :: Doc -> Doc-quotes  = liftPJ1 PJ.quotes+quotes  = liftPP1 PP.squotes -backticks :: Doc -> Doc-backticks d = hcat [ "`", d, "`" ]+commaSep :: [Doc] -> Doc+commaSep xs = Doc (\e -> PP.sep (PP.punctuate PP.comma [ d e | Doc d <- xs ])) -punctuate :: Doc -> [Doc] -> [Doc]-punctuate p = go+-- | Print a comma-separated list. Lay out each item on a single line+-- if it will fit. If an item requires multiple lines, then start it+-- on its own line.+commaSepFill :: [Doc] -> Doc+commaSepFill xs = Doc (\e -> fillSep (PP.punctuate PP.comma [ d e | Doc d <- xs ]))   where-  go (d:ds) | null ds   = [d]-            | otherwise = d <.> p : go ds-  go []                 = []+    fillSep [] = mempty+    fillSep (d0 : ds) = foldl (\a d -> a <> PP.group (PP.line <> d)) d0 ds +ppList :: [Doc] -> Doc+ppList xs = group (nest 1 (brackets (commaSepFill xs)))++ppTuple :: [Doc] -> Doc+ppTuple xs = group (nest 1 (parens (commaSep xs)))++ppRecord :: [Doc] -> Doc+ppRecord xs = group (nest 1 (braces (commaSep xs)))++backticks :: Doc -> Doc+backticks d = hcat [ "`", d, "`" ]+ text :: String -> Doc-text s = liftPJ (PJ.text s)+text s = liftPP (PP.pretty s)  char :: Char -> Doc-char c = liftPJ (PJ.char c)+char c = liftPP (PP.pretty c)  integer :: Integer -> Doc-integer i = liftPJ (PJ.integer i)+integer i = liftPP (PP.pretty i)  int :: Int -> Doc-int i = liftPJ (PJ.int i)+int i = liftPP (PP.pretty i)  comma :: Doc-comma  = liftPJ PJ.comma--empty :: Doc-empty  = liftPJ PJ.empty+comma  = liftPP PP.comma  colon :: Doc-colon  = liftPJ PJ.colon+colon  = liftPP PP.colon  instance PP T.Text where   ppPrec _ str = text (T.unpack str)@@ -325,6 +346,7 @@ instance PP ModName where   ppPrec _   = text . T.unpack . modNameToText + instance PP Assoc where   ppPrec _ LeftAssoc  = text "left-associative"   ppPrec _ RightAssoc = text "right-associative"@@ -333,3 +355,31 @@ instance PP Fixity where   ppPrec _ (Fixity assoc level) =     text "precedence" <+> int level <.> comma <+> pp assoc++instance PP ModPath where+  ppPrec _ p =+    case p of+      TopModule m -> pp m+      Nested q t  -> pp q <.> "::" <.> pp t++instance PP OrigName where+  ppPrec _ og =+    withNameDisp $ \disp ->+      case getNameFormat og disp of+        UnQualified -> pp (ogName og)+        Qualified m -> ppQual (TopModule m) (pp (ogName og))+        NotInScope  -> ppQual (ogModule og) (pp (ogName og))+    where+   ppQual mo x =+    case mo of+      TopModule m+        | m == exprModName -> x+        | otherwise -> pp m <.> "::" <.> x+      Nested m y -> ppQual m (pp y <.> "::" <.> x)++instance PP Namespace where+  ppPrec _ ns =+    case ns of+      NSValue   -> "/*value*/"+      NSType    -> "/*type*/"+      NSModule  -> "/*module*/"