packages feed

clash-ghc 1.0.1 → 1.2.0

raw patch · 37 files changed

+1224/−7176 lines, 37 filesdep +splitdep ~clash-libdep ~clash-preludedep ~ghcPVP ok

version bump matches the API change (PVP)

Dependencies added: split

Dependency ranges changed: clash-lib, clash-prelude, ghc, ghc-boot, ghc-typelits-extra, ghci, haskeline, lens

API changes (from Hackage documentation)

- Clash.GHC.Evaluator: PEM :: (Supply -> (a, Supply)) -> PrimEvalMonad a
- Clash.GHC.Evaluator: [runPEM] :: PrimEvalMonad a -> Supply -> (a, Supply)
- Clash.GHC.Evaluator: bConPrim :: Type -> Term
- Clash.GHC.Evaluator: bitLiterals :: [Value] -> [(Integer, Integer)]
- Clash.GHC.Evaluator: bitVectorLitIntLit :: TyConMap -> [Type] -> [Value] -> Maybe (Type, Integer, (Integer, Integer), Integer)
- Clash.GHC.Evaluator: bitVectorLiterals :: [Value] -> Maybe ((Integer, Integer), (Integer, Integer))
- Clash.GHC.Evaluator: bitVectorLiterals' :: [Value] -> [(Integer, Integer)]
- Clash.GHC.Evaluator: boolToBoolLiteral :: TyConMap -> Type -> Bool -> Term
- Clash.GHC.Evaluator: boolToIntLiteral :: Bool -> Term
- Clash.GHC.Evaluator: bvAppendPrim :: TyConName -> Term
- Clash.GHC.Evaluator: bvAppendTy :: TyConName -> Type
- Clash.GHC.Evaluator: bvConPrim :: Type -> Term
- Clash.GHC.Evaluator: bvSplitPrim :: TyConName -> Term
- Clash.GHC.Evaluator: bvSplitTy :: TyConName -> Type
- Clash.GHC.Evaluator: charLiterals :: [Value] -> Maybe (Char, Char)
- Clash.GHC.Evaluator: charLiterals' :: [Value] -> [Char]
- Clash.GHC.Evaluator: charToCharLiteral :: Char -> Term
- Clash.GHC.Evaluator: doubleLiterals' :: [Value] -> [Rational]
- Clash.GHC.Evaluator: extractKnownNat :: TyConMap -> [Type] -> Maybe (Type, Integer)
- Clash.GHC.Evaluator: extractKnownNatVal :: TyConMap -> [Type] -> Maybe Integer
- Clash.GHC.Evaluator: extractKnownNatVals :: TyConMap -> [Type] -> [Integer]
- Clash.GHC.Evaluator: extractKnownNats :: TyConMap -> [Type] -> [(Type, Integer)]
- Clash.GHC.Evaluator: extractTySizeInfo :: TyConMap -> Type -> [Type] -> (Type, Type, Integer)
- Clash.GHC.Evaluator: floatLiterals' :: [Value] -> [Rational]
- Clash.GHC.Evaluator: foldSplitAtTy :: TyConName -> Type
- Clash.GHC.Evaluator: getResultTy :: TyConMap -> Type -> [Type] -> Type
- Clash.GHC.Evaluator: ghcTyconToTyConName :: TyCon -> TyConName
- Clash.GHC.Evaluator: indexAddTy :: TyConName -> Type
- Clash.GHC.Evaluator: indexConPrim :: Type -> Term
- Clash.GHC.Evaluator: indexLiterals :: [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: indexLiterals' :: [Value] -> [Integer]
- Clash.GHC.Evaluator: intCLiteral :: Value -> Maybe Integer
- Clash.GHC.Evaluator: intCLiterals :: [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: intCLiterals' :: [Value] -> [Integer]
- Clash.GHC.Evaluator: intLiterals :: [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: intLiterals' :: [Value] -> [Integer]
- Clash.GHC.Evaluator: integerLiterals :: [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: integerLiterals' :: [Value] -> [Integer]
- Clash.GHC.Evaluator: integerToIntLiteral :: Integer -> Term
- Clash.GHC.Evaluator: integerToIntegerLiteral :: Integer -> Term
- Clash.GHC.Evaluator: integerToWordLiteral :: Integer -> Term
- Clash.GHC.Evaluator: liftBitVector2 :: KnownNat n => (BitVector n -> BitVector n -> BitVector n) -> Type -> TyConMap -> [Type] -> [Value] -> Proxy n -> Maybe Term
- Clash.GHC.Evaluator: liftBitVector2Bool :: KnownNat n => (BitVector n -> BitVector n -> Bool) -> Type -> TyConMap -> [Value] -> Proxy n -> Maybe Term
- Clash.GHC.Evaluator: liftDD :: (Double# -> Double#) -> [Value] -> Maybe Term
- Clash.GHC.Evaluator: liftDDD :: (Double# -> Double# -> Double#) -> [Value] -> Maybe Term
- Clash.GHC.Evaluator: liftDDI :: (Double# -> Double# -> Int#) -> [Value] -> Maybe Term
- Clash.GHC.Evaluator: liftFF :: (Float# -> Float#) -> [Value] -> Maybe Term
- Clash.GHC.Evaluator: liftFFF :: (Float# -> Float# -> Float#) -> [Value] -> Maybe Term
- Clash.GHC.Evaluator: liftFFI :: (Float# -> Float# -> Int#) -> [Value] -> Maybe Term
- Clash.GHC.Evaluator: liftSigned2 :: KnownNat n => (Signed n -> Signed n -> Signed n) -> Type -> TyConMap -> [Type] -> [Value] -> Proxy n -> Maybe Term
- Clash.GHC.Evaluator: liftSized2 :: (KnownNat n, Integral (sized n)) => ([Value] -> [Integer]) -> (Type -> Type -> Integer -> Integer -> Term) -> (sized n -> sized n -> sized n) -> Type -> TyConMap -> [Type] -> [Value] -> Proxy n -> Maybe Term
- Clash.GHC.Evaluator: liftUnsigned2 :: KnownNat n => (Unsigned n -> Unsigned n -> Unsigned n) -> Type -> TyConMap -> [Type] -> [Value] -> Proxy n -> Maybe Term
- Clash.GHC.Evaluator: mkBitLit :: Type -> Integer -> Integer -> Term
- Clash.GHC.Evaluator: mkBitVectorLit :: Type -> Type -> Integer -> Integer -> Integer -> Term
- Clash.GHC.Evaluator: mkBitVectorLit' :: (Type, Type, Integer) -> Integer -> Integer -> Term
- Clash.GHC.Evaluator: mkIndexLit :: Type -> Type -> Integer -> Integer -> Term
- Clash.GHC.Evaluator: mkIndexLit' :: (Type, Type, Integer) -> Integer -> Term
- Clash.GHC.Evaluator: mkIndexLitE :: Type -> Type -> Integer -> Integer -> Either Term Term
- Clash.GHC.Evaluator: mkIntCLiteral :: HasCallStack => Value -> Integer -> Term
- Clash.GHC.Evaluator: mkSignedLit :: Type -> Type -> Integer -> Integer -> Term
- Clash.GHC.Evaluator: mkSignedLit' :: (Type, Type, Integer) -> Integer -> Term
- Clash.GHC.Evaluator: mkSizedLit :: (Type -> Term) -> Type -> Type -> Integer -> Integer -> Term
- Clash.GHC.Evaluator: mkSizedLit' :: (Type -> Term) -> (Type, Type, Integer) -> Integer -> Term
- Clash.GHC.Evaluator: mkUnsignedLit :: Type -> Type -> Integer -> Integer -> Term
- Clash.GHC.Evaluator: mkUnsignedLit' :: (Type, Type, Integer) -> Integer -> Term
- Clash.GHC.Evaluator: mkVecCons :: DataCon -> Type -> Integer -> Term -> Term -> Term
- Clash.GHC.Evaluator: mkVecNil :: DataCon -> Type -> Term
- Clash.GHC.Evaluator: naturalLiterals :: [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: naturalLiterals' :: [Value] -> [Integer]
- Clash.GHC.Evaluator: naturalToNaturalLiteral :: Natural -> Term
- Clash.GHC.Evaluator: newtype PrimEvalMonad a
- Clash.GHC.Evaluator: reduceConstant :: PrimEvaluator
- Clash.GHC.Evaluator: runDD :: (Double# -> Double#) -> Rational -> Term
- Clash.GHC.Evaluator: runDDD :: (Double# -> Double# -> Double#) -> Rational -> Rational -> Term
- Clash.GHC.Evaluator: runDDI :: (Double# -> Double# -> Int#) -> Rational -> Rational -> Term
- Clash.GHC.Evaluator: runFF :: (Float# -> Float#) -> Rational -> Term
- Clash.GHC.Evaluator: runFFF :: (Float# -> Float# -> Float#) -> Rational -> Rational -> Term
- Clash.GHC.Evaluator: runFFI :: (Float# -> Float# -> Int#) -> Rational -> Rational -> Term
- Clash.GHC.Evaluator: runSizedF :: (KnownNat n, Integral (sized n)) => (sized n -> sized n -> sized n) -> Integer -> Integer -> Proxy n -> Integer
- Clash.GHC.Evaluator: signedConPrim :: Type -> Term
- Clash.GHC.Evaluator: signedLitIntLit :: TyConMap -> [Type] -> [Value] -> Maybe (Type, Integer, Integer, Integer)
- Clash.GHC.Evaluator: signedLiterals :: [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: signedLiterals' :: [Value] -> [Integer]
- Clash.GHC.Evaluator: sizedLitIntLit :: Text -> TyConMap -> [Type] -> [Value] -> Maybe (Type, Integer, Integer, Integer)
- Clash.GHC.Evaluator: sizedLiteral :: Text -> Value -> Maybe Integer
- Clash.GHC.Evaluator: sizedLiterals :: Text -> [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: sizedLiterals' :: Text -> [Value] -> [Integer]
- Clash.GHC.Evaluator: splitAtPrim :: TyConName -> TyConName -> Term
- Clash.GHC.Evaluator: splitAtTy :: TyConName -> TyConName -> Type
- Clash.GHC.Evaluator: splitBV :: BitVector n -> (Integer, Integer)
- Clash.GHC.Evaluator: svoid :: (State# RealWorld -> State# RealWorld) -> IO ()
- Clash.GHC.Evaluator: toBV :: (Integer, Integer) -> BitVector n
- Clash.GHC.Evaluator: typeNatAdd :: TyConName
- Clash.GHC.Evaluator: typeNatMul :: TyConName
- Clash.GHC.Evaluator: typeNatSub :: TyConName
- Clash.GHC.Evaluator: typedLiterals' :: (Value -> Maybe a) -> [Value] -> [a]
- Clash.GHC.Evaluator: unsignedConPrim :: Type -> Term
- Clash.GHC.Evaluator: unsignedLitIntLit :: TyConMap -> [Type] -> [Value] -> Maybe (Type, Integer, Integer, Integer)
- Clash.GHC.Evaluator: unsignedLiterals :: [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: unsignedLiterals' :: [Value] -> [Integer]
- Clash.GHC.Evaluator: valArgs :: Value -> Maybe [Term]
- Clash.GHC.Evaluator: vecAppendPrim :: TyConName -> Term
- Clash.GHC.Evaluator: vecAppendTy :: TyConName -> Type
- Clash.GHC.Evaluator: vecHeadPrim :: TyConName -> Term
- Clash.GHC.Evaluator: vecHeadTy :: TyConName -> Type
- Clash.GHC.Evaluator: vecImapGoTy :: TyConName -> TyConName -> Type
- Clash.GHC.Evaluator: vecInitPrim :: TyConName -> Term
- Clash.GHC.Evaluator: vecLastPrim :: TyConName -> Term
- Clash.GHC.Evaluator: vecTailPrim :: TyConName -> Term
- Clash.GHC.Evaluator: vecTailTy :: TyConName -> Type
- Clash.GHC.Evaluator: vecZipWithPrim :: TyConName -> Term
- Clash.GHC.Evaluator: vecZipWithTy :: TyConName -> Type
- Clash.GHC.Evaluator: wordLiterals :: [Value] -> Maybe (Integer, Integer)
- Clash.GHC.Evaluator: wordLiterals' :: [Value] -> [Integer]
- Clash.GHC.LoadModules: wantedLanguageExtensions :: DynFlags -> DynFlags
+ Clash.GHC.Evaluator: instance Control.Monad.State.Class.MonadState Control.Concurrent.Supply.Supply Clash.GHC.Evaluator.PrimEvalMonad
+ Clash.GHC.Evaluator: primEvaluator :: PrimEvaluator
+ Clash.GHC.LoadModules: setWantedLanguageExtensions :: DynFlags -> DynFlags
+ Clash.GHCi.Common: checkClashDynamic :: DynFlags -> IO ()
- Clash.GHC.GenerateBindings: generateBindings :: OverridingBool -> [FilePath] -> [FilePath] -> [FilePath] -> HDL -> String -> Maybe DynFlags -> IO (BindingMap, TyConMap, IntMap TyConName, [(Id, Maybe TopEntity, Maybe Id)], CompiledPrimMap, [DataRepr'])
+ Clash.GHC.GenerateBindings: generateBindings :: OverridingBool -> [FilePath] -> [FilePath] -> [FilePath] -> HDL -> String -> Maybe DynFlags -> IO (BindingMap, TyConMap, IntMap TyConName, [TopEntityT], CompiledPrimMap, [DataRepr'])

Files

CHANGELOG.md view
@@ -1,36 +1,155 @@-# Changelog for the [`clash-ghc`](http://hackage.haskell.org/package/clash-ghc) package+# Changelog for the Clash project -## 1.0.1+## 1.2.0 *March 5th 2020*+As promised when releasing 1.0, we've tried our best to keep the API stable. We+think most designs will continue to compile with this new version, although special+care needs to be taken when using:++  * Use inline blackboxes. Instead of taking a single HDL, inline primitives now+    take multiple. For example, `InlinePrimitive VHDL ".."` must now be written+    as `InlinePrimitive [VHDL] ".."`.++  * Use the `Enum` instance for `BitVector`, `Index`, `Signed`, or `Unsigned`, as+    they now respect their `maxBound`. See [#1089](https://github.com/clash-lang/clash-compiler/issues/1089).++On top of that, we've added a number of new features:++  * `makeTopEntity`: Template Haskell function for generating TopEntity annotations. See [the documentation on Haddock](http://hackage.haskell.org/package/clash-prelude-1.2.0/docs/Clash-Annotations-TopEntity.html) for more information.++  * `Clash.Explicit.SimIO`: ((System)Verilog only) I/O actions that can be translated to HDL I/O. See [the documentation on Haddock](http://hackage.haskell.org/package/clash-prelude-1.2.0/docs/Clash-Explicit-SimIO.html) for more information.++  * `Clash.Class.AutoReg`: A smart register that improves the chances of synthesis tools inferring clock-gated registers, when used. See [the documentation on Haddock](http://hackage.haskell.org/package/clash-prelude-1.2.0/docs/Clash-Class-AutoReg.html) for more information.++The full list of changes follows. Happy hacking!++* New features (API):+  * `Clash.Class.Parity` type class replaces Prelude `odd` and `even` functions due to assumptions that don't hold for Clash specific numerical types, see [#970](https://github.com/clash-lang/clash-compiler/pull/970).+  * `NFDataX.ensureSpine`, see [#748](https://github.com/clash-lang/clash-compiler/pull/803)+  * `makeTopEntity` Template Haskell function for generating TopEntity annotations+    intended to cover the majority of use cases. Generation failures should either+    result in an explicit error, or a valid annotation of an empty `PortProduct`.+    Any discrepancy between the _shape_ of generated annotations and the _shape_+    of the Clash compiler is a bug. See [#795](https://github.com/clash-lang/clash-compiler/pull/795).+    Known limitations:+    * Type application (excluding `Signal`s and `:::`) is best effort:+    * Data types with type parameters will work if the generator can discover a single relevant constructor after attempting type application.+    * Arbitrary explicit clock/reset/enables are supported, but only a single `HiddenClockResetEnable` constraint is supported.+    * Data/type family support is best effort.+  * Added `Bundle ((f :*: g) a)` instance+  * Added `NFDataX CUShort` instance+  * Clash's internal type family solver now recognizes `AppendSymbol` and `CmpSymbol`+  * Added `Clash.Magic.suffixNameFromNat`: can be used in cases where `suffixName` is too slow+  * Added `Clash.Class.AutoReg`. Improves the chances of synthesis tools inferring clock-gated registers, when used. See [#873](https://github.com/clash-lang/clash-compiler/pull/873).+  * `Clash.Magic.suffixNameP`, `Clash.Magic.suffixNameFromNatP`: enable prefixing of name suffixes+  * Added `Clash.Magic.noDeDup`: can be used to instruct Clash to /not/ share a function between multiple branches+  * A `BitPack a` constraint now implies a `KnownNat (BitSize a)` constraint, so you won't have to add it manually anymore. See [#942](https://github.com/clash-lang/clash-compiler/pull/942).+  * `Clash.Explicit.SimIO`: ((System)Verilog only) I/O actions that can be translated to HDL I/O; useful for generated test benches.+  * Export `Clash.Explicit.Testbench.assertBitVector` [#888](https://github.com/clash-lang/clash-compiler/pull/888/files)+  * Add `Clash.Prelude.Testbench.assertBitVector` to achieve feature parity with `Clash.Explicit.Testbench`. [#891](https://github.com/clash-lang/clash-compiler/pull/891/files)+  * Add `Clash.XException.NFDataX.ensureSpine` [#803](https://github.com/clash-lang/clash-compiler/pull/803)+  * Add `Clash.Class.BitPack.bitCoerceMap` [#798](https://github.com/clash-lang/clash-compiler/pull/798)+  * Add `Clash.Magic.deDup`: instruct Clash to force sharing an operator between multiple branches of a case-expression+  * `InlinePrimitive` can now support multiple backends simultaneously [#425](https://github.com/clash-lang/clash-compiler/issues/425)+  * Add `Clash.XException.hwSeqX`: render declarations of an argument, but don't assign it to a result signal+  * Add `Clash.Signal.Bundle.TaggedEmptyTuple`: allows users to emulate the pre-1.0 behavior of "Bundle ()". See [#1100](https://github.com/clash-lang/clash-compiler/pull/1100)++* New features (Compiler):+  * [#961](https://github.com/clash-lang/clash-compiler/pull/961): Show `-fclash-*` Options in `clash --show-options`++* New internal features:+  * [#918](https://github.com/clash-lang/clash-compiler/pull/935): Add X-Optimization to normalization passes (-fclash-aggressive-x-optimization)+  * [#821](https://github.com/clash-lang/clash-compiler/pull/821): Add `DebugTry`: print name of all tried transformations, even if they didn't succeed+  * [#856](https://github.com/clash-lang/clash-compiler/pull/856): Add `-fclash-debug-transformations`: only print debug info for specific transformations+  * [#911](https://github.com/clash-lang/clash-compiler/pull/911): Add 'RenderVoid' option to blackboxes+  * [#958](https://github.com/clash-lang/clash-compiler/pull/958): Prefix names of inlined functions+  * [#947](https://github.com/clash-lang/clash-compiler/pull/947): Add "Clash.Core.TermLiteral"+  * [#887](https://github.com/clash-lang/clash-compiler/pull/887): Show nicer error messages when failing in TH code+  * [#884](https://github.com/clash-lang/clash-compiler/pull/884): Teach reduceTypeFamily about AppendSymbol and CmpSymbol+  * [#784](https://github.com/clash-lang/clash-compiler/pull/784): Print whether `Id` is global or local in ppr output+  * [#781](https://github.com/clash-lang/clash-compiler/pull/781): Use naming contexts in register names+  * [#1061](https://github.com/clash-lang/clash-compiler/pull/1061): Add 'usedArguments' to BlackBoxHaskell blackboxes+ * Fixes issues:+  * [#974](https://github.com/clash-lang/clash-compiler/issues/974): Fix indirect shadowing in `reduceNonRepPrim`+  * [#964](https://github.com/clash-lang/clash-compiler/issues/964): SaturatingNum instance of `Index` now behaves correctly when the size of the index overflows+  an `Int`.   * [#810](https://github.com/clash-lang/clash-compiler/issues/810): Verilog backend now correctly specifies type of `BitVector 1`   * [#811](https://github.com/clash-lang/clash-compiler/issues/811): Improve module load behavior in clashi   * [#439](https://github.com/clash-lang/clash-compiler/issues/439): Template Haskell splices and TopEntity annotations can now be used in clashi-  * [#818](https://github.com/clash-lang/clash-compiler/issues/818): Fixed various mistakes in tutorial   * [#662](https://github.com/clash-lang/clash-compiler/issues/662): Clash will now constant specialize partially constant constructs   * [#700](https://github.com/clash-lang/clash-compiler/issues/700): Check work content of expression in cast before warning users. Should eliminate a lot of (superfluous) warnings about "specializing on non work-free cast"s.   * [#837](https://github.com/clash-lang/clash-compiler/issues/837): Blackboxes will now report clearer error messages if they're given unexpected arguments.+  * [#869](https://github.com/clash-lang/clash-compiler/issues/869): PLL is no longer duplicated in Blinker.hs example+  * [#749](https://github.com/clash-lang/clash-compiler/issues/749): Clash's dependencies now all work with GHC 8.8, allowing `clash-{prelude,lib,ghc}` to be compiled from Hackage soon.+  * [#871](https://github.com/clash-lang/clash-compiler/issues/871): RTree Bundle instance is now properly lazy+  * [#895](https://github.com/clash-lang/clash-compiler/issues/895): VHDL type error when generating `Maybe (Vec 2 (Signed 8), Index 1)`+  * [#880](https://github.com/clash-lang/clash-compiler/issues/880): Custom bit representations can now be used on product types too+  * [#976](https://github.com/clash-lang/clash-compiler/issues/976): Prevent shadowing in Clash's core evaluator+  * [#1007](https://github.com/clash-lang/clash-compiler/issues/1007): Can't translate domain tagType.Errors.IfStuck...+  * [#967](https://github.com/clash-lang/clash-compiler/issues/967): Naming registers disconnects their output+  * [#990](https://github.com/clash-lang/clash-compiler/issues/990): Internal shadowing bug results in incorrect HDL+  * [#945](https://github.com/clash-lang/clash-compiler/issues/945): Rewrite rules for Vec Applicative Functor+  * [#919](https://github.com/clash-lang/clash-compiler/issues/919): Clash generating invalid Verilog after Vec operations #919+  * [#996](https://github.com/clash-lang/clash-compiler/issues/996): Ambiguous clock when using `ClearOnReset` and `resetGen` together+  * [#701](https://github.com/clash-lang/clash-compiler/issues/701): Unexpected behaviour with the `Synthesize` annotation+  * [#694](https://github.com/clash-lang/clash-compiler/issues/694): Custom bit representation error only with VHDL+  * [#347](https://github.com/clash-lang/clash-compiler/issues/347): topEntity synthesis fails due to insufficient type-level normalisation+  * [#626](https://github.com/clash-lang/clash-compiler/issues/626): Missing Clash.Explicit.Prelude definitions+  * [#960](https://github.com/clash-lang/clash-compiler/issues/626): Blackbox Error Caused by Simple map+  * [#1012](https://github.com/clash-lang/clash-compiler/issues/1012): Case-let doesn't look through ticks+  * [#430](https://github.com/clash-lang/clash-compiler/issues/430): Issue warning when not compiled with `executable-dynamic: True`+  * [#374](https://github.com/clash-lang/clash-compiler/issues/1012): Clash.Sized.Fixed: fromInteger and fromRational don't saturate correctly+  * [#836](https://github.com/clash-lang/clash-compiler/issues/836): Generate warning when `toInteger` blackbox drops MSBs+  * [#1019](https://github.com/clash-lang/clash-compiler/issues/1019): Clash breaks on constants defined in terms of `GHC.Natural.gcdNatural`+  * [#1025](https://github.com/clash-lang/clash-compiler/issues/1025): `inlineCleanup`will not produce empty letrecs anymore+  * [#1030](https://github.com/clash-lang/clash-compiler/issues/1030): `bindConstantVar` will bind (workfree) constructs+  * [#1034](https://github.com/clash-lang/clash-compiler/issues/1034): Error (10137): object "pllLock" on lhs must have a variable data type+  * [#1046](https://github.com/clash-lang/clash-compiler/issues/1046): Don't confuse term/type namespaces in 'lookupIdSubst'+  * [#1041](https://github.com/clash-lang/clash-compiler/issues/1041): Nested product types incorrectly decomposed into ports+  * [#1058](https://github.com/clash-lang/clash-compiler/issues/1058): Prevent substitution warning when using type equalities in top entities+  * [#1033](https://github.com/clash-lang/clash-compiler/issues/1033): Fix issue where Clash breaks when using Clock/Reset/Enable in product types in combination with Synthesize annotations+  * [#1075](https://github.com/clash-lang/clash-compiler/issues/1075): Removed superfluous constraints on 'maybeX' and 'maybeIsX'+  * [#1085](https://github.com/clash-lang/clash-compiler/issues/1085): Suggest exporting topentities if they can't be found in a module+  * [#1065](https://github.com/clash-lang/clash-compiler/pull/1065): Report polymorphic topEntities as errors+  * [#1089](https://github.com/clash-lang/clash-compiler/issues/1089): Respect maxBound in Enum instances for BitVector,Index,Signed,Unsigned -* Small fixes without issue reports:-  * Fix bug in `rnfX` defined for `Down` ([814fd52](https://github.com/clash-lang/clash-compiler/commit/814fd520191123be38af8ef28fc49130424f3b93))+* Fixes without issue reports:+  * Fix bug in `rnfX` defined for `Down` ([baef30e](https://github.com/clash-lang/clash-compiler/commit/baef30eae03dc02ba847ffbb8fae7f365c5287c2))+  * Render numbers inside gensym ([bc76f0f](https://github.com/clash-lang/clash-compiler/commit/bc76f0f1934fd6e6ed9c33bcf950dae21e2f7903))   * Report blackbox name when encountering an error in 'setSym' ([#858](https://github.com/clash-lang/clash-compiler/pull/858))+  * Fix blackbox issues causing Clash to generate invalid HDL ([#865](https://github.com/clash-lang/clash-compiler/pull/865))+  * Treat types with a zero-width custom bit representation like other zero-width constructs ([#874](https://github.com/clash-lang/clash-compiler/pull/874))+  * TH code for auto deriving bit representations now produces nicer error messages ([7190793](https://github.com/clash-lang/clash-compiler/commit/7190793928545f85157f9b8d4b8ec2edb2cd8a26))+  * Adds '--enable-shared-executables' for nix builds; this should make Clash run _much_ faster ([#894](https://github.com/clash-lang/clash-compiler/pull/894))+  * Custom bit representations can now mark fields as zero-width without crashing the compiler ([#898](https://github.com/clash-lang/clash-compiler/pull/898))+  * Throw an error if there's data left to parse after successfully parsing a valid JSON construct ([#904](https://github.com/clash-lang/clash-compiler/pull/904))+  * `Data.gfoldl` is now manually implemented, in turn fixing issues with `gshow` ([#933](https://github.com/clash-lang/clash-compiler/pull/933))+  * Fix a number of issues with blackbox implementations ([#934](https://github.com/clash-lang/clash-compiler/pull/934))+  * Don't inline registers with non-constant clock and reset ([#998](https://github.com/clash-lang/clash-compiler/pull/998))+  * Inline let-binders called [dsN | N <- [1..]] ([#992](https://github.com/clash-lang/clash-compiler/pull/992))+  * ClockGens use their name at the Haskell level [#827](https://github.com/clash-lang/clash-compiler/pull/827)+  * Render numbers inside gensym [#809](https://github.com/clash-lang/clash-compiler/pull/809)+  * Don't overwrite existing binders when specializing [#790](https://github.com/clash-lang/clash-compiler/pull/790)+  * Deshadow in 'caseCase' [#1067](https://github.com/clash-lang/clash-compiler/pull/1067)+  * Deshadow in 'caseLet' and 'nonRepANF' [#1071](https://github.com/clash-lang/clash-compiler/pull/1071) +* Deprecations & removals:+  * Removed support for GHC 8.2 ([#842](https://github.com/clash-lang/clash-compiler/pull/842))+  * Removed support for older cabal versions, only Cabal >=2.2 supported ([#851](https://github.com/clash-lang/clash-compiler/pull/851))+  * Reset and Enable constructors are now only exported from Clash.Signal.Internal+  * [#986](https://github.com/clash-lang/clash-compiler/issues/986) Remove -fclash-allow-zero-width flag+ ## 1.0.0 *September 3rd 2019* * 10x - 50x faster compile times * New features:   * API changes: check the migration guide at the end of `Clash.Tutorial`-  * All memory elements now have an (implicit) enable line; "Gated" clocks have-    been removed as the clock wasn't actually gated, but implemented as an-    enable line.+  * All memory elements now have an (implicit) enable line; "Gated" clocks have been removed as the clock wasn't actually gated, but implemented as an enable line.   * Circuit domains are now configurable in:     * (old) The clock period-    * (new) Clock edge on which memory elements latch their inputs-      (rising edge or falling edge)-    * (new) Whether the reset port of a memory element is level sensitive-      (asynchronous reset) or edge sensitive (synchronous reset)-    * (new) Whether the reset port of a memory element is active-high or-      active-low (negated reset)-    * (new) Whether memory element power on in a configurable/defined state-      (common on FPGAs) or in an undefined state (ASICs)+    * (new) Clock edge on which memory elements latch their inputs (rising edge or falling edge)+    * (new) Whether the reset port of a memory element is level sensitive asynchronous reset) or edge sensitive (synchronous reset)+    * (new) Whether the reset port of a memory element is active-high or active-low (negated reset)+    * (new) Whether memory element power on in a configurable/defined state (common on FPGAs) or in an undefined state (ASICs)      * See the [blog post](https://clash-lang.org/blog/0005-synthesis-domain/) on this new feature   * Data types can now be given custom bit-representations: http://hackage.haskell.org/package/clash-prelude/docs/Clash-Annotations-BitRepresentation.html@@ -50,95 +169,95 @@     See for example: http://hackage.haskell.org/package/clash-lib/docs/Clash-Primitives-Intel-ClockGen.html  * Fixes issues:-  * [#316](https://github.com/clash-lang/clash-prelude/issues/316)-  * [#319](https://github.com/clash-lang/clash-prelude/issues/319)-  * [#323](https://github.com/clash-lang/clash-prelude/issues/323)-  * [#324](https://github.com/clash-lang/clash-prelude/issues/324)-  * [#329](https://github.com/clash-lang/clash-prelude/issues/329)-  * [#331](https://github.com/clash-lang/clash-prelude/issues/331)-  * [#332](https://github.com/clash-lang/clash-prelude/issues/332)-  * [#335](https://github.com/clash-lang/clash-prelude/issues/335)-  * [#348](https://github.com/clash-lang/clash-prelude/issues/348)-  * [#349](https://github.com/clash-lang/clash-prelude/issues/349)-  * [#350](https://github.com/clash-lang/clash-prelude/issues/350)-  * [#351](https://github.com/clash-lang/clash-prelude/issues/351)-  * [#352](https://github.com/clash-lang/clash-prelude/issues/352)-  * [#353](https://github.com/clash-lang/clash-prelude/issues/353)-  * [#358](https://github.com/clash-lang/clash-prelude/issues/358)-  * [#359](https://github.com/clash-lang/clash-prelude/issues/359)-  * [#363](https://github.com/clash-lang/clash-prelude/issues/363)-  * [#364](https://github.com/clash-lang/clash-prelude/issues/364)-  * [#365](https://github.com/clash-lang/clash-prelude/issues/365)-  * [#371](https://github.com/clash-lang/clash-prelude/issues/371)-  * [#372](https://github.com/clash-lang/clash-prelude/issues/372)-  * [#373](https://github.com/clash-lang/clash-prelude/issues/373)-  * [#378](https://github.com/clash-lang/clash-prelude/issues/378)-  * [#380](https://github.com/clash-lang/clash-prelude/issues/380)-  * [#381](https://github.com/clash-lang/clash-prelude/issues/381)-  * [#382](https://github.com/clash-lang/clash-prelude/issues/382)-  * [#383](https://github.com/clash-lang/clash-prelude/issues/383)-  * [#387](https://github.com/clash-lang/clash-prelude/issues/387)-  * [#393](https://github.com/clash-lang/clash-prelude/issues/393)-  * [#396](https://github.com/clash-lang/clash-prelude/issues/396)-  * [#398](https://github.com/clash-lang/clash-prelude/issues/398)-  * [#399](https://github.com/clash-lang/clash-prelude/issues/399)-  * [#401](https://github.com/clash-lang/clash-prelude/issues/401)-  * [#403](https://github.com/clash-lang/clash-prelude/issues/403)-  * [#407](https://github.com/clash-lang/clash-prelude/issues/407)-  * [#412](https://github.com/clash-lang/clash-prelude/issues/412)-  * [#413](https://github.com/clash-lang/clash-prelude/issues/413)-  * [#420](https://github.com/clash-lang/clash-prelude/issues/420)-  * [#422](https://github.com/clash-lang/clash-prelude/issues/422)-  * [#423](https://github.com/clash-lang/clash-prelude/issues/423)-  * [#424](https://github.com/clash-lang/clash-prelude/issues/424)-  * [#438](https://github.com/clash-lang/clash-prelude/issues/438)-  * [#450](https://github.com/clash-lang/clash-prelude/issues/450)-  * [#452](https://github.com/clash-lang/clash-prelude/issues/452)-  * [#455](https://github.com/clash-lang/clash-prelude/issues/455)-  * [#460](https://github.com/clash-lang/clash-prelude/issues/460)-  * [#461](https://github.com/clash-lang/clash-prelude/issues/461)-  * [#463](https://github.com/clash-lang/clash-prelude/issues/463)-  * [#468](https://github.com/clash-lang/clash-prelude/issues/468)-  * [#475](https://github.com/clash-lang/clash-prelude/issues/475)-  * [#476](https://github.com/clash-lang/clash-prelude/issues/476)-  * [#500](https://github.com/clash-lang/clash-prelude/issues/500)-  * [#507](https://github.com/clash-lang/clash-prelude/issues/507)-  * [#512](https://github.com/clash-lang/clash-prelude/issues/512)-  * [#516](https://github.com/clash-lang/clash-prelude/issues/516)-  * [#517](https://github.com/clash-lang/clash-prelude/issues/517)-  * [#526](https://github.com/clash-lang/clash-prelude/issues/526)-  * [#556](https://github.com/clash-lang/clash-prelude/issues/556)-  * [#560](https://github.com/clash-lang/clash-prelude/issues/560)-  * [#566](https://github.com/clash-lang/clash-prelude/issues/566)-  * [#567](https://github.com/clash-lang/clash-prelude/issues/567)-  * [#569](https://github.com/clash-lang/clash-prelude/issues/569)-  * [#573](https://github.com/clash-lang/clash-prelude/issues/573)-  * [#575](https://github.com/clash-lang/clash-prelude/issues/575)-  * [#581](https://github.com/clash-lang/clash-prelude/issues/581)-  * [#582](https://github.com/clash-lang/clash-prelude/issues/582)-  * [#586](https://github.com/clash-lang/clash-prelude/issues/586)-  * [#588](https://github.com/clash-lang/clash-prelude/issues/588)-  * [#591](https://github.com/clash-lang/clash-prelude/issues/591)-  * [#596](https://github.com/clash-lang/clash-prelude/issues/596)-  * [#601](https://github.com/clash-lang/clash-prelude/issues/601)-  * [#607](https://github.com/clash-lang/clash-prelude/issues/607)-  * [#629](https://github.com/clash-lang/clash-prelude/issues/629)-  * [#637](https://github.com/clash-lang/clash-prelude/issues/637)-  * [#644](https://github.com/clash-lang/clash-prelude/issues/644)-  * [#647](https://github.com/clash-lang/clash-prelude/issues/647)-  * [#661](https://github.com/clash-lang/clash-prelude/issues/661)-  * [#668](https://github.com/clash-lang/clash-prelude/issues/668)-  * [#677](https://github.com/clash-lang/clash-prelude/issues/677)-  * [#678](https://github.com/clash-lang/clash-prelude/issues/678)-  * [#682](https://github.com/clash-lang/clash-prelude/issues/682)-  * [#691](https://github.com/clash-lang/clash-prelude/issues/691)-  * [#703](https://github.com/clash-lang/clash-prelude/issues/703)-  * [#713](https://github.com/clash-lang/clash-prelude/issues/713)-  * [#715](https://github.com/clash-lang/clash-prelude/issues/715)-  * [#727](https://github.com/clash-lang/clash-prelude/issues/727)-  * [#730](https://github.com/clash-lang/clash-prelude/issues/730)-  * [#736](https://github.com/clash-lang/clash-prelude/issues/736)-  * [#738](https://github.com/clash-lang/clash-prelude/issues/738)+  * [#316](https://github.com/clash-lang/clash-compiler/issues/316)+  * [#319](https://github.com/clash-lang/clash-compiler/issues/319)+  * [#323](https://github.com/clash-lang/clash-compiler/issues/323)+  * [#324](https://github.com/clash-lang/clash-compiler/issues/324)+  * [#329](https://github.com/clash-lang/clash-compiler/issues/329)+  * [#331](https://github.com/clash-lang/clash-compiler/issues/331)+  * [#332](https://github.com/clash-lang/clash-compiler/issues/332)+  * [#335](https://github.com/clash-lang/clash-compiler/issues/335)+  * [#348](https://github.com/clash-lang/clash-compiler/issues/348)+  * [#349](https://github.com/clash-lang/clash-compiler/issues/349)+  * [#350](https://github.com/clash-lang/clash-compiler/issues/350)+  * [#351](https://github.com/clash-lang/clash-compiler/issues/351)+  * [#352](https://github.com/clash-lang/clash-compiler/issues/352)+  * [#353](https://github.com/clash-lang/clash-compiler/issues/353)+  * [#358](https://github.com/clash-lang/clash-compiler/issues/358)+  * [#359](https://github.com/clash-lang/clash-compiler/issues/359)+  * [#363](https://github.com/clash-lang/clash-compiler/issues/363)+  * [#364](https://github.com/clash-lang/clash-compiler/issues/364)+  * [#365](https://github.com/clash-lang/clash-compiler/issues/365)+  * [#371](https://github.com/clash-lang/clash-compiler/issues/371)+  * [#372](https://github.com/clash-lang/clash-compiler/issues/372)+  * [#373](https://github.com/clash-lang/clash-compiler/issues/373)+  * [#378](https://github.com/clash-lang/clash-compiler/issues/378)+  * [#380](https://github.com/clash-lang/clash-compiler/issues/380)+  * [#381](https://github.com/clash-lang/clash-compiler/issues/381)+  * [#382](https://github.com/clash-lang/clash-compiler/issues/382)+  * [#383](https://github.com/clash-lang/clash-compiler/issues/383)+  * [#387](https://github.com/clash-lang/clash-compiler/issues/387)+  * [#393](https://github.com/clash-lang/clash-compiler/issues/393)+  * [#396](https://github.com/clash-lang/clash-compiler/issues/396)+  * [#398](https://github.com/clash-lang/clash-compiler/issues/398)+  * [#399](https://github.com/clash-lang/clash-compiler/issues/399)+  * [#401](https://github.com/clash-lang/clash-compiler/issues/401)+  * [#403](https://github.com/clash-lang/clash-compiler/issues/403)+  * [#407](https://github.com/clash-lang/clash-compiler/issues/407)+  * [#412](https://github.com/clash-lang/clash-compiler/issues/412)+  * [#413](https://github.com/clash-lang/clash-compiler/issues/413)+  * [#420](https://github.com/clash-lang/clash-compiler/issues/420)+  * [#422](https://github.com/clash-lang/clash-compiler/issues/422)+  * [#423](https://github.com/clash-lang/clash-compiler/issues/423)+  * [#424](https://github.com/clash-lang/clash-compiler/issues/424)+  * [#438](https://github.com/clash-lang/clash-compiler/issues/438)+  * [#450](https://github.com/clash-lang/clash-compiler/issues/450)+  * [#452](https://github.com/clash-lang/clash-compiler/issues/452)+  * [#455](https://github.com/clash-lang/clash-compiler/issues/455)+  * [#460](https://github.com/clash-lang/clash-compiler/issues/460)+  * [#461](https://github.com/clash-lang/clash-compiler/issues/461)+  * [#463](https://github.com/clash-lang/clash-compiler/issues/463)+  * [#468](https://github.com/clash-lang/clash-compiler/issues/468)+  * [#475](https://github.com/clash-lang/clash-compiler/issues/475)+  * [#476](https://github.com/clash-lang/clash-compiler/issues/476)+  * [#500](https://github.com/clash-lang/clash-compiler/issues/500)+  * [#507](https://github.com/clash-lang/clash-compiler/issues/507)+  * [#512](https://github.com/clash-lang/clash-compiler/issues/512)+  * [#516](https://github.com/clash-lang/clash-compiler/issues/516)+  * [#517](https://github.com/clash-lang/clash-compiler/issues/517)+  * [#526](https://github.com/clash-lang/clash-compiler/issues/526)+  * [#556](https://github.com/clash-lang/clash-compiler/issues/556)+  * [#560](https://github.com/clash-lang/clash-compiler/issues/560)+  * [#566](https://github.com/clash-lang/clash-compiler/issues/566)+  * [#567](https://github.com/clash-lang/clash-compiler/issues/567)+  * [#569](https://github.com/clash-lang/clash-compiler/issues/569)+  * [#573](https://github.com/clash-lang/clash-compiler/issues/573)+  * [#575](https://github.com/clash-lang/clash-compiler/issues/575)+  * [#581](https://github.com/clash-lang/clash-compiler/issues/581)+  * [#582](https://github.com/clash-lang/clash-compiler/issues/582)+  * [#586](https://github.com/clash-lang/clash-compiler/issues/586)+  * [#588](https://github.com/clash-lang/clash-compiler/issues/588)+  * [#591](https://github.com/clash-lang/clash-compiler/issues/591)+  * [#596](https://github.com/clash-lang/clash-compiler/issues/596)+  * [#601](https://github.com/clash-lang/clash-compiler/issues/601)+  * [#607](https://github.com/clash-lang/clash-compiler/issues/607)+  * [#629](https://github.com/clash-lang/clash-compiler/issues/629)+  * [#637](https://github.com/clash-lang/clash-compiler/issues/637)+  * [#644](https://github.com/clash-lang/clash-compiler/issues/644)+  * [#647](https://github.com/clash-lang/clash-compiler/issues/647)+  * [#661](https://github.com/clash-lang/clash-compiler/issues/661)+  * [#668](https://github.com/clash-lang/clash-compiler/issues/668)+  * [#677](https://github.com/clash-lang/clash-compiler/issues/677)+  * [#678](https://github.com/clash-lang/clash-compiler/issues/678)+  * [#682](https://github.com/clash-lang/clash-compiler/issues/682)+  * [#691](https://github.com/clash-lang/clash-compiler/issues/691)+  * [#703](https://github.com/clash-lang/clash-compiler/issues/703)+  * [#713](https://github.com/clash-lang/clash-compiler/issues/713)+  * [#715](https://github.com/clash-lang/clash-compiler/issues/715)+  * [#727](https://github.com/clash-lang/clash-compiler/issues/727)+  * [#730](https://github.com/clash-lang/clash-compiler/issues/730)+  * [#736](https://github.com/clash-lang/clash-compiler/issues/736)+  * [#738](https://github.com/clash-lang/clash-compiler/issues/738)  ## 0.99.3 *July 28th 2018* * Fixes bugs:@@ -150,16 +269,38 @@   * Create empty component when result needs 0 bits   * Evaluator performs BigNat arithmetic +* Features:+  * Bundle and BitPack instances up to and including 62-tuples+  * Handle undefined writes to RAM properly+  * Handle undefined clock enables properly++ ## 0.99.1 *May 12th 2018* * Allow `~NAME[N]` tag inside `~GENSYM[X]` * Support HDL record selector generation [#313](https://github.com/clash-lang/clash-compiler/pull/313) * `InlinePrimitive` support: specify HDL primitives inline with Haskell code+* Support for `ghc-typelits-natnormalise-0.6.1`+* `Lift` instances for `TopEntity` and `PortName`+* `InlinePrimitive` support: specify HDL primitives inline with Haskell code  ## 0.99 *March 31st 2018* * New features:-  * Support for `clash-prelude-0.99`:-      * Explicit clock and reset arguments-      * Overhaul of `TopEntity` annotations+  * Major API overhaul: check the migration guide at the end of `Clash.Tutorial`+  * New features:+    * Explicit clock and reset arguments+    * Rename `CLaSH` to `Clash`+    * Implicit/`Hidden` clock and reset arguments using a combination of+    `reflection` and `ImplicitParams`.+    * Large overhaul of `TopEntity`  annotations+    * PLL and other clock sources can now be instantiated using regular functions:+    `Clash.Intel.ClockGen` and `Clash.Xilinx.ClockGen`.+    * DDR registers:+      * Generic/ASIC: `Clash.Explicit.DDR`+      * Intel: `Clash.Intel.DDR`+      * Xilinx: `Clash.Intel.Xilinx`+  * `Bit` is now a `newtype` instead of a `type` synonym and will be mapped to+    a HDL scalar instead of an array of one (e.g `std_logic` instead of+    `std_logic_vector(0 downto 0)`)   * Hierarchies with multiple synthesisable boundaries by allowing more than one     function in scope to have a `Synthesize` annotation.     * Local caching of functions with a `Synthesize` annotation@@ -169,357 +310,10 @@   * Improved compile-time computation * Many bug fixes -## 0.7.2-* New features:-  * Sum-of-product types: unused bits now "don't-care" [#212](https://github.com/clash-lang/clash-compiler/commit/fabf745793491ce3baf84ef0066b4ccf0753d503)-* Fixes bugs:-  * Eagerness bug in `regEn` [#104](https://github.com/clash-lang/clash-prelude/issues/104) (Thanks to @cbiffle)+## Older versions+Check out:+ * https://github.com/clash-lang/clash-compiler/blob/3649a2962415ea8ca2d6f7f5e673b4c14de26b4f/clash-prelude/CHANGELOG.md+ * https://github.com/clash-lang/clash-compiler/blob/3649a2962415ea8ca2d6f7f5e673b4c14de26b4f/clash-lib/CHANGELOG.md+ * https://github.com/clash-lang/clash-compiler/blob/3649a2962415ea8ca2d6f7f5e673b4c14de26b4f/clash-ghc/CHANGELOG.md -## 0.7.1 *April 11th 2017*-* New features:-  * Support distribution of primitive templates with Cabal/Hackage packages [commit](https://github.com/clash-lang/clash-compiler/commit/82cd31863aafcbaf3bdbf7746d89d13859af5aaf)-  * Find memory data files and primitive files relative to import dirs (`-i<DIR>`)-  * Add 'clashi' program and 'clash-ghc' package [#208](https://github.com/clash-lang/clash-compiler/issues/208), thanks to @thoughtpolice-* Fixes bugs:-  * `case (EmptyCase ty) of ty' { ... }` -> `EmptyCase ty'` [#198](https://github.com/clash-lang/clash-compiler/issues/198)-  * `BitVector.split#` apply the correct type arguments -## 0.7.0.1 *January 17th 2017-* Fixes bugs:-  * Include HsVersions.h in source distribution--## 0.7 *January 16th 2017*-* New features:-  * Support for `clash-prelude` 0.11-  * Primitive templates can include QSys files-  * VHDL blackboxes: support additional libraries and uses keywords in generated VHDL-  * Highly limited Float/Double support (literals and `Rational` conversion), hidden behind the `-clash-float-support` flag.-* Fixes bugs:-  * Reduce type families inside clock period calculation [#180](https://github.com/clash-lang/clash-compiler/issues/180)-  * Only output signed literals as hex when they're multiple of 4 bits [#187](https://github.com/clash-lang/clash-compiler/issues/187)-  * Correctly print negative hex literals--## 0.6.24 *October 17th 20168-* Call generatePrimMap after loadModules [#175](https://github.com/clash-lang/clash-compiler/pull/175)-* Fixes bugs:-  * (System)Verilog: CLaSH.Sized.Vector.imap primitive gets indices in reverse order-  * Template Haskell splices are run twice-  * CLaSH errors out when observing the constructor for `Signal` [#174](https://github.com/clash-lang/clash-compiler/issues/174)--## 0.6.23 *August 18th 2015*-* Fixes bugs:-  * Type families are not being reduced correctly  [#167](https://github.com/clash-lang/clash-compiler/issues/167)-  * (System)Verilog: Fix primitives for {Signed,Unsigned} rotateL# and rotateR# [#169](https://github.com/clash-lang/clash-compiler/issues/169)--## 0.6.22 *August 3rd 2016*-* Fixes bugs:-  * Bug in DEC transformation overwrites case-alternatives-  * Bug in DEC transformation creates non-representable let-binders-  * VHDL: Incorrect primitive for `Integer`s `ltInteger#` and `geInteger#`-  * (System)Verilog: Fix primitive for CLaSH.Sized.Internal.Signed.mod# and GHC.Type.Integer.modInteger [#164](https://github.com/clash-lang/clash-compiler/issues/164)--## 0.6.21 *July 19th 2016*-* Fixes bugs:-  * Rounding error in `logBase` calculation-  * VHDL: Incorrect primitive for `Index`s `*#`-  * VHDL: Incorrect handling of `Index`s `fromInteger#` and `maxBound#` primitives for values larger than 2^MACHINE_WIDTH--## 0.6.20 *July 15th 2016*-* New features:-  * Better error location reporting-* Fixes bugs:-  * `CLaSH.Sized.Internal.Unsigned.maxBound#` not evaluated at compile-time [#155](https://github.com/clash-lang/clash-compiler/issues/155)-  * `CLaSH.Sized.Internal.Unsigned.minBound#` not evaluated at compile-time [#157](https://github.com/clash-lang/clash-compiler/issues/157)-  * Values of type Index 'n', where 'n' > 2^MACHINE_WIDTH, incorrectly considered non-synthesisable due to overflow-  * VHDL: Types in generated types.vhdl incorrectly sorted-  * Casts of CLaSH numeric types result in incorrect VHDL/Verilog (Such casts are now reported as an error)--## 0.6.19 *June 9th 2016*-* Fixes bugs:-  * `Eq` instance of `Vec` sometimes not synthesisable-  * VHDL: Converting product types to std_logic_vector fails when the `clash-hdlsyn Vivado` flag is enabled--## 0.6.18 *June 7th 2016*-* New features:-  * DEC transformation also lifts HO-primitives applied to "interesting" primitives (i.e. `zipWith (*)`)-  * New `-clash-hdlsyn Xilinx` flag to generate HDL tweaked for Xilinx synthesis tools (both ISE and Vivado)-* Fixes bugs:-  * replicate unfolded incorrectly [#150](https://github.com/clash-lang/clash-compiler/issues/150)-  * `imap` is not unrolled [#151](https://github.com/clash-lang/clash-compiler/issues/151)-  * VHDL: Incorrect primitive specification for `snatToInteger` [#149](https://github.com/clash-lang/clash-compiler/issues/149)--## 0.6.17 *April 7th 2016*-* New features:-  * Up to 2x reduced compilation times when working with large `Vec` literals-* Fixes bugs:-  * VHDL: Incorrect primitives for `BitVector`s `quot#` and `rem#`-  * VHDL: Bit indexing and replacement primitives fail to synthesise in Synopsis tools-  * Bug in DEC transformation throws CLaSH into an endless loop [#140](https://github.com/clash-lang/clash-compiler/issues/140)-  * Missed constant folding opportunity results in an error [#50](https://github.com/clash-lang/clash-prelude/issues/50)--## 0.6.16 *March 21st 2016*-* New features:-  * Also generate testbench for circuits without input ports [#135](https://github.com/clash-lang/clash-compiler/issues/135)-* Fixes bugs:-  * `clockWizard` broken [#49](https://github.com/clash-lang/clash-prelude/issues/49)--## 0.6.15 *March 15th 2016*-* Fixes bugs:-  * XST cannot finds "_types" package unless it is prefixed with "work." [#133](https://github.com/clash-lang/clash-compiler/pull/133)--## 0.6.14 *March 15th 2016*-* Fixes bugs:-  * XST cannot finds "_types" package unless it is prefixed with "work." [#133](https://github.com/clash-lang/clash-compiler/pull/133)--## 0.6.13 *March 14th 2016*-* Fixes bugs:-  * Not all lambda's in a function position removed--## 0.6.12 *March 14th 2016*-* Fixes bugs:-  * Not all lambda's in a function position removed due to bad eta-expansion [#132](https://github.com/clash-lang/clash-compiler/issues/132)--## 0.6.11 *March 11th 2016*-* New features:-  * Add support for HDL synthesis tool specific HDL generation:-    * New `-clash-hdlsyn Vivado` flag to generate HDL tweaked for Xilinx Vivado-  * Preserve more Haskell names in generated HDL [#128](https://github.com/clash-lang/clash-compiler/issues/128)-* Fixes bugs:-  * VHDL: Vivado fails to infer block ram [#127](https://github.com/clash-lang/clash-compiler/issues/127)-    * Users must use the `-clash-hdlsyn Vivado` flag in order to generate Xilinx Vivado specific HDL for which Vivado can infer block RAM.--## 0.6.10 *February 10th 2016*-* New features:-  * hdl files can be written to a directory (set by the `-clash-hdldir` flag) other than the current working directory [#125](https://github.com/clash-lang/clash-compiler/issues/125).-    Also respects the `-outputdir` directory, _unless_:-      * `-clash-hdldir` is set to a different directory.-      * `-hidir`, `-stubdir`, and `-dumbdir` are not the same directory as `-odir`-* Fixes bugs:-  * `caseCon` transformation does not work on non-exhaustive case-expressions [#123](https://github.com/clash-lang/clash-compiler/issues/123)-  * VHDL: insufficient type-qualifiers for concatenation operator [#121](https://github.com/clash-lang/clash-compiler/issues/121)-  * Primitive reductions don't look through `Signal` [#126](https://github.com/clash-lang/clash-compiler/issues/126)--## 0.6.9 *January 29th 2016*-* New features:-  * Support for `Debug.Trace.trace`, thanks to @ggreif--* Fixes bugs:-  * `case undefined of ...` should reduce to `undefined` [#116](https://github.com/clash-lang/clash-compiler/issues/109)-  * VHDL/SystemVerilog: BlockRAM elements must be bit vectors [#113](https://github.com/clash-lang/clash-compiler/issues/113)-  * Type families obscure eligibility for synthesis [#114](https://github.com/clash-lang/clash-compiler/issues/114)--## 0.6.8 *January 13th 2016*-* New features:-  * Support for Haskell's: `Char`, `Int8`, `Int16`, `Int32`, `Int64`, `Word`, `Word8`, `Word16`, `Word32`, `Word64`.-  * Int/Word/Integer bitwidth for generated HDL is configurable using the `-clash-intwidth=N` flag, where `N` can be either 32 or 64.-* Fixes bugs:-  * Cannot reduce `case error ... of ...` to `error ...` [#109](https://github.com/clash-lang/clash-compiler/issues/109)--## 0.6.7 *December 21st 2015*-* Support for `unbound-generics-0.3`-* New features:-  * Only look for 'topEntity' in the root module. [#22](https://github.com/clash-lang/clash-compiler/issues/22)-* Fixes bugs:-  * Unhelpful error message when GHC is not in PATH [#104](https://github.com/clash-lang/clash-compiler/issues/104)--## 0.6.6 *December 11th 2015*-* New features:-  * Remove all existing HDL files before generating new ones. This can be disabled by the `-clash-noclean` flag. [#96](https://github.com/clash-lang/clash-compiler/issues/96)-  * Support for `clash-prelude` 0.10.4--## 0.6.5 *November 17th 2015*-* Fixes bugs:-  * Integer literals used as arguments not always properly annotated with their type.-  * Verilog: Name collision in verilog code [#93](https://github.com/clash-lang/clash-compiler/issues/93)-  * (System)Verilog: Integer literals missing "32'sd" prefix when used in assignments.-  * VHDL: Integer literals should only be capped to 32-bit when used in assignments.-  * Verilog: HO-primitives incorrect for nested vectors.--## 0.6.4 *November 12th 2015*-* Fixes bugs:-  * Reversing alternatives is not meaning preserving for literal patterns [#91](https://github.com/clash-lang/clash-compiler/issues/91)-  * DEC: root of the case-tree must contain at least 2 alternatives [#92](https://github.com/clash-lang/clash-compiler/issues/92)-  * Do not generate overlapping literal patterns in VHDL [#91](https://github.com/clash-lang/clash-compiler/issues/91)--## 0.6.3 *October 24th 2015*-* New features:-  * Improve DEC transformation: consider alternatives before the subject when checking for disjoint expressions.-* Fixes bugs:-  * DEC: don't generate single-branch case-expressions [#90](https://github.com/clash-lang/clash-compiler/issues/90)--## 0.6.2 *October 21st 2015*-* New features:-  * Support `clash-prelude` 0.10.2--* Fixes bugs:-  * CLaSH interpreter was reading '.ghci' file instead of '.clashi' file [#87](https://github.com/clash-lang/clash-compiler/issues/87)-  * DEC: Subject and alternatives are not disjoint [#88](https://github.com/clash-lang/clash-compiler/issues/88)--## 0.6.1 *October 16th 2015*-* New features:-  * Support for `clash-prelude` 0.10.1-  * Transformation that lifts applications of the same function out of alternatives of case-statements. e.g.--    ```haskell-    case x of-      A -> f 3 y-      B -> f x x-      C -> h x-    ```--    is transformed into:--    ```haskell-    let f_arg0 = case x of {A -> 3; B -> x}-        f_arg1 = case x of {A -> y; B -> x}-        f_out  = f f_arg0 f_arg1-    in  case x of-          A -> f_out-          B -> f_out-          C -> h x-    ```--* Fixes bugs:-  * clash won't run when not compiled with usual ghc [#82](https://github.com/clash-lang/clash-compiler/issues/82)-  * Fail to generate VHDL with blockRamFile' in clash-ghc 0.6 [#85](https://github.com/clash-lang/clash-compiler/issues/85)-  * Case-statements acting like normal decoder circuits are erroneously synthesised to priority decoder circuits.--## 0.6 *October 3rd 2015*-* New features:-  * Support `clash-prelude-0.10`-  * Pattern matching on `CLaSH.Sized.Vector`'s `:>` is now supported-  * Unroll "definitions" of the following primitives: `fold`, `dfold`, `foldr`--## 0.5.15 *September 21st 2015*-* New features:-  * Report simulation time in (System)Verilog assert messages--* Fixes bugs:-  * Performance bug: top-level definitions of type "Signal" erroneously inlined.-  * Fix Index maxBound [#79](https://github.com/clash-lang/clash-compiler/pull/79)--## 0.5.14 *September 14th 2015*-* New features:-  * Completely unroll "definitions" of some higher-order primitives with non-representable argument or result vectors:-    It is now possible to translate e.g. `f xs ys = zipWith ($) (map (+) xs) ys :: Vec 4 Int -> Vec 4 Int -> Vec 4 Int`--* Fixes bugs:-  * Converting Bool to Unsigned generates broken VHDL [#77](https://github.com/clash-lang/clash-compiler/issues/77)-  * `topLet` transformation erroneously not performed in a top-down traversal-  * Specialisation limit unchecked on types and constants-  * Vector of functions cannot be translated [#25](https://github.com/clash-lang/clash-compiler/issues/25 )-  * CLaSH fails to generate VHDL when map is applied [#78](https://github.com/clash-lang/clash-compiler/issues/78)--## 0.5.13 *September 8th 2015*-* Fixes bugs:-  * Cannot translate GHC `MachLabel` literal-  * Maybe (Index n) not translatable to VHDL [#75](https://github.com/clash-lang/clash-compiler/issues/75)--## 0.5.12 *September 7th 2015*-* New features:-  * Modest compilation time speed-up. Compilation time of the [I2C](https://github.com/clash-lang/clash-compiler/tree/master/examples/i2c) module on my machine went down from 43s to 24s, and maximum memory usage went down from 840 MB to 700 MB.--* Fixes bugs:-  * Bug in VHDL ROM generation [#69](https://github.com/clash-lang/clash-compiler/issues/69)-  * Clash running out of memory on Simple-ish project [#70](https://github.com/clash-lang/clash-compiler/issues/70)-  * Fix asyncRom VHDL primitive [#71](https://github.com/clash-lang/clash-compiler/pull/71)-  * Fix primitive for CLaSH.Sized.Internal.Signed.size# [#72](https://github.com/clash-lang/clash-compiler/pull/72)-  * rem and quot on Signed are broken [#73](https://github.com/clash-lang/clash-compiler/issues/73)--## 0.5.11 *August 2nd 2015*-* New features:-  * Re-enable GHC's strictness analysis pass, which improves dead-code removal, which hopefully leads to smaller circuits.--## 0.5.10 *July 9th 2015*-* New features:-  * Use new VHDL backend which outputs VHDL-93 instead of VHDL-2002: generated VHDL is now accepted by a larger number of tools.-  * Treat all so-called bottom values (`error "FOO"`, `let x = x in x`, etc.) occuring in installed libraries as `undefined`.-    Before, there were (very) rare situations where we couldn't find the expressions belonging to a function and demanded a BlackBox, even though we knew the expression would be a bottom value.-    Now, we stop demanding a BlackBox for such a function and simply treat it as `undefined`, thus allowing a greater range of circuit descriptions that we can compile.--## 0.5.9 *June 26th 2015*-* New features:-  * Use new verilog backend which outputs Verilog-2001 instead of Verilog-2005: generated Verilog is now accepted by Altera/Quartus--* Fixes bugs:-  * `--systemverilog` switch incorrectly generates verilog code instead of systemverilog code--## 0.5.8 *June 25th 2015*-* New features:-  * Support for copying string literals from Haskell to generated code-  * Support `clash-prelude-0.9`-  * Size at below which functions are always inlined is configurable, run with `-clash-inline-below=N` to set the size limit to `N`--## 0.5.7 *June 3rd 2015*-* New features:-  * New Verilog backend, run `:verilog` in interactive mode, or `--verilog` for batch mode-  * Generated component names are prefixed by the name of the module containing the `topEntity`--## 0.5.6 *May 18th 2015*-* New features:-  * Inlining limit is configurable, run with `-clash-inline-limit=N` to set the inlining limit to `N`-  * Specialisation limit is configurable, run with `clash-spec-limit=N` to set the inline limit to `N`-  * Debug level is configurable, run with `-clash-debug <LEVEL>` where `<LEVEL>` can be: `DebugNone, DebugFinal, DebugName, DebugApplied, DebugAll`. Be default, `clash` runs with `DebugNone`.--* Fixes bugs:-  * Extend evaluator for `GHC.Integer.Type.minusInteger` and `CLaSH.Promoted.Nat.SNat`.--## 0.5.5 *May 5th 2015*-* New features:-  * `TopEntity` wrappers are now specified as `ANN` annotation pragmas [#42](https://github.com/clash-lang/clash-compiler/issues/42)--## 0.5.4 *May 1st 2015*-* New features:-  * Generate wrappers around `topEntity` that have constant names and types--## 0.5.3 *April 24th 2015*-* Fixes bugs:-  * Fix bug where not enough array type definitions were created by the VHDL backend--## 0.5.2 *April 21st 2015*-* Use latest ghc-typelits-natnormalise--## 0.5.1 *April 20th 2015*-* New features:-  * GHC 7.10 support-  * Update to clash-prelude 0.7.2-  * Use http://hackage.haskell.org/package/ghc-typelits-natnormalise typechecker plugin for better type-level natural number handling--## 0.5 *March 11th 2015*-* New features:-  * SystemVerilog backend. [#45](https://github.com/clash-lang/clash-compiler/issues/45)--## 0.4.1 *February 4th 2015*-* Include bug fixes from clash-lib 0.4.1--## 0.4 *November 17th 2014*-* New features:-  * Support for clash-prelude 0.6--* Fixes bugs:-  * clash-ghc ignores "-package-db" flag [#35](https://github.com/christiaanb/clash2/issues/35)--## 0.3.3 *August 12th 2014*-* Fixes bugs:-  * Compile with GHC 7.8.3 [#31](https://github.com/christiaanb/clash2/issues/31)--## 0.3.2 *June 5th 2014*--* Fixes bugs:-  * Type synonym improperly expanded [#17](https://github.com/christiaanb/clash2/issues/17)-  * BlackBox for `Signed` `maxBound` and `minBound` generate incorrect VHDL. [#19](https://github.com/christiaanb/clash2/issues/19)-  * Generate failure code in the VHDL for recSelError [#23](https://github.com/christiaanb/clash2/issues/23)--## 0.3.1 *May 15th 2014*--* New features:-  * Hardcode `fromInteger` for `Signed` and `Unsigned` [#9](https://github.com/christiaanb/clash2/issues/9)-  * Better blackbox operation for vindex [#12](https://github.com/christiaanb/clash2/issues/12)-  * Replace VHDL default hole by error hole [#13](https://github.com/christiaanb/clash2/issues/13)--* Fixes bugs:-  * Update GHC2Core.hs [#1](https://github.com/christiaanb/clash2/issues/1)-  * primitives (clash.sized.vector) [#2](https://github.com/christiaanb/clash2/issues/2)-  * Type families are not expanded [#3](https://github.com/christiaanb/clash2/issues/3)-  * Incorrect vhdl generation for default value in blackbox [#6](https://github.com/christiaanb/clash2/issues/6)-  * Missing begin keyword in Signed/Unsigned JSON files [#16](https://github.com/christiaanb/clash2/issues/16)
clash-ghc.cabal view
@@ -1,5 +1,6 @@+Cabal-version:        2.2 Name:                 clash-ghc-Version:              1.0.1+Version:              1.2.0 Synopsis:             CAES Language for Synchronous Hardware Description:   Clash is a functional hardware description language that borrows both its@@ -29,10 +30,10 @@   * Clash Compiler binary using GHC/Haskell as a frontend   .   .-  Prelude library: <http://hackage.haskell.org/package/clash-prelude>-Homepage:             http://www.clash-lang.org/-bug-reports:          http://github.com/clash-lang/clash-compiler/issues-License:              BSD2+  Prelude library: <https://hackage.haskell.org/package/clash-prelude>+Homepage:             https://clash-lang.org/+bug-reports:          https://github.com/clash-lang/clash-compiler/issues+License:              BSD-2-Clause License-file:         LICENSE Author:               The Clash Authors Maintainer:           QBayLogic B.V. <devops@qbaylogic.com>@@ -46,14 +47,12 @@                       CHANGELOG.md,                       LICENSE_GHC,                       cbits/PosixSource.h,-                      src-bin-821/Clash/GHCi/HsVersions.h                       src-bin-841/Clash/GHCi/HsVersions.h -Cabal-version:        >=1.10- source-repository head   type: git   location: https://github.com/clash-lang/clash-compiler.git+  subdir: clash-ghc  flag dynamic   description:@@ -85,39 +84,48 @@   extra-libraries:    pthread   default-language:   Haskell2010 +common common-options+  default-language:   Haskell2010+  default-extensions: BangPatterns+                      BinaryLiterals+                      DataKinds+                      DefaultSignatures+                      DeriveDataTypeable+                      DeriveFoldable+                      DeriveFunctor+                      DeriveGeneric+                      DeriveLift+                      DeriveTraversable+                      DerivingStrategies+                      InstanceSigs+                      KindSignatures+                      ScopedTypeVariables+                      StandaloneDeriving+                      TupleSections+                      TypeApplications+                      TypeOperators+                      ViewPatterns++  if impl(ghc >= 8.6)+      default-extensions: NoStarIsType+ library+  import:             common-options   HS-Source-Dirs:     src-ghc, src-bin-common-  -- when we move to `cabal-version: 2.2`, we can use elif instead of these nested ifs, but ghc-8.2 comes with cabal-2.0   if impl(ghc >= 8.7.0)-    HS-Source-Dirs:   src-bin-881-  else-    if impl(ghc >= 8.6.0)-      HS-Source-Dirs:   src-bin-861-    else-      if impl(ghc >= 8.4.1)-        HS-Source-Dirs:   src-bin-841-      else-        if impl(ghc >= 8.2.1)-          HS-Source-Dirs:   src-bin-821+    HS-Source-Dirs: src-bin-881+  elif impl(ghc >= 8.6.0)+    HS-Source-Dirs: src-bin-861+  elif impl(ghc >= 8.4.1)+    HS-Source-Dirs: src-bin-841 -  default-language:   Haskell2010-  GHC-Options:        -Wall -fno-warn-name-shadowing+  GHC-Options:        -Wall   CPP-Options:        -DGHCI-  default-extensions: ForeignFunctionInterface-                      UnboxedTuples-                      FlexibleInstances-                      MagicHash-                      CPP-                      PatternGuards-                      NondecreasingIndentation    other-extensions:   FlexibleContexts                       OverloadedStrings                       RecordWildCards-                      ScopedTypeVariables                       TemplateHaskell-                      TupleSections-                      ViewPatterns    Build-Depends:      array                     >= 0.4      && < 0.6,                       base                      >= 4.10     && < 5,@@ -126,27 +134,28 @@                       containers                >= 0.5.4.0  && < 0.7,                       directory                 >= 1.2      && < 1.4,                       filepath                  >= 1.3      && < 1.5,-                      ghc                       >= 8.2.0    && < 8.9,+                      ghc                       >= 8.4.0    && < 8.9,                       process                   >= 1.2      && < 1.7,                       hashable                  >= 1.1.2.3  && < 1.4,-                      haskeline                 >= 0.7.0.3  && < 0.8,-                      lens                      >= 4.0.5    && < 4.19,+                      haskeline                 >= 0.7.0.3  && < 0.9,+                      lens                      >= 4.10     && < 4.20,                       mtl                       >= 2.1.1    && < 2.3,+                      split                     >= 0.2.3    && < 0.3,                       text                      >= 1.2.2    && < 1.3,                       transformers              >= 0.5.2.0  && < 0.6,                       unordered-containers      >= 0.2.1.0  && < 0.3, -                      clash-lib                 >= 1.0      && < 1.1,-                      clash-prelude             >= 1.0      && < 1.1,+                      clash-lib                 == 1.2.0,+                      clash-prelude             == 1.2.0,                       concurrent-supply         >= 0.1.7    && < 0.2,-                      ghc-typelits-extra        >= 0.3.1    && < 0.4,+                      ghc-typelits-extra        >= 0.3.2    && < 0.4,                       ghc-typelits-knownnat     >= 0.6      && < 0.8,                       ghc-typelits-natnormalise >= 0.6      && < 0.8,                       deepseq                   >= 1.3.0.2  && < 1.5,                       time                      >= 1.4.0.1  && < 1.10,-                      ghc-boot                  >= 8.2.0    && < 8.9,+                      ghc-boot                  >= 8.4.0    && < 8.9,                       ghc-prim                  >= 0.3.1.0  && < 0.6,-                      ghci                      >= 8.2.0    && < 8.9,+                      ghci                      >= 8.4.0    && < 8.9,                       uniplate                  >= 1.6.12   && < 1.8,                       reflection                >= 2.1.2    && < 3.0,                       integer-gmp               >= 1.0.1.0  && < 2.0,@@ -165,6 +174,8 @@    Include-dirs:       cbits   C-Sources:          cbits/hschooks.c++  Autogen-Modules:    Paths_clash_ghc    Exposed-Modules:    Clash.Main 
− src-bin-821/Clash/GHCi/HsVersions.h
@@ -1,68 +0,0 @@-#ifndef HSVERSIONS_H-#define HSVERSIONS_H--#if 0--IMPORTANT!  If you put extra tabs/spaces in these macro definitions,-you will screw up the layout where they are used in case expressions!--(This is cpp-dependent, of course)--#endif--/* Useful in the headers that we share with the RTS */-#define COMPILING_GHC 1--/* Pull in all the platform defines for this build (foo_TARGET_ARCH etc.) */-/* #include "ghc_boot_platform.h" */--/* Pull in the autoconf defines (HAVE_FOO), but don't include- * ghcconfig.h, because that will include ghcplatform.h which has the- * wrong platform settings for the compiler (it has the platform- * settings for the target plat instead). */-/* #include "ghcautoconf.h" */--#define GLOBAL_VAR(name,value,ty)  \-{-# NOINLINE name #-};             \-name :: IORef (ty);                \-name = Util.global (value);--#define GLOBAL_VAR_M(name,value,ty) \-{-# NOINLINE name #-};              \-name :: IORef (ty);                 \-name = Util.globalM (value);---#define SHARED_GLOBAL_VAR(name,accessor,saccessor,value,ty) \-{-# NOINLINE name #-};                                      \-name :: IORef (ty);                                         \-name = Util.sharedGlobal (value) (accessor);                \-foreign import ccall unsafe saccessor                       \-  accessor :: Ptr (IORef a) -> IO (Ptr (IORef a));--#define SHARED_GLOBAL_VAR_M(name,accessor,saccessor,value,ty)  \-{-# NOINLINE name #-};                                         \-name :: IORef (ty);                                            \-name = Util.sharedGlobalM (value) (accessor);                  \-foreign import ccall unsafe saccessor                          \-  accessor :: Ptr (IORef a) -> IO (Ptr (IORef a));---#define ASSERT(e)      if debugIsOn && not (e) then (assertPanic __FILE__ __LINE__) else-#define ASSERT2(e,msg) if debugIsOn && not (e) then (assertPprPanic __FILE__ __LINE__ (msg)) else-#define WARN( e, msg ) (warnPprTrace (e) __FILE__ __LINE__ (msg)) $---- Examples:   Assuming   flagSet :: String -> m Bool------    do { c   <- getChar; MASSERT( isUpper c ); ... }---    do { c   <- getChar; MASSERT2( isUpper c, text "Bad" ); ... }---    do { str <- getStr;  ASSERTM( flagSet str ); .. }---    do { str <- getStr;  ASSERTM2( flagSet str, text "Bad" ); .. }---    do { str <- getStr;  WARNM2( flagSet str, text "Flag is set" ); .. }-#define MASSERT(e)      ASSERT(e) return ()-#define MASSERT2(e,msg) ASSERT2(e,msg) return ()-#define ASSERTM(e)      do { bool <- e; MASSERT(bool) }-#define ASSERTM2(e,msg) do { bool <- e; MASSERT2(bool,msg) }-#define WARNM2(e,msg)   do { bool <- e; WARN(bool, msg) return () }--#endif /* HsVersions.h */
− src-bin-821/Clash/GHCi/UI.hs
@@ -1,3893 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE MagicHash #-}-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE NondecreasingIndentation #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE ViewPatterns #-}--{-# OPTIONS -fno-cse #-}--- -fno-cse is needed for GLOBAL_VAR's to behave properly------------------------------------------------------------------------------------- GHC Interactive User Interface------ (c) The GHC Team 2005-2006-----------------------------------------------------------------------------------module Clash.GHCi.UI (-        interactiveUI,-        GhciSettings(..),-        defaultGhciSettings,-        ghciCommands,-        ghciWelcomeMsg,-        makeHDL-    ) where--#include "HsVersions.h"---- GHCi-import qualified Clash.GHCi.UI.Monad as GhciMonad ( args, runStmt, runDecls )-import Clash.GHCi.UI.Monad hiding ( args, runStmt, runDecls )-import Clash.GHCi.UI.Tags-import Clash.GHCi.UI.Info-import Debugger---- The GHC interface-import GHCi-import GHCi.RemoteTypes-import GHCi.BreakArray-import DynFlags-import ErrUtils-import GhcMonad ( modifySession )-import qualified GHC-import GHC ( LoadHowMuch(..), Target(..),  TargetId(..), InteractiveImport(..),-             TyThing(..), Phase, BreakIndex, Resume, SingleStep, Ghc,-             getModuleGraph, handleSourceError )-import HsImpExp-import HsSyn-import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, hsc_IC,-                  setInteractivePrintName, hsc_dflags, msObjFilePath )-import Module-import Name-import Packages ( trusted, getPackageDetails, getInstalledPackageDetails,-                  listVisibleModuleNames, pprFlag )-import IfaceSyn ( showToHeader )-import PprTyThing-import PrelNames-import RdrName ( RdrName, getGRE_NameQualifier_maybes, getRdrName )-import SrcLoc-import qualified Lexer--import StringBuffer-import Outputable hiding ( printForUser, printForUserPartWay )---- Other random utilities-import BasicTypes hiding ( isTopLevel )-import Digraph-import Encoding-import FastString-import Linker-import Maybes ( orElse, expectJust )-import NameSet-import Panic hiding ( showException )-import Util-import qualified GHC.LanguageExtensions as LangExt---- Haskell Libraries-import System.Console.Haskeline as Haskeline--import Control.Applicative hiding (empty)-import Control.DeepSeq (deepseq)-import Control.Monad as Monad-import Control.Monad.IO.Class-import Control.Monad.Trans.Class-import Control.Monad.Trans.Except--import Data.Array-import qualified Data.ByteString.Char8 as BS-import Data.Char-import Data.Function-import Data.IORef ( IORef, modifyIORef, newIORef, readIORef, writeIORef )-import Data.List ( find, group, intercalate, intersperse, isPrefixOf, nub,-                   partition, sort, sortBy )-import qualified Data.Set as S-import Data.Maybe-import qualified Data.Map as M-import Data.Time.LocalTime ( getZonedTime )-import Data.Time.Format ( formatTime, defaultTimeLocale )-import Data.Version ( showVersion )--import Exception hiding (catch)-import Foreign hiding (void)-import GHC.Stack hiding (SrcLoc(..))--import System.Directory-import System.Environment-import System.Exit ( exitWith, ExitCode(..) )-import System.FilePath-import System.Info-import System.IO-import System.IO.Error-import System.IO.Unsafe ( unsafePerformIO )-import System.Process-import Text.Printf-import Text.Read ( readMaybe )-import Text.Read.Lex (isSymbolChar)--import Unsafe.Coerce--#if !defined(mingw32_HOST_OS)-import System.Posix hiding ( getEnv )-#else-import qualified System.Win32-#endif--import GHC.IO.Exception ( IOErrorType(InvalidArgument) )-import GHC.IO.Handle ( hFlushAll )-import GHC.TopHandler ( topHandler )---- clash additions-import qualified Clash.Backend-import           Clash.Backend.SystemVerilog (SystemVerilogState)-import           Clash.Backend.VHDL (VHDLState)-import           Clash.Backend.Verilog (VerilogState)-import qualified Clash.Driver-import           Clash.Driver.Types (ClashOpts (..))-import           Clash.GHC.Evaluator-import           Clash.GHC.GenerateBindings-import           Clash.GHC.NetlistTypes-import           Clash.GHCi.Common-import           Clash.Netlist.BlackBox.Types (HdlSyn)-import           Clash.Util (clashLibVersion, reportTimeDiff)-import qualified Data.Time.Clock as Clock-import qualified Paths_clash_ghc--import           Clash.Annotations.BitRepresentation.Internal (buildCustomReprs)---------------------------------------------------------------------------------data GhciSettings = GhciSettings {-        availableCommands :: [Command],-        shortHelpText     :: String,-        fullHelpText      :: String,-        defPrompt         :: PromptFunction,-        defPromptCont     :: PromptFunction-    }--defaultGhciSettings :: IORef ClashOpts -> GhciSettings-defaultGhciSettings opts =-    GhciSettings {-        availableCommands = ghciCommands opts,-        shortHelpText     = defShortHelpText,-        defPrompt         = default_prompt,-        defPromptCont     = default_prompt_cont,-        fullHelpText      = defFullHelpText-    }--ghciWelcomeMsg :: String-ghciWelcomeMsg = "Clashi, version " ++ Data.Version.showVersion Paths_clash_ghc.version ++-                 " (using clash-lib, version " ++ Data.Version.showVersion clashLibVersion ++-                 "):\nhttp://www.clash-lang.org/  :? for help"--ghciCommands :: IORef ClashOpts -> [Command]-ghciCommands opts = map mkCmd [-  -- Hugs users are accustomed to :e, so make sure it doesn't overlap-  ("?",         keepGoing help,                 noCompletion),-  ("add",       keepGoingPaths addModule,       completeFilename),-  ("abandon",   keepGoing abandonCmd,           noCompletion),-  ("break",     keepGoing breakCmd,             completeIdentifier),-  ("back",      keepGoing backCmd,              noCompletion),-  ("browse",    keepGoing' (browseCmd False),   completeModule),-  ("browse!",   keepGoing' (browseCmd True),    completeModule),-  ("cd",        keepGoing' changeDirectory,     completeFilename),-  ("check",     keepGoing' checkModule,         completeHomeModule),-  ("continue",  keepGoing continueCmd,          noCompletion),-  ("cmd",       keepGoing cmdCmd,               completeExpression),-  ("ctags",     keepGoing createCTagsWithLineNumbersCmd, completeFilename),-  ("ctags!",    keepGoing createCTagsWithRegExesCmd, completeFilename),-  ("def",       keepGoing (defineMacro False),  completeExpression),-  ("def!",      keepGoing (defineMacro True),   completeExpression),-  ("delete",    keepGoing deleteCmd,            noCompletion),-  ("edit",      keepGoing' editFile,            completeFilename),-  ("etags",     keepGoing createETagsFileCmd,   completeFilename),-  ("force",     keepGoing forceCmd,             completeExpression),-  ("forward",   keepGoing forwardCmd,           noCompletion),-  ("help",      keepGoing help,                 noCompletion),-  ("history",   keepGoing historyCmd,           noCompletion),-  ("info",      keepGoing' (info False),        completeIdentifier),-  ("info!",     keepGoing' (info True),         completeIdentifier),-  ("issafe",    keepGoing' isSafeCmd,           completeModule),-  ("kind",      keepGoing' (kindOfType False),  completeIdentifier),-  ("kind!",     keepGoing' (kindOfType True),   completeIdentifier),-  ("load",      keepGoingPaths loadModule_,     completeHomeModuleOrFile),-  ("load!",     keepGoingPaths loadModuleDefer, completeHomeModuleOrFile),-  ("list",      keepGoing' listCmd,             noCompletion),-  ("module",    keepGoing moduleCmd,            completeSetModule),-  ("main",      keepGoing runMain,              completeFilename),-  ("print",     keepGoing printCmd,             completeExpression),-  ("quit",      quit,                           noCompletion),-  ("reload",    keepGoing' reloadModule,        noCompletion),-  ("reload!",   keepGoing' reloadModuleDefer,   noCompletion),-  ("run",       keepGoing runRun,               completeFilename),-  ("script",    keepGoing' scriptCmd,           completeFilename),-  ("set",       keepGoing setCmd,               completeSetOptions),-  ("seti",      keepGoing setiCmd,              completeSeti),-  ("show",      keepGoing showCmd,              completeShowOptions),-  ("showi",     keepGoing showiCmd,             completeShowiOptions),-  ("sprint",    keepGoing sprintCmd,            completeExpression),-  ("step",      keepGoing stepCmd,              completeIdentifier),-  ("steplocal", keepGoing stepLocalCmd,         completeIdentifier),-  ("stepmodule",keepGoing stepModuleCmd,        completeIdentifier),-  ("type",      keepGoing' typeOfExpr,          completeExpression),-  ("trace",     keepGoing traceCmd,             completeExpression),-  ("undef",     keepGoing undefineMacro,        completeMacro),-  ("unset",     keepGoing unsetOptions,         completeSetOptions),-  ("where",     keepGoing whereCmd,             noCompletion),-  ("vhdl",      keepGoingPaths (makeVHDL opts),        completeHomeModuleOrFile),-  ("verilog",   keepGoingPaths (makeVerilog opts),     completeHomeModuleOrFile),-  ("systemverilog",   keepGoingPaths (makeSystemVerilog opts),     completeHomeModuleOrFile)-  ] ++ map mkCmdHidden [ -- hidden commands-  ("all-types", keepGoing' allTypesCmd),-  ("complete",  keepGoing completeCmd),-  ("loc-at",    keepGoing' locAtCmd),-  ("type-at",   keepGoing' typeAtCmd),-  ("uses",      keepGoing' usesCmd)-  ]- where-  mkCmd (n,a,c) = Command { cmdName = n-                          , cmdAction = a-                          , cmdHidden = False-                          , cmdCompletionFunc = c-                          }--  mkCmdHidden (n,a) = Command { cmdName = n-                              , cmdAction = a-                              , cmdHidden = True-                              , cmdCompletionFunc = noCompletion-                              }---- We initialize readline (in the interactiveUI function) to use--- word_break_chars as the default set of completion word break characters.--- This can be overridden for a particular command (for example, filename--- expansion shouldn't consider '/' to be a word break) by setting the third--- entry in the Command tuple above.------ NOTE: in order for us to override the default correctly, any custom entry--- must be a SUBSET of word_break_chars.-word_break_chars :: String-word_break_chars = spaces ++ specials ++ symbols--symbols, specials, spaces :: String-symbols = "!#$%&*+/<=>?@\\^|-~"-specials = "(),;[]`{}"-spaces = " \t\n"--flagWordBreakChars :: String-flagWordBreakChars = " \t\n"---keepGoing :: (String -> GHCi ()) -> (String -> InputT GHCi Bool)-keepGoing a str = keepGoing' (lift . a) str--keepGoing' :: Monad m => (String -> m ()) -> String -> m Bool-keepGoing' a str = a str >> return False--keepGoingPaths :: ([FilePath] -> InputT GHCi ()) -> (String -> InputT GHCi Bool)-keepGoingPaths a str- = do case toArgs str of-          Left err -> liftIO $ hPutStrLn stderr err-          Right args -> a args-      return False--defShortHelpText :: String-defShortHelpText = "use :? for help.\n"--defFullHelpText :: String-defFullHelpText =-  " Commands available from the prompt:\n" ++-  "\n" ++-  "   <statement>                 evaluate/run <statement>\n" ++-  "   :                           repeat last command\n" ++-  "   :{\\n ..lines.. \\n:}\\n       multiline command\n" ++-  "   :add [*]<module> ...        add module(s) to the current target set\n" ++-  "   :browse[!] [[*]<mod>]       display the names defined by module <mod>\n" ++-  "                               (!: more details; *: all top-level names)\n" ++-  "   :cd <dir>                   change directory to <dir>\n" ++-  "   :cmd <expr>                 run the commands returned by <expr>::IO String\n" ++-  "   :complete <dom> [<rng>] <s> list completions for partial input string\n" ++-  "   :ctags[!] [<file>]          create tags file <file> for Vi (default: \"tags\")\n" ++-  "                               (!: use regex instead of line number)\n" ++-  "   :def <cmd> <expr>           define command :<cmd> (later defined command has\n" ++-  "                               precedence, ::<cmd> is always a builtin command)\n" ++-  "   :edit <file>                edit file\n" ++-  "   :edit                       edit last module\n" ++-  "   :etags [<file>]             create tags file <file> for Emacs (default: \"TAGS\")\n" ++-  "   :help, :?                   display this list of commands\n" ++-  "   :info[!] [<name> ...]       display information about the given names\n" ++-  "                               (!: do not filter instances)\n" ++-  "   :issafe [<mod>]             display safe haskell information of module <mod>\n" ++-  "   :kind[!] <type>             show the kind of <type>\n" ++-  "                               (!: also print the normalised type)\n" ++-  "   :load[!] [*]<module> ...    load module(s) and their dependents\n" ++-  "                               (!: defer type errors)\n" ++-  "   :main [<arguments> ...]     run the main function with the given arguments\n" ++-  "   :module [+/-] [*]<mod> ...  set the context for expression evaluation\n" ++-  "   :quit                       exit GHCi\n" ++-  "   :reload[!]                  reload the current module set\n" ++-  "                               (!: defer type errors)\n" ++-  "   :run function [<arguments> ...] run the function with the given arguments\n" ++-  "   :script <file>              run the script <file>\n" ++-  "   :type <expr>                show the type of <expr>\n" ++-  "   :type +d <expr>             show the type of <expr>, defaulting type variables\n" ++-  "   :type +v <expr>             show the type of <expr>, with its specified tyvars\n" ++-  "   :undef <cmd>                undefine user-defined command :<cmd>\n" ++-  "   :!<command>                 run the shell command <command>\n" ++-  "   :vhdl                       synthesize currently loaded module to vhdl\n" ++-  "   :vhdl [<module>]            synthesize specified modules/files to vhdl\n" ++-  "   :verilog                    synthesize currently loaded module to verilog\n" ++-  "   :verilog [<module>]         synthesize specified modules/files to verilog\n" ++-  "   :systemverilog              synthesize currently loaded module to systemverilog\n" ++-  "   :systemverilog [<module>]   synthesize specified modules/files to systemverilog\n" ++-  "\n" ++-  " -- Commands for debugging:\n" ++-  "\n" ++-  "   :abandon                    at a breakpoint, abandon current computation\n" ++-  "   :back [<n>]                 go back in the history N steps (after :trace)\n" ++-  "   :break [<mod>] <l> [<col>]  set a breakpoint at the specified location\n" ++-  "   :break <name>               set a breakpoint on the specified function\n" ++-  "   :continue                   resume after a breakpoint\n" ++-  "   :delete <number>            delete the specified breakpoint\n" ++-  "   :delete *                   delete all breakpoints\n" ++-  "   :force <expr>               print <expr>, forcing unevaluated parts\n" ++-  "   :forward [<n>]              go forward in the history N step s(after :back)\n" ++-  "   :history [<n>]              after :trace, show the execution history\n" ++-  "   :list                       show the source code around current breakpoint\n" ++-  "   :list <identifier>          show the source code for <identifier>\n" ++-  "   :list [<module>] <line>     show the source code around line number <line>\n" ++-  "   :print [<name> ...]         show a value without forcing its computation\n" ++-  "   :sprint [<name> ...]        simplified version of :print\n" ++-  "   :step                       single-step after stopping at a breakpoint\n"++-  "   :step <expr>                single-step into <expr>\n"++-  "   :steplocal                  single-step within the current top-level binding\n"++-  "   :stepmodule                 single-step restricted to the current module\n"++-  "   :trace                      trace after stopping at a breakpoint\n"++-  "   :trace <expr>               evaluate <expr> with tracing on (see :history)\n"++--  "\n" ++-  " -- Commands for changing settings:\n" ++-  "\n" ++-  "   :set <option> ...           set options\n" ++-  "   :seti <option> ...          set options for interactive evaluation only\n" ++-  "   :set args <arg> ...         set the arguments returned by System.getArgs\n" ++-  "   :set prog <progname>        set the value returned by System.getProgName\n" ++-  "   :set prompt <prompt>        set the prompt used in GHCi\n" ++-  "   :set prompt-cont <prompt>   set the continuation prompt used in GHCi\n" ++-  "   :set prompt-function <expr> set the function to handle the prompt\n" ++-  "   :set prompt-cont-function <expr>" ++-                     "set the function to handle the continuation prompt\n" ++-  "   :set editor <cmd>           set the command used for :edit\n" ++-  "   :set stop [<n>] <cmd>       set the command to run when a breakpoint is hit\n" ++-  "   :unset <option> ...         unset options\n" ++-  "\n" ++-  "  Options for ':set' and ':unset':\n" ++-  "\n" ++-  "    +m            allow multiline commands\n" ++-  "    +r            revert top-level expressions after each evaluation\n" ++-  "    +s            print timing/memory stats after each evaluation\n" ++-  "    +t            print type after evaluation\n" ++-  "    +c            collect type/location info after loading modules\n" ++-  "    -<flags>      most GHC command line flags can also be set here\n" ++-  "                         (eg. -v2, -XFlexibleInstances, etc.)\n" ++-  "                    for GHCi-specific flags, see User's Guide,\n"++-  "                    Flag reference, Interactive-mode options\n" ++-  "\n" ++-  " -- Commands for displaying information:\n" ++-  "\n" ++-  "   :show bindings              show the current bindings made at the prompt\n" ++-  "   :show breaks                show the active breakpoints\n" ++-  "   :show context               show the breakpoint context\n" ++-  "   :show imports               show the current imports\n" ++-  "   :show linker                show current linker state\n" ++-  "   :show modules               show the currently loaded modules\n" ++-  "   :show packages              show the currently active package flags\n" ++-  "   :show paths                 show the currently active search paths\n" ++-  "   :show language              show the currently active language flags\n" ++-  "   :show <setting>             show value of <setting>, which is one of\n" ++-  "                                  [args, prog, editor, stop]\n" ++-  "   :showi language             show language flags for interactive evaluation\n" ++-  "\n"--findEditor :: IO String-findEditor = do-  getEnv "EDITOR"-    `catchIO` \_ -> do-#if defined(mingw32_HOST_OS)-        win <- System.Win32.getWindowsDirectory-        return (win </> "notepad.exe")-#else-        return ""-#endif--default_progname, default_stop :: String-default_progname = "<interactive>"-default_stop = ""--default_prompt, default_prompt_cont :: PromptFunction-default_prompt = generatePromptFunctionFromString "%s> "-default_prompt_cont = generatePromptFunctionFromString "%s| "--default_args :: [String]-default_args = []--interactiveUI :: GhciSettings -> [(FilePath, Maybe Phase)] -> Maybe [String]-              -> Ghc ()-interactiveUI config srcs maybe_exprs = do-   -- HACK! If we happen to get into an infinite loop (eg the user-   -- types 'let x=x in x' at the prompt), then the thread will block-   -- on a blackhole, and become unreachable during GC.  The GC will-   -- detect that it is unreachable and send it the NonTermination-   -- exception.  However, since the thread is unreachable, everything-   -- it refers to might be finalized, including the standard Handles.-   -- This sounds like a bug, but we don't have a good solution right-   -- now.-   _ <- liftIO $ newStablePtr stdin-   _ <- liftIO $ newStablePtr stdout-   _ <- liftIO $ newStablePtr stderr--    -- Initialise buffering for the *interpreted* I/O system-   (nobuffering, flush) <- initInterpBuffering--   -- The initial set of DynFlags used for interactive evaluation is the same-   -- as the global DynFlags, plus -XExtendedDefaultRules and-   -- -XNoMonomorphismRestriction.-   dflags <- getDynFlags-   let dflags' = (`xopt_set` LangExt.ExtendedDefaultRules)-               . (`xopt_unset` LangExt.MonomorphismRestriction)-               $ dflags-   GHC.setInteractiveDynFlags dflags'--   lastErrLocationsRef <- liftIO $ newIORef []-   progDynFlags <- GHC.getProgramDynFlags-   _ <- GHC.setProgramDynFlags $-      progDynFlags { log_action = ghciLogAction lastErrLocationsRef }--   when (isNothing maybe_exprs) $ do-        -- Only for GHCi (not runghc and ghc -e):--        -- Turn buffering off for the compiled program's stdout/stderr-        turnOffBuffering_ nobuffering-        -- Turn buffering off for GHCi's stdout-        liftIO $ hFlush stdout-        liftIO $ hSetBuffering stdout NoBuffering-        -- We don't want the cmd line to buffer any input that might be-        -- intended for the program, so unbuffer stdin.-        liftIO $ hSetBuffering stdin NoBuffering-        liftIO $ hSetBuffering stderr NoBuffering-#if defined(mingw32_HOST_OS)-        -- On Unix, stdin will use the locale encoding.  The IO library-        -- doesn't do this on Windows (yet), so for now we use UTF-8,-        -- for consistency with GHC 6.10 and to make the tests work.-        liftIO $ hSetEncoding stdin utf8-#endif--   default_editor <- liftIO $ findEditor-   eval_wrapper <- mkEvalWrapper default_progname default_args-   let prelude_import = simpleImportDecl preludeModuleName-   startGHCi (runGHCi srcs maybe_exprs)-        GHCiState{ progname           = default_progname,-                   args               = default_args,-                   evalWrapper        = eval_wrapper,-                   prompt             = default_prompt,-                   prompt_cont        = default_prompt_cont,-                   stop               = default_stop,-                   editor             = default_editor,-                   options            = [],-                   -- We initialize line number as 0, not 1, because we use-                   -- current line number while reporting errors which is-                   -- incremented after reading a line.-                   line_number        = 0,-                   break_ctr          = 0,-                   breaks             = [],-                   tickarrays         = emptyModuleEnv,-                   ghci_commands      = availableCommands config,-                   ghci_macros        = [],-                   last_command       = Nothing,-                   cmdqueue           = [],-                   remembered_ctx     = [],-                   transient_ctx      = [],-                   extra_imports      = [],-                   prelude_imports    = [prelude_import],-                   ghc_e              = isJust maybe_exprs,-                   short_help         = shortHelpText config,-                   long_help          = fullHelpText config,-                   lastErrorLocations = lastErrLocationsRef,-                   mod_infos          = M.empty,-                   flushStdHandles    = flush,-                   noBuffering        = nobuffering-                 }--   return ()--resetLastErrorLocations :: GHCi ()-resetLastErrorLocations = do-    st <- getGHCiState-    liftIO $ writeIORef (lastErrorLocations st) []--ghciLogAction :: IORef [(FastString, Int)] ->  LogAction-ghciLogAction lastErrLocations dflags flag severity srcSpan style msg = do-    defaultLogAction dflags flag severity srcSpan style msg-    case severity of-        SevError -> case srcSpan of-            RealSrcSpan rsp -> modifyIORef lastErrLocations-                (++ [(srcLocFile (realSrcSpanStart rsp), srcLocLine (realSrcSpanStart rsp))])-            _ -> return ()-        _ -> return ()--withGhcAppData :: (FilePath -> IO a) -> IO a -> IO a-withGhcAppData right left = do-    either_dir <- tryIO (getAppUserDataDirectory "clash")-    case either_dir of-        Right dir ->-            do createDirectoryIfMissing False dir `catchIO` \_ -> return ()-               right dir-        _ -> left--runGHCi :: [(FilePath, Maybe Phase)] -> Maybe [String] -> GHCi ()-runGHCi paths maybe_exprs = do-  dflags <- getDynFlags-  let-   ignore_dot_ghci = gopt Opt_IgnoreDotGhci dflags--   current_dir = return (Just ".clashi")--   app_user_dir = liftIO $ withGhcAppData-                    (\dir -> return (Just (dir </> "clashi.conf")))-                    (return Nothing)--   home_dir = do-    either_dir <- liftIO $ tryIO (getEnv "HOME")-    case either_dir of-      Right home -> return (Just (home </> ".clashi"))-      _ -> return Nothing--   canonicalizePath' :: FilePath -> IO (Maybe FilePath)-   canonicalizePath' fp = liftM Just (canonicalizePath fp)-                `catchIO` \_ -> return Nothing--   sourceConfigFile :: FilePath -> GHCi ()-   sourceConfigFile file = do-     exists <- liftIO $ doesFileExist file-     when exists $ do-       either_hdl <- liftIO $ tryIO (openFile file ReadMode)-       case either_hdl of-         Left _e   -> return ()-         -- NOTE: this assumes that runInputT won't affect the terminal;-         -- can we assume this will always be the case?-         -- This would be a good place for runFileInputT.-         Right hdl ->-             do runInputTWithPrefs defaultPrefs defaultSettings $-                          runCommands $ fileLoop hdl-                liftIO (hClose hdl `catchIO` \_ -> return ())-                -- Don't print a message if this is really ghc -e (#11478).-                -- Also, let the user silence the message with -v0-                -- (the default verbosity in GHCi is 1).-                when (isNothing maybe_exprs && verbosity dflags > 0) $-                  liftIO $ putStrLn ("Loaded Clashi configuration from " ++ file)--  ----  setGHCContextFromGHCiState--  dot_cfgs <- if ignore_dot_ghci then return [] else do-    dot_files <- catMaybes <$> sequence [ current_dir, app_user_dir, home_dir ]-    liftIO $ filterM checkFileAndDirPerms dot_files-  mdot_cfgs <- liftIO $ mapM canonicalizePath' dot_cfgs--  let arg_cfgs = reverse $ ghciScripts dflags-    -- -ghci-script are collected in reverse order-    -- We don't require that a script explicitly added by -ghci-script-    -- is owned by the current user. (#6017)-  mapM_ sourceConfigFile $ nub $ (catMaybes mdot_cfgs) ++ arg_cfgs-    -- nub, because we don't want to read .ghci twice if the CWD is $HOME.--  -- Perform a :load for files given on the GHCi command line-  -- When in -e mode, if the load fails then we want to stop-  -- immediately rather than going on to evaluate the expression.-  when (not (null paths)) $ do-     ok <- ghciHandle (\e -> do showException e; return Failed) $-                -- TODO: this is a hack.-                runInputTWithPrefs defaultPrefs defaultSettings $-                    loadModule paths-     when (isJust maybe_exprs && failed ok) $-        liftIO (exitWith (ExitFailure 1))--  installInteractivePrint (interactivePrint dflags) (isJust maybe_exprs)--  -- if verbosity is greater than 0, or we are connected to a-  -- terminal, display the prompt in the interactive loop.-  is_tty <- liftIO (hIsTerminalDevice stdin)-  let show_prompt = verbosity dflags > 0 || is_tty--  -- reset line number-  modifyGHCiState $ \st -> st{line_number=0}--  case maybe_exprs of-        Nothing ->-          do-            -- enter the interactive loop-            runGHCiInput $ runCommands $ nextInputLine show_prompt is_tty-        Just exprs -> do-            -- just evaluate the expression we were given-            enqueueCommands exprs-            let hdle e = do st <- getGHCiState-                            -- flush the interpreter's stdout/stderr on exit (#3890)-                            flushInterpBuffers-                            -- Jump through some hoops to get the-                            -- current progname in the exception text:-                            -- <progname>: <exception>-                            liftIO $ withProgName (progname st)-                                   $ topHandler e-                                   -- this used to be topHandlerFastExit, see #2228-            runInputTWithPrefs defaultPrefs defaultSettings $ do-                -- make `ghc -e` exit nonzero on invalid input, see Trac #7962-                _ <- runCommands' hdle-                     (Just $ hdle (toException $ ExitFailure 1) >> return ())-                     (return Nothing)-                return ()--  -- and finally, exit-  liftIO $ when (verbosity dflags > 0) $ putStrLn "Leaving Clashi."--runGHCiInput :: InputT GHCi a -> GHCi a-runGHCiInput f = do-    dflags <- getDynFlags-    let ghciHistory = gopt Opt_GhciHistory dflags-    let localGhciHistory = gopt Opt_LocalGhciHistory dflags-    currentDirectory <- liftIO $ getCurrentDirectory--    histFile <- case (ghciHistory, localGhciHistory) of-      (True, True) -> return (Just (currentDirectory </> ".clashi_history"))-      (True, _) -> liftIO $ withGhcAppData-        (\dir -> return (Just (dir </> "clashi_history"))) (return Nothing)-      _ -> return Nothing--    runInputT-        (setComplete ghciCompleteWord $ defaultSettings {historyFile = histFile})-        f---- | How to get the next input line from the user-nextInputLine :: Bool -> Bool -> InputT GHCi (Maybe String)-nextInputLine show_prompt is_tty-  | is_tty = do-    prmpt <- if show_prompt then lift mkPrompt else return ""-    r <- getInputLine prmpt-    incrementLineNo-    return r-  | otherwise = do-    when show_prompt $ lift mkPrompt >>= liftIO . putStr-    fileLoop stdin---- NOTE: We only read .ghci files if they are owned by the current user,--- and aren't world writable (files owned by root are ok, see #9324).--- Otherwise, we could be accidentally running code planted by--- a malicious third party.---- Furthermore, We only read ./.ghci if . is owned by the current user--- and isn't writable by anyone else.  I think this is sufficient: we--- don't need to check .. and ../.. etc. because "."  always refers to--- the same directory while a process is running.--checkFileAndDirPerms :: FilePath -> IO Bool-checkFileAndDirPerms file = do-  file_ok <- checkPerms file-  -- Do not check dir perms when .ghci doesn't exist, otherwise GHCi will-  -- print some confusing and useless warnings in some cases (e.g. in-  -- travis). Note that we can't add a test for this, as all ghci tests should-  -- run with -ignore-dot-ghci, which means we never get here.-  if file_ok then checkPerms (getDirectory file) else return False-  where-  getDirectory f = case takeDirectory f of-    "" -> "."-    d -> d--checkPerms :: FilePath -> IO Bool-#if defined(mingw32_HOST_OS)-checkPerms _ = return True-#else-checkPerms file =-  handleIO (\_ -> return False) $ do-    st <- getFileStatus file-    me <- getRealUserID-    let mode = System.Posix.fileMode st-        ok = (fileOwner st == me || fileOwner st == 0) &&-             groupWriteMode /= mode `intersectFileModes` groupWriteMode &&-             otherWriteMode /= mode `intersectFileModes` otherWriteMode-    unless ok $-      -- #8248: Improving warning to include a possible fix.-      putStrLn $ "*** WARNING: " ++ file ++-                 " is writable by someone else, IGNORING!" ++-                 "\nSuggested fix: execute 'chmod go-w " ++ file ++ "'"-    return ok-#endif--incrementLineNo :: InputT GHCi ()-incrementLineNo = modifyGHCiState incLineNo-  where-    incLineNo st = st { line_number = line_number st + 1 }--fileLoop :: Handle -> InputT GHCi (Maybe String)-fileLoop hdl = do-   l <- liftIO $ tryIO $ hGetLine hdl-   case l of-        Left e | isEOFError e              -> return Nothing-               | -- as we share stdin with the program, the program-                 -- might have already closed it, so we might get a-                 -- handle-closed exception. We therefore catch that-                 -- too.-                 isIllegalOperation e      -> return Nothing-               | InvalidArgument <- etype  -> return Nothing-               | otherwise                 -> liftIO $ ioError e-                where etype = ioeGetErrorType e-                -- treat InvalidArgument in the same way as EOF:-                -- this can happen if the user closed stdin, or-                -- perhaps did getContents which closes stdin at-                -- EOF.-        Right l' -> do-           incrementLineNo-           return (Just l')--formatCurrentTime :: String -> IO String-formatCurrentTime format =-  getZonedTime >>= return . (formatTime defaultTimeLocale format)--getUserName :: IO String-getUserName = do-#if defined(mingw32_HOST_OS)-  getEnv "USERNAME"-    `catchIO` \e -> do-      putStrLn $ show e-      return ""-#else-  getLoginName-#endif--getInfoForPrompt :: GHCi (SDoc, [String], Int)-getInfoForPrompt = do-  st <- getGHCiState-  imports <- GHC.getContext-  resumes <- GHC.getResumeContext--  context_bit <--        case resumes of-            [] -> return empty-            r:_ -> do-                let ix = GHC.resumeHistoryIx r-                if ix == 0-                   then return (brackets (ppr (GHC.resumeSpan r)) <> space)-                   else do-                        let hist = GHC.resumeHistory r !! (ix-1)-                        pan <- GHC.getHistorySpan hist-                        return (brackets (ppr (negate ix) <> char ':'-                                          <+> ppr pan) <> space)--  let-        dots | _:rs <- resumes, not (null rs) = text "... "-             | otherwise = empty--        rev_imports = reverse imports -- rightmost are the most recent--        myIdeclName d | Just m <- ideclAs d = unLoc m-                      | otherwise           = unLoc (ideclName d)--        modules_names =-             ['*':(moduleNameString m) | IIModule m <- rev_imports] ++-             [moduleNameString (myIdeclName d) | IIDecl d <- rev_imports]-        line = 1 + line_number st--  return (dots <> context_bit, modules_names, line)--parseCallEscape :: String -> (String, String)-parseCallEscape s-  | not (all isSpace beforeOpen) = ("", "")-  | null sinceOpen               = ("", "")-  | null sinceClosed             = ("", "")-  | null cmd                     = ("", "")-  | otherwise                    = (cmd, tail sinceClosed)-  where-    (beforeOpen, sinceOpen) = span (/='(') s-    (cmd, sinceClosed) = span (/=')') (tail sinceOpen)--checkPromptStringForErrors :: String -> Maybe String-checkPromptStringForErrors ('%':'c':'a':'l':'l':xs) =-  case parseCallEscape xs of-    ("", "") -> Just ("Incorrect %call syntax. " ++-                      "Should be %call(a command and arguments).")-    (_, afterClosed) -> checkPromptStringForErrors afterClosed-checkPromptStringForErrors ('%':'%':xs) = checkPromptStringForErrors xs-checkPromptStringForErrors (_:xs) = checkPromptStringForErrors xs-checkPromptStringForErrors "" = Nothing--generatePromptFunctionFromString :: String -> PromptFunction-generatePromptFunctionFromString promptS = \_ _ -> do-    (context, modules_names, line) <- getInfoForPrompt--    let-        processString :: String -> GHCi SDoc-        processString ('%':'s':xs) =-            liftM2 (<>) (return modules_list) (processString xs)-            where-              modules_list = context <> modules_bit-              modules_bit = hsep $ map text modules_names-        processString ('%':'l':xs) =-            liftM2 (<>) (return $ ppr line) (processString xs)-        processString ('%':'d':xs) =-            liftM2 (<>) (liftM text formatted_time) (processString xs)-            where-              formatted_time = liftIO $ formatCurrentTime "%a %b %d"-        processString ('%':'t':xs) =-            liftM2 (<>) (liftM text formatted_time) (processString xs)-            where-              formatted_time = liftIO $ formatCurrentTime "%H:%M:%S"-        processString ('%':'T':xs) = do-            liftM2 (<>) (liftM text formatted_time) (processString xs)-            where-              formatted_time = liftIO $ formatCurrentTime "%I:%M:%S"-        processString ('%':'@':xs) = do-            liftM2 (<>) (liftM text formatted_time) (processString xs)-            where-              formatted_time = liftIO $ formatCurrentTime "%I:%M %P"-        processString ('%':'A':xs) = do-            liftM2 (<>) (liftM text formatted_time) (processString xs)-            where-              formatted_time = liftIO $ formatCurrentTime "%H:%M"-        processString ('%':'u':xs) =-            liftM2 (<>) (liftM text user_name) (processString xs)-            where-              user_name = liftIO $ getUserName-        processString ('%':'w':xs) =-            liftM2 (<>) (liftM text current_directory) (processString xs)-            where-              current_directory = liftIO $ getCurrentDirectory-        processString ('%':'o':xs) =-            liftM ((text os) <>) (processString xs)-        processString ('%':'a':xs) =-            liftM ((text arch) <>) (processString xs)-        processString ('%':'N':xs) =-            liftM ((text compilerName) <>) (processString xs)-        processString ('%':'V':xs) =-            liftM ((text $ showVersion compilerVersion) <>) (processString xs)-        processString ('%':'c':'a':'l':'l':xs) = do-            respond <- liftIO $ do-                (code, out, err) <--                    readProcessWithExitCode-                    (head list_words) (tail list_words) ""-                    `catchIO` \e -> return (ExitFailure 1, "", show e)-                case code of-                    ExitSuccess -> return out-                    _ -> do-                        hPutStrLn stderr err-                        return ""-            liftM ((text respond) <>) (processString afterClosed)-            where-              (cmd, afterClosed) = parseCallEscape xs-              list_words = words cmd-        processString ('%':'%':xs) =-            liftM ((char '%') <>) (processString xs)-        processString (x:xs) =-            liftM (char x <>) (processString xs)-        processString "" =-            return empty--    processString promptS--mkPrompt :: GHCi String-mkPrompt = do-  st <- getGHCiState-  dflags <- getDynFlags-  (context, modules_names, line) <- getInfoForPrompt--  prompt_string <- (prompt st) modules_names line-  let prompt_doc = context <> prompt_string--  return (showSDoc dflags prompt_doc)--queryQueue :: GHCi (Maybe String)-queryQueue = do-  st <- getGHCiState-  case cmdqueue st of-    []   -> return Nothing-    c:cs -> do setGHCiState st{ cmdqueue = cs }-               return (Just c)---- Reconfigurable pretty-printing Ticket #5461-installInteractivePrint :: Maybe String -> Bool -> GHCi ()-installInteractivePrint Nothing _  = return ()-installInteractivePrint (Just ipFun) exprmode = do-  ok <- trySuccess $ do-                (name:_) <- GHC.parseName ipFun-                modifySession (\he -> let new_ic = setInteractivePrintName (hsc_IC he) name-                                      in he{hsc_IC = new_ic})-                return Succeeded--  when (failed ok && exprmode) $ liftIO (exitWith (ExitFailure 1))---- | The main read-eval-print loop-runCommands :: InputT GHCi (Maybe String) -> InputT GHCi ()-runCommands gCmd = runCommands' handler Nothing gCmd >> return ()--runCommands' :: (SomeException -> GHCi Bool) -- ^ Exception handler-             -> Maybe (GHCi ()) -- ^ Source error handler-             -> InputT GHCi (Maybe String)-             -> InputT GHCi (Maybe Bool)-         -- We want to return () here, but have to return (Maybe Bool)-         -- because gmask is not polymorphic enough: we want to use-         -- unmask at two different types.-runCommands' eh sourceErrorHandler gCmd = gmask $ \unmask -> do-    b <- ghandle (\e -> case fromException e of-                          Just UserInterrupt -> return $ Just False-                          _ -> case fromException e of-                                 Just ghce ->-                                   do liftIO (print (ghce :: GhcException))-                                      return Nothing-                                 _other ->-                                   liftIO (Exception.throwIO e))-            (unmask $ runOneCommand eh gCmd)-    case b of-      Nothing -> return Nothing-      Just success -> do-        unless success $ maybe (return ()) lift sourceErrorHandler-        unmask $ runCommands' eh sourceErrorHandler gCmd---- | Evaluate a single line of user input (either :<command> or Haskell code).--- A result of Nothing means there was no more input to process.--- Otherwise the result is Just b where b is True if the command succeeded;--- this is relevant only to ghc -e, which will exit with status 1--- if the command was unsuccessful. GHCi will continue in either case.-runOneCommand :: (SomeException -> GHCi Bool) -> InputT GHCi (Maybe String)-            -> InputT GHCi (Maybe Bool)-runOneCommand eh gCmd = do-  -- run a previously queued command if there is one, otherwise get new-  -- input from user-  mb_cmd0 <- noSpace (lift queryQueue)-  mb_cmd1 <- maybe (noSpace gCmd) (return . Just) mb_cmd0-  case mb_cmd1 of-    Nothing -> return Nothing-    Just c  -> ghciHandle (\e -> lift $ eh e >>= return . Just) $-             handleSourceError printErrorAndFail-               (doCommand c)-               -- source error's are handled by runStmt-               -- is the handler necessary here?-  where-    printErrorAndFail err = do-        GHC.printException err-        return $ Just False     -- Exit ghc -e, but not GHCi--    noSpace q = q >>= maybe (return Nothing)-                            (\c -> case removeSpaces c of-                                     ""   -> noSpace q-                                     ":{" -> multiLineCmd q-                                     _    -> return (Just c) )-    multiLineCmd q = do-      st <- getGHCiState-      let p = prompt st-      setGHCiState st{ prompt = prompt_cont st }-      mb_cmd <- collectCommand q "" `GHC.gfinally`-                modifyGHCiState (\st' -> st' { prompt = p })-      return mb_cmd-    -- we can't use removeSpaces for the sublines here, so-    -- multiline commands are somewhat more brittle against-    -- fileformat errors (such as \r in dos input on unix),-    -- we get rid of any extra spaces for the ":}" test;-    -- we also avoid silent failure if ":}" is not found;-    -- and since there is no (?) valid occurrence of \r (as-    -- opposed to its String representation, "\r") inside a-    -- ghci command, we replace any such with ' ' (argh:-(-    collectCommand q c = q >>=-      maybe (liftIO (ioError collectError))-            (\l->if removeSpaces l == ":}"-                 then return (Just c)-                 else collectCommand q (c ++ "\n" ++ map normSpace l))-      where normSpace '\r' = ' '-            normSpace   x  = x-    -- SDM (2007-11-07): is userError the one to use here?-    collectError = userError "unterminated multiline command :{ .. :}"--    -- | Handle a line of input-    doCommand :: String -> InputT GHCi (Maybe Bool)--    -- command-    doCommand stmt | (':' : cmd) <- removeSpaces stmt = do-      result <- specialCommand cmd-      case result of-        True -> return Nothing-        _    -> return $ Just True--    -- haskell-    doCommand stmt = do-      -- if 'stmt' was entered via ':{' it will contain '\n's-      let stmt_nl_cnt = length [ () | '\n' <- stmt ]-      ml <- lift $ isOptionSet Multiline-      if ml && stmt_nl_cnt == 0 -- don't trigger automatic multi-line mode for ':{'-multiline input-        then do-          fst_line_num <- line_number <$> getGHCiState-          mb_stmt <- checkInputForLayout stmt gCmd-          case mb_stmt of-            Nothing      -> return $ Just True-            Just ml_stmt -> do-              -- temporarily compensate line-number for multi-line input-              result <- timeIt runAllocs $ lift $-                runStmtWithLineNum fst_line_num ml_stmt GHC.RunToCompletion-              return $ Just (runSuccess result)-        else do -- single line input and :{ - multiline input-          last_line_num <- line_number <$> getGHCiState-          -- reconstruct first line num from last line num and stmt-          let fst_line_num | stmt_nl_cnt > 0 = last_line_num - (stmt_nl_cnt2 + 1)-                           | otherwise = last_line_num -- single line input-              stmt_nl_cnt2 = length [ () | '\n' <- stmt' ]-              stmt' = dropLeadingWhiteLines stmt -- runStmt doesn't like leading empty lines-          -- temporarily compensate line-number for multi-line input-          result <- timeIt runAllocs $ lift $-            runStmtWithLineNum fst_line_num stmt' GHC.RunToCompletion-          return $ Just (runSuccess result)--    -- runStmt wrapper for temporarily overridden line-number-    runStmtWithLineNum :: Int -> String -> SingleStep-                       -> GHCi (Maybe GHC.ExecResult)-    runStmtWithLineNum lnum stmt step = do-        st0 <- getGHCiState-        setGHCiState st0 { line_number = lnum }-        result <- runStmt stmt step-        -- restore original line_number-        getGHCiState >>= \st -> setGHCiState st { line_number = line_number st0 }-        return result--    -- note: this is subtly different from 'unlines . dropWhile (all isSpace) . lines'-    dropLeadingWhiteLines s | (l0,'\n':r) <- break (=='\n') s-                            , all isSpace l0 = dropLeadingWhiteLines r-                            | otherwise = s----- #4316--- lex the input.  If there is an unclosed layout context, request input-checkInputForLayout :: String -> InputT GHCi (Maybe String)-                    -> InputT GHCi (Maybe String)-checkInputForLayout stmt getStmt = do-   dflags' <- getDynFlags-   let dflags = xopt_set dflags' LangExt.AlternativeLayoutRule-   st0 <- getGHCiState-   let buf'   =  stringToStringBuffer stmt-       loc    = mkRealSrcLoc (fsLit (progname st0)) (line_number st0) 1-       pstate = Lexer.mkPState dflags buf' loc-   case Lexer.unP goToEnd pstate of-     (Lexer.POk _ False) -> return $ Just stmt-     _other              -> do-       st1 <- getGHCiState-       let p = prompt st1-       setGHCiState st1{ prompt = prompt_cont st1 }-       mb_stmt <- ghciHandle (\ex -> case fromException ex of-                            Just UserInterrupt -> return Nothing-                            _ -> case fromException ex of-                                 Just ghce ->-                                   do liftIO (print (ghce :: GhcException))-                                      return Nothing-                                 _other -> liftIO (Exception.throwIO ex))-                     getStmt-       modifyGHCiState (\st' -> st' { prompt = p })-       -- the recursive call does not recycle parser state-       -- as we use a new string buffer-       case mb_stmt of-         Nothing  -> return Nothing-         Just str -> if str == ""-           then return $ Just stmt-           else do-             checkInputForLayout (stmt++"\n"++str) getStmt-     where goToEnd = do-             eof <- Lexer.nextIsEOF-             if eof-               then Lexer.activeContext-               else Lexer.lexer False return >> goToEnd--enqueueCommands :: [String] -> GHCi ()-enqueueCommands cmds = do-  -- make sure we force any exceptions in the commands while we're-  -- still inside the exception handler, otherwise bad things will-  -- happen (see #10501)-  cmds `deepseq` return ()-  modifyGHCiState $ \st -> st{ cmdqueue = cmds ++ cmdqueue st }---- | Entry point to execute some haskell code from user.--- The return value True indicates success, as in `runOneCommand`.-runStmt :: String -> SingleStep -> GHCi (Maybe GHC.ExecResult)-runStmt stmt step = do-  dflags <- GHC.getInteractiveDynFlags-  if | GHC.isStmt dflags stmt    -> run_stmt-     | GHC.isImport dflags stmt  -> run_import-     -- Every import declaration should be handled by `run_import`. As GHCi-     -- in general only accepts one command at a time, we simply throw an-     -- exception when the input contains multiple commands of which at least-     -- one is an import command (see #10663).-     | GHC.hasImport dflags stmt -> throwGhcException-       (CmdLineError "error: expecting a single import declaration")-     -- Note: `GHC.isDecl` returns False on input like-     -- `data Infix a b = a :@: b; infixl 4 :@:`-     -- and should therefore not be used here.-     | otherwise                 -> run_decl--  where-    run_import = do-      addImportToContext stmt-      return (Just (GHC.ExecComplete (Right []) 0))--    run_decl =-        do _ <- liftIO $ tryIO $ hFlushAll stdin-           m_result <- GhciMonad.runDecls stmt-           case m_result of-               Nothing     -> return Nothing-               Just result ->-                 Just <$> afterRunStmt (const True)-                            (GHC.ExecComplete (Right result) 0)--    run_stmt =-        do -- In the new IO library, read handles buffer data even if the Handle-           -- is set to NoBuffering.  This causes problems for GHCi where there-           -- are really two stdin Handles.  So we flush any bufferred data in-           -- GHCi's stdin Handle here (only relevant if stdin is attached to-           -- a file, otherwise the read buffer can't be flushed).-           _ <- liftIO $ tryIO $ hFlushAll stdin-           m_result <- GhciMonad.runStmt stmt step-           case m_result of-               Nothing     -> return Nothing-               Just result -> Just <$> afterRunStmt (const True) result---- | Clean up the GHCi environment after a statement has run-afterRunStmt :: (SrcSpan -> Bool) -> GHC.ExecResult -> GHCi GHC.ExecResult-afterRunStmt step_here run_result = do-  resumes <- GHC.getResumeContext-  case run_result of-     GHC.ExecComplete{..} ->-       case execResult of-          Left ex -> liftIO $ Exception.throwIO ex-          Right names -> do-            show_types <- isOptionSet ShowType-            when show_types $ printTypeOfNames names-     GHC.ExecBreak names mb_info-         | isNothing  mb_info ||-           step_here (GHC.resumeSpan $ head resumes) -> do-               mb_id_loc <- toBreakIdAndLocation mb_info-               let bCmd = maybe "" ( \(_,l) -> onBreakCmd l ) mb_id_loc-               if (null bCmd)-                 then printStoppedAtBreakInfo (head resumes) names-                 else enqueueCommands [bCmd]-               -- run the command set with ":set stop <cmd>"-               st <- getGHCiState-               enqueueCommands [stop st]-               return ()-         | otherwise -> resume step_here GHC.SingleStep >>=-                        afterRunStmt step_here >> return ()--  flushInterpBuffers-  withSignalHandlers $ do-     b <- isOptionSet RevertCAFs-     when b revertCAFs--  return run_result--runSuccess :: Maybe GHC.ExecResult -> Bool-runSuccess run_result-  | Just (GHC.ExecComplete { execResult = Right _ }) <- run_result = True-  | otherwise = False--runAllocs :: Maybe GHC.ExecResult -> Maybe Integer-runAllocs m = do-  res <- m-  case res of-    GHC.ExecComplete{..} -> Just (fromIntegral execAllocation)-    _ -> Nothing--toBreakIdAndLocation ::-  Maybe GHC.BreakInfo -> GHCi (Maybe (Int, BreakLocation))-toBreakIdAndLocation Nothing = return Nothing-toBreakIdAndLocation (Just inf) = do-  let md = GHC.breakInfo_module inf-      nm = GHC.breakInfo_number inf-  st <- getGHCiState-  return $ listToMaybe [ id_loc | id_loc@(_,loc) <- breaks st,-                                  breakModule loc == md,-                                  breakTick loc == nm ]--printStoppedAtBreakInfo :: Resume -> [Name] -> GHCi ()-printStoppedAtBreakInfo res names = do-  printForUser $ pprStopped res-  --  printTypeOfNames session names-  let namesSorted = sortBy compareNames names-  tythings <- catMaybes `liftM` mapM GHC.lookupName namesSorted-  docs <- mapM pprTypeAndContents [i | AnId i <- tythings]-  printForUserPartWay $ vcat docs--printTypeOfNames :: [Name] -> GHCi ()-printTypeOfNames names- = mapM_ (printTypeOfName ) $ sortBy compareNames names--compareNames :: Name -> Name -> Ordering-n1 `compareNames` n2 = compareWith n1 `compare` compareWith n2-    where compareWith n = (getOccString n, getSrcSpan n)--printTypeOfName :: Name -> GHCi ()-printTypeOfName n-   = do maybe_tything <- GHC.lookupName n-        case maybe_tything of-            Nothing    -> return ()-            Just thing -> printTyThing thing---data MaybeCommand = GotCommand Command | BadCommand | NoLastCommand---- | Entry point for execution a ':<command>' input from user-specialCommand :: String -> InputT GHCi Bool-specialCommand ('!':str) = lift $ shellEscape (dropWhile isSpace str)-specialCommand str = do-  let (cmd,rest) = break isSpace str-  maybe_cmd <- lift $ lookupCommand cmd-  htxt <- short_help <$> getGHCiState-  case maybe_cmd of-    GotCommand cmd -> (cmdAction cmd) (dropWhile isSpace rest)-    BadCommand ->-      do liftIO $ hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n"-                           ++ htxt)-         return False-    NoLastCommand ->-      do liftIO $ hPutStr stdout ("there is no last command to perform\n"-                           ++ htxt)-         return False--shellEscape :: String -> GHCi Bool-shellEscape str = liftIO (system str >> return False)--lookupCommand :: String -> GHCi (MaybeCommand)-lookupCommand "" = do-  st <- getGHCiState-  case last_command st of-      Just c -> return $ GotCommand c-      Nothing -> return NoLastCommand-lookupCommand str = do-  mc <- lookupCommand' str-  modifyGHCiState (\st -> st { last_command = mc })-  return $ case mc of-           Just c -> GotCommand c-           Nothing -> BadCommand--lookupCommand' :: String -> GHCi (Maybe Command)-lookupCommand' ":" = return Nothing-lookupCommand' str' = do-  macros    <- ghci_macros <$> getGHCiState-  ghci_cmds <- ghci_commands <$> getGHCiState--  let ghci_cmds_nohide = filter (not . cmdHidden) ghci_cmds--  let (str, xcmds) = case str' of-          ':' : rest -> (rest, [])     -- "::" selects a builtin command-          _          -> (str', macros) -- otherwise include macros in lookup--      lookupExact  s = find $ (s ==)           . cmdName-      lookupPrefix s = find $ (s `isPrefixOf`) . cmdName--      -- hidden commands can only be matched exact-      builtinPfxMatch = lookupPrefix str ghci_cmds_nohide--  -- first, look for exact match (while preferring macros); then, look-  -- for first prefix match (preferring builtins), *unless* a macro-  -- overrides the builtin; see #8305 for motivation-  return $ lookupExact str xcmds <|>-           lookupExact str ghci_cmds <|>-           (builtinPfxMatch >>= \c -> lookupExact (cmdName c) xcmds) <|>-           builtinPfxMatch <|>-           lookupPrefix str xcmds--getCurrentBreakSpan :: GHCi (Maybe SrcSpan)-getCurrentBreakSpan = do-  resumes <- GHC.getResumeContext-  case resumes of-    [] -> return Nothing-    (r:_) -> do-        let ix = GHC.resumeHistoryIx r-        if ix == 0-           then return (Just (GHC.resumeSpan r))-           else do-                let hist = GHC.resumeHistory r !! (ix-1)-                pan <- GHC.getHistorySpan hist-                return (Just pan)--getCallStackAtCurrentBreakpoint :: GHCi (Maybe [String])-getCallStackAtCurrentBreakpoint = do-  resumes <- GHC.getResumeContext-  case resumes of-    [] -> return Nothing-    (r:_) -> do-       hsc_env <- GHC.getSession-       Just <$> liftIO (costCentreStackInfo hsc_env (GHC.resumeCCS r))--getCurrentBreakModule :: GHCi (Maybe Module)-getCurrentBreakModule = do-  resumes <- GHC.getResumeContext-  case resumes of-    [] -> return Nothing-    (r:_) -> do-        let ix = GHC.resumeHistoryIx r-        if ix == 0-           then return (GHC.breakInfo_module `liftM` GHC.resumeBreakInfo r)-           else do-                let hist = GHC.resumeHistory r !! (ix-1)-                return $ Just $ GHC.getHistoryModule  hist------------------------------------------------------------------------------------- Commands-----------------------------------------------------------------------------------noArgs :: GHCi () -> String -> GHCi ()-noArgs m "" = m-noArgs _ _  = liftIO $ putStrLn "This command takes no arguments"--withSandboxOnly :: String -> GHCi () -> GHCi ()-withSandboxOnly cmd this = do-   dflags <- getDynFlags-   if not (gopt Opt_GhciSandbox dflags)-      then printForUser (text cmd <+>-                         ptext (sLit "is not supported with -fno-ghci-sandbox"))-      else this---------------------------------------------------------------------------------- :help--help :: String -> GHCi ()-help _ = do-    txt <- long_help `fmap` getGHCiState-    liftIO $ putStr txt---------------------------------------------------------------------------------- :info--info :: Bool -> String -> InputT GHCi ()-info _ "" = throwGhcException (CmdLineError "syntax: ':i <thing-you-want-info-about>'")-info allInfo s  = handleSourceError GHC.printException $ do-    unqual <- GHC.getPrintUnqual-    dflags <- getDynFlags-    sdocs  <- mapM (infoThing allInfo) (words s)-    mapM_ (liftIO . putStrLn . showSDocForUser dflags unqual) sdocs--infoThing :: GHC.GhcMonad m => Bool -> String -> m SDoc-infoThing allInfo str = do-    names     <- GHC.parseName str-    mb_stuffs <- mapM (GHC.getInfo allInfo) names-    let filtered = filterOutChildren (\(t,_f,_ci,_fi) -> t) (catMaybes mb_stuffs)-    return $ vcat (intersperse (text "") $ map pprInfo filtered)--  -- Filter out names whose parent is also there Good-  -- example is '[]', which is both a type and data-  -- constructor in the same type-filterOutChildren :: (a -> TyThing) -> [a] -> [a]-filterOutChildren get_thing xs-  = filterOut has_parent xs-  where-    all_names = mkNameSet (map (getName . get_thing) xs)-    has_parent x = case tyThingParent_maybe (get_thing x) of-                     Just p  -> getName p `elemNameSet` all_names-                     Nothing -> False--pprInfo :: (TyThing, Fixity, [GHC.ClsInst], [GHC.FamInst]) -> SDoc-pprInfo (thing, fixity, cls_insts, fam_insts)-  =  pprTyThingInContextLoc thing-  $$ show_fixity-  $$ vcat (map GHC.pprInstance cls_insts)-  $$ vcat (map GHC.pprFamInst  fam_insts)-  where-    show_fixity-        | fixity == GHC.defaultFixity = empty-        | otherwise                   = ppr fixity <+> pprInfixName (GHC.getName thing)---------------------------------------------------------------------------------- :main--runMain :: String -> GHCi ()-runMain s = case toArgs s of-            Left err   -> liftIO (hPutStrLn stderr err)-            Right args ->-                do dflags <- getDynFlags-                   let main = fromMaybe "main" (mainFunIs dflags)-                   -- Wrap the main function in 'void' to discard its value instead-                   -- of printing it (#9086). See Haskell 2010 report Chapter 5.-                   doWithArgs args $ "Control.Monad.void (" ++ main ++ ")"---------------------------------------------------------------------------------- :run--runRun :: String -> GHCi ()-runRun s = case toCmdArgs s of-           Left err          -> liftIO (hPutStrLn stderr err)-           Right (cmd, args) -> doWithArgs args cmd--doWithArgs :: [String] -> String -> GHCi ()-doWithArgs args cmd = enqueueCommands ["System.Environment.withArgs " ++-                                       show args ++ " (" ++ cmd ++ ")"]---------------------------------------------------------------------------------- :cd--changeDirectory :: String -> InputT GHCi ()-changeDirectory "" = do-  -- :cd on its own changes to the user's home directory-  either_dir <- liftIO $ tryIO getHomeDirectory-  case either_dir of-     Left _e -> return ()-     Right dir -> changeDirectory dir-changeDirectory dir = do-  graph <- GHC.getModuleGraph-  when (not (null graph)) $-        liftIO $ putStrLn "Warning: changing directory causes all loaded modules to be unloaded,\nbecause the search path has changed."-  GHC.setTargets []-  _ <- GHC.load LoadAllTargets-  lift $ setContextAfterLoad False []-  GHC.workingDirectoryChanged-  dir' <- expandPath dir-  liftIO $ setCurrentDirectory dir'-  dflags <- getDynFlags-  -- With -fexternal-interpreter, we have to change the directory of the subprocess too.-  -- (this gives consistent behavior with and without -fexternal-interpreter)-  when (gopt Opt_ExternalInterpreter dflags) $-    lift $ enqueueCommands ["System.Directory.setCurrentDirectory " ++ show dir']--trySuccess :: GHC.GhcMonad m => m SuccessFlag -> m SuccessFlag-trySuccess act =-    handleSourceError (\e -> do GHC.printException e-                                return Failed) $ do-      act---------------------------------------------------------------------------------- :edit--editFile :: String -> InputT GHCi ()-editFile str =-  do file <- if null str then lift chooseEditFile else expandPath str-     st <- getGHCiState-     errs <- liftIO $ readIORef $ lastErrorLocations st-     let cmd = editor st-     when (null cmd)-       $ throwGhcException (CmdLineError "editor not set, use :set editor")-     lineOpt <- liftIO $ do-         let sameFile p1 p2 = liftA2 (==) (canonicalizePath p1) (canonicalizePath p2)-              `catchIO` (\_ -> return False)--         curFileErrs <- filterM (\(f, _) -> unpackFS f `sameFile` file) errs-         return $ case curFileErrs of-             (_, line):_ -> " +" ++ show line-             _ -> ""-     let cmdArgs = ' ':(file ++ lineOpt)-     code <- liftIO $ system (cmd ++ cmdArgs)--     when (code == ExitSuccess)-       $ reloadModule ""---- The user didn't specify a file so we pick one for them.--- Our strategy is to pick the first module that failed to load,--- or otherwise the first target.------ XXX: Can we figure out what happened if the depndecy analysis fails---      (e.g., because the porgrammeer mistyped the name of a module)?--- XXX: Can we figure out the location of an error to pass to the editor?--- XXX: if we could figure out the list of errors that occured during the--- last load/reaload, then we could start the editor focused on the first--- of those.-chooseEditFile :: GHCi String-chooseEditFile =-  do let hasFailed x = fmap not $ GHC.isLoaded $ GHC.ms_mod_name x--     graph <- GHC.getModuleGraph-     failed_graph <- filterM hasFailed graph-     let order g  = flattenSCCs $ GHC.topSortModuleGraph True g Nothing-         pick xs  = case xs of-                      x : _ -> GHC.ml_hs_file (GHC.ms_location x)-                      _     -> Nothing--     case pick (order failed_graph) of-       Just file -> return file-       Nothing   ->-         do targets <- GHC.getTargets-            case msum (map fromTarget targets) of-              Just file -> return file-              Nothing   -> throwGhcException (CmdLineError "No files to edit.")--  where fromTarget (GHC.Target (GHC.TargetFile f _) _ _) = Just f-        fromTarget _ = Nothing -- when would we get a module target?----------------------------------------------------------------------------------- :def--defineMacro :: Bool{-overwrite-} -> String -> GHCi ()-defineMacro _ (':':_) =-  liftIO $ putStrLn "macro name cannot start with a colon"-defineMacro overwrite s = do-  let (macro_name, definition) = break isSpace s-  macros <- ghci_macros <$> getGHCiState-  let defined = map cmdName macros-  if null macro_name-        then if null defined-                then liftIO $ putStrLn "no macros defined"-                else liftIO $ putStr ("the following macros are defined:\n" ++-                                      unlines defined)-        else do-  if (not overwrite && macro_name `elem` defined)-        then throwGhcException (CmdLineError-                ("macro '" ++ macro_name ++ "' is already defined"))-        else do--  -- compile the expression-  handleSourceError GHC.printException $ do-    step <- getGhciStepIO-    expr <- GHC.parseExpr definition-    -- > ghciStepIO . definition :: String -> IO String-    let stringTy = nlHsTyVar stringTy_RDR-        ioM = nlHsTyVar (getRdrName ioTyConName) `nlHsAppTy` stringTy-        body = nlHsVar compose_RDR `mkHsApp` (nlHsPar step)-                                   `mkHsApp` (nlHsPar expr)-        tySig = mkLHsSigWcType (stringTy `nlHsFunTy` ioM)-        new_expr = L (getLoc expr) $ ExprWithTySig body tySig-    hv <- GHC.compileParsedExprRemote new_expr--    let newCmd = Command { cmdName = macro_name-                         , cmdAction = lift . runMacro hv-                         , cmdHidden = False-                         , cmdCompletionFunc = noCompletion-                         }--    -- later defined macros have precedence-    modifyGHCiState $ \s ->-        let filtered = [ cmd | cmd <- macros, cmdName cmd /= macro_name ]-        in s { ghci_macros = newCmd : filtered }--runMacro :: GHC.ForeignHValue{-String -> IO String-} -> String -> GHCi Bool-runMacro fun s = do-  hsc_env <- GHC.getSession-  str <- liftIO $ evalStringToIOString hsc_env fun s-  enqueueCommands (lines str)-  return False----------------------------------------------------------------------------------- :undef--undefineMacro :: String -> GHCi ()-undefineMacro str = mapM_ undef (words str)- where undef macro_name = do-        cmds <- ghci_macros <$> getGHCiState-        if (macro_name `notElem` map cmdName cmds)-           then throwGhcException (CmdLineError-                ("macro '" ++ macro_name ++ "' is not defined"))-           else do-            -- This is a tad racy but really, it's a shell-            modifyGHCiState $ \s ->-                s { ghci_macros = filter ((/= macro_name) . cmdName)-                                         (ghci_macros s) }----------------------------------------------------------------------------------- :cmd--cmdCmd :: String -> GHCi ()-cmdCmd str = handleSourceError GHC.printException $ do-    step <- getGhciStepIO-    expr <- GHC.parseExpr str-    -- > ghciStepIO str :: IO String-    let new_expr = step `mkHsApp` expr-    hv <- GHC.compileParsedExprRemote new_expr--    hsc_env <- GHC.getSession-    cmds <- liftIO $ evalString hsc_env hv-    enqueueCommands (lines cmds)---- | Generate a typed ghciStepIO expression--- @ghciStepIO :: Ty String -> IO String@.-getGhciStepIO :: GHCi (LHsExpr RdrName)-getGhciStepIO = do-  ghciTyConName <- GHC.getGHCiMonad-  let stringTy = nlHsTyVar stringTy_RDR-      ghciM = nlHsTyVar (getRdrName ghciTyConName) `nlHsAppTy` stringTy-      ioM = nlHsTyVar (getRdrName ioTyConName) `nlHsAppTy` stringTy-      body = nlHsVar (getRdrName ghciStepIoMName)-      tySig = mkLHsSigWcType (ghciM `nlHsFunTy` ioM)-  return $ noLoc $ ExprWithTySig body tySig---------------------------------------------------------------------------------- :check--checkModule :: String -> InputT GHCi ()-checkModule m = do-  let modl = GHC.mkModuleName m-  ok <- handleSourceError (\e -> GHC.printException e >> return False) $ do-          r <- GHC.typecheckModule =<< GHC.parseModule =<< GHC.getModSummary modl-          dflags <- getDynFlags-          liftIO $ putStrLn $ showSDoc dflags $-           case GHC.moduleInfo r of-             cm | Just scope <- GHC.modInfoTopLevelScope cm ->-                let-                    (loc, glob) = ASSERT( all isExternalName scope )-                                  partition ((== modl) . GHC.moduleName . GHC.nameModule) scope-                in-                        (text "global names: " <+> ppr glob) $$-                        (text "local  names: " <+> ppr loc)-             _ -> empty-          return True-  afterLoad (successIf ok) False----------------------------------------------------------------------------------- :load, :add, :reload---- | Sets '-fdefer-type-errors' if 'defer' is true, executes 'load' and unsets--- '-fdefer-type-errors' again if it has not been set before.-wrapDeferTypeErrors :: InputT GHCi a -> InputT GHCi a-wrapDeferTypeErrors load =-  gbracket-    (do-      -- Force originalFlags to avoid leaking the associated HscEnv-      !originalFlags <- getDynFlags-      void $ GHC.setProgramDynFlags $-         setGeneralFlag' Opt_DeferTypeErrors originalFlags-      return originalFlags)-    (\originalFlags -> void $ GHC.setProgramDynFlags originalFlags)-    (\_ -> load)--loadModule :: [(FilePath, Maybe Phase)] -> InputT GHCi SuccessFlag-loadModule fs = timeIt (const Nothing) (loadModule' fs)---- | @:load@ command-loadModule_ :: [FilePath] -> InputT GHCi ()-loadModule_ fs = void $ loadModule (zip fs (repeat Nothing))--loadModuleDefer :: [FilePath] -> InputT GHCi ()-loadModuleDefer = wrapDeferTypeErrors . loadModule_--loadModule' :: [(FilePath, Maybe Phase)] -> InputT GHCi SuccessFlag-loadModule' files = do-  let (filenames, phases) = unzip files-  exp_filenames <- mapM expandPath filenames-  let files' = zip exp_filenames phases-  targets <- mapM (uncurry GHC.guessTarget) files'--  -- NOTE: we used to do the dependency anal first, so that if it-  -- fails we didn't throw away the current set of modules.  This would-  -- require some re-working of the GHC interface, so we'll leave it-  -- as a ToDo for now.--  -- unload first-  _ <- GHC.abandonAll-  lift discardActiveBreakPoints-  GHC.setTargets []-  _ <- GHC.load LoadAllTargets--  GHC.setTargets targets-  doLoadAndCollectInfo False LoadAllTargets---- | @:add@ command-addModule :: [FilePath] -> InputT GHCi ()-addModule files = do-  lift revertCAFs -- always revert CAFs on load/add.-  files' <- mapM expandPath files-  targets <- mapM (\m -> GHC.guessTarget m Nothing) files'-  -- remove old targets with the same id; e.g. for :add *M-  mapM_ GHC.removeTarget [ tid | Target tid _ _ <- targets ]-  mapM_ GHC.addTarget targets-  _ <- doLoadAndCollectInfo False LoadAllTargets-  return ()---- | @:reload@ command-reloadModule :: String -> InputT GHCi ()-reloadModule m = void $ doLoadAndCollectInfo True loadTargets-  where-    loadTargets | null m    = LoadAllTargets-                | otherwise = LoadUpTo (GHC.mkModuleName m)--reloadModuleDefer :: String -> InputT GHCi ()-reloadModuleDefer = wrapDeferTypeErrors . reloadModule---- | Load/compile targets and (optionally) collect module-info------ This collects the necessary SrcSpan annotated type information (via--- 'collectInfo') required by the @:all-types@, @:loc-at@, @:type-at@,--- and @:uses@ commands.------ Meta-info collection is not enabled by default and needs to be--- enabled explicitly via @:set +c@.  The reason is that collecting--- the type-information for all sub-spans can be quite expensive, and--- since those commands are designed to be used by editors and--- tooling, it's useless to collect this data for normal GHCi--- sessions.-doLoadAndCollectInfo :: Bool -> LoadHowMuch -> InputT GHCi SuccessFlag-doLoadAndCollectInfo retain_context howmuch = do-  doCollectInfo <- lift (isOptionSet CollectInfo)--  doLoad retain_context howmuch >>= \case-    Succeeded | doCollectInfo -> do-      loaded <- getModuleGraph >>= filterM GHC.isLoaded . map GHC.ms_mod_name-      v <- mod_infos <$> getGHCiState-      !newInfos <- collectInfo v loaded-      modifyGHCiState (\st -> st { mod_infos = newInfos })-      return Succeeded-    flag -> return flag--doLoad :: Bool -> LoadHowMuch -> InputT GHCi SuccessFlag-doLoad retain_context howmuch = do-  -- turn off breakpoints before we load: we can't turn them off later, because-  -- the ModBreaks will have gone away.-  lift discardActiveBreakPoints--  lift resetLastErrorLocations-  -- Enable buffering stdout and stderr as we're compiling. Keeping these-  -- handles unbuffered will just slow the compilation down, especially when-  -- compiling in parallel.-  gbracket (liftIO $ do hSetBuffering stdout LineBuffering-                        hSetBuffering stderr LineBuffering)-           (\_ ->-            liftIO $ do hSetBuffering stdout NoBuffering-                        hSetBuffering stderr NoBuffering) $ \_ -> do-      ok <- trySuccess $ GHC.load howmuch-      afterLoad ok retain_context-      return ok---afterLoad :: SuccessFlag-          -> Bool   -- keep the remembered_ctx, as far as possible (:reload)-          -> InputT GHCi ()-afterLoad ok retain_context = do-  lift revertCAFs  -- always revert CAFs on load.-  lift discardTickArrays-  loaded_mods <- getLoadedModules-  modulesLoadedMsg ok loaded_mods-  lift $ setContextAfterLoad retain_context loaded_mods--setContextAfterLoad :: Bool -> [GHC.ModSummary] -> GHCi ()-setContextAfterLoad keep_ctxt [] = do-  setContextKeepingPackageModules keep_ctxt []-setContextAfterLoad keep_ctxt ms = do-  -- load a target if one is available, otherwise load the topmost module.-  targets <- GHC.getTargets-  case [ m | Just m <- map (findTarget ms) targets ] of-        []    ->-          let graph' = flattenSCCs (GHC.topSortModuleGraph True ms Nothing) in-          load_this (last graph')-        (m:_) ->-          load_this m- where-   findTarget mds t-    = case filter (`matches` t) mds of-        []    -> Nothing-        (m:_) -> Just m--   summary `matches` Target (TargetModule m) _ _-        = GHC.ms_mod_name summary == m-   summary `matches` Target (TargetFile f _) _ _-        | Just f' <- GHC.ml_hs_file (GHC.ms_location summary)   = f == f'-   _ `matches` _-        = False--   load_this summary | m <- GHC.ms_mod summary = do-        is_interp <- GHC.moduleIsInterpreted m-        dflags <- getDynFlags-        let star_ok = is_interp && not (safeLanguageOn dflags)-              -- We import the module with a * iff-              --   - it is interpreted, and-              --   - -XSafe is off (it doesn't allow *-imports)-        let new_ctx | star_ok   = [mkIIModule (GHC.moduleName m)]-                    | otherwise = [mkIIDecl   (GHC.moduleName m)]-        setContextKeepingPackageModules keep_ctxt new_ctx----- | Keep any package modules (except Prelude) when changing the context.-setContextKeepingPackageModules-        :: Bool                 -- True  <=> keep all of remembered_ctx-                                -- False <=> just keep package imports-        -> [InteractiveImport]  -- new context-        -> GHCi ()--setContextKeepingPackageModules keep_ctx trans_ctx = do--  st <- getGHCiState-  let rem_ctx = remembered_ctx st-  new_rem_ctx <- if keep_ctx then return rem_ctx-                             else keepPackageImports rem_ctx-  setGHCiState st{ remembered_ctx = new_rem_ctx,-                   transient_ctx  = filterSubsumed new_rem_ctx trans_ctx }-  setGHCContextFromGHCiState---- | Filters a list of 'InteractiveImport', clearing out any home package--- imports so only imports from external packages are preserved.  ('IIModule'--- counts as a home package import, because we are only able to bring a--- full top-level into scope when the source is available.)-keepPackageImports :: [InteractiveImport] -> GHCi [InteractiveImport]-keepPackageImports = filterM is_pkg_import-  where-     is_pkg_import :: InteractiveImport -> GHCi Bool-     is_pkg_import (IIModule _) = return False-     is_pkg_import (IIDecl d)-         = do e <- gtry $ GHC.findModule mod_name (fmap sl_fs $ ideclPkgQual d)-              case e :: Either SomeException Module of-                Left _  -> return False-                Right m -> return (not (isHomeModule m))-        where-          mod_name = unLoc (ideclName d)---modulesLoadedMsg :: SuccessFlag -> [GHC.ModSummary] -> InputT GHCi ()-modulesLoadedMsg ok mods = do-  dflags <- getDynFlags-  unqual <- GHC.getPrintUnqual-  let mod_name mod = do-        is_interpreted <- GHC.moduleIsBootOrNotObjectLinkable mod-        return $ if is_interpreted-                  then ppr (GHC.ms_mod mod)-                  else ppr (GHC.ms_mod mod)-                       <> text " ("-                       <> text (normalise $ msObjFilePath mod)-                       <> text ")" -- fix #9887-  mod_names <- mapM mod_name mods-  let mod_commas-        | null mods = text "none."-        | otherwise = hsep (punctuate comma mod_names) <> text "."-      status = case ok of-                   Failed    -> text "Failed"-                   Succeeded -> text "Ok"--      msg = status <> text ", modules loaded:" <+> mod_commas--  when (verbosity dflags > 0) $-     liftIO $ putStrLn $ showSDocForUser dflags unqual msg----- | Run an 'ExceptT' wrapped 'GhcMonad' while handling source errors--- and printing 'throwE' strings to 'stderr'-runExceptGhcMonad :: GHC.GhcMonad m => ExceptT SDoc m () -> m ()-runExceptGhcMonad act = handleSourceError GHC.printException $-                        either handleErr pure =<<-                        runExceptT act-  where-    handleErr sdoc = do-        dflags <- getDynFlags-        liftIO . hPutStrLn stderr . showSDocForUser dflags alwaysQualify $ sdoc---- | Inverse of 'runExceptT' for \"pure\" computations--- (c.f. 'except' for 'Except')-exceptT :: Applicative m => Either e a -> ExceptT e m a-exceptT = ExceptT . pure--makeHDL' :: Clash.Backend.Backend backend-         => (Int -> HdlSyn -> Bool -> Maybe (Maybe Int) -> backend)-         -> IORef ClashOpts-         -> [FilePath]-         -> InputT GHCi ()-makeHDL' backend opts lst = go =<< case lst of-  srcs@(_:_) -> return srcs-  []         -> do-    modGraph <- GHC.getModuleGraph-    let sortedGraph = GHC.topSortModuleGraph False modGraph Nothing-    return $ case (reverse sortedGraph) of-      ((AcyclicSCC top) : _) -> maybeToList $ (GHC.ml_hs_file . GHC.ms_location) top-      _                      -> []- where-  go srcs = do-    dflags <- GHC.getSessionDynFlags-    goX dflags srcs `gfinally` recover dflags--  goX dflags srcs = do-    (dflagsX,_,_) <- parseDynamicFlagsCmdLine dflags-                       [ noLoc "-fobject-code"   -- For #439-                       , noLoc "-fforce-recomp"  -- Actually compile to object-code-                       , noLoc "-keep-tmp-files" -- To prevent linker errors from-                                                 -- multiple calls to :hdl command-                       ]-    _ <- GHC.setSessionDynFlags dflagsX-    reloadModule ""-    makeHDL backend opts srcs--  recover dflags = do-    _ <- GHC.setSessionDynFlags dflags-    reloadModule ""--makeHDL :: GHC.GhcMonad m-        => Clash.Backend.Backend backend-        => (Int -> HdlSyn -> Bool -> Maybe (Maybe Int) -> backend)-        -> IORef ClashOpts-        -> [FilePath]-        -> m ()-makeHDL backend optsRef srcs = do-  dflags <- GHC.getSessionDynFlags-  liftIO $ do startTime <- Clock.getCurrentTime-              opts0  <- readIORef optsRef-              let opts1  = opts0 { opt_color = useColor dflags }-              let iw     = opt_intWidth opts1-                  fp     = opt_floatSupport opts1-                  syn    = opt_hdlSyn opts1-                  color  = opt_color opts1-                  esc    = opt_escapedIds opts1-                  frcUdf = opt_forceUndefined opts1-                  hdl    = Clash.Backend.hdlKind backend'-                  -- determine whether `-outputdir` was used-                  outputDir = do odir <- objectDir dflags-                                 hidir <- hiDir dflags-                                 sdir <- stubDir dflags-                                 ddir <- dumpDir dflags-                                 if all (== odir) [hidir,sdir,ddir]-                                    then Just odir-                                    else Nothing-                  idirs = importPaths dflags-                  opts2 = opts1 { opt_hdlDir = maybe outputDir Just (opt_hdlDir opts1)-                                , opt_importPaths = idirs}-                  backend' = backend iw syn esc frcUdf--              checkMonoLocalBinds dflags-              checkImportDirs opts0 idirs--              primDirs <- Clash.Backend.primDirs backend'--              forM_ srcs $ \src -> do-                -- Generate bindings:-                let dbs = reverse [p | PackageDB (PkgConfFile p) <- packageDBFlags dflags]-                (bindingsMap,tcm,tupTcm,topEntities,primMap,reprs) <--                  generateBindings color primDirs idirs dbs hdl src (Just dflags)-                prepTime <- startTime `deepseq` bindingsMap `deepseq` tcm `deepseq` Clock.getCurrentTime-                let prepStartDiff = reportTimeDiff prepTime startTime-                putStrLn $ "GHC+Clash: Loading modules cumulatively took " ++ prepStartDiff--                -- Generate HDL:-                Clash.Driver.generateHDL-                  (buildCustomReprs reprs)-                  bindingsMap-                  (Just backend')-                  primMap-                  tcm-                  tupTcm-                  (ghcTypeToHWType iw fp)-                  reduceConstant-                  topEntities-                  opts2-                  (startTime,prepTime)--makeVHDL :: IORef ClashOpts -> [FilePath] -> InputT GHCi ()-makeVHDL = makeHDL' (Clash.Backend.initBackend :: Int -> HdlSyn -> Bool -> Maybe (Maybe Int) -> VHDLState)--makeVerilog :: IORef ClashOpts -> [FilePath] -> InputT GHCi ()-makeVerilog = makeHDL' (Clash.Backend.initBackend :: Int -> HdlSyn -> Bool -> Maybe (Maybe Int) -> VerilogState)--makeSystemVerilog :: IORef ClashOpts -> [FilePath] -> InputT GHCi ()-makeSystemVerilog = makeHDL' (Clash.Backend.initBackend :: Int -> HdlSyn -> Bool -> Maybe (Maybe Int) -> SystemVerilogState)---------------------------------------------------------------------------------- | @:type@ command. See also Note [TcRnExprMode] in TcRnDriver.--typeOfExpr :: String -> InputT GHCi ()-typeOfExpr str = handleSourceError GHC.printException $ do-    let (mode, expr_str) = case break isSpace str of-          ("+d", rest) -> (GHC.TM_Default, dropWhile isSpace rest)-          ("+v", rest) -> (GHC.TM_NoInst,  dropWhile isSpace rest)-          _            -> (GHC.TM_Inst,    str)-    ty <- GHC.exprType mode expr_str-    printForUser $ sep [text expr_str, nest 2 (dcolon <+> pprTypeForUser ty)]---------------------------------------------------------------------------------- | @:type-at@ command--typeAtCmd :: String -> InputT GHCi ()-typeAtCmd str = runExceptGhcMonad $ do-    (span',sample) <- exceptT $ parseSpanArg str-    infos      <- mod_infos <$> getGHCiState-    (info, ty) <- findType infos span' sample-    lift $ printForUserModInfo (modinfoInfo info)-                               (sep [text sample,nest 2 (dcolon <+> ppr ty)])---------------------------------------------------------------------------------- | @:uses@ command--usesCmd :: String -> InputT GHCi ()-usesCmd str = runExceptGhcMonad $ do-    (span',sample) <- exceptT $ parseSpanArg str-    infos  <- mod_infos <$> getGHCiState-    uses   <- findNameUses infos span' sample-    forM_ uses (liftIO . putStrLn . showSrcSpan)---------------------------------------------------------------------------------- | @:loc-at@ command--locAtCmd :: String -> InputT GHCi ()-locAtCmd str = runExceptGhcMonad $ do-    (span',sample) <- exceptT $ parseSpanArg str-    infos    <- mod_infos <$> getGHCiState-    (_,_,sp) <- findLoc infos span' sample-    liftIO . putStrLn . showSrcSpan $ sp---------------------------------------------------------------------------------- | @:all-types@ command--allTypesCmd :: String -> InputT GHCi ()-allTypesCmd _ = runExceptGhcMonad $ do-    infos <- mod_infos <$> getGHCiState-    forM_ (M.elems infos) $ \mi ->-        forM_ (modinfoSpans mi) (lift . printSpan)-  where-    printSpan span'-      | Just ty <- spaninfoType span' = do-        df <- getDynFlags-        let tyInfo = unwords . words $-                     showSDocForUser df alwaysQualify (pprTypeForUser ty)-        liftIO . putStrLn $-            showRealSrcSpan (spaninfoSrcSpan span') ++ ": " ++ tyInfo-      | otherwise = return ()---------------------------------------------------------------------------------- Helpers for locAtCmd/typeAtCmd/usesCmd---- | Parse a span: <module-name/filepath> <sl> <sc> <el> <ec> <string>-parseSpanArg :: String -> Either SDoc (RealSrcSpan,String)-parseSpanArg s = do-    (fp,s0) <- readAsString (skipWs s)-    s0'     <- skipWs1 s0-    (sl,s1) <- readAsInt s0'-    s1'     <- skipWs1 s1-    (sc,s2) <- readAsInt s1'-    s2'     <- skipWs1 s2-    (el,s3) <- readAsInt s2'-    s3'     <- skipWs1 s3-    (ec,s4) <- readAsInt s3'--    trailer <- case s4 of-        [] -> Right ""-        _  -> skipWs1 s4--    let fs    = mkFastString fp-        span' = mkRealSrcSpan (mkRealSrcLoc fs sl sc)-                              (mkRealSrcLoc fs el ec)--    return (span',trailer)-  where-    readAsInt :: String -> Either SDoc (Int,String)-    readAsInt "" = Left "Premature end of string while expecting Int"-    readAsInt s0 = case reads s0 of-        [s_rest] -> Right s_rest-        _        -> Left ("Couldn't read" <+> text (show s0) <+> "as Int")--    readAsString :: String -> Either SDoc (String,String)-    readAsString s0-      | '"':_ <- s0 = case reads s0 of-          [s_rest] -> Right s_rest-          _        -> leftRes-      | s_rest@(_:_,_) <- breakWs s0 = Right s_rest-      | otherwise = leftRes-      where-        leftRes = Left ("Couldn't read" <+> text (show s0) <+> "as String")--    skipWs1 :: String -> Either SDoc String-    skipWs1 (c:cs) | isWs c = Right (skipWs cs)-    skipWs1 s0 = Left ("Expected whitespace in" <+> text (show s0))--    isWs    = (`elem` [' ','\t'])-    skipWs  = dropWhile isWs-    breakWs = break isWs----- | Pretty-print \"real\" 'SrcSpan's as--- @<filename>:(<line>,<col>)-(<line-end>,<col-end>)@--- while simply unpacking 'UnhelpfulSpan's-showSrcSpan :: SrcSpan -> String-showSrcSpan (UnhelpfulSpan s)  = unpackFS s-showSrcSpan (RealSrcSpan spn)  = showRealSrcSpan spn---- | Variant of 'showSrcSpan' for 'RealSrcSpan's-showRealSrcSpan :: RealSrcSpan -> String-showRealSrcSpan spn = concat [ fp, ":(", show sl, ",", show sc-                             , ")-(", show el, ",", show ec, ")"-                             ]-  where-    fp = unpackFS (srcSpanFile spn)-    sl = srcSpanStartLine spn-    sc = srcSpanStartCol  spn-    el = srcSpanEndLine   spn-    ec = srcSpanEndCol    spn---------------------------------------------------------------------------------- | @:kind@ command--kindOfType :: Bool -> String -> InputT GHCi ()-kindOfType norm str = handleSourceError GHC.printException $ do-    (ty, kind) <- GHC.typeKind norm str-    printForUser $ vcat [ text str <+> dcolon <+> pprTypeForUser kind-                        , ppWhen norm $ equals <+> pprTypeForUser ty ]---------------------------------------------------------------------------------- :quit--quit :: String -> InputT GHCi Bool-quit _ = return True----------------------------------------------------------------------------------- :script---- running a script file #1363--scriptCmd :: String -> InputT GHCi ()-scriptCmd ws = do-  case words ws of-    [s]    -> runScript s-    _      -> throwGhcException (CmdLineError "syntax:  :script <filename>")--runScript :: String    -- ^ filename-           -> InputT GHCi ()-runScript filename = do-  filename' <- expandPath filename-  either_script <- liftIO $ tryIO (openFile filename' ReadMode)-  case either_script of-    Left _err    -> throwGhcException (CmdLineError $ "IO error:  \""++filename++"\" "-                      ++(ioeGetErrorString _err))-    Right script -> do-      st <- getGHCiState-      let prog = progname st-          line = line_number st-      setGHCiState st{progname=filename',line_number=0}-      scriptLoop script-      liftIO $ hClose script-      new_st <- getGHCiState-      setGHCiState new_st{progname=prog,line_number=line}-  where scriptLoop script = do-          res <- runOneCommand handler $ fileLoop script-          case res of-            Nothing -> return ()-            Just s  -> if s-              then scriptLoop script-              else return ()---------------------------------------------------------------------------------- :issafe---- Displaying Safe Haskell properties of a module--isSafeCmd :: String -> InputT GHCi ()-isSafeCmd m =-    case words m of-        [s] | looksLikeModuleName s -> do-            md <- lift $ lookupModule s-            isSafeModule md-        [] -> do md <- guessCurrentModule "issafe"-                 isSafeModule md-        _ -> throwGhcException (CmdLineError "syntax:  :issafe <module>")--isSafeModule :: Module -> InputT GHCi ()-isSafeModule m = do-    mb_mod_info <- GHC.getModuleInfo m-    when (isNothing mb_mod_info)-         (throwGhcException $ CmdLineError $ "unknown module: " ++ mname)--    dflags <- getDynFlags-    let iface = GHC.modInfoIface $ fromJust mb_mod_info-    when (isNothing iface)-         (throwGhcException $ CmdLineError $ "can't load interface file for module: " ++-                                    (GHC.moduleNameString $ GHC.moduleName m))--    (msafe, pkgs) <- GHC.moduleTrustReqs m-    let trust  = showPpr dflags $ getSafeMode $ GHC.mi_trust $ fromJust iface-        pkg    = if packageTrusted dflags m then "trusted" else "untrusted"-        (good, bad) = tallyPkgs dflags pkgs--    -- print info to user...-    liftIO $ putStrLn $ "Trust type is (Module: " ++ trust ++ ", Package: " ++ pkg ++ ")"-    liftIO $ putStrLn $ "Package Trust: " ++ (if packageTrustOn dflags then "On" else "Off")-    when (not $ S.null good)-         (liftIO $ putStrLn $ "Trusted package dependencies (trusted): " ++-                        (intercalate ", " $ map (showPpr dflags) (S.toList good)))-    case msafe && S.null bad of-        True -> liftIO $ putStrLn $ mname ++ " is trusted!"-        False -> do-            when (not $ null bad)-                 (liftIO $ putStrLn $ "Trusted package dependencies (untrusted): "-                            ++ (intercalate ", " $ map (showPpr dflags) (S.toList bad)))-            liftIO $ putStrLn $ mname ++ " is NOT trusted!"--  where-    mname = GHC.moduleNameString $ GHC.moduleName m--    packageTrusted dflags md-        | thisPackage dflags == moduleUnitId md = True-        | otherwise = trusted $ getPackageDetails dflags (moduleUnitId md)--    tallyPkgs dflags deps | not (packageTrustOn dflags) = (S.empty, S.empty)-                          | otherwise = S.partition part deps-        where part pkg = trusted $ getInstalledPackageDetails dflags pkg---------------------------------------------------------------------------------- :browse---- Browsing a module's contents--browseCmd :: Bool -> String -> InputT GHCi ()-browseCmd bang m =-  case words m of-    ['*':s] | looksLikeModuleName s -> do-        md <- lift $ wantInterpretedModule s-        browseModule bang md False-    [s] | looksLikeModuleName s -> do-        md <- lift $ lookupModule s-        browseModule bang md True-    [] -> do md <- guessCurrentModule ("browse" ++ if bang then "!" else "")-             browseModule bang md True-    _ -> throwGhcException (CmdLineError "syntax:  :browse <module>")--guessCurrentModule :: String -> InputT GHCi Module--- Guess which module the user wants to browse.  Pick--- modules that are interpreted first.  The most--- recently-added module occurs last, it seems.-guessCurrentModule cmd-  = do imports <- GHC.getContext-       when (null imports) $ throwGhcException $-          CmdLineError (':' : cmd ++ ": no current module")-       case (head imports) of-          IIModule m -> GHC.findModule m Nothing-          IIDecl d   -> GHC.findModule (unLoc (ideclName d))-                                       (fmap sl_fs $ ideclPkgQual d)---- without bang, show items in context of their parents and omit children--- with bang, show class methods and data constructors separately, and---            indicate import modules, to aid qualifying unqualified names--- with sorted, sort items alphabetically-browseModule :: Bool -> Module -> Bool -> InputT GHCi ()-browseModule bang modl exports_only = do-  -- :browse reports qualifiers wrt current context-  unqual <- GHC.getPrintUnqual--  mb_mod_info <- GHC.getModuleInfo modl-  case mb_mod_info of-    Nothing -> throwGhcException (CmdLineError ("unknown module: " ++-                                GHC.moduleNameString (GHC.moduleName modl)))-    Just mod_info -> do-        dflags <- getDynFlags-        let names-               | exports_only = GHC.modInfoExports mod_info-               | otherwise    = GHC.modInfoTopLevelScope mod_info-                                `orElse` []--                -- sort alphabetically name, but putting locally-defined-                -- identifiers first. We would like to improve this; see #1799.-            sorted_names = loc_sort local ++ occ_sort external-                where-                (local,external) = ASSERT( all isExternalName names )-                                   partition ((==modl) . nameModule) names-                occ_sort = sortBy (compare `on` nameOccName)-                -- try to sort by src location. If the first name in our list-                -- has a good source location, then they all should.-                loc_sort ns-                      | n:_ <- ns, isGoodSrcSpan (nameSrcSpan n)-                      = sortBy (compare `on` nameSrcSpan) ns-                      | otherwise-                      = occ_sort ns--        mb_things <- mapM GHC.lookupName sorted_names-        let filtered_things = filterOutChildren (\t -> t) (catMaybes mb_things)--        rdr_env <- GHC.getGRE--        let things | bang      = catMaybes mb_things-                   | otherwise = filtered_things-            pretty | bang      = pprTyThing showToHeader-                   | otherwise = pprTyThingInContext showToHeader--            labels  [] = text "-- not currently imported"-            labels  l  = text $ intercalate "\n" $ map qualifier l--            qualifier :: Maybe [ModuleName] -> String-            qualifier  = maybe "-- defined locally"-                             (("-- imported via "++) . intercalate ", "-                               . map GHC.moduleNameString)-            importInfo = RdrName.getGRE_NameQualifier_maybes rdr_env--            modNames :: [[Maybe [ModuleName]]]-            modNames   = map (importInfo . GHC.getName) things--            -- annotate groups of imports with their import modules-            -- the default ordering is somewhat arbitrary, so we group-            -- by header and sort groups; the names themselves should-            -- really come in order of source appearance.. (trac #1799)-            annotate mts = concatMap (\(m,ts)->labels m:ts)-                         $ sortBy cmpQualifiers $ grp mts-              where cmpQualifiers =-                      compare `on` (map (fmap (map moduleNameFS)) . fst)-            grp []            = []-            grp mts@((m,_):_) = (m,map snd g) : grp ng-              where (g,ng) = partition ((==m).fst) mts--        let prettyThings, prettyThings' :: [SDoc]-            prettyThings = map pretty things-            prettyThings' | bang      = annotate $ zip modNames prettyThings-                          | otherwise = prettyThings-        liftIO $ putStrLn $ showSDocForUser dflags unqual (vcat prettyThings')-        -- ToDo: modInfoInstances currently throws an exception for-        -- package modules.  When it works, we can do this:-        --        $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))----------------------------------------------------------------------------------- :module---- Setting the module context.  For details on context handling see--- "remembered_ctx" and "transient_ctx" in GhciMonad.--moduleCmd :: String -> GHCi ()-moduleCmd str-  | all sensible strs = cmd-  | otherwise = throwGhcException (CmdLineError "syntax:  :module [+/-] [*]M1 ... [*]Mn")-  where-    (cmd, strs) =-        case str of-          '+':stuff -> rest addModulesToContext   stuff-          '-':stuff -> rest remModulesFromContext stuff-          stuff     -> rest setContext            stuff--    rest op stuff = (op as bs, stuffs)-       where (as,bs) = partitionWith starred stuffs-             stuffs  = words stuff--    sensible ('*':m) = looksLikeModuleName m-    sensible m       = looksLikeModuleName m--    starred ('*':m) = Left  (GHC.mkModuleName m)-    starred m       = Right (GHC.mkModuleName m)----- -------------------------------------------------------------------------------- Four ways to manipulate the context:---   (a) :module +<stuff>:     addModulesToContext---   (b) :module -<stuff>:     remModulesFromContext---   (c) :module <stuff>:      setContext---   (d) import <module>...:   addImportToContext--addModulesToContext :: [ModuleName] -> [ModuleName] -> GHCi ()-addModulesToContext starred unstarred = restoreContextOnFailure $ do-   addModulesToContext_ starred unstarred--addModulesToContext_ :: [ModuleName] -> [ModuleName] -> GHCi ()-addModulesToContext_ starred unstarred = do-   mapM_ addII (map mkIIModule starred ++ map mkIIDecl unstarred)-   setGHCContextFromGHCiState--remModulesFromContext :: [ModuleName] -> [ModuleName] -> GHCi ()-remModulesFromContext  starred unstarred = do-   -- we do *not* call restoreContextOnFailure here.  If the user-   -- is trying to fix up a context that contains errors by removing-   -- modules, we don't want GHC to silently put them back in again.-   mapM_ rm (starred ++ unstarred)-   setGHCContextFromGHCiState- where-   rm :: ModuleName -> GHCi ()-   rm str = do-     m <- moduleName <$> lookupModuleName str-     let filt = filter ((/=) m . iiModuleName)-     modifyGHCiState $ \st ->-        st { remembered_ctx = filt (remembered_ctx st)-           , transient_ctx  = filt (transient_ctx st) }--setContext :: [ModuleName] -> [ModuleName] -> GHCi ()-setContext starred unstarred = restoreContextOnFailure $ do-  modifyGHCiState $ \st -> st { remembered_ctx = [], transient_ctx = [] }-                                -- delete the transient context-  addModulesToContext_ starred unstarred--addImportToContext :: String -> GHCi ()-addImportToContext str = restoreContextOnFailure $ do-  idecl <- GHC.parseImportDecl str-  addII (IIDecl idecl)   -- #5836-  setGHCContextFromGHCiState---- Util used by addImportToContext and addModulesToContext-addII :: InteractiveImport -> GHCi ()-addII iidecl = do-  checkAdd iidecl-  modifyGHCiState $ \st ->-     st { remembered_ctx = addNotSubsumed iidecl (remembered_ctx st)-        , transient_ctx = filter (not . (iidecl `iiSubsumes`))-                                 (transient_ctx st)-        }---- Sometimes we can't tell whether an import is valid or not until--- we finally call 'GHC.setContext'.  e.g.------   import System.IO (foo)------ will fail because System.IO does not export foo.  In this case we--- don't want to store the import in the context permanently, so we--- catch the failure from 'setGHCContextFromGHCiState' and set the--- context back to what it was.------ See #6007----restoreContextOnFailure :: GHCi a -> GHCi a-restoreContextOnFailure do_this = do-  st <- getGHCiState-  let rc = remembered_ctx st; tc = transient_ctx st-  do_this `gonException` (modifyGHCiState $ \st' ->-     st' { remembered_ctx = rc, transient_ctx = tc })---- -------------------------------------------------------------------------------- Validate a module that we want to add to the context--checkAdd :: InteractiveImport -> GHCi ()-checkAdd ii = do-  dflags <- getDynFlags-  let safe = safeLanguageOn dflags-  case ii of-    IIModule modname-       | safe -> throwGhcException $ CmdLineError "can't use * imports with Safe Haskell"-       | otherwise -> wantInterpretedModuleName modname >> return ()--    IIDecl d -> do-       let modname = unLoc (ideclName d)-           pkgqual = ideclPkgQual d-       m <- GHC.lookupModule modname (fmap sl_fs pkgqual)-       when safe $ do-           t <- GHC.isModuleTrusted m-           when (not t) $ throwGhcException $ ProgramError $ ""---- -------------------------------------------------------------------------------- Update the GHC API's view of the context---- | Sets the GHC context from the GHCi state.  The GHC context is--- always set this way, we never modify it incrementally.------ We ignore any imports for which the ModuleName does not currently--- exist.  This is so that the remembered_ctx can contain imports for--- modules that are not currently loaded, perhaps because we just did--- a :reload and encountered errors.------ Prelude is added if not already present in the list.  Therefore to--- override the implicit Prelude import you can say 'import Prelude ()'--- at the prompt, just as in Haskell source.----setGHCContextFromGHCiState :: GHCi ()-setGHCContextFromGHCiState = do-  st <- getGHCiState-      -- re-use checkAdd to check whether the module is valid.  If the-      -- module does not exist, we do *not* want to print an error-      -- here, we just want to silently keep the module in the context-      -- until such time as the module reappears again.  So we ignore-      -- the actual exception thrown by checkAdd, using tryBool to-      -- turn it into a Bool.-  iidecls <- filterM (tryBool.checkAdd) (transient_ctx st ++ remembered_ctx st)--  prel_iidecls <- getImplicitPreludeImports iidecls-  valid_prel_iidecls <- filterM (tryBool . checkAdd) prel_iidecls--  extra_imports <- filterM (tryBool . checkAdd) (map IIDecl (extra_imports st))--  GHC.setContext $ iidecls ++ extra_imports ++ valid_prel_iidecls---getImplicitPreludeImports :: [InteractiveImport] -> GHCi [InteractiveImport]-getImplicitPreludeImports iidecls = do-     -- allow :seti to override -XNoImplicitPrelude-  st <- getGHCiState--  -- We add the prelude imports if there are no *-imports, and we also-  -- allow each prelude import to be subsumed by another explicit import-  -- of the same module.  This means that you can override the prelude import-  -- with "import Prelude hiding (map)", for example.-  let prel_iidecls =-         if not (any isIIModule iidecls)-            then [ IIDecl imp-                 | imp <- prelude_imports st-                 , not (any (sameImpModule imp) iidecls) ]-            else []--  return prel_iidecls---- -------------------------------------------------------------------------------- Utils on InteractiveImport--mkIIModule :: ModuleName -> InteractiveImport-mkIIModule = IIModule--mkIIDecl :: ModuleName -> InteractiveImport-mkIIDecl = IIDecl . simpleImportDecl--iiModules :: [InteractiveImport] -> [ModuleName]-iiModules is = [m | IIModule m <- is]--isIIModule :: InteractiveImport -> Bool-isIIModule (IIModule _) = True-isIIModule _ = False--iiModuleName :: InteractiveImport -> ModuleName-iiModuleName (IIModule m) = m-iiModuleName (IIDecl d)   = unLoc (ideclName d)--preludeModuleName :: ModuleName-preludeModuleName = GHC.mkModuleName "Clash.Prelude"--sameImpModule :: ImportDecl RdrName -> InteractiveImport -> Bool-sameImpModule _ (IIModule _) = False -- we only care about imports here-sameImpModule imp (IIDecl d) = unLoc (ideclName d) == unLoc (ideclName imp)--addNotSubsumed :: InteractiveImport-               -> [InteractiveImport] -> [InteractiveImport]-addNotSubsumed i is-  | any (`iiSubsumes` i) is = is-  | otherwise               = i : filter (not . (i `iiSubsumes`)) is---- | @filterSubsumed is js@ returns the elements of @js@ not subsumed--- by any of @is@.-filterSubsumed :: [InteractiveImport] -> [InteractiveImport]-               -> [InteractiveImport]-filterSubsumed is js = filter (\j -> not (any (`iiSubsumes` j) is)) js---- | Returns True if the left import subsumes the right one.  Doesn't--- need to be 100% accurate, conservatively returning False is fine.--- (EXCEPT: (IIModule m) *must* subsume itself, otherwise a panic in--- plusProv will ensue (#5904))------ Note that an IIModule does not necessarily subsume an IIDecl,--- because e.g. a module might export a name that is only available--- qualified within the module itself.------ Note that 'import M' does not necessarily subsume 'import M(foo)',--- because M might not export foo and we want an error to be produced--- in that case.----iiSubsumes :: InteractiveImport -> InteractiveImport -> Bool-iiSubsumes (IIModule m1) (IIModule m2) = m1==m2-iiSubsumes (IIDecl d1) (IIDecl d2)      -- A bit crude-  =  unLoc (ideclName d1) == unLoc (ideclName d2)-     && ideclAs d1 == ideclAs d2-     && (not (ideclQualified d1) || ideclQualified d2)-     && (ideclHiding d1 `hidingSubsumes` ideclHiding d2)-  where-     _                    `hidingSubsumes` Just (False,L _ []) = True-     Just (False, L _ xs) `hidingSubsumes` Just (False,L _ ys)-                                                           = all (`elem` xs) ys-     h1                   `hidingSubsumes` h2              = h1 == h2-iiSubsumes _ _ = False---------------------------------------------------------------------------------- :set---- set options in the interpreter.  Syntax is exactly the same as the--- ghc command line, except that certain options aren't available (-C,--- -E etc.)------ This is pretty fragile: most options won't work as expected.  ToDo:--- figure out which ones & disallow them.--setCmd :: String -> GHCi ()-setCmd ""   = showOptions False-setCmd "-a" = showOptions True-setCmd str-  = case getCmd str of-    Right ("args",    rest) ->-        case toArgs rest of-            Left err -> liftIO (hPutStrLn stderr err)-            Right args -> setArgs args-    Right ("prog",    rest) ->-        case toArgs rest of-            Right [prog] -> setProg prog-            _ -> liftIO (hPutStrLn stderr "syntax: :set prog <progname>")--    Right ("prompt",           rest) ->-        setPromptString setPrompt (dropWhile isSpace rest)-                        "syntax: set prompt <string>"-    Right ("prompt-function",  rest) ->-        setPromptFunc setPrompt $ dropWhile isSpace rest-    Right ("prompt-cont",          rest) ->-        setPromptString setPromptCont (dropWhile isSpace rest)-                        "syntax: :set prompt-cont <string>"-    Right ("prompt-cont-function", rest) ->-        setPromptFunc setPromptCont $ dropWhile isSpace rest--    Right ("editor",  rest) -> setEditor  $ dropWhile isSpace rest-    Right ("stop",    rest) -> setStop    $ dropWhile isSpace rest-    _ -> case toArgs str of-         Left err -> liftIO (hPutStrLn stderr err)-         Right wds -> setOptions wds--setiCmd :: String -> GHCi ()-setiCmd ""   = GHC.getInteractiveDynFlags >>= liftIO . showDynFlags False-setiCmd "-a" = GHC.getInteractiveDynFlags >>= liftIO . showDynFlags True-setiCmd str  =-  case toArgs str of-    Left err -> liftIO (hPutStrLn stderr err)-    Right wds -> newDynFlags True wds--showOptions :: Bool -> GHCi ()-showOptions show_all-  = do st <- getGHCiState-       dflags <- getDynFlags-       let opts = options st-       liftIO $ putStrLn (showSDoc dflags (-              text "options currently set: " <>-              if null opts-                   then text "none."-                   else hsep (map (\o -> char '+' <> text (optToStr o)) opts)-           ))-       getDynFlags >>= liftIO . showDynFlags show_all---showDynFlags :: Bool -> DynFlags -> IO ()-showDynFlags show_all dflags = do-  showLanguages' show_all dflags-  putStrLn $ showSDoc dflags $-     text "GHCi-specific dynamic flag settings:" $$-         nest 2 (vcat (map (setting "-f" "-fno-" gopt) ghciFlags))-  putStrLn $ showSDoc dflags $-     text "other dynamic, non-language, flag settings:" $$-         nest 2 (vcat (map (setting "-f" "-fno-" gopt) others))-  putStrLn $ showSDoc dflags $-     text "warning settings:" $$-         nest 2 (vcat (map (setting "-W" "-Wno-" wopt) DynFlags.wWarningFlags))-  where-        setting prefix noPrefix test flag-          | quiet     = empty-          | is_on     = text prefix <> text name-          | otherwise = text noPrefix <> text name-          where name = flagSpecName flag-                f = flagSpecFlag flag-                is_on = test f dflags-                quiet = not show_all && test f default_dflags == is_on--        default_dflags = defaultDynFlags (settings dflags)--        (ghciFlags,others)  = partition (\f -> flagSpecFlag f `elem` flgs)-                                        DynFlags.fFlags-        flgs = [ Opt_PrintExplicitForalls-               , Opt_PrintExplicitKinds-               , Opt_PrintUnicodeSyntax-               , Opt_PrintBindResult-               , Opt_BreakOnException-               , Opt_BreakOnError-               , Opt_PrintEvldWithShow-               ]--setArgs, setOptions :: [String] -> GHCi ()-setProg, setEditor, setStop :: String -> GHCi ()--setArgs args = do-  st <- getGHCiState-  wrapper <- mkEvalWrapper (progname st) args-  setGHCiState st { GhciMonad.args = args, evalWrapper = wrapper }--setProg prog = do-  st <- getGHCiState-  wrapper <- mkEvalWrapper prog (GhciMonad.args st)-  setGHCiState st { progname = prog, evalWrapper = wrapper }--setEditor cmd = modifyGHCiState (\st -> st { editor = cmd })--setStop str@(c:_) | isDigit c-  = do let (nm_str,rest) = break (not.isDigit) str-           nm = read nm_str-       st <- getGHCiState-       let old_breaks = breaks st-       if all ((/= nm) . fst) old_breaks-              then printForUser (text "Breakpoint" <+> ppr nm <+>-                                 text "does not exist")-              else do-       let new_breaks = map fn old_breaks-           fn (i,loc) | i == nm   = (i,loc { onBreakCmd = dropWhile isSpace rest })-                      | otherwise = (i,loc)-       setGHCiState st{ breaks = new_breaks }-setStop cmd = modifyGHCiState (\st -> st { stop = cmd })--setPrompt :: PromptFunction -> GHCi ()-setPrompt v = modifyGHCiState (\st -> st {prompt = v})--setPromptCont :: PromptFunction -> GHCi ()-setPromptCont v = modifyGHCiState (\st -> st {prompt_cont = v})--setPromptFunc :: (PromptFunction -> GHCi ()) -> String -> GHCi ()-setPromptFunc fSetPrompt s = do-    -- We explicitly annotate the type of the expression to ensure-    -- that unsafeCoerce# is passed the exact type necessary rather-    -- than a more general one-    let exprStr = "(" ++ s ++ ") :: [String] -> Int -> IO String"-    (HValue funValue) <- GHC.compileExpr exprStr-    fSetPrompt (convertToPromptFunction $ unsafeCoerce funValue)-    where-      convertToPromptFunction :: ([String] -> Int -> IO String)-                              -> PromptFunction-      convertToPromptFunction func = (\mods line -> liftIO $-                                       liftM text (func mods line))--setPromptString :: (PromptFunction -> GHCi ()) -> String -> String -> GHCi ()-setPromptString fSetPrompt value err = do-  if null value-    then liftIO $ hPutStrLn stderr $ err-    else case value of-           ('\"':_) ->-             case reads value of-               [(value', xs)] | all isSpace xs ->-                 setParsedPromptString fSetPrompt value'-               _ -> liftIO $ hPutStrLn stderr-                             "Can't parse prompt string. Use Haskell syntax."-           _ ->-             setParsedPromptString fSetPrompt value--setParsedPromptString :: (PromptFunction -> GHCi ()) ->  String -> GHCi ()-setParsedPromptString fSetPrompt s = do-  case (checkPromptStringForErrors s) of-    Just err ->-      liftIO $ hPutStrLn stderr err-    Nothing ->-      fSetPrompt $ generatePromptFunctionFromString s--setOptions wds =-   do -- first, deal with the GHCi opts (+s, +t, etc.)-      let (plus_opts, minus_opts)  = partitionWith isPlus wds-      mapM_ setOpt plus_opts-      -- then, dynamic flags-      when (not (null minus_opts)) $ newDynFlags False minus_opts--newDynFlags :: Bool -> [String] -> GHCi ()-newDynFlags interactive_only minus_opts = do-      let lopts = map noLoc minus_opts--      idflags0 <- GHC.getInteractiveDynFlags-      (idflags1, leftovers, warns) <- GHC.parseDynamicFlags idflags0 lopts--      liftIO $ handleFlagWarnings idflags1 warns-      when (not $ null leftovers)-           (throwGhcException . CmdLineError-            $ "Some flags have not been recognized: "-            ++ (concat . intersperse ", " $ map unLoc leftovers))--      when (interactive_only && packageFlagsChanged idflags1 idflags0) $ do-          liftIO $ hPutStrLn stderr "cannot set package flags with :seti; use :set"-      GHC.setInteractiveDynFlags idflags1-      installInteractivePrint (interactivePrint idflags1) False--      dflags0 <- getDynFlags-      when (not interactive_only) $ do-        (dflags1, _, _) <- liftIO $ GHC.parseDynamicFlags dflags0 lopts-        new_pkgs <- GHC.setProgramDynFlags dflags1--        -- if the package flags changed, reset the context and link-        -- the new packages.-        hsc_env <- GHC.getSession-        let dflags2 = hsc_dflags hsc_env-        when (packageFlagsChanged dflags2 dflags0) $ do-          when (verbosity dflags2 > 0) $-            liftIO . putStrLn $-              "package flags have changed, resetting and loading new packages..."-          GHC.setTargets []-          _ <- GHC.load LoadAllTargets-          liftIO $ linkPackages hsc_env new_pkgs-          -- package flags changed, we can't re-use any of the old context-          setContextAfterLoad False []-          -- and copy the package state to the interactive DynFlags-          idflags <- GHC.getInteractiveDynFlags-          GHC.setInteractiveDynFlags-              idflags{ pkgState = pkgState dflags2-                     , pkgDatabase = pkgDatabase dflags2-                     , packageFlags = packageFlags dflags2 }--        let ld0length   = length $ ldInputs dflags0-            fmrk0length = length $ cmdlineFrameworks dflags0--            newLdInputs     = drop ld0length (ldInputs dflags2)-            newCLFrameworks = drop fmrk0length (cmdlineFrameworks dflags2)--            hsc_env' = hsc_env { hsc_dflags =-                         dflags2 { ldInputs = newLdInputs-                                 , cmdlineFrameworks = newCLFrameworks } }--        when (not (null newLdInputs && null newCLFrameworks)) $-          liftIO $ linkCmdLineLibs hsc_env'--      return ()---unsetOptions :: String -> GHCi ()-unsetOptions str-  =   -- first, deal with the GHCi opts (+s, +t, etc.)-     let opts = words str-         (minus_opts, rest1) = partition isMinus opts-         (plus_opts, rest2)  = partitionWith isPlus rest1-         (other_opts, rest3) = partition (`elem` map fst defaulters) rest2--         defaulters =-           [ ("args"   , setArgs default_args)-           , ("prog"   , setProg default_progname)-           , ("prompt"     , setPrompt default_prompt)-           , ("prompt-cont", setPromptCont default_prompt_cont)-           , ("editor" , liftIO findEditor >>= setEditor)-           , ("stop"   , setStop default_stop)-           ]--         no_flag ('-':'f':rest) = return ("-fno-" ++ rest)-         no_flag ('-':'X':rest) = return ("-XNo" ++ rest)-         no_flag f = throwGhcException (ProgramError ("don't know how to reverse " ++ f))--     in if (not (null rest3))-           then liftIO (putStrLn ("unknown option: '" ++ head rest3 ++ "'"))-           else do-             mapM_ (fromJust.flip lookup defaulters) other_opts--             mapM_ unsetOpt plus_opts--             no_flags <- mapM no_flag minus_opts-             when (not (null no_flags)) $ newDynFlags False no_flags--isMinus :: String -> Bool-isMinus ('-':_) = True-isMinus _ = False--isPlus :: String -> Either String String-isPlus ('+':opt) = Left opt-isPlus other     = Right other--setOpt, unsetOpt :: String -> GHCi ()--setOpt str-  = case strToGHCiOpt str of-        Nothing -> liftIO (putStrLn ("unknown option: '" ++ str ++ "'"))-        Just o  -> setOption o--unsetOpt str-  = case strToGHCiOpt str of-        Nothing -> liftIO (putStrLn ("unknown option: '" ++ str ++ "'"))-        Just o  -> unsetOption o--strToGHCiOpt :: String -> (Maybe GHCiOption)-strToGHCiOpt "m" = Just Multiline-strToGHCiOpt "s" = Just ShowTiming-strToGHCiOpt "t" = Just ShowType-strToGHCiOpt "r" = Just RevertCAFs-strToGHCiOpt "c" = Just CollectInfo-strToGHCiOpt _   = Nothing--optToStr :: GHCiOption -> String-optToStr Multiline  = "m"-optToStr ShowTiming = "s"-optToStr ShowType   = "t"-optToStr RevertCAFs = "r"-optToStr CollectInfo = "c"----- ------------------------------------------------------------------------------ :show--showCmd :: String -> GHCi ()-showCmd ""   = showOptions False-showCmd "-a" = showOptions True-showCmd str = do-    st <- getGHCiState-    dflags <- getDynFlags--    let lookupCmd :: String -> Maybe (GHCi ())-        lookupCmd name = lookup name $ map (\(_,b,c) -> (b,c)) cmds--        -- (show in help?, command name, action)-        action :: String -> GHCi () -> (Bool, String, GHCi ())-        action name m = (True, name, m)--        hidden :: String -> GHCi () -> (Bool, String, GHCi ())-        hidden name m = (False, name, m)--        cmds =-            [ action "args"       $ liftIO $ putStrLn (show (GhciMonad.args st))-            , action "prog"       $ liftIO $ putStrLn (show (progname st))-            , action "editor"     $ liftIO $ putStrLn (show (editor st))-            , action "stop"       $ liftIO $ putStrLn (show (stop st))-            , action "imports"    $ showImports-            , action "modules"    $ showModules-            , action "bindings"   $ showBindings-            , action "linker"     $ getDynFlags >>= liftIO . showLinkerState-            , action "breaks"     $ showBkptTable-            , action "context"    $ showContext-            , action "packages"   $ showPackages-            , action "paths"      $ showPaths-            , action "language"   $ showLanguages-            , hidden "languages"  $ showLanguages -- backwards compat-            , hidden "lang"       $ showLanguages -- useful abbreviation-            ]--    case words str of-      [w] | Just action <- lookupCmd w -> action--      _ -> let helpCmds = [ text name | (True, name, _) <- cmds ]-           in throwGhcException $ CmdLineError $ showSDoc dflags-              $ hang (text "syntax:") 4-              $ hang (text ":show") 6-              $ brackets (fsep $ punctuate (text " |") helpCmds)--showiCmd :: String -> GHCi ()-showiCmd str = do-  case words str of-        ["languages"]  -> showiLanguages -- backwards compat-        ["language"]   -> showiLanguages-        ["lang"]       -> showiLanguages -- useful abbreviation-        _ -> throwGhcException (CmdLineError ("syntax:  :showi language"))--showImports :: GHCi ()-showImports = do-  st <- getGHCiState-  dflags <- getDynFlags-  let rem_ctx   = reverse (remembered_ctx st)-      trans_ctx = transient_ctx st--      show_one (IIModule star_m)-          = ":module +*" ++ moduleNameString star_m-      show_one (IIDecl imp) = showPpr dflags imp--  prel_iidecls <- getImplicitPreludeImports (rem_ctx ++ trans_ctx)--  let show_prel p = show_one p ++ " -- implicit"-      show_extra p = show_one (IIDecl p) ++ " -- fixed"--      trans_comment s = s ++ " -- added automatically" :: String-  ---  liftIO $ mapM_ putStrLn (map show_one rem_ctx ++-                           map (trans_comment . show_one) trans_ctx ++-                           map show_prel prel_iidecls ++-                           map show_extra (extra_imports st))--showModules :: GHCi ()-showModules = do-  loaded_mods <- getLoadedModules-        -- we want *loaded* modules only, see #1734-  let show_one ms = do m <- GHC.showModule ms; liftIO (putStrLn m)-  mapM_ show_one loaded_mods--getLoadedModules :: GHC.GhcMonad m => m [GHC.ModSummary]-getLoadedModules = do-  graph <- GHC.getModuleGraph-  filterM (GHC.isLoaded . GHC.ms_mod_name) graph--showBindings :: GHCi ()-showBindings = do-    bindings <- GHC.getBindings-    (insts, finsts) <- GHC.getInsts-    docs     <- mapM makeDoc (reverse bindings)-                  -- reverse so the new ones come last-    let idocs  = map GHC.pprInstanceHdr insts-        fidocs = map GHC.pprFamInst finsts-    mapM_ printForUserPartWay (docs ++ idocs ++ fidocs)-  where-    makeDoc (AnId i) = pprTypeAndContents i-    makeDoc tt = do-        mb_stuff <- GHC.getInfo False (getName tt)-        return $ maybe (text "") pprTT mb_stuff--    pprTT :: (TyThing, Fixity, [GHC.ClsInst], [GHC.FamInst]) -> SDoc-    pprTT (thing, fixity, _cls_insts, _fam_insts)-      = pprTyThing showToHeader thing-        $$ show_fixity-      where-        show_fixity-            | fixity == GHC.defaultFixity  = empty-            | otherwise                    = ppr fixity <+> ppr (GHC.getName thing)---printTyThing :: TyThing -> GHCi ()-printTyThing tyth = printForUser (pprTyThing showToHeader tyth)--showBkptTable :: GHCi ()-showBkptTable = do-  st <- getGHCiState-  printForUser $ prettyLocations (breaks st)--showContext :: GHCi ()-showContext = do-   resumes <- GHC.getResumeContext-   printForUser $ vcat (map pp_resume (reverse resumes))-  where-   pp_resume res =-        ptext (sLit "--> ") <> text (GHC.resumeStmt res)-        $$ nest 2 (pprStopped res)--pprStopped :: GHC.Resume -> SDoc-pprStopped res =-  ptext (sLit "Stopped in")-    <+> ((case mb_mod_name of-           Nothing -> empty-           Just mod_name -> text (moduleNameString mod_name) <> char '.')-         <> text (GHC.resumeDecl res))-    <> char ',' <+> ppr (GHC.resumeSpan res)- where-  mb_mod_name = moduleName <$> GHC.breakInfo_module <$> GHC.resumeBreakInfo res--showPackages :: GHCi ()-showPackages = do-  dflags <- getDynFlags-  let pkg_flags = packageFlags dflags-  liftIO $ putStrLn $ showSDoc dflags $-    text ("active package flags:"++if null pkg_flags then " none" else "") $$-      nest 2 (vcat (map pprFlag pkg_flags))--showPaths :: GHCi ()-showPaths = do-  dflags <- getDynFlags-  liftIO $ do-    cwd <- getCurrentDirectory-    putStrLn $ showSDoc dflags $-      text "current working directory: " $$-        nest 2 (text cwd)-    let ipaths = importPaths dflags-    putStrLn $ showSDoc dflags $-      text ("module import search paths:"++if null ipaths then " none" else "") $$-        nest 2 (vcat (map text ipaths))--showLanguages :: GHCi ()-showLanguages = getDynFlags >>= liftIO . showLanguages' False--showiLanguages :: GHCi ()-showiLanguages = GHC.getInteractiveDynFlags >>= liftIO . showLanguages' False--showLanguages' :: Bool -> DynFlags -> IO ()-showLanguages' show_all dflags =-  putStrLn $ showSDoc dflags $ vcat-     [ text "base language is: " <>-         case language dflags of-           Nothing          -> text "Haskell2010"-           Just Haskell98   -> text "Haskell98"-           Just Haskell2010 -> text "Haskell2010"-     , (if show_all then text "all active language options:"-                    else text "with the following modifiers:") $$-          nest 2 (vcat (map (setting xopt) DynFlags.xFlags))-     ]-  where-   setting test flag-          | quiet     = empty-          | is_on     = text "-X" <> text name-          | otherwise = text "-XNo" <> text name-          where name = flagSpecName flag-                f = flagSpecFlag flag-                is_on = test f dflags-                quiet = not show_all && test f default_dflags == is_on--   default_dflags =-       defaultDynFlags (settings dflags) `lang_set`-         case language dflags of-           Nothing -> Just Haskell2010-           other   -> other---- -------------------------------------------------------------------------------- Completion--completeCmd :: String -> GHCi ()-completeCmd argLine0 = case parseLine argLine0 of-    Just ("repl", resultRange, left) -> do-        (unusedLine,compls) <- ghciCompleteWord (reverse left,"")-        let compls' = takeRange resultRange compls-        liftIO . putStrLn $ unwords [ show (length compls'), show (length compls), show (reverse unusedLine) ]-        forM_ (takeRange resultRange compls) $ \(Completion r _ _) -> do-            liftIO $ print r-    _ -> throwGhcException (CmdLineError "Syntax: :complete repl [<range>] <quoted-string-to-complete>")-  where-    parseLine argLine-        | null argLine = Nothing-        | null rest1   = Nothing-        | otherwise    = (,,) dom <$> resRange <*> s-      where-        (dom, rest1) = breakSpace argLine-        (rng, rest2) = breakSpace rest1-        resRange | head rest1 == '"' = parseRange ""-                 | otherwise         = parseRange rng-        s | head rest1 == '"' = readMaybe rest1 :: Maybe String-          | otherwise         = readMaybe rest2-        breakSpace = fmap (dropWhile isSpace) . break isSpace--    takeRange (lb,ub) = maybe id (drop . pred) lb . maybe id take ub--    -- syntax: [n-][m] with semantics "drop (n-1) . take m"-    parseRange :: String -> Maybe (Maybe Int,Maybe Int)-    parseRange s = case span isDigit s of-                   (_, "") ->-                       -- upper limit only-                       Just (Nothing, bndRead s)-                   (s1, '-' : s2)-                    | all isDigit s2 ->-                       Just (bndRead s1, bndRead s2)-                   _ ->-                       Nothing-      where-        bndRead x = if null x then Nothing else Just (read x)----completeGhciCommand, completeMacro, completeIdentifier, completeModule,-    completeSetModule, completeSeti, completeShowiOptions,-    completeHomeModule, completeSetOptions, completeShowOptions,-    completeHomeModuleOrFile, completeExpression-    :: CompletionFunc GHCi---- | Provide completions for last word in a given string.------ Takes a tuple of two strings.  First string is a reversed line to be--- completed.  Second string is likely unused, 'completeCmd' always passes an--- empty string as second item in tuple.-ghciCompleteWord :: CompletionFunc GHCi-ghciCompleteWord line@(left,_) = case firstWord of-    -- If given string starts with `:` colon, and there is only one following-    -- word then provide REPL command completions.  If there is more than one-    -- word complete either filename or builtin ghci commands or macros.-    ':':cmd     | null rest     -> completeGhciCommand line-                | otherwise     -> do-                        completion <- lookupCompletion cmd-                        completion line-    -- If given string starts with `import` keyword provide module name-    -- completions-    "import"    -> completeModule line-    -- otherwise provide identifier completions-    _           -> completeExpression line-  where-    (firstWord,rest) = break isSpace $ dropWhile isSpace $ reverse left-    lookupCompletion ('!':_) = return completeFilename-    lookupCompletion c = do-        maybe_cmd <- lookupCommand' c-        case maybe_cmd of-            Just cmd -> return (cmdCompletionFunc cmd)-            Nothing  -> return completeFilename--completeGhciCommand = wrapCompleter " " $ \w -> do-  macros <- ghci_macros <$> getGHCiState-  cmds   <- ghci_commands `fmap` getGHCiState-  let macro_names = map (':':) . map cmdName $ macros-  let command_names = map (':':) . map cmdName $ filter (not . cmdHidden) cmds-  let{ candidates = case w of-      ':' : ':' : _ -> map (':':) command_names-      _ -> nub $ macro_names ++ command_names }-  return $ filter (w `isPrefixOf`) candidates--completeMacro = wrapIdentCompleter $ \w -> do-  cmds <- ghci_macros <$> getGHCiState-  return (filter (w `isPrefixOf`) (map cmdName cmds))--completeIdentifier line@(left, _) =-  -- Note: `left` is a reversed input-  case left of-    (x:_) | isSymbolChar x -> wrapCompleter (specials ++ spaces) complete line-    _                      -> wrapIdentCompleter complete line-  where-    complete w = do-      rdrs <- GHC.getRdrNamesInScope-      dflags <- GHC.getSessionDynFlags-      return (filter (w `isPrefixOf`) (map (showPpr dflags) rdrs))--completeModule = wrapIdentCompleter $ \w -> do-  dflags <- GHC.getSessionDynFlags-  let pkg_mods = allVisibleModules dflags-  loaded_mods <- liftM (map GHC.ms_mod_name) getLoadedModules-  return $ filter (w `isPrefixOf`)-        $ map (showPpr dflags) $ loaded_mods ++ pkg_mods--completeSetModule = wrapIdentCompleterWithModifier "+-" $ \m w -> do-  dflags <- GHC.getSessionDynFlags-  modules <- case m of-    Just '-' -> do-      imports <- GHC.getContext-      return $ map iiModuleName imports-    _ -> do-      let pkg_mods = allVisibleModules dflags-      loaded_mods <- liftM (map GHC.ms_mod_name) getLoadedModules-      return $ loaded_mods ++ pkg_mods-  return $ filter (w `isPrefixOf`) $ map (showPpr dflags) modules--completeHomeModule = wrapIdentCompleter listHomeModules--listHomeModules :: String -> GHCi [String]-listHomeModules w = do-    g <- GHC.getModuleGraph-    let home_mods = map GHC.ms_mod_name g-    dflags <- getDynFlags-    return $ sort $ filter (w `isPrefixOf`)-            $ map (showPpr dflags) home_mods--completeSetOptions = wrapCompleter flagWordBreakChars $ \w -> do-  return (filter (w `isPrefixOf`) opts)-    where opts = "args":"prog":"prompt":"prompt-cont":"prompt-function":-                 "prompt-cont-function":"editor":"stop":flagList-          flagList = map head $ group $ sort allNonDeprecatedFlags--completeSeti = wrapCompleter flagWordBreakChars $ \w -> do-  return (filter (w `isPrefixOf`) flagList)-    where flagList = map head $ group $ sort allNonDeprecatedFlags--completeShowOptions = wrapCompleter flagWordBreakChars $ \w -> do-  return (filter (w `isPrefixOf`) opts)-    where opts = ["args", "prog", "editor", "stop",-                     "modules", "bindings", "linker", "breaks",-                     "context", "packages", "paths", "language", "imports"]--completeShowiOptions = wrapCompleter flagWordBreakChars $ \w -> do-  return (filter (w `isPrefixOf`) ["language"])--completeHomeModuleOrFile = completeWord Nothing filenameWordBreakChars-                $ unionComplete (fmap (map simpleCompletion) . listHomeModules)-                            listFiles--unionComplete :: Monad m => (a -> m [b]) -> (a -> m [b]) -> a -> m [b]-unionComplete f1 f2 line = do-  cs1 <- f1 line-  cs2 <- f2 line-  return (cs1 ++ cs2)--wrapCompleter :: String -> (String -> GHCi [String]) -> CompletionFunc GHCi-wrapCompleter breakChars fun = completeWord Nothing breakChars-    $ fmap (map simpleCompletion . nubSort) . fun--wrapIdentCompleter :: (String -> GHCi [String]) -> CompletionFunc GHCi-wrapIdentCompleter = wrapCompleter word_break_chars--wrapIdentCompleterWithModifier :: String -> (Maybe Char -> String -> GHCi [String]) -> CompletionFunc GHCi-wrapIdentCompleterWithModifier modifChars fun = completeWordWithPrev Nothing word_break_chars-    $ \rest -> fmap (map simpleCompletion . nubSort) . fun (getModifier rest)- where-  getModifier = find (`elem` modifChars)---- | Return a list of visible module names for autocompletion.--- (NB: exposed != visible)-allVisibleModules :: DynFlags -> [ModuleName]-allVisibleModules dflags = listVisibleModuleNames dflags--completeExpression = completeQuotedWord (Just '\\') "\"" listFiles-                        completeIdentifier----- -------------------------------------------------------------------------------- commands for debugger--sprintCmd, printCmd, forceCmd :: String -> GHCi ()-sprintCmd = pprintCommand False False-printCmd  = pprintCommand True False-forceCmd  = pprintCommand False True--pprintCommand :: Bool -> Bool -> String -> GHCi ()-pprintCommand bind force str = do-  pprintClosureCommand bind force str--stepCmd :: String -> GHCi ()-stepCmd arg = withSandboxOnly ":step" $ step arg-  where-  step []         = doContinue (const True) GHC.SingleStep-  step expression = runStmt expression GHC.SingleStep >> return ()--stepLocalCmd :: String -> GHCi ()-stepLocalCmd arg = withSandboxOnly ":steplocal" $ step arg-  where-  step expr-   | not (null expr) = stepCmd expr-   | otherwise = do-      mb_span <- getCurrentBreakSpan-      case mb_span of-        Nothing  -> stepCmd []-        Just loc -> do-           Just md <- getCurrentBreakModule-           current_toplevel_decl <- enclosingTickSpan md loc-           doContinue (`isSubspanOf` RealSrcSpan current_toplevel_decl) GHC.SingleStep--stepModuleCmd :: String -> GHCi ()-stepModuleCmd arg = withSandboxOnly ":stepmodule" $ step arg-  where-  step expr-   | not (null expr) = stepCmd expr-   | otherwise = do-      mb_span <- getCurrentBreakSpan-      case mb_span of-        Nothing  -> stepCmd []-        Just pan -> do-           let f some_span = srcSpanFileName_maybe pan == srcSpanFileName_maybe some_span-           doContinue f GHC.SingleStep---- | Returns the span of the largest tick containing the srcspan given-enclosingTickSpan :: Module -> SrcSpan -> GHCi RealSrcSpan-enclosingTickSpan _ (UnhelpfulSpan _) = panic "enclosingTickSpan UnhelpfulSpan"-enclosingTickSpan md (RealSrcSpan src) = do-  ticks <- getTickArray md-  let line = srcSpanStartLine src-  ASSERT(inRange (bounds ticks) line) do-  let enclosing_spans = [ pan | (_,pan) <- ticks ! line-                               , realSrcSpanEnd pan >= realSrcSpanEnd src]-  return . head . sortBy leftmostLargestRealSrcSpan $ enclosing_spans- where--leftmostLargestRealSrcSpan :: RealSrcSpan -> RealSrcSpan -> Ordering-leftmostLargestRealSrcSpan a b =-  (realSrcSpanStart a `compare` realSrcSpanStart b)-     `thenCmp`-  (realSrcSpanEnd b `compare` realSrcSpanEnd a)--traceCmd :: String -> GHCi ()-traceCmd arg-  = withSandboxOnly ":trace" $ tr arg-  where-  tr []         = doContinue (const True) GHC.RunAndLogSteps-  tr expression = runStmt expression GHC.RunAndLogSteps >> return ()--continueCmd :: String -> GHCi ()-continueCmd = noArgs $ withSandboxOnly ":continue" $ doContinue (const True) GHC.RunToCompletion---- doContinue :: SingleStep -> GHCi ()-doContinue :: (SrcSpan -> Bool) -> SingleStep -> GHCi ()-doContinue pre step = do-  runResult <- resume pre step-  _ <- afterRunStmt pre runResult-  return ()--abandonCmd :: String -> GHCi ()-abandonCmd = noArgs $ withSandboxOnly ":abandon" $ do-  b <- GHC.abandon -- the prompt will change to indicate the new context-  when (not b) $ liftIO $ putStrLn "There is no computation running."--deleteCmd :: String -> GHCi ()-deleteCmd argLine = withSandboxOnly ":delete" $ do-   deleteSwitch $ words argLine-   where-   deleteSwitch :: [String] -> GHCi ()-   deleteSwitch [] =-      liftIO $ putStrLn "The delete command requires at least one argument."-   -- delete all break points-   deleteSwitch ("*":_rest) = discardActiveBreakPoints-   deleteSwitch idents = do-      mapM_ deleteOneBreak idents-      where-      deleteOneBreak :: String -> GHCi ()-      deleteOneBreak str-         | all isDigit str = deleteBreak (read str)-         | otherwise = return ()--historyCmd :: String -> GHCi ()-historyCmd arg-  | null arg        = history 20-  | all isDigit arg = history (read arg)-  | otherwise       = liftIO $ putStrLn "Syntax:  :history [num]"-  where-  history num = do-    resumes <- GHC.getResumeContext-    case resumes of-      [] -> liftIO $ putStrLn "Not stopped at a breakpoint"-      (r:_) -> do-        let hist = GHC.resumeHistory r-            (took,rest) = splitAt num hist-        case hist of-          [] -> liftIO $ putStrLn $-                   "Empty history. Perhaps you forgot to use :trace?"-          _  -> do-                 pans <- mapM GHC.getHistorySpan took-                 let nums  = map (printf "-%-3d:") [(1::Int)..]-                     names = map GHC.historyEnclosingDecls took-                 printForUser (vcat(zipWith3-                                 (\x y z -> x <+> y <+> z)-                                 (map text nums)-                                 (map (bold . hcat . punctuate colon . map text) names)-                                 (map (parens . ppr) pans)))-                 liftIO $ putStrLn $ if null rest then "<end of history>" else "..."--bold :: SDoc -> SDoc-bold c | do_bold   = text start_bold <> c <> text end_bold-       | otherwise = c--backCmd :: String -> GHCi ()-backCmd arg-  | null arg        = back 1-  | all isDigit arg = back (read arg)-  | otherwise       = liftIO $ putStrLn "Syntax:  :back [num]"-  where-  back num = withSandboxOnly ":back" $ do-      (names, _, pan, _) <- GHC.back num-      printForUser $ ptext (sLit "Logged breakpoint at") <+> ppr pan-      printTypeOfNames names-       -- run the command set with ":set stop <cmd>"-      st <- getGHCiState-      enqueueCommands [stop st]--forwardCmd :: String -> GHCi ()-forwardCmd arg-  | null arg        = forward 1-  | all isDigit arg = forward (read arg)-  | otherwise       = liftIO $ putStrLn "Syntax:  :back [num]"-  where-  forward num = withSandboxOnly ":forward" $ do-      (names, ix, pan, _) <- GHC.forward num-      printForUser $ (if (ix == 0)-                        then ptext (sLit "Stopped at")-                        else ptext (sLit "Logged breakpoint at")) <+> ppr pan-      printTypeOfNames names-       -- run the command set with ":set stop <cmd>"-      st <- getGHCiState-      enqueueCommands [stop st]---- handle the "break" command-breakCmd :: String -> GHCi ()-breakCmd argLine = withSandboxOnly ":break" $ breakSwitch $ words argLine--breakSwitch :: [String] -> GHCi ()-breakSwitch [] = do-   liftIO $ putStrLn "The break command requires at least one argument."-breakSwitch (arg1:rest)-   | looksLikeModuleName arg1 && not (null rest) = do-        md <- wantInterpretedModule arg1-        breakByModule md rest-   | all isDigit arg1 = do-        imports <- GHC.getContext-        case iiModules imports of-           (mn : _) -> do-              md <- lookupModuleName mn-              breakByModuleLine md (read arg1) rest-           [] -> do-              liftIO $ putStrLn "No modules are loaded with debugging support."-   | otherwise = do -- try parsing it as an identifier-        wantNameFromInterpretedModule noCanDo arg1 $ \name -> do-        maybe_info <- GHC.getModuleInfo (GHC.nameModule name)-        case maybe_info of-          Nothing -> noCanDo name (ptext (sLit "cannot get module info"))-          Just minf ->-               ASSERT( isExternalName name )-                    findBreakAndSet (GHC.nameModule name) $-                       findBreakForBind name (GHC.modInfoModBreaks minf)-       where-          noCanDo n why = printForUser $-                text "cannot set breakpoint on " <> ppr n <> text ": " <> why--breakByModule :: Module -> [String] -> GHCi ()-breakByModule md (arg1:rest)-   | all isDigit arg1 = do  -- looks like a line number-        breakByModuleLine md (read arg1) rest-breakByModule _ _-   = breakSyntax--breakByModuleLine :: Module -> Int -> [String] -> GHCi ()-breakByModuleLine md line args-   | [] <- args = findBreakAndSet md $ maybeToList . findBreakByLine line-   | [col] <- args, all isDigit col =-        findBreakAndSet md $ maybeToList . findBreakByCoord Nothing (line, read col)-   | otherwise = breakSyntax--breakSyntax :: a-breakSyntax = throwGhcException (CmdLineError "Syntax: :break [<mod>] <line> [<column>]")--findBreakAndSet :: Module -> (TickArray -> [(Int, RealSrcSpan)]) -> GHCi ()-findBreakAndSet md lookupTickTree = do-   tickArray <- getTickArray md-   (breakArray, _) <- getModBreak md-   case lookupTickTree tickArray of-      []  -> liftIO $ putStrLn $ "No breakpoints found at that location."-      some -> mapM_ (breakAt breakArray) some- where-   breakAt breakArray (tick, pan) = do-         setBreakFlag True breakArray tick-         (alreadySet, nm) <--               recordBreak $ BreakLocation-                       { breakModule = md-                       , breakLoc = RealSrcSpan pan-                       , breakTick = tick-                       , onBreakCmd = ""-                       }-         printForUser $-            text "Breakpoint " <> ppr nm <>-            if alreadySet-               then text " was already set at " <> ppr pan-               else text " activated at " <> ppr pan---- When a line number is specified, the current policy for choosing--- the best breakpoint is this:---    - the leftmost complete subexpression on the specified line, or---    - the leftmost subexpression starting on the specified line, or---    - the rightmost subexpression enclosing the specified line----findBreakByLine :: Int -> TickArray -> Maybe (BreakIndex,RealSrcSpan)-findBreakByLine line arr-  | not (inRange (bounds arr) line) = Nothing-  | otherwise =-    listToMaybe (sortBy (leftmostLargestRealSrcSpan `on` snd)  comp)   `mplus`-    listToMaybe (sortBy (compare `on` snd) incomp) `mplus`-    listToMaybe (sortBy (flip compare `on` snd) ticks)-  where-        ticks = arr ! line--        starts_here = [ (ix,pan) | (ix, pan) <- ticks,-                        GHC.srcSpanStartLine pan == line ]--        (comp, incomp) = partition ends_here starts_here-            where ends_here (_,pan) = GHC.srcSpanEndLine pan == line---- The aim is to find the breakpoints for all the RHSs of the--- equations corresponding to a binding.  So we find all breakpoints--- for---   (a) this binder only (not a nested declaration)---   (b) that do not have an enclosing breakpoint-findBreakForBind :: Name -> GHC.ModBreaks -> TickArray-                 -> [(BreakIndex,RealSrcSpan)]-findBreakForBind name modbreaks _ = filter (not . enclosed) ticks-  where-    ticks = [ (index, span)-            | (index, [n]) <- assocs (GHC.modBreaks_decls modbreaks),-              n == occNameString (nameOccName name),-              RealSrcSpan span <- [GHC.modBreaks_locs modbreaks ! index] ]-    enclosed (_,sp0) = any subspan ticks-      where subspan (_,sp) = sp /= sp0 &&-                         realSrcSpanStart sp <= realSrcSpanStart sp0 &&-                         realSrcSpanEnd sp0 <= realSrcSpanEnd sp--findBreakByCoord :: Maybe FastString -> (Int,Int) -> TickArray-                 -> Maybe (BreakIndex,RealSrcSpan)-findBreakByCoord mb_file (line, col) arr-  | not (inRange (bounds arr) line) = Nothing-  | otherwise =-    listToMaybe (sortBy (flip compare `on` snd) contains ++-                 sortBy (compare `on` snd) after_here)-  where-        ticks = arr ! line--        -- the ticks that span this coordinate-        contains = [ tick | tick@(_,pan) <- ticks, RealSrcSpan pan `spans` (line,col),-                            is_correct_file pan ]--        is_correct_file pan-                 | Just f <- mb_file = GHC.srcSpanFile pan == f-                 | otherwise         = True--        after_here = [ tick | tick@(_,pan) <- ticks,-                              GHC.srcSpanStartLine pan == line,-                              GHC.srcSpanStartCol pan >= col ]---- For now, use ANSI bold on terminals that we know support it.--- Otherwise, we add a line of carets under the active expression instead.--- In particular, on Windows and when running the testsuite (which sets--- TERM to vt100 for other reasons) we get carets.--- We really ought to use a proper termcap/terminfo library.-do_bold :: Bool-do_bold = (`isPrefixOf` unsafePerformIO mTerm) `any` ["xterm", "linux"]-    where mTerm = System.Environment.getEnv "TERM"-                  `catchIO` \_ -> return "TERM not set"--start_bold :: String-start_bold = "\ESC[1m"-end_bold :: String-end_bold   = "\ESC[0m"---------------------------------------------------------------------------------- :where--whereCmd :: String -> GHCi ()-whereCmd = noArgs $ do-  mstrs <- getCallStackAtCurrentBreakpoint-  case mstrs of-    Nothing -> return ()-    Just strs -> liftIO $ putStrLn (renderStack strs)---------------------------------------------------------------------------------- :list--listCmd :: String -> InputT GHCi ()-listCmd c = listCmd' c--listCmd' :: String -> InputT GHCi ()-listCmd' "" = do-   mb_span <- lift getCurrentBreakSpan-   case mb_span of-      Nothing ->-          printForUser $ text "Not stopped at a breakpoint; nothing to list"-      Just (RealSrcSpan pan) ->-          listAround pan True-      Just pan@(UnhelpfulSpan _) ->-          do resumes <- GHC.getResumeContext-             case resumes of-                 [] -> panic "No resumes"-                 (r:_) ->-                     do let traceIt = case GHC.resumeHistory r of-                                      [] -> text "rerunning with :trace,"-                                      _ -> empty-                            doWhat = traceIt <+> text ":back then :list"-                        printForUser (text "Unable to list source for" <+>-                                      ppr pan-                                   $$ text "Try" <+> doWhat)-listCmd' str = list2 (words str)--list2 :: [String] -> InputT GHCi ()-list2 [arg] | all isDigit arg = do-    imports <- GHC.getContext-    case iiModules imports of-        [] -> liftIO $ putStrLn "No module to list"-        (mn : _) -> do-          md <- lift $ lookupModuleName mn-          listModuleLine md (read arg)-list2 [arg1,arg2] | looksLikeModuleName arg1, all isDigit arg2 = do-        md <- wantInterpretedModule arg1-        listModuleLine md (read arg2)-list2 [arg] = do-        wantNameFromInterpretedModule noCanDo arg $ \name -> do-        let loc = GHC.srcSpanStart (GHC.nameSrcSpan name)-        case loc of-            RealSrcLoc l ->-               do tickArray <- ASSERT( isExternalName name )-                               lift $ getTickArray (GHC.nameModule name)-                  let mb_span = findBreakByCoord (Just (GHC.srcLocFile l))-                                        (GHC.srcLocLine l, GHC.srcLocCol l)-                                        tickArray-                  case mb_span of-                    Nothing       -> listAround (realSrcLocSpan l) False-                    Just (_, pan) -> listAround pan False-            UnhelpfulLoc _ ->-                  noCanDo name $ text "can't find its location: " <>-                                 ppr loc-    where-        noCanDo n why = printForUser $-            text "cannot list source code for " <> ppr n <> text ": " <> why-list2  _other =-        liftIO $ putStrLn "syntax:  :list [<line> | <module> <line> | <identifier>]"--listModuleLine :: Module -> Int -> InputT GHCi ()-listModuleLine modl line = do-   graph <- GHC.getModuleGraph-   let this = filter ((== modl) . GHC.ms_mod) graph-   case this of-     [] -> panic "listModuleLine"-     summ:_ -> do-           let filename = expectJust "listModuleLine" (ml_hs_file (GHC.ms_location summ))-               loc = mkRealSrcLoc (mkFastString (filename)) line 0-           listAround (realSrcLocSpan loc) False---- | list a section of a source file around a particular SrcSpan.--- If the highlight flag is True, also highlight the span using--- start_bold\/end_bold.---- GHC files are UTF-8, so we can implement this by:--- 1) read the file in as a BS and syntax highlight it as before--- 2) convert the BS to String using utf-string, and write it out.--- It would be better if we could convert directly between UTF-8 and the--- console encoding, of course.-listAround :: MonadIO m => RealSrcSpan -> Bool -> InputT m ()-listAround pan do_highlight = do-      contents <- liftIO $ BS.readFile (unpackFS file)-      -- Drop carriage returns to avoid duplicates, see #9367.-      let ls  = BS.split '\n' $ BS.filter (/= '\r') contents-          ls' = take (line2 - line1 + 1 + pad_before + pad_after) $-                        drop (line1 - 1 - pad_before) $ ls-          fst_line = max 1 (line1 - pad_before)-          line_nos = [ fst_line .. ]--          highlighted | do_highlight = zipWith highlight line_nos ls'-                      | otherwise    = [\p -> BS.concat[p,l] | l <- ls']--          bs_line_nos = [ BS.pack (show l ++ "  ") | l <- line_nos ]-          prefixed = zipWith ($) highlighted bs_line_nos-          output   = BS.intercalate (BS.pack "\n") prefixed--      let utf8Decoded = utf8DecodeByteString output-      liftIO $ putStrLn utf8Decoded-  where-        file  = GHC.srcSpanFile pan-        line1 = GHC.srcSpanStartLine pan-        col1  = GHC.srcSpanStartCol pan - 1-        line2 = GHC.srcSpanEndLine pan-        col2  = GHC.srcSpanEndCol pan - 1--        pad_before | line1 == 1 = 0-                   | otherwise  = 1-        pad_after = 1--        highlight | do_bold   = highlight_bold-                  | otherwise = highlight_carets--        highlight_bold no line prefix-          | no == line1 && no == line2-          = let (a,r) = BS.splitAt col1 line-                (b,c) = BS.splitAt (col2-col1) r-            in-            BS.concat [prefix, a,BS.pack start_bold,b,BS.pack end_bold,c]-          | no == line1-          = let (a,b) = BS.splitAt col1 line in-            BS.concat [prefix, a, BS.pack start_bold, b]-          | no == line2-          = let (a,b) = BS.splitAt col2 line in-            BS.concat [prefix, a, BS.pack end_bold, b]-          | otherwise   = BS.concat [prefix, line]--        highlight_carets no line prefix-          | no == line1 && no == line2-          = BS.concat [prefix, line, nl, indent, BS.replicate col1 ' ',-                                         BS.replicate (col2-col1) '^']-          | no == line1-          = BS.concat [indent, BS.replicate (col1 - 2) ' ', BS.pack "vv", nl,-                                         prefix, line]-          | no == line2-          = BS.concat [prefix, line, nl, indent, BS.replicate col2 ' ',-                                         BS.pack "^^"]-          | otherwise   = BS.concat [prefix, line]-         where-           indent = BS.pack ("  " ++ replicate (length (show no)) ' ')-           nl = BS.singleton '\n'----- ----------------------------------------------------------------------------- Tick arrays--getTickArray :: Module -> GHCi TickArray-getTickArray modl = do-   st <- getGHCiState-   let arrmap = tickarrays st-   case lookupModuleEnv arrmap modl of-      Just arr -> return arr-      Nothing  -> do-        (_breakArray, ticks) <- getModBreak modl-        let arr = mkTickArray (assocs ticks)-        setGHCiState st{tickarrays = extendModuleEnv arrmap modl arr}-        return arr--discardTickArrays :: GHCi ()-discardTickArrays = modifyGHCiState (\st -> st {tickarrays = emptyModuleEnv})--mkTickArray :: [(BreakIndex,SrcSpan)] -> TickArray-mkTickArray ticks-  = accumArray (flip (:)) [] (1, max_line)-        [ (line, (nm,pan)) | (nm,RealSrcSpan pan) <- ticks, line <- srcSpanLines pan ]-    where-        max_line = foldr max 0 [ GHC.srcSpanEndLine sp | (_, RealSrcSpan sp) <- ticks ]-        srcSpanLines pan = [ GHC.srcSpanStartLine pan ..  GHC.srcSpanEndLine pan ]---- don't reset the counter back to zero?-discardActiveBreakPoints :: GHCi ()-discardActiveBreakPoints = do-   st <- getGHCiState-   mapM_ (turnOffBreak.snd) (breaks st)-   setGHCiState $ st { breaks = [] }--deleteBreak :: Int -> GHCi ()-deleteBreak identity = do-   st <- getGHCiState-   let oldLocations    = breaks st-       (this,rest)     = partition (\loc -> fst loc == identity) oldLocations-   if null this-      then printForUser (text "Breakpoint" <+> ppr identity <+>-                         text "does not exist")-      else do-           mapM_ (turnOffBreak.snd) this-           setGHCiState $ st { breaks = rest }--turnOffBreak :: BreakLocation -> GHCi ()-turnOffBreak loc = do-  (arr, _) <- getModBreak (breakModule loc)-  hsc_env <- GHC.getSession-  liftIO $ enableBreakpoint hsc_env arr (breakTick loc) False--getModBreak :: Module -> GHCi (ForeignRef BreakArray, Array Int SrcSpan)-getModBreak m = do-   Just mod_info <- GHC.getModuleInfo m-   let modBreaks  = GHC.modInfoModBreaks mod_info-   let arr        = GHC.modBreaks_flags modBreaks-   let ticks      = GHC.modBreaks_locs  modBreaks-   return (arr, ticks)--setBreakFlag :: Bool -> ForeignRef BreakArray -> Int -> GHCi ()-setBreakFlag toggle arr i = do-  hsc_env <- GHC.getSession-  liftIO $ enableBreakpoint hsc_env arr i toggle---- ------------------------------------------------------------------------------ User code exception handling---- This is the exception handler for exceptions generated by the--- user's code and exceptions coming from children sessions;--- it normally just prints out the exception.  The--- handler must be recursive, in case showing the exception causes--- more exceptions to be raised.------ Bugfix: if the user closed stdout or stderr, the flushing will fail,--- raising another exception.  We therefore don't put the recursive--- handler arond the flushing operation, so if stderr is closed--- GHCi will just die gracefully rather than going into an infinite loop.-handler :: SomeException -> GHCi Bool--handler exception = do-  flushInterpBuffers-  withSignalHandlers $-     ghciHandle handler (showException exception >> return False)--showException :: SomeException -> GHCi ()-showException se =-  liftIO $ case fromException se of-           -- omit the location for CmdLineError:-           Just (CmdLineError s)    -> putException s-           -- ditto:-           Just other_ghc_ex        -> putException (show other_ghc_ex)-           Nothing                  ->-               case fromException se of-               Just UserInterrupt -> putException "Interrupted."-               _                  -> putException ("*** Exception: " ++ show se)-  where-    putException = hPutStrLn stderr----------------------------------------------------------------------------------- recursive exception handlers---- Don't forget to unblock async exceptions in the handler, or if we're--- in an exception loop (eg. let a = error a in a) the ^C exception--- may never be delivered.  Thanks to Marcin for pointing out the bug.--ghciHandle :: (HasDynFlags m, ExceptionMonad m) => (SomeException -> m a) -> m a -> m a-ghciHandle h m = gmask $ \restore -> do-                 -- Force dflags to avoid leaking the associated HscEnv-                 !dflags <- getDynFlags-                 gcatch (restore (GHC.prettyPrintGhcErrors dflags m)) $ \e -> restore (h e)--ghciTry :: GHCi a -> GHCi (Either SomeException a)-ghciTry (GHCi m) = GHCi $ \s -> gtry (m s)--tryBool :: GHCi a -> GHCi Bool-tryBool m = do-    r <- ghciTry m-    case r of-      Left _  -> return False-      Right _ -> return True---- ------------------------------------------------------------------------------- Utils--lookupModule :: GHC.GhcMonad m => String -> m Module-lookupModule mName = lookupModuleName (GHC.mkModuleName mName)--lookupModuleName :: GHC.GhcMonad m => ModuleName -> m Module-lookupModuleName mName = GHC.lookupModule mName Nothing--isHomeModule :: Module -> Bool-isHomeModule m = GHC.moduleUnitId m == mainUnitId---- TODO: won't work if home dir is encoded.--- (changeDirectory may not work either in that case.)-expandPath :: MonadIO m => String -> InputT m String-expandPath = liftIO . expandPathIO--expandPathIO :: String -> IO String-expandPathIO p =-  case dropWhile isSpace p of-   ('~':d) -> do-        tilde <- getHomeDirectory -- will fail if HOME not defined-        return (tilde ++ '/':d)-   other ->-        return other--wantInterpretedModule :: GHC.GhcMonad m => String -> m Module-wantInterpretedModule str = wantInterpretedModuleName (GHC.mkModuleName str)--wantInterpretedModuleName :: GHC.GhcMonad m => ModuleName -> m Module-wantInterpretedModuleName modname = do-   modl <- lookupModuleName modname-   let str = moduleNameString modname-   dflags <- getDynFlags-   when (GHC.moduleUnitId modl /= thisPackage dflags) $-      throwGhcException (CmdLineError ("module '" ++ str ++ "' is from another package;\nthis command requires an interpreted module"))-   is_interpreted <- GHC.moduleIsInterpreted modl-   when (not is_interpreted) $-       throwGhcException (CmdLineError ("module '" ++ str ++ "' is not interpreted; try \':add *" ++ str ++ "' first"))-   return modl--wantNameFromInterpretedModule :: GHC.GhcMonad m-                              => (Name -> SDoc -> m ())-                              -> String-                              -> (Name -> m ())-                              -> m ()-wantNameFromInterpretedModule noCanDo str and_then =-  handleSourceError GHC.printException $ do-   names <- GHC.parseName str-   case names of-      []    -> return ()-      (n:_) -> do-            let modl = ASSERT( isExternalName n ) GHC.nameModule n-            if not (GHC.isExternalName n)-               then noCanDo n $ ppr n <>-                                text " is not defined in an interpreted module"-               else do-            is_interpreted <- GHC.moduleIsInterpreted modl-            if not is_interpreted-               then noCanDo n $ text "module " <> ppr modl <>-                                text " is not interpreted"-               else and_then n
− src-bin-821/Clash/GHCi/UI/Info.hs
@@ -1,366 +0,0 @@-{-# LANGUAGE LambdaCase          #-}-{-# LANGUAGE RankNTypes          #-}-{-# LANGUAGE OverloadedStrings   #-}-{-# LANGUAGE ScopedTypeVariables #-}---- | Get information on modules, expreesions, and identifiers-module Clash.GHCi.UI.Info-    ( ModInfo(..)-    , SpanInfo(..)-    , spanInfoFromRealSrcSpan-    , collectInfo-    , findLoc-    , findNameUses-    , findType-    , getModInfo-    ) where--import           Control.Exception-import           Control.Monad-import           Control.Monad.Trans.Class-import           Control.Monad.Trans.Except-import           Control.Monad.Trans.Maybe-import           Data.Data-import           Data.Function-import           Data.List-import           Data.Map.Strict   (Map)-import qualified Data.Map.Strict   as M-import           Data.Maybe-import           Data.Time-import           Prelude           hiding (mod)-import           System.Directory--import qualified CoreUtils-import           Desugar-import           DynFlags (HasDynFlags(..))-import           FastString-import           GHC-import           GhcMonad-import           Name-import           NameSet-import           Outputable-import           SrcLoc-import           TcHsSyn-import           Var---- | Info about a module. This information is generated every time a--- module is loaded.-data ModInfo = ModInfo-    { modinfoSummary    :: !ModSummary-      -- ^ Summary generated by GHC. Can be used to access more-      -- information about the module.-    , modinfoSpans      :: [SpanInfo]-      -- ^ Generated set of information about all spans in the-      -- module that correspond to some kind of identifier for-      -- which there will be type info and/or location info.-    , modinfoInfo       :: !ModuleInfo-      -- ^ Again, useful from GHC for accessing information-      -- (exports, instances, scope) from a module.-    , modinfoLastUpdate :: !UTCTime-    }---- | Type of some span of source code. Most of these fields are--- unboxed but Haddock doesn't show that.-data SpanInfo = SpanInfo-    { spaninfoSrcSpan   :: {-# UNPACK #-} !RealSrcSpan-      -- ^ The span we associate information with-    , spaninfoType      :: !(Maybe Type)-      -- ^ The 'Type' associated with the span-    , spaninfoVar       :: !(Maybe Id)-      -- ^ The actual 'Var' associated with the span, if-      -- any. This can be useful for accessing a variety of-      -- information about the identifier such as module,-      -- locality, definition location, etc.-    }---- | Test whether second span is contained in (or equal to) first span.--- This is basically 'containsSpan' for 'SpanInfo'-containsSpanInfo :: SpanInfo -> SpanInfo -> Bool-containsSpanInfo = containsSpan `on` spaninfoSrcSpan---- | Filter all 'SpanInfo' which are contained in 'SpanInfo'-spaninfosWithin :: [SpanInfo] -> SpanInfo -> [SpanInfo]-spaninfosWithin spans' si = filter (si `containsSpanInfo`) spans'---- | Construct a 'SpanInfo' from a 'RealSrcSpan' and optionally a--- 'Type' and an 'Id' (for 'spaninfoType' and 'spaninfoVar'--- respectively)-spanInfoFromRealSrcSpan :: RealSrcSpan -> Maybe Type -> Maybe Id -> SpanInfo-spanInfoFromRealSrcSpan spn mty mvar =-    SpanInfo spn mty mvar---- | Convenience wrapper around 'spanInfoFromRealSrcSpan' which needs--- only a 'RealSrcSpan'-spanInfoFromRealSrcSpan' :: RealSrcSpan -> SpanInfo-spanInfoFromRealSrcSpan' s = spanInfoFromRealSrcSpan s Nothing Nothing---- | Convenience wrapper around 'srcSpanFile' which results in a 'FilePath'-srcSpanFilePath :: RealSrcSpan -> FilePath-srcSpanFilePath = unpackFS . srcSpanFile---- | Try to find the location of the given identifier at the given--- position in the module.-findLoc :: GhcMonad m-        => Map ModuleName ModInfo-        -> RealSrcSpan-        -> String-        -> ExceptT SDoc m (ModInfo,Name,SrcSpan)-findLoc infos span0 string = do-    name  <- maybeToExceptT "Couldn't guess that module name. Does it exist?" $-             guessModule infos (srcSpanFilePath span0)--    info  <- maybeToExceptT "No module info for current file! Try loading it?" $-             MaybeT $ pure $ M.lookup name infos--    name' <- findName infos span0 info string--    case getSrcSpan name' of-        UnhelpfulSpan{} -> do-            throwE ("Found a name, but no location information." <+>-                    "The module is:" <+>-                    maybe "<unknown>" (ppr . moduleName)-                          (nameModule_maybe name'))--        span' -> return (info,name',span')---- | Find any uses of the given identifier in the codebase.-findNameUses :: (GhcMonad m)-             => Map ModuleName ModInfo-             -> RealSrcSpan-             -> String-             -> ExceptT SDoc m [SrcSpan]-findNameUses infos span0 string =-    locToSpans <$> findLoc infos span0 string-  where-    locToSpans (modinfo,name',span') =-        stripSurrounding (span' : map toSrcSpan spans)-      where-        toSrcSpan = RealSrcSpan . spaninfoSrcSpan-        spans = filter ((== Just name') . fmap getName . spaninfoVar)-                       (modinfoSpans modinfo)---- | Filter out redundant spans which surround/contain other spans.-stripSurrounding :: [SrcSpan] -> [SrcSpan]-stripSurrounding xs = filter (not . isRedundant) xs-  where-    isRedundant x = any (x `strictlyContains`) xs--    (RealSrcSpan s1) `strictlyContains` (RealSrcSpan s2)-         = s1 /= s2 && s1 `containsSpan` s2-    _                `strictlyContains` _ = False---- | Try to resolve the name located at the given position, or--- otherwise resolve based on the current module's scope.-findName :: GhcMonad m-         => Map ModuleName ModInfo-         -> RealSrcSpan-         -> ModInfo-         -> String-         -> ExceptT SDoc m Name-findName infos span0 mi string =-    case resolveName (modinfoSpans mi) (spanInfoFromRealSrcSpan' span0) of-      Nothing -> tryExternalModuleResolution-      Just name ->-        case getSrcSpan name of-          UnhelpfulSpan {} -> tryExternalModuleResolution-          RealSrcSpan   {} -> return (getName name)-  where-    tryExternalModuleResolution =-      case find (matchName $ mkFastString string)-                (fromMaybe [] (modInfoTopLevelScope (modinfoInfo mi))) of-        Nothing -> throwE "Couldn't resolve to any modules."-        Just imported -> resolveNameFromModule infos imported--    matchName :: FastString -> Name -> Bool-    matchName str name =-      str ==-      occNameFS (getOccName name)---- | Try to resolve the name from another (loaded) module's exports.-resolveNameFromModule :: GhcMonad m-                      => Map ModuleName ModInfo-                      -> Name-                      -> ExceptT SDoc m Name-resolveNameFromModule infos name = do-     modL <- maybe (throwE $ "No module for" <+> ppr name) return $-             nameModule_maybe name--     info <- maybe (throwE (ppr (moduleUnitId modL) <> ":" <>-                            ppr modL)) return $-             M.lookup (moduleName modL) infos--     maybe (throwE "No matching export in any local modules.") return $-         find (matchName name) (modInfoExports (modinfoInfo info))-  where-    matchName :: Name -> Name -> Bool-    matchName x y = occNameFS (getOccName x) ==-                    occNameFS (getOccName y)---- | Try to resolve the type display from the given span.-resolveName :: [SpanInfo] -> SpanInfo -> Maybe Var-resolveName spans' si = listToMaybe $ mapMaybe spaninfoVar $-                        reverse spans' `spaninfosWithin` si---- | Try to find the type of the given span.-findType :: GhcMonad m-         => Map ModuleName ModInfo-         -> RealSrcSpan-         -> String-         -> ExceptT SDoc m (ModInfo, Type)-findType infos span0 string = do-    name  <- maybeToExceptT "Couldn't guess that module name. Does it exist?" $-             guessModule infos (srcSpanFilePath span0)--    info  <- maybeToExceptT "No module info for current file! Try loading it?" $-             MaybeT $ pure $ M.lookup name infos--    case resolveType (modinfoSpans info) (spanInfoFromRealSrcSpan' span0) of-        Nothing -> (,) info <$> lift (exprType TM_Inst string)-        Just ty -> return (info, ty)-  where-    -- | Try to resolve the type display from the given span.-    resolveType :: [SpanInfo] -> SpanInfo -> Maybe Type-    resolveType spans' si = listToMaybe $ mapMaybe spaninfoType $-                            reverse spans' `spaninfosWithin` si---- | Guess a module name from a file path.-guessModule :: GhcMonad m-            => Map ModuleName ModInfo -> FilePath -> MaybeT m ModuleName-guessModule infos fp = do-    target <- lift $ guessTarget fp Nothing-    case targetId target of-        TargetModule mn  -> return mn-        TargetFile fp' _ -> guessModule' fp'-  where-    guessModule' :: GhcMonad m => FilePath -> MaybeT m ModuleName-    guessModule' fp' = case findModByFp fp' of-        Just mn -> return mn-        Nothing -> do-            fp'' <- liftIO (makeRelativeToCurrentDirectory fp')--            target' <- lift $ guessTarget fp'' Nothing-            case targetId target' of-                TargetModule mn -> return mn-                _               -> MaybeT . pure $ findModByFp fp''--    findModByFp :: FilePath -> Maybe ModuleName-    findModByFp fp' = fst <$> find ((Just fp' ==) . mifp) (M.toList infos)-      where-        mifp :: (ModuleName, ModInfo) -> Maybe FilePath-        mifp = ml_hs_file . ms_location . modinfoSummary . snd----- | Collect type info data for the loaded modules.-collectInfo :: (GhcMonad m) => Map ModuleName ModInfo -> [ModuleName]-               -> m (Map ModuleName ModInfo)-collectInfo ms loaded = do-    df <- getDynFlags-    liftIO (filterM cacheInvalid loaded) >>= \case-        [] -> return ms-        invalidated -> do-            liftIO (putStrLn ("Collecting type info for " ++-                              show (length invalidated) ++-                              " module(s) ... "))--            foldM (go df) ms invalidated-  where-    go df m name = do { info <- getModInfo name; return (M.insert name info m) }-                   `gcatch`-                   (\(e :: SomeException) -> do-                         liftIO $ putStrLn-                                $ showSDocForUser df alwaysQualify-                                $ "Error while getting type info from" <+>-                                  ppr name <> ":" <+> text (show e)-                         return m)--    cacheInvalid name = case M.lookup name ms of-        Nothing -> return True-        Just mi -> do-            let fp = ml_obj_file (ms_location (modinfoSummary mi))-                last' = modinfoLastUpdate mi-            exists <- doesFileExist fp-            if exists-                then (> last') <$> getModificationTime fp-                else return True---- | Get info about the module: summary, types, etc.-getModInfo :: (GhcMonad m) => ModuleName -> m ModInfo-getModInfo name = do-    m <- getModSummary name-    p <- parseModule m-    typechecked <- typecheckModule p-    allTypes <- processAllTypeCheckedModule typechecked-    let i = tm_checked_module_info typechecked-    now <- liftIO getCurrentTime-    return (ModInfo m allTypes i now)---- | Get ALL source spans in the module.-processAllTypeCheckedModule :: forall m . GhcMonad m => TypecheckedModule-                            -> m [SpanInfo]-processAllTypeCheckedModule tcm = do-    bts <- mapM getTypeLHsBind $ listifyAllSpans tcs-    ets <- mapM getTypeLHsExpr $ listifyAllSpans tcs-    pts <- mapM getTypeLPat    $ listifyAllSpans tcs-    return $ mapMaybe toSpanInfo-           $ sortBy cmpSpan-           $ catMaybes (bts ++ ets ++ pts)-  where-    tcs = tm_typechecked_source tcm--    -- | Extract 'Id', 'SrcSpan', and 'Type' for 'LHsBind's-    getTypeLHsBind :: LHsBind Id -> m (Maybe (Maybe Id,SrcSpan,Type))-    getTypeLHsBind (L _spn FunBind{fun_id = pid,fun_matches = MG _ _ _typ _})-        = pure $ Just (Just (unLoc pid),getLoc pid,varType (unLoc pid))-    getTypeLHsBind _ = pure Nothing--    -- | Extract 'Id', 'SrcSpan', and 'Type' for 'LHsExpr's-    getTypeLHsExpr :: LHsExpr Id -> m (Maybe (Maybe Id,SrcSpan,Type))-    getTypeLHsExpr e = do-        hs_env  <- getSession-        (_,mbe) <- liftIO $ deSugarExpr hs_env e-        return $ fmap (\expr -> (mid, getLoc e, CoreUtils.exprType expr)) mbe-      where-        mid :: Maybe Id-        mid | HsVar (L _ i) <- unwrapVar (unLoc e) = Just i-            | otherwise                            = Nothing--        unwrapVar (HsWrap _ var) = var-        unwrapVar e'             = e'--    -- | Extract 'Id', 'SrcSpan', and 'Type' for 'LPats's-    getTypeLPat :: LPat Id -> m (Maybe (Maybe Id,SrcSpan,Type))-    getTypeLPat (L spn pat) =-        pure (Just (getMaybeId pat,spn,hsPatType pat))-      where-        getMaybeId (VarPat (L _ vid)) = Just vid-        getMaybeId _                  = Nothing--    -- | Get ALL source spans in the source.-    listifyAllSpans :: Typeable a => TypecheckedSource -> [Located a]-    listifyAllSpans = everythingAllSpans (++) [] ([] `mkQ` (\x -> [x | p x]))-      where-        p (L spn _) = isGoodSrcSpan spn--    -- | Variant of @syb@'s @everything@ (which summarises all nodes-    -- in top-down, left-to-right order) with a stop-condition on 'NameSet's-    everythingAllSpans :: (r -> r -> r) -> r -> GenericQ r -> GenericQ r-    everythingAllSpans k z f x-      | (False `mkQ` (const True :: NameSet -> Bool)) x = z-      | otherwise = foldl k (f x) (gmapQ (everythingAllSpans k z f) x)--    cmpSpan (_,a,_) (_,b,_)-      | a `isSubspanOf` b = LT-      | b `isSubspanOf` a = GT-      | otherwise         = EQ--    -- | Pretty print the types into a 'SpanInfo'.-    toSpanInfo :: (Maybe Id,SrcSpan,Type) -> Maybe SpanInfo-    toSpanInfo (n,RealSrcSpan spn,typ)-        = Just $ spanInfoFromRealSrcSpan spn (Just typ) n-    toSpanInfo _ = Nothing---- helper stolen from @syb@ package-type GenericQ r = forall a. Data a => a -> r--mkQ :: (Typeable a, Typeable b) => r -> (b -> r) -> a -> r-(r `mkQ` br) a = maybe r br (cast a)
− src-bin-821/Clash/GHCi/UI/Monad.hs
@@ -1,454 +0,0 @@-{-# LANGUAGE CPP, FlexibleInstances, UnboxedTuples, MagicHash #-}-{-# OPTIONS_GHC -fno-cse -fno-warn-orphans #-}--- -fno-cse is needed for GLOBAL_VAR's to behave properly------------------------------------------------------------------------------------- Monadery code used in InteractiveUI------ (c) The GHC Team 2005-2006-----------------------------------------------------------------------------------module Clash.GHCi.UI.Monad (-        GHCi(..), startGHCi,-        GHCiState(..), setGHCiState, getGHCiState, modifyGHCiState,-        GHCiOption(..), isOptionSet, setOption, unsetOption,-        Command(..),-        PromptFunction,-        BreakLocation(..),-        TickArray,-        getDynFlags,--        runStmt, runDecls, resume, timeIt, recordBreak, revertCAFs,--        printForUserNeverQualify, printForUserModInfo,-        printForUser, printForUserPartWay, prettyLocations,-        initInterpBuffering,-        turnOffBuffering, turnOffBuffering_,-        flushInterpBuffers,-        mkEvalWrapper-    ) where--#include "../HsVersions.h"--import Clash.GHCi.UI.Info (ModInfo)-import qualified GHC-import GhcMonad         hiding (liftIO)-import Outputable       hiding (printForUser, printForUserPartWay)-import qualified Outputable-import DynFlags-import FastString-import HscTypes-import SrcLoc-import Module-import GHCi-import GHCi.RemoteTypes-import HsSyn (ImportDecl)-import RdrName (RdrName)--import Exception-import Numeric-import Data.Array-import Data.IORef-import Data.Time-import System.Environment-import System.IO-import Control.Monad--import System.Console.Haskeline (CompletionFunc, InputT)-import qualified System.Console.Haskeline as Haskeline-import Control.Monad.Trans.Class-import Control.Monad.IO.Class-import Data.Map.Strict (Map)---------------------------------------------------------------------------------- GHCi monad--data GHCiState = GHCiState-     {-        progname       :: String,-        args           :: [String],-        evalWrapper    :: ForeignHValue, -- ^ of type @IO a -> IO a@-        prompt         :: PromptFunction,-        prompt_cont    :: PromptFunction,-        editor         :: String,-        stop           :: String,-        options        :: [GHCiOption],-        line_number    :: !Int,         -- ^ input line-        break_ctr      :: !Int,-        breaks         :: ![(Int, BreakLocation)],-        tickarrays     :: ModuleEnv TickArray,-            -- ^ 'tickarrays' caches the 'TickArray' for loaded modules,-            -- so that we don't rebuild it each time the user sets-            -- a breakpoint.-        ghci_commands  :: [Command],-            -- ^ available ghci commands-        ghci_macros    :: [Command],-            -- ^ user-defined macros-        last_command   :: Maybe Command,-            -- ^ @:@ at the GHCi prompt repeats the last command, so we-            -- remember it here-        cmdqueue       :: [String],--        remembered_ctx :: [InteractiveImport],-            -- ^ The imports that the user has asked for, via import-            -- declarations and :module commands.  This list is-            -- persistent over :reloads (but any imports for modules-            -- that are not loaded are temporarily ignored).  After a-            -- :load, all the home-package imports are stripped from-            -- this list.-            ---            -- See bugs #2049, #1873, #1360--        transient_ctx  :: [InteractiveImport],-            -- ^ An import added automatically after a :load, usually of-            -- the most recently compiled module.  May be empty if-            -- there are no modules loaded.  This list is replaced by-            -- :load, :reload, and :add.  In between it may be modified-            -- by :module.--        extra_imports  :: [ImportDecl RdrName],-            -- ^ These are "always-on" imports, added to the-            -- context regardless of what other imports we have.-            -- This is useful for adding imports that are required-            -- by setGHCiMonad.  Be careful adding things here:-            -- you can create ambiguities if these imports overlap-            -- with other things in scope.-            ---            -- NB. although this is not currently used by GHCi itself,-            -- it was added to support other front-ends that are based-            -- on the GHCi code.  Potentially we could also expose-            -- this functionality via GHCi commands.--        prelude_imports :: [ImportDecl RdrName],-            -- ^ These imports are added to the context when-            -- -XImplicitPrelude is on and we don't have a *-module-            -- in the context.  They can also be overridden by another-            -- import for the same module, e.g.-            -- "import Prelude hiding (map)"--        ghc_e :: Bool, -- ^ True if this is 'ghc -e' (or runghc)--        short_help :: String,-            -- ^ help text to display to a user-        long_help  :: String,-        lastErrorLocations :: IORef [(FastString, Int)],--        mod_infos  :: !(Map ModuleName ModInfo),--        flushStdHandles :: ForeignHValue,-            -- ^ @hFlush stdout; hFlush stderr@ in the interpreter-        noBuffering :: ForeignHValue-            -- ^ @hSetBuffering NoBuffering@ for stdin/stdout/stderr-     }--type TickArray = Array Int [(GHC.BreakIndex,RealSrcSpan)]---- | A GHCi command-data Command-   = Command-   { cmdName           :: String-     -- ^ Name of GHCi command (e.g. "exit")-   , cmdAction         :: String -> InputT GHCi Bool-     -- ^ The 'Bool' value denotes whether to exit GHCi-   , cmdHidden         :: Bool-     -- ^ Commands which are excluded from default completion-     -- and @:help@ summary. This is usually set for commands not-     -- useful for interactive use but rather for IDEs.-   , cmdCompletionFunc :: CompletionFunc GHCi-     -- ^ 'CompletionFunc' for arguments-   }--type PromptFunction = [String]-                   -> Int-                   -> GHCi SDoc--data GHCiOption-        = ShowTiming            -- show time/allocs after evaluation-        | ShowType              -- show the type of expressions-        | RevertCAFs            -- revert CAFs after every evaluation-        | Multiline             -- use multiline commands-        | CollectInfo           -- collect and cache information about-                                -- modules after load-        deriving Eq--data BreakLocation-   = BreakLocation-   { breakModule :: !GHC.Module-   , breakLoc    :: !SrcSpan-   , breakTick   :: {-# UNPACK #-} !Int-   , onBreakCmd  :: String-   }--instance Eq BreakLocation where-  loc1 == loc2 = breakModule loc1 == breakModule loc2 &&-                 breakTick loc1   == breakTick loc2--prettyLocations :: [(Int, BreakLocation)] -> SDoc-prettyLocations []   = text "No active breakpoints."-prettyLocations locs = vcat $ map (\(i, loc) -> brackets (int i) <+> ppr loc) $ reverse $ locs--instance Outputable BreakLocation where-   ppr loc = (ppr $ breakModule loc) <+> ppr (breakLoc loc) <+>-                if null (onBreakCmd loc)-                   then Outputable.empty-                   else doubleQuotes (text (onBreakCmd loc))--recordBreak :: BreakLocation -> GHCi (Bool{- was already present -}, Int)-recordBreak brkLoc = do-   st <- getGHCiState-   let oldActiveBreaks = breaks st-   -- don't store the same break point twice-   case [ nm | (nm, loc) <- oldActiveBreaks, loc == brkLoc ] of-     (nm:_) -> return (True, nm)-     [] -> do-      let oldCounter = break_ctr st-          newCounter = oldCounter + 1-      setGHCiState $ st { break_ctr = newCounter,-                          breaks = (oldCounter, brkLoc) : oldActiveBreaks-                        }-      return (False, oldCounter)--newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> Ghc a }--reflectGHCi :: (Session, IORef GHCiState) -> GHCi a -> IO a-reflectGHCi (s, gs) m = unGhc (unGHCi m gs) s--reifyGHCi :: ((Session, IORef GHCiState) -> IO a) -> GHCi a-reifyGHCi f = GHCi f'-  where-    -- f' :: IORef GHCiState -> Ghc a-    f' gs = reifyGhc (f'' gs)-    -- f'' :: IORef GHCiState -> Session -> IO a-    f'' gs s = f (s, gs)--startGHCi :: GHCi a -> GHCiState -> Ghc a-startGHCi g state = do ref <- liftIO $ newIORef state; unGHCi g ref--instance Functor GHCi where-    fmap = liftM--instance Applicative GHCi where-    pure a = GHCi $ \_ -> pure a-    (<*>) = ap--instance Monad GHCi where-  (GHCi m) >>= k  =  GHCi $ \s -> m s >>= \a -> unGHCi (k a) s--class HasGhciState m where-    getGHCiState    :: m GHCiState-    setGHCiState    :: GHCiState -> m ()-    modifyGHCiState :: (GHCiState -> GHCiState) -> m ()--instance HasGhciState GHCi where-    getGHCiState      = GHCi $ \r -> liftIO $ readIORef r-    setGHCiState s    = GHCi $ \r -> liftIO $ writeIORef r s-    modifyGHCiState f = GHCi $ \r -> liftIO $ modifyIORef r f--instance (MonadTrans t, Monad m, HasGhciState m) => HasGhciState (t m) where-    getGHCiState    = lift getGHCiState-    setGHCiState    = lift . setGHCiState-    modifyGHCiState = lift . modifyGHCiState--liftGhc :: Ghc a -> GHCi a-liftGhc m = GHCi $ \_ -> m--instance MonadIO GHCi where-  liftIO = liftGhc . liftIO--instance HasDynFlags GHCi where-  getDynFlags = getSessionDynFlags--instance GhcMonad GHCi where-  setSession s' = liftGhc $ setSession s'-  getSession    = liftGhc $ getSession--instance HasDynFlags (InputT GHCi) where-  getDynFlags = lift getDynFlags--instance GhcMonad (InputT GHCi) where-  setSession = lift . setSession-  getSession = lift getSession--instance ExceptionMonad GHCi where-  gcatch m h = GHCi $ \r -> unGHCi m r `gcatch` (\e -> unGHCi (h e) r)-  gmask f =-      GHCi $ \s -> gmask $ \io_restore ->-                             let-                                g_restore (GHCi m) = GHCi $ \s' -> io_restore (m s')-                             in-                                unGHCi (f g_restore) s--instance Haskeline.MonadException Ghc where-  controlIO f = Ghc $ \s -> Haskeline.controlIO $ \(Haskeline.RunIO run) -> let-                    run' = Haskeline.RunIO (fmap (Ghc . const) . run . flip unGhc s)-                    in fmap (flip unGhc s) $ f run'--instance Haskeline.MonadException GHCi where-  controlIO f = GHCi $ \s -> Haskeline.controlIO $ \(Haskeline.RunIO run) -> let-                    run' = Haskeline.RunIO (fmap (GHCi . const) . run . flip unGHCi s)-                    in fmap (flip unGHCi s) $ f run'--instance ExceptionMonad (InputT GHCi) where-  gcatch = Haskeline.catch-  gmask f = Haskeline.liftIOOp gmask (f . Haskeline.liftIOOp_)--isOptionSet :: GHCiOption -> GHCi Bool-isOptionSet opt- = do st <- getGHCiState-      return (opt `elem` options st)--setOption :: GHCiOption -> GHCi ()-setOption opt- = do st <- getGHCiState-      setGHCiState (st{ options = opt : filter (/= opt) (options st) })--unsetOption :: GHCiOption -> GHCi ()-unsetOption opt- = do st <- getGHCiState-      setGHCiState (st{ options = filter (/= opt) (options st) })--printForUserNeverQualify :: GhcMonad m => SDoc -> m ()-printForUserNeverQualify doc = do-  dflags <- getDynFlags-  liftIO $ Outputable.printForUser dflags stdout neverQualify doc--printForUserModInfo :: GhcMonad m => GHC.ModuleInfo -> SDoc -> m ()-printForUserModInfo info doc = do-  dflags <- getDynFlags-  mUnqual <- GHC.mkPrintUnqualifiedForModule info-  unqual <- maybe GHC.getPrintUnqual return mUnqual-  liftIO $ Outputable.printForUser dflags stdout unqual doc--printForUser :: GhcMonad m => SDoc -> m ()-printForUser doc = do-  unqual <- GHC.getPrintUnqual-  dflags <- getDynFlags-  liftIO $ Outputable.printForUser dflags stdout unqual doc--printForUserPartWay :: SDoc -> GHCi ()-printForUserPartWay doc = do-  unqual <- GHC.getPrintUnqual-  dflags <- getDynFlags-  liftIO $ Outputable.printForUserPartWay dflags stdout (pprUserLength dflags) unqual doc---- | Run a single Haskell expression-runStmt :: String -> GHC.SingleStep -> GHCi (Maybe GHC.ExecResult)-runStmt expr step = do-  st <- getGHCiState-  GHC.handleSourceError (\e -> do GHC.printException e; return Nothing) $ do-    let opts = GHC.execOptions-                  { GHC.execSourceFile = progname st-                  , GHC.execLineNumber = line_number st-                  , GHC.execSingleStep = step-                  , GHC.execWrap = \fhv -> EvalApp (EvalThis (evalWrapper st))-                                                   (EvalThis fhv) }-    Just <$> GHC.execStmt expr opts--runDecls :: String -> GHCi (Maybe [GHC.Name])-runDecls decls = do-  st <- getGHCiState-  reifyGHCi $ \x ->-    withProgName (progname st) $-    withArgs (args st) $-      reflectGHCi x $ do-        GHC.handleSourceError (\e -> do GHC.printException e;-                                        return Nothing) $ do-          r <- GHC.runDeclsWithLocation (progname st) (line_number st) decls-          return (Just r)--resume :: (SrcSpan -> Bool) -> GHC.SingleStep -> GHCi GHC.ExecResult-resume canLogSpan step = do-  st <- getGHCiState-  reifyGHCi $ \x ->-    withProgName (progname st) $-    withArgs (args st) $-      reflectGHCi x $ do-        GHC.resumeExec canLogSpan step---- ----------------------------------------------------------------------------- timing & statistics--timeIt :: (a -> Maybe Integer) -> InputT GHCi a -> InputT GHCi a-timeIt getAllocs action-  = do b <- lift $ isOptionSet ShowTiming-       if not b-          then action-          else do time1   <- liftIO $ getCurrentTime-                  a <- action-                  let allocs = getAllocs a-                  time2   <- liftIO $ getCurrentTime-                  dflags  <- getDynFlags-                  let period = time2 `diffUTCTime` time1-                  liftIO $ printTimes dflags allocs (realToFrac period)-                  return a--printTimes :: DynFlags -> Maybe Integer -> Double -> IO ()-printTimes dflags mallocs secs-   = do let secs_str = showFFloat (Just 2) secs-        putStrLn (showSDoc dflags (-                 parens (text (secs_str "") <+> text "secs" <> comma <+>-                         case mallocs of-                           Nothing -> empty-                           Just allocs ->-                             text (separateThousands allocs) <+> text "bytes")))-  where-    separateThousands n = reverse . sep . reverse . show $ n-      where sep n'-              | length n' <= 3 = n'-              | otherwise = take 3 n' ++ "," ++ sep (drop 3 n')---------------------------------------------------------------------------------- reverting CAFs--revertCAFs :: GHCi ()-revertCAFs = do-  liftIO rts_revertCAFs-  s <- getGHCiState-  when (not (ghc_e s)) turnOffBuffering-     -- Have to turn off buffering again, because we just-     -- reverted stdout, stderr & stdin to their defaults.--foreign import ccall "revertCAFs" rts_revertCAFs  :: IO ()-        -- Make it "safe", just in case---------------------------------------------------------------------------------- To flush buffers for the *interpreted* computation we need--- to refer to *its* stdout/stderr handles---- | Compile "hFlush stdout; hFlush stderr" once, so we can use it repeatedly-initInterpBuffering :: Ghc (ForeignHValue, ForeignHValue)-initInterpBuffering = do-  nobuf <- GHC.compileExprRemote $-   "do { System.IO.hSetBuffering System.IO.stdin System.IO.NoBuffering; " ++-       " System.IO.hSetBuffering System.IO.stdout System.IO.NoBuffering; " ++-       " System.IO.hSetBuffering System.IO.stderr System.IO.NoBuffering }"-  flush <- GHC.compileExprRemote $-   "do { System.IO.hFlush System.IO.stdout; " ++-       " System.IO.hFlush System.IO.stderr }"-  return (nobuf, flush)---- | Invoke "hFlush stdout; hFlush stderr" in the interpreter-flushInterpBuffers :: GHCi ()-flushInterpBuffers = do-  st <- getGHCiState-  hsc_env <- GHC.getSession-  liftIO $ evalIO hsc_env (flushStdHandles st)---- | Turn off buffering for stdin, stdout, and stderr in the interpreter-turnOffBuffering :: GHCi ()-turnOffBuffering = do-  st <- getGHCiState-  turnOffBuffering_ (noBuffering st)--turnOffBuffering_ :: GhcMonad m => ForeignHValue -> m ()-turnOffBuffering_ fhv = do-  hsc_env <- getSession-  liftIO $ evalIO hsc_env fhv--mkEvalWrapper :: GhcMonad m => String -> [String] ->  m ForeignHValue-mkEvalWrapper progname args =-  GHC.compileExprRemote $-    "\\m -> System.Environment.withProgName " ++ show progname ++-    "(System.Environment.withArgs " ++ show args ++ " m)"
− src-bin-821/Clash/GHCi/UI/Tags.hs
@@ -1,215 +0,0 @@------------------------------------------------------------------------------------ GHCi's :ctags and :etags commands------ (c) The GHC Team 2005-2007-----------------------------------------------------------------------------------{-# OPTIONS_GHC -fno-warn-name-shadowing #-}-module Clash.GHCi.UI.Tags (-  createCTagsWithLineNumbersCmd,-  createCTagsWithRegExesCmd,-  createETagsFileCmd-) where--import Exception-import GHC-import Clash.GHCi.UI.Monad-import Outputable---- ToDo: figure out whether we need these, and put something appropriate--- into the GHC API instead-import Name (nameOccName)-import OccName (pprOccName)-import ConLike-import MonadUtils--import Data.Function-import Data.Maybe-import Data.Ord-import DriverPhases-import Panic-import Data.List-import Control.Monad-import System.Directory-import System.IO-import System.IO.Error---------------------------------------------------------------------------------- create tags file for currently loaded modules.--createCTagsWithLineNumbersCmd, createCTagsWithRegExesCmd,-  createETagsFileCmd :: String -> GHCi ()--createCTagsWithLineNumbersCmd ""   =-  ghciCreateTagsFile CTagsWithLineNumbers "tags"-createCTagsWithLineNumbersCmd file =-  ghciCreateTagsFile CTagsWithLineNumbers file--createCTagsWithRegExesCmd ""   =-  ghciCreateTagsFile CTagsWithRegExes "tags"-createCTagsWithRegExesCmd file =-  ghciCreateTagsFile CTagsWithRegExes file--createETagsFileCmd ""    = ghciCreateTagsFile ETags "TAGS"-createETagsFileCmd file  = ghciCreateTagsFile ETags file--data TagsKind = ETags | CTagsWithLineNumbers | CTagsWithRegExes--ghciCreateTagsFile :: TagsKind -> FilePath -> GHCi ()-ghciCreateTagsFile kind file = do-  createTagsFile kind file---- ToDo:---      - remove restriction that all modules must be interpreted---        (problem: we don't know source locations for entities unless---        we compiled the module.------      - extract createTagsFile so it can be used from the command-line---        (probably need to fix first problem before this is useful).----createTagsFile :: TagsKind -> FilePath -> GHCi ()-createTagsFile tagskind tagsFile = do-  graph <- GHC.getModuleGraph-  mtags <- mapM listModuleTags (map GHC.ms_mod graph)-  either_res <- liftIO $ collateAndWriteTags tagskind tagsFile $ concat mtags-  case either_res of-    Left e  -> liftIO $ hPutStrLn stderr $ ioeGetErrorString e-    Right _ -> return ()---listModuleTags :: GHC.Module -> GHCi [TagInfo]-listModuleTags m = do-  is_interpreted <- GHC.moduleIsInterpreted m-  -- should we just skip these?-  when (not is_interpreted) $-    let mName = GHC.moduleNameString (GHC.moduleName m) in-    throwGhcException (CmdLineError ("module '" ++ mName ++ "' is not interpreted"))-  mbModInfo <- GHC.getModuleInfo m-  case mbModInfo of-    Nothing -> return []-    Just mInfo -> do-       dflags <- getDynFlags-       mb_print_unqual <- GHC.mkPrintUnqualifiedForModule mInfo-       let unqual = fromMaybe GHC.alwaysQualify mb_print_unqual-       let names = fromMaybe [] $GHC.modInfoTopLevelScope mInfo-       let localNames = filter ((m==) . nameModule) names-       mbTyThings <- mapM GHC.lookupName localNames-       return $! [ tagInfo dflags unqual exported kind name realLoc-                     | tyThing <- catMaybes mbTyThings-                     , let name = getName tyThing-                     , let exported = GHC.modInfoIsExportedName mInfo name-                     , let kind = tyThing2TagKind tyThing-                     , let loc = srcSpanStart (nameSrcSpan name)-                     , RealSrcLoc realLoc <- [loc]-                     ]--  where-    tyThing2TagKind (AnId _)                 = 'v'-    tyThing2TagKind (AConLike RealDataCon{}) = 'd'-    tyThing2TagKind (AConLike PatSynCon{})   = 'p'-    tyThing2TagKind (ATyCon _)               = 't'-    tyThing2TagKind (ACoAxiom _)             = 'x'---data TagInfo = TagInfo-  { tagExported :: Bool -- is tag exported-  , tagKind :: Char   -- tag kind-  , tagName :: String -- tag name-  , tagFile :: String -- file name-  , tagLine :: Int    -- line number-  , tagCol :: Int     -- column number-  , tagSrcInfo :: Maybe (String,Integer)  -- source code line and char offset-  }----- get tag info, for later translation into Vim or Emacs style-tagInfo :: DynFlags -> PrintUnqualified -> Bool -> Char -> Name -> RealSrcLoc-        -> TagInfo-tagInfo dflags unqual exported kind name loc-    = TagInfo exported kind-        (showSDocForUser dflags unqual $ pprOccName (nameOccName name))-        (showSDocForUser dflags unqual $ ftext (srcLocFile loc))-        (srcLocLine loc) (srcLocCol loc) Nothing---- throw an exception when someone tries to overwrite existing source file (fix for #10989)-writeTagsSafely :: FilePath -> String -> IO ()-writeTagsSafely file str = do-    dfe <- doesFileExist file-    if dfe && isSourceFilename file-        then throwGhcException (CmdLineError (file ++ " is existing source file. " ++-             "Please specify another file name to store tags data"))-        else writeFile file str--collateAndWriteTags :: TagsKind -> FilePath -> [TagInfo] -> IO (Either IOError ())--- ctags style with the Ex exresion being just the line number, Vim et al-collateAndWriteTags CTagsWithLineNumbers file tagInfos = do-  let tags = unlines $ sort $ map showCTag tagInfos-  tryIO (writeTagsSafely file tags)---- ctags style with the Ex exresion being a regex searching the line, Vim et al-collateAndWriteTags CTagsWithRegExes file tagInfos = do -- ctags style, Vim et al-  tagInfoGroups <- makeTagGroupsWithSrcInfo tagInfos-  let tags = unlines $ sort $ map showCTag $concat tagInfoGroups-  tryIO (writeTagsSafely file tags)--collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs-  tagInfoGroups <- makeTagGroupsWithSrcInfo $filter tagExported tagInfos-  let tagGroups = map processGroup tagInfoGroups-  tryIO (writeTagsSafely file $ concat tagGroups)--  where-    processGroup [] = throwGhcException (CmdLineError "empty tag file group??")-    processGroup group@(tagInfo:_) =-      let tags = unlines $ map showETag group in-      "\x0c\n" ++ tagFile tagInfo ++ "," ++ show (length tags) ++ "\n" ++ tags---makeTagGroupsWithSrcInfo :: [TagInfo] -> IO [[TagInfo]]-makeTagGroupsWithSrcInfo tagInfos = do-  let groups = groupBy ((==) `on` tagFile) $ sortBy (comparing tagFile) tagInfos-  mapM addTagSrcInfo groups--  where-    addTagSrcInfo [] = throwGhcException (CmdLineError "empty tag file group??")-    addTagSrcInfo group@(tagInfo:_) = do-      file <- readFile $tagFile tagInfo-      let sortedGroup = sortBy (comparing tagLine) group-      return $ perFile sortedGroup 1 0 $ lines file--    perFile allTags@(tag:tags) cnt pos allLs@(l:ls)-     | tagLine tag > cnt =-         perFile allTags (cnt+1) (pos+fromIntegral(length l)) ls-     | tagLine tag == cnt =-         tag{ tagSrcInfo = Just(l,pos) } : perFile tags cnt pos allLs-    perFile _ _ _ _ = []----- ctags format, for Vim et al-showCTag :: TagInfo -> String-showCTag ti =-  tagName ti ++ "\t" ++ tagFile ti ++ "\t" ++ tagCmd ++ ";\"\t" ++-    tagKind ti : ( if tagExported ti then "" else "\tfile:" )--  where-    tagCmd =-      case tagSrcInfo ti of-        Nothing -> show $tagLine ti-        Just (srcLine,_) -> "/^"++ foldr escapeSlashes [] srcLine ++"$/"--      where-        escapeSlashes '/' r = '\\' : '/' : r-        escapeSlashes '\\' r = '\\' : '\\' : r-        escapeSlashes c r = c : r----- etags format, for Emacs/XEmacs-showETag :: TagInfo -> String-showETag TagInfo{ tagName = tag, tagLine = lineNo, tagCol = colNo,-                  tagSrcInfo = Just (srcLine,charPos) }-    =  take (colNo - 1) srcLine ++ tag-    ++ "\x7f" ++ tag-    ++ "\x01" ++ show lineNo-    ++ "," ++ show charPos-showETag _ = throwGhcException (CmdLineError "missing source file info in showETag")
− src-bin-821/Clash/Main.hs
@@ -1,1016 +0,0 @@-{-# LANGUAGE CPP, NondecreasingIndentation, ScopedTypeVariables, TupleSections #-}-{-# OPTIONS -fno-warn-incomplete-patterns -optc-DNON_POSIX_SOURCE #-}------------------------------------------------------------------------------------- GHC Driver program------ (c) The University of Glasgow 2005-----------------------------------------------------------------------------------module Clash.Main (defaultMain) where---- For Int/Word size-#include "MachDeps.h"---- The official GHC API-import qualified GHC-import GHC              ( -- DynFlags(..), HscTarget(..),-                          -- GhcMode(..), GhcLink(..),-                          Ghc, GhcMonad(..),-                          LoadHowMuch(..) )-import CmdLineParser---- Implementations of the various modes (--show-iface, mkdependHS. etc.)-import LoadIface        ( showIface )-import HscMain          ( newHscEnv )-import DriverPipeline   ( oneShot, compileFile )-import DriverMkDepend   ( doMkDependHS )-import DriverBkp   ( doBackpack )-#if defined(GHCI)-import Clash.GHCi.UI    ( interactiveUI, ghciWelcomeMsg, defaultGhciSettings )-#endif---- Frontend plugins-#if defined(GHCI)-import DynamicLoading   ( loadFrontendPlugin )-import Plugins-#else-import DynamicLoading   ( pluginError )-#endif-import Module           ( ModuleName )----- Various other random stuff that we need-import Config-import Constants-import HscTypes-import Packages         ( pprPackages, pprPackagesSimple )-import DriverPhases-import BasicTypes       ( failed )-import DynFlags-import ErrUtils-import FastString-import Outputable-import SrcLoc-import Util-import Panic-import UniqSupply-import MonadUtils       ( liftIO )---- Imports for --abi-hash-import LoadIface           ( loadUserInterface )-import Module              ( mkModuleName )-import Finder              ( findImportedModule, cannotFindModule )-import TcRnMonad           ( initIfaceCheck )-import Binary              ( openBinMem, put_ )-import BinFingerprint      ( fingerprintBinMem )---- Standard Haskell libraries-import System.IO-import System.Environment-import System.Exit-import System.FilePath-import Control.Monad-import Data.Char-import Data.List-import Data.Maybe---- clash additions-import           Paths_clash_ghc-import           Clash.GHCi.UI (makeHDL)-import           Exception (gcatch)-import           Data.IORef (IORef, newIORef, readIORef)-import qualified Data.Version (showVersion)--import qualified Clash.Backend-import           Clash.Backend.SystemVerilog (SystemVerilogState)-import           Clash.Backend.VHDL    (VHDLState)-import           Clash.Backend.Verilog (VerilogState)-import           Clash.Driver.Types (ClashOpts (..), defClashOpts)-import           Clash.GHC.ClashFlags-import           Clash.Netlist.BlackBox.Types (HdlSyn (..))-import           Clash.Util (clashLibVersion)-import           Clash.GHC.LoadModules (ghcLibDir, wantedLanguageExtensions)-import           Clash.GHC.Util (handleClashException)---------------------------------------------------------------------------------- ToDo:---- time commands when run with -v--- user ways--- Win32 support: proper signal handling--- reading the package configuration file is too slow--- -K<size>---------------------------------------------------------------------------------- GHC's command-line interface--defaultMain :: [String] -> IO ()-defaultMain = flip withArgs $ do-   initGCStatistics -- See Note [-Bsymbolic and hooks]-   hSetBuffering stdout LineBuffering-   hSetBuffering stderr LineBuffering--   -- Handle GHC-specific character encoding flags, allowing us to control how-   -- GHC produces output regardless of OS.-   env <- getEnvironment-   case lookup "GHC_CHARENC" env of-    Just "UTF-8" -> do-     hSetEncoding stdout utf8-     hSetEncoding stderr utf8-    _ -> do-     -- Avoid GHC erroring out when trying to display unhandled characters-     hSetTranslit stdout-     hSetTranslit stderr--   GHC.defaultErrorHandler defaultFatalMessager defaultFlushOut $ do-    argv0 <- getArgs-    libDir <- ghcLibDir--    let argv1 = map (mkGeneralLocated "on the commandline") argv0-    r <- newIORef defClashOpts-    (argv2, clashFlagWarnings) <- parseClashFlags r argv1--    -- 2. Parse the "mode" flags (--make, --interactive etc.)-    (mode, argv3, modeFlagWarnings) <- parseModeFlags argv2-    let flagWarnings = modeFlagWarnings ++ clashFlagWarnings--    -- If all we want to do is something like showing the version number-    -- then do it now, before we start a GHC session etc. This makes-    -- getting basic information much more resilient.--    -- In particular, if we wait until later before giving the version-    -- number then bootstrapping gets confused, as it tries to find out-    -- what version of GHC it's using before package.conf exists, so-    -- starting the session fails.-    case mode of-        Left preStartupMode ->-            do case preStartupMode of-                   ShowSupportedExtensions   -> showSupportedExtensions-                   ShowVersion               -> showVersion-                   ShowNumVersion            -> putStrLn cProjectVersion-                   ShowOptions isInteractive -> showOptions isInteractive-        Right postStartupMode ->-            -- start our GHC session-            GHC.runGhc (Just libDir) $ do--            dflags <- GHC.getSessionDynFlags-            let dflagsExtra = wantedLanguageExtensions dflags--                ghcTyLitNormPlugin = GHC.mkModuleName "GHC.TypeLits.Normalise"-                ghcTyLitExtrPlugin = GHC.mkModuleName "GHC.TypeLits.Extra.Solver"-                ghcTyLitKNPlugin   = GHC.mkModuleName "GHC.TypeLits.KnownNat.Solver"-                dflagsExtra1 = dflagsExtra-                                  { DynFlags.pluginModNames = nub $-                                      ghcTyLitNormPlugin : ghcTyLitExtrPlugin :-                                      ghcTyLitKNPlugin :-                                      DynFlags.pluginModNames dflagsExtra-                                  }--            case postStartupMode of-                Left preLoadMode ->-                    liftIO $ do-                        case preLoadMode of-                            ShowInfo               -> showInfo dflagsExtra1-                            ShowGhcUsage           -> showGhcUsage  dflagsExtra1-                            ShowGhciUsage          -> showGhciUsage dflagsExtra1-                            PrintWithDynFlags f    -> putStrLn (f dflagsExtra1)-                Right postLoadMode ->-                    main' postLoadMode dflagsExtra1 argv3 flagWarnings r---main' :: PostLoadMode -> DynFlags -> [Located String] -> [Located String]-      -> IORef ClashOpts-      -> Ghc ()-main' postLoadMode dflags0 args flagWarnings clashOpts = do-  -- set the default GhcMode, HscTarget and GhcLink.  The HscTarget-  -- can be further adjusted on a module by module basis, using only-  -- the -fvia-C and -fasm flags.  If the default HscTarget is not-  -- HscC or HscAsm, -fvia-C and -fasm have no effect.-  let dflt_target = hscTarget dflags0-      (mode, lang, link)-         = case postLoadMode of-               DoInteractive   -> (CompManager, HscInterpreted, LinkInMemory)-               DoEval _        -> (CompManager, HscInterpreted, LinkInMemory)-               DoMake          -> (CompManager, dflt_target,    LinkBinary)-               DoBackpack      -> (CompManager, dflt_target,    LinkBinary)-               DoMkDependHS    -> (MkDepend,    dflt_target,    LinkBinary)-               DoAbiHash       -> (OneShot,     dflt_target,    LinkBinary)-               DoVHDL          -> (CompManager, HscNothing,     NoLink)-               DoVerilog       -> (CompManager, HscNothing,     NoLink)-               DoSystemVerilog -> (CompManager, HscNothing,     NoLink)-               _               -> (OneShot,     dflt_target,    LinkBinary)--  let dflags1 = dflags0{ ghcMode   = mode,-                         hscTarget = lang,-                         ghcLink   = link,-                         verbosity = case postLoadMode of-                                         DoEval _ -> 0-                                         _other   -> 1-                        }--      -- turn on -fimplicit-import-qualified for GHCi now, so that it-      -- can be overriden from the command-line-      -- XXX: this should really be in the interactive DynFlags, but-      -- we don't set that until later in interactiveUI-      dflags2  | DoInteractive <- postLoadMode = imp_qual_enabled-               | DoEval _      <- postLoadMode = imp_qual_enabled-               | otherwise                     = dflags1-        where imp_qual_enabled = dflags1 `gopt_set` Opt_ImplicitImportQualified--        -- The rest of the arguments are "dynamic"-        -- Leftover ones are presumably files-  (dflags3, fileish_args, dynamicFlagWarnings) <--      GHC.parseDynamicFlags dflags2 args--  let dflags4 = case lang of-                HscInterpreted | not (gopt Opt_ExternalInterpreter dflags3) ->-                    let platform = targetPlatform dflags3-                        dflags3a = updateWays $ dflags3 { ways = interpWays }-                        dflags3b = foldl gopt_set dflags3a-                                 $ concatMap (wayGeneralFlags platform)-                                             interpWays-                        dflags3c = foldl gopt_unset dflags3b-                                 $ concatMap (wayUnsetGeneralFlags platform)-                                             interpWays-                    in dflags3c-                _ ->-                    dflags3--  GHC.prettyPrintGhcErrors dflags4 $ do--  let flagWarnings' = flagWarnings ++ dynamicFlagWarnings--  handleSourceError (\e -> do-       GHC.printException e-       liftIO $ exitWith (ExitFailure 1)) $ do-         liftIO $ handleFlagWarnings dflags4 flagWarnings'--  liftIO $ showBanner postLoadMode dflags4--  let-     -- To simplify the handling of filepaths, we normalise all filepaths right-     -- away - e.g., for win32 platforms, backslashes are converted-     -- into forward slashes.-    normal_fileish_paths = map (normalise . unLoc) fileish_args-    (srcs, objs)         = partition_args normal_fileish_paths [] []--    dflags5 = dflags4 { ldInputs = map (FileOption "") objs-                                   ++ ldInputs dflags4 }--  -- we've finished manipulating the DynFlags, update the session-  _ <- GHC.setSessionDynFlags dflags5-  dflags6 <- GHC.getSessionDynFlags-  hsc_env <- GHC.getSession--        ---------------- Display configuration ------------  case verbosity dflags6 of-    v | v == 4 -> liftIO $ dumpPackagesSimple dflags6-      | v >= 5 -> liftIO $ dumpPackages dflags6-      | otherwise -> return ()--  liftIO $ initUniqSupply (initialUnique dflags6) (uniqueIncrement dflags6)-        ---------------- Final sanity checking ------------  liftIO $ checkOptions postLoadMode dflags6 srcs objs--  ---------------- Do the business ------------  handleSourceError (\e -> do-       GHC.printException e-       liftIO $ exitWith (ExitFailure 1)) $ do-    clashOpts' <- liftIO (readIORef clashOpts)-    let clash fun = gcatch (fun clashOpts srcs) (handleClashException dflags6 clashOpts')-    case postLoadMode of-       ShowInterface f        -> liftIO $ doShowIface dflags6 f-       DoMake                 -> doMake srcs-       DoMkDependHS           -> doMkDependHS (map fst srcs)-       StopBefore p           -> liftIO (oneShot hsc_env p srcs)-       DoInteractive          -> ghciUI clashOpts srcs Nothing-       DoEval exprs           -> ghciUI clashOpts srcs $ Just $ reverse exprs-       DoAbiHash              -> abiHash (map fst srcs)-       ShowPackages           -> liftIO $ showPackages dflags6-       DoFrontend f           -> doFrontend f srcs-       DoVHDL                 -> clash makeVHDL-       DoVerilog              -> clash makeVerilog-       DoSystemVerilog        -> clash makeSystemVerilog-       DoBackpack             -> doBackpack (map fst srcs)--  liftIO $ dumpFinalStats dflags6--ghciUI :: IORef ClashOpts -> [(FilePath, Maybe Phase)] -> Maybe [String] -> Ghc ()-#if !defined(GHCI)-ghciUI _ _ _ = throwGhcException (CmdLineError "not built for interactive use")-#else-ghciUI opts  = interactiveUI (defaultGhciSettings opts)-#endif---- -------------------------------------------------------------------------------- Splitting arguments into source files and object files.  This is where we--- interpret the -x <suffix> option, and attach a (Maybe Phase) to each source--- file indicating the phase specified by the -x option in force, if any.--partition_args :: [String] -> [(String, Maybe Phase)] -> [String]-               -> ([(String, Maybe Phase)], [String])-partition_args [] srcs objs = (reverse srcs, reverse objs)-partition_args ("-x":suff:args) srcs objs-  | "none" <- suff      = partition_args args srcs objs-  | StopLn <- phase     = partition_args args srcs (slurp ++ objs)-  | otherwise           = partition_args rest (these_srcs ++ srcs) objs-        where phase = startPhase suff-              (slurp,rest) = break (== "-x") args-              these_srcs = zip slurp (repeat (Just phase))-partition_args (arg:args) srcs objs-  | looks_like_an_input arg = partition_args args ((arg,Nothing):srcs) objs-  | otherwise               = partition_args args srcs (arg:objs)--    {--      We split out the object files (.o, .dll) and add them-      to ldInputs for use by the linker.--      The following things should be considered compilation manager inputs:--       - haskell source files (strings ending in .hs, .lhs or other-         haskellish extension),--       - module names (not forgetting hierarchical module names),--       - things beginning with '-' are flags that were not recognised by-         the flag parser, and we want them to generate errors later in-         checkOptions, so we class them as source files (#5921)--       - and finally we consider everything without an extension to be-         a comp manager input, as shorthand for a .hs or .lhs filename.--      Everything else is considered to be a linker object, and passed-      straight through to the linker.-    -}-looks_like_an_input :: String -> Bool-looks_like_an_input m =  isSourceFilename m-                      || looksLikeModuleName m-                      || "-" `isPrefixOf` m-                      || not (hasExtension m)---- -------------------------------------------------------------------------------- Option sanity checks---- | Ensure sanity of options.------ Throws 'UsageError' or 'CmdLineError' if not.-checkOptions :: PostLoadMode -> DynFlags -> [(String,Maybe Phase)] -> [String] -> IO ()-     -- Final sanity checking before kicking off a compilation (pipeline).-checkOptions mode dflags srcs objs = do-     -- Complain about any unknown flags-   let unknown_opts = [ f | (f@('-':_), _) <- srcs ]-   when (notNull unknown_opts) (unknownFlagsErr unknown_opts)--   when (notNull (filter wayRTSOnly (ways dflags))-         && isInterpretiveMode mode) $-        hPutStrLn stderr ("Warning: -debug, -threaded and -ticky are ignored by GHCi")--        -- -prof and --interactive are not a good combination-   when ((filter (not . wayRTSOnly) (ways dflags) /= interpWays)-         && isInterpretiveMode mode-         && not (gopt Opt_ExternalInterpreter dflags)) $-      do throwGhcException (UsageError-              "-fexternal-interpreter is required when using --interactive with a non-standard way (-prof, -static, or -dynamic).")-        -- -ohi sanity check-   if (isJust (outputHi dflags) &&-      (isCompManagerMode mode || srcs `lengthExceeds` 1))-        then throwGhcException (UsageError "-ohi can only be used when compiling a single source file")-        else do--        -- -o sanity checking-   if (srcs `lengthExceeds` 1 && isJust (outputFile dflags)-         && not (isLinkMode mode))-        then throwGhcException (UsageError "can't apply -o to multiple source files")-        else do--   let not_linking = not (isLinkMode mode) || isNoLink (ghcLink dflags)--   when (not_linking && not (null objs)) $-        hPutStrLn stderr ("Warning: the following files would be used as linker inputs, but linking is not being done: " ++ unwords objs)--        -- Check that there are some input files-        -- (except in the interactive case)-   if null srcs && (null objs || not_linking) && needsInputsMode mode-        then throwGhcException (UsageError "no input files")-        else do--   case mode of-      StopBefore HCc | hscTarget dflags /= HscC-        -> throwGhcException $ UsageError $-           "the option -C is only available with an unregisterised GHC"-      _ -> return ()--     -- Verify that output files point somewhere sensible.-   verifyOutputFiles dflags---- Compiler output options---- Called to verify that the output files point somewhere valid.------ The assumption is that the directory portion of these output--- options will have to exist by the time 'verifyOutputFiles'--- is invoked.------ We create the directories for -odir, -hidir, -outputdir etc. ourselves if--- they don't exist, so don't check for those here (#2278).-verifyOutputFiles :: DynFlags -> IO ()-verifyOutputFiles dflags = do-  let ofile = outputFile dflags-  when (isJust ofile) $ do-     let fn = fromJust ofile-     flg <- doesDirNameExist fn-     when (not flg) (nonExistentDir "-o" fn)-  let ohi = outputHi dflags-  when (isJust ohi) $ do-     let hi = fromJust ohi-     flg <- doesDirNameExist hi-     when (not flg) (nonExistentDir "-ohi" hi)- where-   nonExistentDir flg dir =-     throwGhcException (CmdLineError ("error: directory portion of " ++-                             show dir ++ " does not exist (used with " ++-                             show flg ++ " option.)"))---------------------------------------------------------------------------------- GHC modes of operation--type Mode = Either PreStartupMode PostStartupMode-type PostStartupMode = Either PreLoadMode PostLoadMode--data PreStartupMode-  = ShowVersion                          -- ghc -V/--version-  | ShowNumVersion                       -- ghc --numeric-version-  | ShowSupportedExtensions              -- ghc --supported-extensions-  | ShowOptions Bool {- isInteractive -} -- ghc --show-options--showVersionMode, showNumVersionMode, showSupportedExtensionsMode, showOptionsMode :: Mode-showVersionMode             = mkPreStartupMode ShowVersion-showNumVersionMode          = mkPreStartupMode ShowNumVersion-showSupportedExtensionsMode = mkPreStartupMode ShowSupportedExtensions-showOptionsMode             = mkPreStartupMode (ShowOptions False)--mkPreStartupMode :: PreStartupMode -> Mode-mkPreStartupMode = Left--isShowVersionMode :: Mode -> Bool-isShowVersionMode (Left ShowVersion) = True-isShowVersionMode _ = False--isShowNumVersionMode :: Mode -> Bool-isShowNumVersionMode (Left ShowNumVersion) = True-isShowNumVersionMode _ = False--data PreLoadMode-  = ShowGhcUsage                           -- ghc -?-  | ShowGhciUsage                          -- ghci -?-  | ShowInfo                               -- ghc --info-  | PrintWithDynFlags (DynFlags -> String) -- ghc --print-foo--showGhcUsageMode, showGhciUsageMode, showInfoMode :: Mode-showGhcUsageMode = mkPreLoadMode ShowGhcUsage-showGhciUsageMode = mkPreLoadMode ShowGhciUsage-showInfoMode = mkPreLoadMode ShowInfo--printSetting :: String -> Mode-printSetting k = mkPreLoadMode (PrintWithDynFlags f)-    where f dflags = fromMaybe (panic ("Setting not found: " ++ show k))-                   $ lookup k (compilerInfo dflags)--mkPreLoadMode :: PreLoadMode -> Mode-mkPreLoadMode = Right . Left--isShowGhcUsageMode :: Mode -> Bool-isShowGhcUsageMode (Right (Left ShowGhcUsage)) = True-isShowGhcUsageMode _ = False--isShowGhciUsageMode :: Mode -> Bool-isShowGhciUsageMode (Right (Left ShowGhciUsage)) = True-isShowGhciUsageMode _ = False--data PostLoadMode-  = ShowInterface FilePath  -- ghc --show-iface-  | DoMkDependHS            -- ghc -M-  | StopBefore Phase        -- ghc -E | -C | -S-                            -- StopBefore StopLn is the default-  | DoMake                  -- ghc --make-  | DoBackpack              -- ghc --backpack foo.bkp-  | DoInteractive           -- ghc --interactive-  | DoEval [String]         -- ghc -e foo -e bar => DoEval ["bar", "foo"]-  | DoAbiHash               -- ghc --abi-hash-  | ShowPackages            -- ghc --show-packages-  | DoFrontend ModuleName   -- ghc --frontend Plugin.Module-  | DoVHDL                  -- ghc --vhdl-  | DoVerilog               -- ghc --verilog-  | DoSystemVerilog         -- ghc --systemverilog--doMkDependHSMode, doMakeMode, doInteractiveMode,-  doAbiHashMode, showPackagesMode, doVHDLMode, doVerilogMode,-  doSystemVerilogMode :: Mode-doMkDependHSMode = mkPostLoadMode DoMkDependHS-doMakeMode = mkPostLoadMode DoMake-doInteractiveMode = mkPostLoadMode DoInteractive-doAbiHashMode = mkPostLoadMode DoAbiHash-showPackagesMode = mkPostLoadMode ShowPackages-doVHDLMode = mkPostLoadMode DoVHDL-doVerilogMode = mkPostLoadMode DoVerilog-doSystemVerilogMode = mkPostLoadMode DoSystemVerilog--showInterfaceMode :: FilePath -> Mode-showInterfaceMode fp = mkPostLoadMode (ShowInterface fp)--stopBeforeMode :: Phase -> Mode-stopBeforeMode phase = mkPostLoadMode (StopBefore phase)--doEvalMode :: String -> Mode-doEvalMode str = mkPostLoadMode (DoEval [str])--doFrontendMode :: String -> Mode-doFrontendMode str = mkPostLoadMode (DoFrontend (mkModuleName str))--doBackpackMode :: Mode-doBackpackMode = mkPostLoadMode DoBackpack--mkPostLoadMode :: PostLoadMode -> Mode-mkPostLoadMode = Right . Right--isDoInteractiveMode :: Mode -> Bool-isDoInteractiveMode (Right (Right DoInteractive)) = True-isDoInteractiveMode _ = False--isStopLnMode :: Mode -> Bool-isStopLnMode (Right (Right (StopBefore StopLn))) = True-isStopLnMode _ = False--isDoMakeMode :: Mode -> Bool-isDoMakeMode (Right (Right DoMake)) = True-isDoMakeMode _ = False--isDoEvalMode :: Mode -> Bool-isDoEvalMode (Right (Right (DoEval _))) = True-isDoEvalMode _ = False--#if defined(GHCI)-isInteractiveMode :: PostLoadMode -> Bool-isInteractiveMode DoInteractive = True-isInteractiveMode _             = False-#endif---- isInterpretiveMode: byte-code compiler involved-isInterpretiveMode :: PostLoadMode -> Bool-isInterpretiveMode DoInteractive = True-isInterpretiveMode (DoEval _)    = True-isInterpretiveMode _             = False--needsInputsMode :: PostLoadMode -> Bool-needsInputsMode DoMkDependHS    = True-needsInputsMode (StopBefore _)  = True-needsInputsMode DoMake          = True-needsInputsMode DoVHDL          = True-needsInputsMode DoVerilog       = True-needsInputsMode DoSystemVerilog = True-needsInputsMode _               = False---- True if we are going to attempt to link in this mode.--- (we might not actually link, depending on the GhcLink flag)-isLinkMode :: PostLoadMode -> Bool-isLinkMode (StopBefore StopLn) = True-isLinkMode DoMake              = True-isLinkMode DoInteractive       = True-isLinkMode (DoEval _)          = True-isLinkMode _                   = False--isCompManagerMode :: PostLoadMode -> Bool-isCompManagerMode DoMake        = True-isCompManagerMode DoInteractive = True-isCompManagerMode (DoEval _)    = True-isCompManagerMode DoVHDL        = True-isCompManagerMode DoVerilog     = True-isCompManagerMode DoSystemVerilog = True-isCompManagerMode _             = False---- -------------------------------------------------------------------------------- Parsing the mode flag--parseModeFlags :: [Located String]-               -> IO (Mode,-                      [Located String],-                      [Located String])-parseModeFlags args = do-  let ((leftover, errs1, warns), (mModeFlag, errs2, flags')) =-          runCmdLine (processArgs mode_flags args)-                     (Nothing, [], [])-      mode = case mModeFlag of-             Nothing     -> doMakeMode-             Just (m, _) -> m--  -- See Note [Handling errors when parsing commandline flags]-  unless (null errs1 && null errs2) $ throwGhcException $ errorsToGhcException $-      map (("on the commandline", )) $ map unLoc errs1 ++ errs2--  return (mode, flags' ++ leftover, warns)--type ModeM = CmdLineP (Maybe (Mode, String), [String], [Located String])-  -- mode flags sometimes give rise to new DynFlags (eg. -C, see below)-  -- so we collect the new ones and return them.--mode_flags :: [Flag ModeM]-mode_flags =-  [  ------- help / version -----------------------------------------------    defFlag "?"                     (PassFlag (setMode showGhcUsageMode))-  , defFlag "-help"                 (PassFlag (setMode showGhcUsageMode))-  , defFlag "V"                     (PassFlag (setMode showVersionMode))-  , defFlag "-version"              (PassFlag (setMode showVersionMode))-  , defFlag "-numeric-version"      (PassFlag (setMode showNumVersionMode))-  , defFlag "-info"                 (PassFlag (setMode showInfoMode))-  , defFlag "-show-options"         (PassFlag (setMode showOptionsMode))-  , defFlag "-supported-languages"  (PassFlag (setMode showSupportedExtensionsMode))-  , defFlag "-supported-extensions" (PassFlag (setMode showSupportedExtensionsMode))-  , defFlag "-show-packages"        (PassFlag (setMode showPackagesMode))-  ] ++-  [ defFlag k'                      (PassFlag (setMode (printSetting k)))-  | k <- ["Project version",-          "Project Git commit id",-          "Booter version",-          "Stage",-          "Build platform",-          "Host platform",-          "Target platform",-          "Have interpreter",-          "Object splitting supported",-          "Have native code generator",-          "Support SMP",-          "Unregisterised",-          "Tables next to code",-          "RTS ways",-          "Leading underscore",-          "Debug on",-          "LibDir",-          "Global Package DB",-          "C compiler flags",-          "C compiler link flags",-          "ld flags"],-    let k' = "-print-" ++ map (replaceSpace . toLower) k-        replaceSpace ' ' = '-'-        replaceSpace c   = c-  ] ++-      ------- interfaces -----------------------------------------------------  [ defFlag "-show-iface"  (HasArg (\f -> setMode (showInterfaceMode f)-                                               "--show-iface"))--      ------- primary modes -------------------------------------------------  , defFlag "c"            (PassFlag (\f -> do setMode (stopBeforeMode StopLn) f-                                               addFlag "-no-link" f))-  , defFlag "M"            (PassFlag (setMode doMkDependHSMode))-  , defFlag "E"            (PassFlag (setMode (stopBeforeMode anyHsc)))-  , defFlag "C"            (PassFlag (setMode (stopBeforeMode HCc)))-  , defFlag "S"            (PassFlag (setMode (stopBeforeMode (As False))))-  , defFlag "-make"        (PassFlag (setMode doMakeMode))-  , defFlag "-backpack"    (PassFlag (setMode doBackpackMode))-  , defFlag "-interactive" (PassFlag (setMode doInteractiveMode))-  , defFlag "-abi-hash"    (PassFlag (setMode doAbiHashMode))-  , defFlag "e"            (SepArg   (\s -> setMode (doEvalMode s) "-e"))-  , defFlag "-frontend"    (SepArg   (\s -> setMode (doFrontendMode s) "-frontend"))-  , defFlag "-vhdl"        (PassFlag (setMode doVHDLMode))-  , defFlag "-verilog"     (PassFlag (setMode doVerilogMode))-  , defFlag "-systemverilog" (PassFlag (setMode doSystemVerilogMode))-  ]--setMode :: Mode -> String -> EwM ModeM ()-setMode newMode newFlag = liftEwM $ do-    (mModeFlag, errs, flags') <- getCmdLineState-    let (modeFlag', errs') =-            case mModeFlag of-            Nothing -> ((newMode, newFlag), errs)-            Just (oldMode, oldFlag) ->-                case (oldMode, newMode) of-                    -- -c/--make are allowed together, and mean --make -no-link-                    _ |  isStopLnMode oldMode && isDoMakeMode newMode-                      || isStopLnMode newMode && isDoMakeMode oldMode ->-                      ((doMakeMode, "--make"), [])--                    -- If we have both --help and --interactive then we-                    -- want showGhciUsage-                    _ | isShowGhcUsageMode oldMode &&-                        isDoInteractiveMode newMode ->-                            ((showGhciUsageMode, oldFlag), [])-                      | isShowGhcUsageMode newMode &&-                        isDoInteractiveMode oldMode ->-                            ((showGhciUsageMode, newFlag), [])--                    -- If we have both -e and --interactive then -e always wins-                    _ | isDoEvalMode oldMode &&-                        isDoInteractiveMode newMode ->-                            ((oldMode, oldFlag), [])-                      | isDoEvalMode newMode &&-                        isDoInteractiveMode oldMode ->-                            ((newMode, newFlag), [])--                    -- Otherwise, --help/--version/--numeric-version always win-                      | isDominantFlag oldMode -> ((oldMode, oldFlag), [])-                      | isDominantFlag newMode -> ((newMode, newFlag), [])-                    -- We need to accumulate eval flags like "-e foo -e bar"-                    (Right (Right (DoEval esOld)),-                     Right (Right (DoEval [eNew]))) ->-                        ((Right (Right (DoEval (eNew : esOld))), oldFlag),-                         errs)-                    -- Saying e.g. --interactive --interactive is OK-                    _ | oldFlag == newFlag -> ((oldMode, oldFlag), errs)--                    -- --interactive and --show-options are used together-                    (Right (Right DoInteractive), Left (ShowOptions _)) ->-                      ((Left (ShowOptions True),-                        "--interactive --show-options"), errs)-                    (Left (ShowOptions _), (Right (Right DoInteractive))) ->-                      ((Left (ShowOptions True),-                        "--show-options --interactive"), errs)-                    -- Otherwise, complain-                    _ -> let err = flagMismatchErr oldFlag newFlag-                         in ((oldMode, oldFlag), err : errs)-    putCmdLineState (Just modeFlag', errs', flags')-  where isDominantFlag f = isShowGhcUsageMode   f ||-                           isShowGhciUsageMode  f ||-                           isShowVersionMode    f ||-                           isShowNumVersionMode f--flagMismatchErr :: String -> String -> String-flagMismatchErr oldFlag newFlag-    = "cannot use `" ++ oldFlag ++  "' with `" ++ newFlag ++ "'"--addFlag :: String -> String -> EwM ModeM ()-addFlag s flag = liftEwM $ do-  (m, e, flags') <- getCmdLineState-  putCmdLineState (m, e, mkGeneralLocated loc s : flags')-    where loc = "addFlag by " ++ flag ++ " on the commandline"---- ------------------------------------------------------------------------------- Run --make mode--doMake :: [(String,Maybe Phase)] -> Ghc ()-doMake srcs  = do-    let (hs_srcs, non_hs_srcs) = partition isHaskellishTarget srcs--    hsc_env <- GHC.getSession--    -- if we have no haskell sources from which to do a dependency-    -- analysis, then just do one-shot compilation and/or linking.-    -- This means that "ghc Foo.o Bar.o -o baz" links the program as-    -- we expect.-    if (null hs_srcs)-       then liftIO (oneShot hsc_env StopLn srcs)-       else do--    o_files <- mapM (\x -> liftIO $ compileFile hsc_env StopLn x)-                 non_hs_srcs-    dflags <- GHC.getSessionDynFlags-    let dflags' = dflags { ldInputs = map (FileOption "") o_files-                                      ++ ldInputs dflags }-    _ <- GHC.setSessionDynFlags dflags'--    targets <- mapM (uncurry GHC.guessTarget) hs_srcs-    GHC.setTargets targets-    ok_flag <- GHC.load LoadAllTargets--    when (failed ok_flag) (liftIO $ exitWith (ExitFailure 1))-    return ()----- ------------------------------------------------------------------------------ --show-iface mode--doShowIface :: DynFlags -> FilePath -> IO ()-doShowIface dflags file = do-  hsc_env <- newHscEnv dflags-  showIface hsc_env file---- ------------------------------------------------------------------------------ Various banners and verbosity output.--showBanner :: PostLoadMode -> DynFlags -> IO ()-showBanner _postLoadMode dflags = do-   let verb = verbosity dflags--#if defined(GHCI)-   -- Show the GHCi banner-   when (isInteractiveMode _postLoadMode && verb >= 1) $ putStrLn ghciWelcomeMsg-#endif--   -- Display details of the configuration in verbose mode-   when (verb >= 2) $-    do hPutStr stderr "Glasgow Haskell Compiler, Version "-       hPutStr stderr cProjectVersion-       hPutStr stderr ", stage "-       hPutStr stderr cStage-       hPutStr stderr " booted by GHC version "-       hPutStrLn stderr cBooterVersion---- We print out a Read-friendly string, but a prettier one than the--- Show instance gives us-showInfo :: DynFlags -> IO ()-showInfo dflags = do-        let sq x = " [" ++ x ++ "\n ]"-        putStrLn $ sq $ intercalate "\n ," $ map show $ compilerInfo dflags--showSupportedExtensions :: IO ()-showSupportedExtensions = mapM_ putStrLn supportedLanguagesAndExtensions--showVersion :: IO ()-showVersion = putStrLn $ concat [ "Clash, version "-                                , Data.Version.showVersion Paths_clash_ghc.version-                                , " (using clash-lib, version: "-                                , Data.Version.showVersion clashLibVersion-                                , ")"-                                ]--showOptions :: Bool -> IO ()-showOptions isInteractive = putStr (unlines availableOptions)-    where-      availableOptions = concat [-        flagsForCompletion isInteractive,-        map ('-':) (getFlagNames mode_flags)-        ]-      getFlagNames opts         = map flagName opts--showGhcUsage :: DynFlags -> IO ()-showGhcUsage = showUsage False--showGhciUsage :: DynFlags -> IO ()-showGhciUsage = showUsage True--showUsage :: Bool -> DynFlags -> IO ()-showUsage ghci dflags = do-  let usage_path = if ghci then ghciUsagePath dflags-                           else ghcUsagePath dflags-  usage <- readFile usage_path-  dump usage-  where-     dump ""          = return ()-     dump ('$':'$':s) = putStr progName >> dump s-     dump (c:s)       = putChar c >> dump s--dumpFinalStats :: DynFlags -> IO ()-dumpFinalStats dflags =-  when (gopt Opt_D_faststring_stats dflags) $ dumpFastStringStats dflags--dumpFastStringStats :: DynFlags -> IO ()-dumpFastStringStats dflags = do-  buckets <- getFastStringTable-  let (entries, longest, has_z) = countFS 0 0 0 buckets-      msg = text "FastString stats:" $$-            nest 4 (vcat [text "size:           " <+> int (length buckets),-                          text "entries:        " <+> int entries,-                          text "longest chain:  " <+> int longest,-                          text "has z-encoding: " <+> (has_z `pcntOf` entries)-                         ])-        -- we usually get more "has z-encoding" than "z-encoded", because-        -- when we z-encode a string it might hash to the exact same string,-        -- which will is not counted as "z-encoded".  Only strings whose-        -- Z-encoding is different from the original string are counted in-        -- the "z-encoded" total.-  putMsg dflags msg-  where-   x `pcntOf` y = int ((x * 100) `quot` y) <> char '%'--countFS :: Int -> Int -> Int -> [[FastString]] -> (Int, Int, Int)-countFS entries longest has_z [] = (entries, longest, has_z)-countFS entries longest has_z (b:bs) =-  let-        len = length b-        longest' = max len longest-        entries' = entries + len-        has_zs = length (filter hasZEncoding b)-  in-        countFS entries' longest' (has_z + has_zs) bs--showPackages, dumpPackages, dumpPackagesSimple :: DynFlags -> IO ()-showPackages       dflags = putStrLn (showSDoc dflags (pprPackages dflags))-dumpPackages       dflags = putMsg dflags (pprPackages dflags)-dumpPackagesSimple dflags = putMsg dflags (pprPackagesSimple dflags)---- -------------------------------------------------------------------------------- Frontend plugin support--doFrontend :: ModuleName -> [(String, Maybe Phase)] -> Ghc ()-#if !defined(GHCI)-doFrontend modname _ = pluginError [modname]-#else-doFrontend modname srcs = do-    hsc_env <- getSession-    frontend_plugin <- liftIO $ loadFrontendPlugin hsc_env modname-    frontend frontend_plugin-      (reverse $ frontendPluginOpts (hsc_dflags hsc_env)) srcs-#endif---- -------------------------------------------------------------------------------- ABI hash support--{--        ghc --abi-hash Data.Foo System.Bar--Generates a combined hash of the ABI for modules Data.Foo and-System.Bar.  The modules must already be compiled, and appropriate -i-options may be necessary in order to find the .hi files.--This is used by Cabal for generating the ComponentId for a-package.  The ComponentId must change when the visible ABI of-the package chagnes, so during registration Cabal calls ghc --abi-hash-to get a hash of the package's ABI.--}---- | Print ABI hash of input modules.------ The resulting hash is the MD5 of the GHC version used (Trac #5328,--- see 'hiVersion') and of the existing ABI hash from each module (see--- 'mi_mod_hash').-abiHash :: [String] -- ^ List of module names-        -> Ghc ()-abiHash strs = do-  hsc_env <- getSession-  let dflags = hsc_dflags hsc_env--  liftIO $ do--  let find_it str = do-         let modname = mkModuleName str-         r <- findImportedModule hsc_env modname Nothing-         case r of-           Found _ m -> return m-           _error    -> throwGhcException $ CmdLineError $ showSDoc dflags $-                          cannotFindModule dflags modname r--  mods <- mapM find_it strs--  let get_iface modl = loadUserInterface False (text "abiHash") modl-  ifaces <- initIfaceCheck (text "abiHash") hsc_env $ mapM get_iface mods--  bh <- openBinMem (3*1024) -- just less than a block-  put_ bh hiVersion-    -- package hashes change when the compiler version changes (for now)-    -- see #5328-  mapM_ (put_ bh . mi_mod_hash) ifaces-  f <- fingerprintBinMem bh--  putStrLn (showPpr dflags f)---------------------------------------------------------------------------------- VHDL Generation--makeHDL' :: Clash.Backend.Backend backend => (Int -> HdlSyn -> Bool -> Maybe (Maybe Int) ->  backend)-         -> IORef ClashOpts -> [(String,Maybe Phase)] -> Ghc ()-makeHDL' _       _ []   = throwGhcException (CmdLineError "No input files")-makeHDL' backend r srcs = makeHDL backend r $ fmap fst srcs--makeVHDL :: IORef ClashOpts -> [(String, Maybe Phase)] -> Ghc ()-makeVHDL = makeHDL' (Clash.Backend.initBackend :: Int -> HdlSyn -> Bool -> Maybe (Maybe Int) ->  VHDLState)--makeVerilog ::  IORef ClashOpts -> [(String, Maybe Phase)] -> Ghc ()-makeVerilog = makeHDL' (Clash.Backend.initBackend :: Int -> HdlSyn -> Bool -> Maybe (Maybe Int) ->  VerilogState)--makeSystemVerilog ::  IORef ClashOpts -> [(String, Maybe Phase)] -> Ghc ()-makeSystemVerilog = makeHDL' (Clash.Backend.initBackend :: Int -> HdlSyn -> Bool -> Maybe (Maybe Int) -> SystemVerilogState)---- -------------------------------------------------------------------------------- Util--unknownFlagsErr :: [String] -> a-unknownFlagsErr fs = throwGhcException $ UsageError $ concatMap oneError fs-  where-    oneError f =-        "unrecognised flag: " ++ f ++ "\n" ++-        (case match f (nubSort allNonDeprecatedFlags) of-            [] -> ""-            suggs -> "did you mean one of:\n" ++ unlines (map ("  " ++) suggs))-    -- fixes #11789-    -- If the flag contains '=',-    -- this uses both the whole and the left side of '=' for comparing.-    match f allFlags-        | elem '=' f =-              let (flagsWithEq, flagsWithoutEq) = partition (elem '=') allFlags-                  fName = takeWhile (/= '=') f-              in (fuzzyMatch f flagsWithEq) ++ (fuzzyMatch fName flagsWithoutEq)-        | otherwise = fuzzyMatch f allFlags--{- Note [-Bsymbolic and hooks]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--Bsymbolic is a flag that prevents the binding of references to global-symbols to symbols outside the shared library being compiled (see `man-ld`). When dynamically linking, we don't use -Bsymbolic on the RTS-package: that is because we want hooks to be overridden by the user,-we don't want to constrain them to the RTS package.--Unfortunately this seems to have broken somehow on OS X: as a result,-defaultHooks (in hschooks.c) is not called, which does not initialize-the GC stats. As a result, this breaks things like `:set +s` in GHCi-(#8754). As a hacky workaround, we instead call 'defaultHooks'-directly to initalize the flags in the RTS.--A byproduct of this, I believe, is that hooks are likely broken on OS-X when dynamically linking. But this probably doesn't affect most-people since we're linking GHC dynamically, but most things themselves-link statically.--}--foreign import ccall safe "initGCStatistics"-  initGCStatistics :: IO ()
src-bin-841/Clash/GHCi/UI.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-} {-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MagicHash #-}@@ -6,8 +6,6 @@ {-# LANGUAGE NondecreasingIndentation #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE ViewPatterns #-}  {-# OPTIONS -fno-cse #-} -- -fno-cse is needed for GLOBAL_VAR's to behave properly@@ -175,7 +173,7 @@ ghciWelcomeMsg :: String ghciWelcomeMsg = "Clashi, version " ++ Data.Version.showVersion Paths_clash_ghc.version ++                  " (using clash-lib, version " ++ Data.Version.showVersion clashLibVersion ++-                 "):\nhttp://www.clash-lang.org/  :? for help"+                 "):\nhttps://clash-lang.org/  :? for help"  ghciCommands :: IORef ClashOpts -> [Command] ghciCommands opts = map mkCmd [@@ -625,30 +623,36 @@   case maybe_exprs of         Nothing ->           do+            -- Set different defaulting rules (See #280)+            runGHCiExpressions ["default ((),[],Integer,Int,Double,String)"]             -- enter the interactive loop             runGHCiInput $ runCommands $ nextInputLine show_prompt is_tty         Just exprs -> do             -- just evaluate the expression we were given-            enqueueCommands exprs-            let hdle e = do st <- getGHCiState-                            -- flush the interpreter's stdout/stderr on exit (#3890)-                            flushInterpBuffers-                            -- Jump through some hoops to get the-                            -- current progname in the exception text:-                            -- <progname>: <exception>-                            liftIO $ withProgName (progname st)-                                   $ topHandler e-                                   -- this used to be topHandlerFastExit, see #2228-            runInputTWithPrefs defaultPrefs defaultSettings $ do-                -- make `ghc -e` exit nonzero on invalid input, see Trac #7962-                _ <- runCommands' hdle-                     (Just $ hdle (toException $ ExitFailure 1) >> return ())-                     (return Nothing)-                return ()+            runGHCiExpressions exprs    -- and finally, exit   liftIO $ when (verbosity dflags > 0) $ putStrLn "Leaving Clashi." +runGHCiExpressions :: [String] -> GHCi ()+runGHCiExpressions exprs = do+    enqueueCommands exprs+    let hdle e = do st <- getGHCiState+                    -- flush the interpreter's stdout/stderr on exit (#3890)+                    flushInterpBuffers+                    -- Jump through some hoops to get the+                    -- current progname in the exception text:+                    -- <progname>: <exception>+                    liftIO $ withProgName (progname st)+                           $ topHandler e+                           -- this used to be topHandlerFastExit, see #2228+    runInputTWithPrefs defaultPrefs defaultSettings $ do+        -- make `ghc -e` exit nonzero on invalid input, see Trac #7962+        _ <- runCommands' hdle+             (Just $ hdle (toException $ ExitFailure 1) >> return ())+             (return Nothing)+        return ()+ runGHCiInput :: InputT GHCi a -> GHCi a runGHCiInput f = do     dflags <- getDynFlags@@ -2007,7 +2011,7 @@                   tcm                   tupTcm                   (ghcTypeToHWType iw fp)-                  reduceConstant+                  primEvaluator                   topEntities                   opts2                   (startTime,prepTime)
src-bin-841/Clash/GHCi/UI/Info.hs view
@@ -1,7 +1,7 @@-{-# LANGUAGE LambdaCase          #-}-{-# LANGUAGE RankNTypes          #-}-{-# LANGUAGE OverloadedStrings   #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}  -- | Get information on modules, expressions, and identifiers module Clash.GHCi.UI.Info
src-bin-841/Clash/GHCi/UI/Monad.hs view
@@ -1,4 +1,9 @@-{-# LANGUAGE CPP, FlexibleInstances, UnboxedTuples, MagicHash #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}+ {-# OPTIONS_GHC -fno-cse -fno-warn-orphans #-} -- -fno-cse is needed for GLOBAL_VAR's to behave properly 
src-bin-841/Clash/GHCi/UI/Tags.hs view
@@ -7,6 +7,7 @@ -----------------------------------------------------------------------------  {-# OPTIONS_GHC -fno-warn-name-shadowing #-}+ module Clash.GHCi.UI.Tags (   createCTagsWithLineNumbersCmd,   createCTagsWithRegExesCmd,
src-bin-841/Clash/Main.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE CPP, NondecreasingIndentation, ScopedTypeVariables, TupleSections #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE NondecreasingIndentation #-}+ {-# OPTIONS -fno-warn-incomplete-patterns -optc-DNON_POSIX_SOURCE #-}  -----------------------------------------------------------------------------@@ -79,6 +81,7 @@  -- clash additions import           Paths_clash_ghc+import           Clash.GHCi.Common (checkClashDynamic) import           Clash.GHCi.UI (makeHDL) import           Exception (gcatch) import           Data.IORef (IORef, newIORef, readIORef)@@ -92,7 +95,7 @@ import           Clash.GHC.ClashFlags import           Clash.Netlist.BlackBox.Types (HdlSyn (..)) import           Clash.Util (clashLibVersion)-import           Clash.GHC.LoadModules (ghcLibDir, wantedLanguageExtensions)+import           Clash.GHC.LoadModules (ghcLibDir, setWantedLanguageExtensions) import           Clash.GHC.Util (handleClashException)  -----------------------------------------------------------------------------@@ -160,13 +163,14 @@                    ShowSupportedExtensions   -> showSupportedExtensions                    ShowVersion               -> showVersion                    ShowNumVersion            -> putStrLn cProjectVersion-                   ShowOptions isInteractive -> showOptions isInteractive+                   ShowOptions isInteractive -> showOptions isInteractive r         Right postStartupMode ->             -- start our GHC session             GHC.runGhc (Just libDir) $ do              dflags <- GHC.getSessionDynFlags-            let dflagsExtra = wantedLanguageExtensions dflags+            liftIO (checkClashDynamic dflags)+            let dflagsExtra = setWantedLanguageExtensions dflags                  ghcTyLitNormPlugin = GHC.mkModuleName "GHC.TypeLits.Normalise"                 ghcTyLitExtrPlugin = GHC.mkModuleName "GHC.TypeLits.Extra.Solver"@@ -838,12 +842,13 @@                                 , ")"                                 ] -showOptions :: Bool -> IO ()-showOptions isInteractive = putStr (unlines availableOptions)+showOptions :: Bool -> IORef ClashOpts -> IO ()+showOptions isInteractive = putStr . unlines . availableOptions     where-      availableOptions = concat [-        flagsForCompletion isInteractive,-        map ('-':) (getFlagNames mode_flags)+      availableOptions opts = concat+        [ flagsForCompletion isInteractive+        , map ('-':) (getFlagNames mode_flags)+        , map ('-':) (getFlagNames (flagsClash opts))         ]       getFlagNames opts         = map flagName opts 
src-bin-861/Clash/GHCi/Leak.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE RecordWildCards, LambdaCase #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE RecordWildCards #-}+ module Clash.GHCi.Leak   ( LeakIndicators   , getLeakIndicators
src-bin-861/Clash/GHCi/UI.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-} {-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MagicHash #-}@@ -6,8 +6,6 @@ {-# LANGUAGE NondecreasingIndentation #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE ViewPatterns #-}  {-# OPTIONS -fno-cse #-} -- -fno-cse is needed for GLOBAL_VAR's to behave properly@@ -181,7 +179,7 @@ ghciWelcomeMsg :: String ghciWelcomeMsg = "Clashi, version " ++ Data.Version.showVersion Paths_clash_ghc.version ++                  " (using clash-lib, version " ++ Data.Version.showVersion clashLibVersion ++-                 "):\nhttp://www.clash-lang.org/  :? for help"+                 "):\nhttps://clash-lang.org/  :? for help"  ghciCommands :: IORef ClashOpts -> [Command] ghciCommands opts = map mkCmd [@@ -633,30 +631,36 @@   case maybe_exprs of         Nothing ->           do+            -- Set different defaulting rules (See #280)+            runGHCiExpressions ["default ((),[],Integer,Int,Double,String)"]             -- enter the interactive loop             runGHCiInput $ runCommands $ nextInputLine show_prompt is_tty         Just exprs -> do             -- just evaluate the expression we were given-            enqueueCommands exprs-            let hdle e = do st <- getGHCiState-                            -- flush the interpreter's stdout/stderr on exit (#3890)-                            flushInterpBuffers-                            -- Jump through some hoops to get the-                            -- current progname in the exception text:-                            -- <progname>: <exception>-                            liftIO $ withProgName (progname st)-                                   $ topHandler e-                                   -- this used to be topHandlerFastExit, see #2228-            runInputTWithPrefs defaultPrefs defaultSettings $ do-                -- make `ghc -e` exit nonzero on invalid input, see Trac #7962-                _ <- runCommands' hdle-                     (Just $ hdle (toException $ ExitFailure 1) >> return ())-                     (return Nothing)-                return ()+            runGHCiExpressions exprs    -- and finally, exit   liftIO $ when (verbosity dflags > 0) $ putStrLn "Leaving Clashi." +runGHCiExpressions :: [String] -> GHCi ()+runGHCiExpressions exprs = do+    enqueueCommands exprs+    let hdle e = do st <- getGHCiState+                    -- flush the interpreter's stdout/stderr on exit (#3890)+                    flushInterpBuffers+                    -- Jump through some hoops to get the+                    -- current progname in the exception text:+                    -- <progname>: <exception>+                    liftIO $ withProgName (progname st)+                           $ topHandler e+                           -- this used to be topHandlerFastExit, see #2228+    runInputTWithPrefs defaultPrefs defaultSettings $ do+        -- make `ghc -e` exit nonzero on invalid input, see Trac #7962+        _ <- runCommands' hdle+             (Just $ hdle (toException $ ExitFailure 1) >> return ())+             (return Nothing)+        return ()+ runGHCiInput :: InputT GHCi a -> GHCi a runGHCiInput f = do     dflags <- getDynFlags@@ -2056,7 +2060,7 @@                   tcm                   tupTcm                   (ghcTypeToHWType iw fp)-                  reduceConstant+                  primEvaluator                   topEntities                   opts2                   (startTime,prepTime)
src-bin-861/Clash/GHCi/UI/Info.hs view
@@ -1,7 +1,7 @@-{-# LANGUAGE LambdaCase          #-}-{-# LANGUAGE RankNTypes          #-}-{-# LANGUAGE OverloadedStrings   #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}  -- | Get information on modules, expressions, and identifiers module Clash.GHCi.UI.Info
src-bin-861/Clash/GHCi/UI/Monad.hs view
@@ -1,4 +1,9 @@-{-# LANGUAGE CPP, FlexibleInstances, UnboxedTuples, MagicHash #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}+ {-# OPTIONS_GHC -fno-cse -fno-warn-orphans #-} -- -fno-cse is needed for GLOBAL_VAR's to behave properly 
src-bin-861/Clash/GHCi/UI/Tags.hs view
@@ -7,6 +7,7 @@ -----------------------------------------------------------------------------  {-# OPTIONS_GHC -fno-warn-name-shadowing #-}+ module Clash.GHCi.UI.Tags (   createCTagsWithLineNumbersCmd,   createCTagsWithRegExesCmd,
src-bin-861/Clash/Main.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE CPP, NondecreasingIndentation, ScopedTypeVariables, TupleSections #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE NondecreasingIndentation #-}+ {-# OPTIONS -fno-warn-incomplete-patterns -optc-DNON_POSIX_SOURCE #-}  -----------------------------------------------------------------------------@@ -81,6 +83,7 @@  -- clash additions import           Paths_clash_ghc+import           Clash.GHCi.Common (checkClashDynamic) import           Clash.GHCi.UI (makeHDL) import           Exception (gcatch) import           Data.IORef (IORef, newIORef, readIORef)@@ -95,7 +98,7 @@ import           Clash.GHC.ClashFlags import           Clash.Netlist.BlackBox.Types (HdlSyn (..)) import           Clash.Util (clashLibVersion)-import           Clash.GHC.LoadModules (ghcLibDir, wantedLanguageExtensions)+import           Clash.GHC.LoadModules (ghcLibDir, setWantedLanguageExtensions) import           Clash.GHC.Util (handleClashException)  -----------------------------------------------------------------------------@@ -151,13 +154,14 @@                    ShowSupportedExtensions   -> showSupportedExtensions                    ShowVersion               -> showVersion                    ShowNumVersion            -> putStrLn cProjectVersion-                   ShowOptions isInteractive -> showOptions isInteractive+                   ShowOptions isInteractive -> showOptions isInteractive r         Right postStartupMode ->             -- start our GHC session             GHC.runGhc (Just libDir) $ do              dflags <- GHC.getSessionDynFlags-            let dflagsExtra = wantedLanguageExtensions dflags+            liftIO (checkClashDynamic dflags)+            let dflagsExtra = setWantedLanguageExtensions dflags                  ghcTyLitNormPlugin = GHC.mkModuleName "GHC.TypeLits.Normalise"                 ghcTyLitExtrPlugin = GHC.mkModuleName "GHC.TypeLits.Extra.Solver"@@ -832,12 +836,13 @@                                 , ")"                                 ] -showOptions :: Bool -> IO ()-showOptions isInteractive = putStr (unlines availableOptions)+showOptions :: Bool -> IORef ClashOpts -> IO ()+showOptions isInteractive = putStr . unlines . availableOptions     where-      availableOptions = concat [-        flagsForCompletion isInteractive,-        map ('-':) (getFlagNames mode_flags)+      availableOptions opts = concat+        [ flagsForCompletion isInteractive+        , map ('-':) (getFlagNames mode_flags)+        , map ('-':) (getFlagNames (flagsClash opts))         ]       getFlagNames opts         = map flagName opts 
src-bin-881/Clash/GHCi/Leak.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE RecordWildCards, LambdaCase #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE RecordWildCards #-}+ module Clash.GHCi.Leak   ( LeakIndicators   , getLeakIndicators
src-bin-881/Clash/GHCi/UI.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-} {-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MagicHash #-}@@ -6,9 +6,6 @@ {-# LANGUAGE NondecreasingIndentation #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TupleSections #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE ViewPatterns #-}  {-# OPTIONS -fno-cse #-} -- -fno-cse is needed for GLOBAL_VAR's to behave properly@@ -184,7 +181,7 @@ ghciWelcomeMsg :: String ghciWelcomeMsg = "Clashi, version " ++ Data.Version.showVersion Paths_clash_ghc.version ++                  " (using clash-lib, version " ++ Data.Version.showVersion clashLibVersion ++-                 "):\nhttp://www.clash-lang.org/  :? for help"+                 "):\nhttps://clash-lang.org/  :? for help"  ghciCommands :: IORef ClashOpts -> [Command] ghciCommands opts = map mkCmd [@@ -670,30 +667,37 @@   case maybe_exprs of         Nothing ->           do+            -- Set different defaulting rules (See #280)+            runGHCiExpressions ["default ((),[],Integer,Int,Double,String)"]+             -- enter the interactive loop             runGHCiInput $ runCommands $ nextInputLine show_prompt is_tty-        Just exprs -> do+        Just exprs ->             -- just evaluate the expression we were given-            enqueueCommands exprs-            let hdle e = do st <- getGHCiState-                            -- flush the interpreter's stdout/stderr on exit (#3890)-                            flushInterpBuffers-                            -- Jump through some hoops to get the-                            -- current progname in the exception text:-                            -- <progname>: <exception>-                            liftIO $ withProgName (progname st)-                                   $ topHandler e-                                   -- this used to be topHandlerFastExit, see #2228-            runInputTWithPrefs defaultPrefs defaultSettings $ do-                -- make `ghc -e` exit nonzero on invalid input, see Trac #7962-                _ <- runCommands' hdle-                     (Just $ hdle (toException $ ExitFailure 1) >> return ())-                     (return Nothing)-                return ()+            runGHCiExpressions exprs    -- and finally, exit   liftIO $ when (verbosity dflags > 0) $ putStrLn "Leaving Clashi." +runGHCiExpressions :: [String] -> GHCi ()+runGHCiExpressions exprs = do+    enqueueCommands exprs+    let hdle e = do st <- getGHCiState+                    -- flush the interpreter's stdout/stderr on exit (#3890)+                    flushInterpBuffers+                    -- Jump through some hoops to get the+                    -- current progname in the exception text:+                    -- <progname>: <exception>+                    liftIO $ withProgName (progname st)+                           $ topHandler e+                           -- this used to be topHandlerFastExit, see #2228+    runInputTWithPrefs defaultPrefs defaultSettings $ do+        -- make `ghc -e` exit nonzero on invalid input, see Trac #7962+        _ <- runCommands' hdle+             (Just $ hdle (toException $ ExitFailure 1) >> return ())+             (return Nothing)+        return ()+ runGHCiInput :: InputT GHCi a -> GHCi a runGHCiInput f = do     dflags <- getDynFlags@@ -2148,7 +2152,7 @@                   tcm                   tupTcm                   (ghcTypeToHWType iw fp)-                  reduceConstant+                  primEvaluator                   topEntities                   opts2                   (startTime,prepTime)
src-bin-881/Clash/GHCi/UI/Info.hs view
@@ -1,8 +1,7 @@-{-# LANGUAGE LambdaCase          #-}-{-# LANGUAGE RankNTypes          #-}-{-# LANGUAGE OverloadedStrings   #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ViewPatterns        #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}  -- | Get information on modules, expressions, and identifiers module Clash.GHCi.UI.Info
src-bin-881/Clash/GHCi/UI/Monad.hs view
@@ -1,4 +1,7 @@-{-# LANGUAGE CPP, FlexibleInstances #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+ {-# OPTIONS_GHC -fno-cse -fno-warn-orphans #-} -- -fno-cse is needed for GLOBAL_VAR's to behave properly 
src-bin-881/Clash/GHCi/UI/Tags.hs view
@@ -7,6 +7,7 @@ -----------------------------------------------------------------------------  {-# OPTIONS_GHC -fno-warn-name-shadowing #-}+ module Clash.GHCi.UI.Tags (   createCTagsWithLineNumbersCmd,   createCTagsWithRegExesCmd,
src-bin-881/Clash/GHCi/Util.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE MagicHash, UnboxedTuples #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}  -- | Utilities for GHCi. module Clash.GHCi.Util where
src-bin-881/Clash/Main.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE CPP, NondecreasingIndentation, ScopedTypeVariables, TupleSections #-}-{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE NondecreasingIndentation #-}+ {-# OPTIONS -fno-warn-incomplete-patterns -optc-DNON_POSIX_SOURCE #-}  -----------------------------------------------------------------------------@@ -79,6 +80,7 @@  -- clash additions import           Paths_clash_ghc+import           Clash.GHCi.Common (checkClashDynamic) import           Clash.GHCi.UI (makeHDL) import           Exception (gcatch) import           Data.IORef (IORef, newIORef, readIORef)@@ -93,7 +95,7 @@ import           Clash.GHC.ClashFlags import           Clash.Netlist.BlackBox.Types (HdlSyn (..)) import           Clash.Util (clashLibVersion)-import           Clash.GHC.LoadModules (ghcLibDir, wantedLanguageExtensions)+import           Clash.GHC.LoadModules (ghcLibDir, setWantedLanguageExtensions) import           Clash.GHC.Util (handleClashException)  -----------------------------------------------------------------------------@@ -147,13 +149,14 @@                  ShowSupportedExtensions   -> showSupportedExtensions                  ShowVersion               -> showVersion                  ShowNumVersion            -> putStrLn cProjectVersion-                 ShowOptions isInteractive -> showOptions isInteractive+                 ShowOptions isInteractive -> showOptions isInteractive r       Right postStartupMode ->           -- start our GHC session           GHC.runGhc (Just libDir) $ do            dflags <- GHC.getSessionDynFlags-          let dflagsExtra = wantedLanguageExtensions dflags+          liftIO (checkClashDynamic dflags)+          let dflagsExtra = setWantedLanguageExtensions dflags                ghcTyLitNormPlugin = GHC.mkModuleName "GHC.TypeLits.Normalise"               ghcTyLitExtrPlugin = GHC.mkModuleName "GHC.TypeLits.Extra.Solver"@@ -844,12 +847,13 @@                                 , ")"                                 ] -showOptions :: Bool -> IO ()-showOptions isInteractive = putStr (unlines availableOptions)+showOptions :: Bool -> IORef ClashOpts -> IO ()+showOptions isInteractive = putStr . unlines . availableOptions     where-      availableOptions = concat [-        flagsForCompletion isInteractive,-        map ('-':) (getFlagNames mode_flags)+      availableOptions opts = concat+        [ flagsForCompletion isInteractive+        , map ('-':) (getFlagNames mode_flags)+        , map ('-':) (getFlagNames (flagsClash opts))         ]       getFlagNames opts         = map flagName opts 
src-bin-common/Clash/GHCi/Common.hs view
@@ -1,16 +1,18 @@-{-# LANGUAGE CPP        #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-}  module Clash.GHCi.Common   ( checkImportDirs   , checkMonoLocalBinds   , checkMonoLocalBindsMod+  , checkClashDynamic   ) where  -- Clash import           Clash.Driver.Types     (ClashOpts (..))  -- The GHC interface+import qualified DynFlags #if MIN_VERSION_base(4,11,0) import qualified EnumSet                as GHC (member) -- ghc84, ghc86 #else@@ -64,3 +66,14 @@     doesDirectoryExist dir >>= \case       False -> throwGhcException (CmdLineError $ "Missing directory: " ++ dir)       _     -> return ()++checkClashDynamic :: GHC.DynFlags -> IO ()+checkClashDynamic dflags = do+  let isStatic = case lookup "GHC Dynamic" (DynFlags.compilerInfo dflags) of+        Just "YES" -> False+        _          -> True+  when isStatic+    (hPutStrLn stderr (unlines+      ["WARNING: Clash is linked statically, which can lead to long startup times."+      ,"See https://gitlab.haskell.org/ghc/ghc/issues/15524"+      ]))
src-ghc/Batch.hs view
@@ -5,6 +5,7 @@    Entry point for the @clash@ executable. -}+ module Main   ( main -- :: IO ()   ) where
src-ghc/Clash/GHC/ClashFlags.hs view
@@ -5,25 +5,30 @@   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com> -} -{-# LANGUAGE CPP           #-}-{-# LANGUAGE LambdaCase    #-}-{-# LANGUAGE TupleSections #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}  module Clash.GHC.ClashFlags   ( parseClashFlags+  , flagsClash   ) where -import CmdLineParser-import Panic-import SrcLoc+import           CmdLineParser+import           Panic+import           SrcLoc -import Data.IORef-import Control.Monad-import Clash.Driver.Types-import Clash.Netlist.BlackBox.Types (HdlSyn (..))-import Text.Read (readMaybe)+import           Control.Monad+import           Data.Char                      (isSpace)+import           Data.IORef+import           Data.List                      (dropWhileEnd)+import           Data.List.Split                (splitOn)+import qualified Data.Set                       as Set+import           Text.Read                      (readMaybe) +import           Clash.Driver.Types+import           Clash.Netlist.BlackBox.Types   (HdlSyn (..))+ parseClashFlags :: IORef ClashOpts -> [Located String]                 -> IO ([Located String] #if MIN_VERSION_ghc(8,4,1)@@ -57,6 +62,7 @@ flagsClash :: IORef ClashOpts -> [Flag IO] flagsClash r = [     defFlag "fclash-debug"                       $ SepArg (setDebugLevel r)+  , defFlag "fclash-debug-transformations"       $ SepArg (setDebugTransformations r)   , defFlag "fclash-hdldir"                      $ SepArg (setHdlDir r)   , defFlag "fclash-hdlsyn"                      $ SepArg (setHdlSyn r)   , defFlag "fclash-nocache"                     $ NoArg (deprecated "nocache" "no-cache" setNoCache r)@@ -72,12 +78,13 @@   , defFlag "fclash-intwidth"                    $ IntSuffix (setIntWidth r)   , defFlag "fclash-error-extra"                 $ NoArg (liftEwM (setErrorExtra r))   , defFlag "fclash-float-support"               $ NoArg (liftEwM (setFloatSupport r))-  , defFlag "fclash-allow-zero-width"            $ NoArg (setAllowZeroWidth r)   , defFlag "fclash-component-prefix"            $ SepArg (liftEwM . setComponentPrefix r)   , defFlag "fclash-old-inline-strategy"         $ NoArg (liftEwM (setOldInlineStrategy r))   , defFlag "fclash-no-escaped-identifiers"      $ NoArg (liftEwM (setNoEscapedIds r))   , defFlag "fclash-compile-ultra"               $ NoArg (liftEwM (setUltra r))   , defFlag "fclash-force-undefined"             $ OptIntSuffix (setUndefined r)+  , defFlag "fclash-aggressive-x-optimization"   $ NoArg (liftEwM (setAggressiveXOpt r))+  , defFlag "fclash-inline-workfree-limit"       $ IntSuffix (liftEwM . setInlineWFLimit r)   ]  -- | Print deprecated flag warning@@ -113,11 +120,24 @@   -> IO () setInlineConstantLimit r n = modifyIORef r (\c -> c {opt_inlineConstantLimit = toEnum n}) +setInlineWFLimit+  :: IORef ClashOpts+  -> Int+  -> IO ()+setInlineWFLimit r n = modifyIORef r (\c -> c {opt_inlineWFCacheLimit = toEnum n})+ setSpecLimit :: IORef ClashOpts              -> Int              -> IO () setSpecLimit r n = modifyIORef r (\c -> c {opt_specLimit = n}) +setDebugTransformations :: IORef ClashOpts -> String -> EwM IO ()+setDebugTransformations r s =+  liftEwM (modifyIORef r (\c -> c {opt_dbgTransformations = transformations}))+ where+  transformations = Set.fromList (filter (not . null) (map trim (splitOn "," s)))+  trim = dropWhileEnd isSpace . dropWhile isSpace+ setDebugLevel :: IORef ClashOpts               -> String               -> EwM IO ()@@ -170,11 +190,6 @@ setFloatSupport :: IORef ClashOpts -> IO () setFloatSupport r = modifyIORef r (\c -> c {opt_floatSupport = True}) -setAllowZeroWidth :: IORef ClashOpts -> EwM IO ()-setAllowZeroWidth _ = do-  addWarn ("-fclash-allow-zero-width is deprecated and will be removed in Clash 1.0")-  -- liftEwM (modifyIORef r (\c -> c {opt_allowZero = True}))- setComponentPrefix   :: IORef ClashOpts   -> String@@ -196,3 +211,7 @@            " not in range [0,1]") setUndefined r iM =   liftEwM (modifyIORef r (\c -> c {opt_forceUndefined = Just iM}))++setAggressiveXOpt :: IORef ClashOpts -> IO ()+setAggressiveXOpt r = modifyIORef r (\c -> c { opt_aggressiveXOpt = True })+
src-ghc/Clash/GHC/Evaluator.hs view
@@ -6,32 +6,28 @@   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com> -} -{-# LANGUAGE BangPatterns      #-}-{-# LANGUAGE CPP               #-}-{-# LANGUAGE DataKinds         #-}-{-# LANGUAGE KindSignatures    #-}-{-# LANGUAGE MagicHash         #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes        #-}-{-# LANGUAGE TemplateHaskell   #-}-{-# LANGUAGE TupleSections     #-}-{-# LANGUAGE UnboxedTuples     #-}-{-# LANGUAGE ViewPatterns      #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UnboxedTuples #-} -module Clash.GHC.Evaluator where+module Clash.GHC.Evaluator+  ( primEvaluator+  ) where -import           Control.Applicative (liftA2) import           Control.Concurrent.Supply  (Supply,freshId) import           Control.DeepSeq            (force) import           Control.Exception          (ArithException(..), Exception, tryJust, evaluate)-import           Control.Monad              (ap)+import           Control.Monad.State.Strict (State, MonadState)+import qualified Control.Monad.State.Strict as State import           Control.Monad.Trans.Except (runExcept) import           Data.Bits import           Data.Char           (chr,ord) import qualified Data.Either         as Either-import qualified Data.IntMap         as IntMap-import           Data.Maybe-  (fromMaybe, mapMaybe, catMaybes)+import           Data.Maybe (fromMaybe, mapMaybe) import qualified Data.List           as List import qualified Data.Primitive.ByteArray as ByteArray import           Data.Proxy          (Proxy)@@ -45,10 +41,11 @@ import           GHC.Integer   (decodeDoubleInteger,encodeDoubleInteger,compareInteger,orInteger,andInteger,    xorInteger,complementInteger,absInteger,signumInteger)+import           GHC.Integer.GMP.Internals+  (Integer (..), BigNat (..)) import           GHC.Natural import           GHC.Prim import           GHC.Real            (Ratio (..))-import           GHC.Stack           (HasCallStack) import           GHC.TypeLits        (KnownNat) import           GHC.Types           (IO (..)) import           GHC.Word@@ -57,7 +54,8 @@ import           BasicTypes          (Boxity (..)) import           Name                (getSrcSpan, nameOccName, occNameString) import           PrelNames-  (typeNatAddTyFamNameKey, typeNatMulTyFamNameKey, typeNatSubTyFamNameKey)+  (typeNatAddTyFamNameKey, typeNatMulTyFamNameKey, typeNatSubTyFamNameKey,+   trueDataConKey, falseDataConKey) import           SrcLoc              (wiredInSrcSpan) import qualified TyCon import           TysWiredIn          (tupleTyCon)@@ -66,8 +64,7 @@ import           Clash.Class.BitPack (pack,unpack) import           Clash.Core.DataCon  (DataCon (..)) import           Clash.Core.Evaluator-  (Heap (..), PrimEvaluator, Stack, Value (..), valToTerm, whnf, integerLiteral,-  naturalLiteral)+import           Clash.Core.Evaluator.Types import           Clash.Core.Literal  (Literal (..)) import           Clash.Core.Name   (Name (..), NameSort (..), mkUnsafeSystemName)@@ -99,24 +96,75 @@ import Clash.Sized.Internal.Unsigned (Unsigned (..)) import Clash.XException (isX) -newtype PrimEvalMonad a = PEM { runPEM :: Supply -> (a,Supply) } -instance Functor PrimEvalMonad where-  fmap f m = PEM (\s -> case runPEM m s of (a,s') -> (f a, s'))+primEvaluator :: PrimEvaluator+primEvaluator = (reduceConstant, unwindPrim) -instance Applicative PrimEvalMonad where-  pure  = return-  (<*>) = ap -instance Monad PrimEvalMonad where-  return a = PEM (\s -> (a,s))-  m >>= k  = PEM (\s -> case runPEM m s of (a,s') -> runPEM (k a) s')+-- | Evaluation of primitive operations.+-- TODO This should really be in Clash.GHC.Evaluator -- the evaluator in+-- clash-lib should NEVER refer to GHC primitives.+unwindPrim :: PrimUnwind+unwindPrim tcm ty tys vs v [] m+  | primName ty `elem` [ "Clash.Sized.Internal.Index.fromInteger#"+                       , "GHC.CString.unpackCString#"+                       , "Clash.Transformations.removedArg"+                       , "GHC.Prim.MutableByteArray#"+                       ]+              -- The above primitives are actually values, and not operations.+  = unwind tcm m (PrimVal ty tys (vs ++ [v]))+  | primName ty == "Clash.Sized.Internal.BitVector.fromInteger#"+  = case (vs,v) of+    ([naturalLiteral -> Just n,mask], integerLiteral -> Just i) ->+      unwind tcm m (PrimVal ty tys [Lit (NaturalLiteral n)+                                             ,mask+                                             ,Lit (IntegerLiteral (wrapUnsigned n i))])+    _ -> error ($(curLoc) ++ "Internal error"  ++ show (vs,v))+  | primName ty == "Clash.Sized.Internal.BitVector.fromInteger##"+  = case (vs,v) of+    ([mask], integerLiteral -> Just i) ->+      unwind tcm m (PrimVal ty tys [mask+                                             ,Lit (IntegerLiteral (wrapUnsigned 1 i))])+    _ -> error ($(curLoc) ++ "Internal error"  ++ show (vs,v))+  | primName ty == "Clash.Sized.Internal.Signed.fromInteger#"+  = case (vs,v) of+    ([naturalLiteral -> Just n],integerLiteral -> Just i) ->+      unwind tcm m (PrimVal ty tys [Lit (NaturalLiteral n)+                                             ,Lit (IntegerLiteral (wrapSigned n i))])+    _ -> error ($(curLoc) ++ "Internal error"  ++ show (vs,v))+  | primName ty == "Clash.Sized.Internal.Unsigned.fromInteger#"+  = case (vs,v) of+    ([naturalLiteral -> Just n],integerLiteral -> Just i) ->+      unwind tcm m (PrimVal ty tys [Lit (NaturalLiteral n)+                                             ,Lit (IntegerLiteral (wrapUnsigned n i))])+    _ -> error ($(curLoc) ++ "Internal error"  ++ show (vs,v))+  | otherwise = mPrimStep m tcm (forcePrims m) ty tys (vs ++ [v]) m +unwindPrim tcm ty tys vs v [e] m0+  | primName ty `elem` [ "Clash.Sized.Vector.lazyV"+                       , "Clash.Sized.Vector.replicate"+                       , "Clash.Sized.Vector.replace_int"+                       , "GHC.Classes.&&"+                       , "GHC.Classes.||"+                       ]+  = let (m1,i) = newLetBinding tcm m0 e+    in  mPrimStep m0 tcm (forcePrims m0) ty tys (vs ++ [v,Suspend (Var i)]) m1++unwindPrim _ ty tys vs (collectValueTicks -> (v, ts)) (e:es) m =+  Just . setTerm e $ stackPush (PrimApply ty tys (vs ++ [foldr TickValue v ts]) es) m+++newtype PrimEvalMonad a = PEM (State Supply a)+  deriving (Functor, Applicative, Monad, MonadState Supply)+ instance MonadUnique PrimEvalMonad where-  getUniqueM = PEM (\s -> case freshId s of (!i,!s') -> (i,s'))+  getUniqueM = PEM $ State.state (\s -> case freshId s of (!i,!s') -> (i,s')) -reduceConstant :: PrimEvaluator-reduceConstant isSubj tcm h k nm pInfo tys args = case nm of+runPEM :: PrimEvalMonad a -> Supply -> (a, Supply)+runPEM (PEM m) = State.runState m++reduceConstant :: PrimStep+reduceConstant tcm isSubj pInfo tys args mach = case primName pInfo of ----------------- -- GHC.Prim.Char# -----------------@@ -624,32 +672,29 @@     "GHC.Prim.newByteArray#"-    | [iV,PrimVal rwNm rwTy _ _] <- args+    | [iV,PrimVal rwTy _ _] <- args     , [i] <- intLiterals' [iV]     -> let (_,tyView -> TyConApp tupTcNm tyArgs) = splitFunForallTy ty            (Just tupTc) = lookupUniqMap tupTcNm tcm            [tupDc] = tyConDataCons tupTc-           Heap (gh,p) gbl ph ids is0 = h+           p = primCount mach            lit = Literal (ByteArrayLiteral (Vector.replicate (fromInteger i) 0))-           h' = Heap (IntMap.insert p lit gh,p+1) gbl ph ids is0            mbaTy = mkFunTy intPrimTy (last tyArgs)            newE = mkApps (Data tupDc) (map Right tyArgs ++-                    [Left (Prim rwNm rwTy)-                    ,Left (mkApps (Prim "GHC.Prim.MutableByteArray#"-                                        (PrimInfo mbaTy WorkNever))+                    [Left (Prim rwTy)+                    ,Left (mkApps (Prim (PrimInfo "GHC.Prim.MutableByteArray#" mbaTy WorkNever))                                   [Left (Literal . IntLiteral $ toInteger p)])                     ])-       in Just (h',k,newE)+       in Just . setTerm newE $ primInsert p lit mach    "GHC.Prim.setByteArray#"-    | [PrimVal _mbaNm _mbaTy _ [baV]+    | [PrimVal _mbaTy _ [baV]       ,offV,lenV,cV-      ,PrimVal rwNm rwTy _ _+      ,PrimVal rwTy _ _       ] <- args     , [ba,off,len,c] <- intLiterals' [baV,offV,lenV,cV]-    -> let Heap (gh,p) gbl ph ids is0 = h-           Just (Literal (ByteArrayLiteral (Vector.Vector voff vlen ba1))) =-              IntMap.lookup (fromInteger ba) gh+    -> let Just (Literal (ByteArrayLiteral (Vector.Vector voff vlen ba1))) =+              primLookup (fromInteger ba) mach            !(I# off') = fromInteger off            !(I# len') = fromInteger len            !(I# c')   = fromInteger c@@ -658,19 +703,17 @@                   svoid (setByteArray# mba off' len' c')                   ByteArray.unsafeFreezeByteArray (ByteArray.MutableByteArray mba)            ba3 = Literal (ByteArrayLiteral (Vector.Vector voff vlen ba2))-           h'  = Heap (IntMap.insert (fromInteger ba) ba3 gh,p) gbl ph ids is0-       in Just (h',k,Prim rwNm rwTy)+       in Just . setTerm (Prim rwTy) $ primUpdate (fromInteger ba) ba3 mach    "GHC.Prim.writeWordArray#"-    | [PrimVal _mbaNm _mbaTy _  [baV]+    | [PrimVal _mbaTy _  [baV]       ,iV,wV-      ,PrimVal rwNm rwTy _ _+      ,PrimVal rwTy _ _       ] <- args     , [ba,i] <- intLiterals' [baV,iV]     , [w] <- wordLiterals' [wV]-    -> let Heap (gh,p) gbl ph ids is0 = h-           Just (Literal (ByteArrayLiteral (Vector.Vector off len ba1))) =-              IntMap.lookup (fromInteger ba) gh+    -> let Just (Literal (ByteArrayLiteral (Vector.Vector off len ba1))) =+              primLookup (fromInteger ba) mach            !(I# i') = fromInteger i            !(W# w') = fromIntegral w            ba2 = unsafeDupablePerformIO $ do@@ -678,21 +721,19 @@                   svoid (writeWordArray# mba i' w')                   ByteArray.unsafeFreezeByteArray (ByteArray.MutableByteArray mba)            ba3 = Literal (ByteArrayLiteral (Vector.Vector off len ba2))-           h'  = Heap (IntMap.insert (fromInteger ba) ba3 gh,p) gbl ph ids is0-       in Just (h',k,Prim rwNm rwTy)+       in Just . setTerm (Prim rwTy) $ primUpdate (fromInteger ba) ba3 mach    "GHC.Prim.unsafeFreezeByteArray#"-    | [PrimVal _mbaNm _mbaTy _ [baV]-      ,PrimVal rwNm rwTy _ _+    | [PrimVal _mbaTy _ [baV]+      ,PrimVal rwTy _ _       ] <- args     , [ba] <-  intLiterals' [baV]     -> let (_,tyView -> TyConApp tupTcNm tyArgs) = splitFunForallTy ty            (Just tupTc) = lookupUniqMap tupTcNm tcm            [tupDc] = tyConDataCons tupTc-           Heap (gh,_) _ _ _ _ = h-           Just ba' = IntMap.lookup (fromInteger ba) gh+           Just ba' = primLookup (fromInteger ba) mach        in  reduce $ mkApps (Data tupDc) (map Right tyArgs ++-                      [Left (Prim rwNm rwTy)+                      [Left (Prim rwTy)                       ,Left ba'])    "GHC.Prim.sizeofByteArray#"@@ -707,32 +748,31 @@        in  reduce (Literal (WordLiteral (toInteger (W# w))))    "GHC.Prim.getSizeofMutBigNat#"-    | [PrimVal _mbaNm _mbaTy _ [baV]-      ,PrimVal rwNm rwTy _ _+    | [PrimVal _mbaTy _ [baV]+      ,PrimVal rwTy _ _       ] <- args     , [ba] <- intLiterals' [baV]     -> let (_,tyView -> TyConApp tupTcNm tyArgs) = splitFunForallTy ty            (Just tupTc) = lookupUniqMap tupTcNm tcm            [tupDc] = tyConDataCons tupTc-           Heap (gh,_) _ _ _ _ = h-           Just (Literal (ByteArrayLiteral ba')) = IntMap.lookup (fromInteger ba) gh+           Just (Literal (ByteArrayLiteral ba')) = primLookup (fromInteger ba) mach            lit = Literal (IntLiteral (toInteger (Vector.length ba')))        in  reduce $ mkApps (Data tupDc) (map Right tyArgs ++-                      [Left (Prim rwNm rwTy)+                      [Left (Prim rwTy)                       ,Left lit])    "GHC.Prim.resizeMutableByteArray#"-    | [PrimVal mbaNm mbaTy _ [baV]+    | [PrimVal mbaTy _ [baV]       ,iV-      ,PrimVal rwNm rwTy _ _+      ,PrimVal rwTy _ _       ] <- args     , [ba,i] <- intLiterals' [baV,iV]     -> let (_,tyView -> TyConApp tupTcNm tyArgs) = splitFunForallTy ty            (Just tupTc) = lookupUniqMap tupTcNm tcm            [tupDc] = tyConDataCons tupTc-           Heap (gh,p) gbl ph ids is0 = h+           p = primCount mach            Just (Literal (ByteArrayLiteral (Vector.Vector 0 _ ba1)))-            = IntMap.lookup (fromInteger ba) gh+            = primLookup (fromInteger ba) mach            !(I# i') = fromInteger i            ba2 = unsafeDupablePerformIO $ do                    ByteArray.MutableByteArray mba <- ByteArray.unsafeThawByteArray ba1@@ -740,43 +780,39 @@                                  (# s', mba' #) -> (# s', ByteArray.MutableByteArray mba' #))                    ByteArray.unsafeFreezeByteArray mba'            ba3 = Literal (ByteArrayLiteral (Vector.Vector 0 (I# i') ba2))-           h'  = Heap (IntMap.insert p ba3 gh,p+1) gbl ph ids is0            newE = mkApps (Data tupDc) (map Right tyArgs ++-                    [Left (Prim rwNm rwTy)-                    ,Left (mkApps (Prim mbaNm mbaTy)+                    [Left (Prim rwTy)+                    ,Left (mkApps (Prim mbaTy)                                   [Left (Literal . IntLiteral $ toInteger p)])                     ])-       in  Just (h',k,newE)+       in Just . setTerm newE $ primInsert p ba3 mach    "GHC.Prim.shrinkMutableByteArray#"-    | [PrimVal _mbaNm _mbaTy _ [baV]+    | [PrimVal _mbaTy _ [baV]       ,lenV-      ,PrimVal rwNm rwTy _ _+      ,PrimVal rwTy _ _       ] <- args     , [ba,len] <- intLiterals' [baV,lenV]-    -> let Heap (gh,p) gbl ph ids is0 = h-           Just (Literal (ByteArrayLiteral (Vector.Vector voff vlen ba1))) =-              IntMap.lookup (fromInteger ba) gh+    -> let Just (Literal (ByteArrayLiteral (Vector.Vector voff vlen ba1))) =+              primLookup (fromInteger ba) mach            !(I# len') = fromInteger len            ba2 = unsafeDupablePerformIO $ do                   ByteArray.MutableByteArray mba <- ByteArray.unsafeThawByteArray ba1                   svoid (shrinkMutableByteArray# mba len')                   ByteArray.unsafeFreezeByteArray (ByteArray.MutableByteArray mba)            ba3 = Literal (ByteArrayLiteral (Vector.Vector voff vlen ba2))-           h'  = Heap (IntMap.insert (fromInteger ba) ba3 gh,p) gbl ph ids is0-       in Just (h',k,Prim rwNm rwTy)+       in Just . setTerm (Prim rwTy) $ primUpdate (fromInteger ba) ba3 mach    "GHC.Prim.copyByteArray#"     | [Lit (ByteArrayLiteral (Vector.Vector _ _ (ByteArray.ByteArray src_ba)))       ,src_offV-      ,PrimVal _mbaNm _mbaTy _ [dst_mbaV]+      ,PrimVal _mbaTy _ [dst_mbaV]       ,dst_offV, nV-      ,PrimVal rwNm rwTy _ _+      ,PrimVal rwTy _ _       ] <- args     , [src_off,dst_mba,dst_off,n] <- intLiterals' [src_offV,dst_mbaV,dst_offV,nV]-    -> let Heap (gh,p) gbl ph ids is0 = h-           Just (Literal (ByteArrayLiteral (Vector.Vector voff vlen dst_ba))) =-              IntMap.lookup (fromInteger dst_mba) gh+    -> let Just (Literal (ByteArrayLiteral (Vector.Vector voff vlen dst_ba))) =+              primLookup (fromInteger dst_mba) mach            !(I# src_off') = fromInteger src_off            !(I# dst_off') = fromInteger dst_off            !(I# n')       = fromInteger n@@ -785,28 +821,26 @@                   svoid (copyByteArray# src_ba src_off' dst_mba1 dst_off' n')                   ByteArray.unsafeFreezeByteArray (ByteArray.MutableByteArray dst_mba1)            ba3 = Literal (ByteArrayLiteral (Vector.Vector voff vlen ba2))-           h'  = Heap (IntMap.insert (fromInteger dst_mba) ba3 gh,p) gbl ph ids is0-       in Just (h',k,Prim rwNm rwTy)+       in Just . setTerm (Prim rwTy) $ primUpdate (fromInteger dst_mba) ba3 mach    "GHC.Prim.readWordArray#"-    | [PrimVal _mbaNm _mbaTy _  [baV]+    | [PrimVal _mbaTy _  [baV]       ,offV-      ,PrimVal rwNm rwTy _ _+      ,PrimVal rwTy _ _       ] <- args     , [ba,off] <- intLiterals' [baV,offV]     -> let (_,tyView -> TyConApp tupTcNm tyArgs) = splitFunForallTy ty            (Just tupTc) = lookupUniqMap tupTcNm tcm            [tupDc] = tyConDataCons tupTc-           Heap (gh,_) _ _ _ _ = h            Just (Literal (ByteArrayLiteral (Vector.Vector _ _ ba1))) =-              IntMap.lookup (fromInteger ba) gh+              primLookup (fromInteger ba) mach            !(I# off') = fromInteger off            w = unsafeDupablePerformIO $ do                   ByteArray.MutableByteArray mba <- ByteArray.unsafeThawByteArray ba1                   IO (\s -> case readWordArray# mba off' s of                         (# s', w' #) -> (# s',  W# w' #))            newE = mkApps (Data tupDc) (map Right tyArgs ++-                    [Left (Prim rwNm rwTy)+                    [Left (Prim rwTy)                     ,Left (Literal (WordLiteral (toInteger w)))                     ])        in reduce newE@@ -823,7 +857,6 @@                    [ Left (Literal . IntLiteral  . toInteger $ I# p)                    , Left (Literal . IntLiteral  . toInteger $ I# q)]) -   "GHC.Prim.tagToEnum#"     | [ConstTy (TyCon tcN)] <- tys     , [Lit (IntLiteral i)]  <- args@@ -831,26 +864,58 @@                    ; let dcs = tyConDataCons tc                    ; List.find ((== (i+1)) . toInteger . dcTag) dcs                    }-       in ((h,k,) . Data) <$> dc+       in (\e -> setTerm (Data e) mach) <$> dc     "GHC.Classes.geInt" | Just (i,j) <- intCLiterals args     -> reduce (boolToBoolLiteral tcm ty (i >= j))    "GHC.Classes.&&"-    | [DC lCon _-      ,DC rCon _] <- args-    -> reduce $ boolToBoolLiteral tcm ty-         ((nameOcc (dcName lCon) == "GHC.Types.True") &&-          (nameOcc (dcName rCon) == "GHC.Types.True"))+    | [ lArg , rArg ] <- args+    -- evaluation of the arguments is deferred until the evaluation of the unwindPrim+    -- to make `&&` lazy in both arguments+    , mach1@Machine{mStack=[],mTerm=lArgWHNF} <- whnf tcm True (setTerm (valToTerm lArg) $ stackClear mach)+    , mach2@Machine{mStack=[],mTerm=rArgWHNF} <- whnf tcm True (setTerm (valToTerm rArg) $ stackClear mach1)+    -> case [ lArgWHNF, rArgWHNF ] of+         [ Data lCon, Data rCon ] ->+           Just $ mach2+             { mStack = mStack mach+             , mTerm = boolToBoolLiteral tcm ty (isTrueDC lCon && isTrueDC rCon)+             } +         [ Data lCon, _ ]+           | isTrueDC lCon -> reduce rArgWHNF+           | otherwise     -> reduce (boolToBoolLiteral tcm ty False)++         [ _, Data rCon ]+           | isTrueDC rCon -> reduce lArgWHNF+           | otherwise     -> reduce (boolToBoolLiteral tcm ty False)++         _ -> Nothing+   "GHC.Classes.||"-    | [DC lCon _-      ,DC rCon _] <- args-    -> reduce $ boolToBoolLiteral tcm ty-         ((nameOcc (dcName lCon) == "GHC.Types.True") ||-          (nameOcc (dcName rCon) == "GHC.Types.True"))+    | [ lArg , rArg ] <- args+    -- evaluation of the arguments is deferred until the evaluation of the unwindPrim+    -- to make `||` lazy in both arguments+    , mach1@Machine{mStack=[],mTerm=lArgWHNF} <- whnf tcm True (setTerm (valToTerm lArg) $ stackClear mach)+    , mach2@Machine{mStack=[],mTerm=rArgWHNF} <- whnf tcm True (setTerm (valToTerm rArg) $ stackClear mach1)+    -> case [ lArgWHNF, rArgWHNF ] of+         [ Data lCon, Data rCon ] ->+           Just $ mach2+             { mStack = mStack mach+             , mTerm = boolToBoolLiteral tcm ty (isTrueDC lCon || isTrueDC rCon)+             } +         [ Data lCon, _ ]+           | isFalseDC lCon -> reduce rArgWHNF+           | otherwise      -> reduce (boolToBoolLiteral tcm ty True)++         [ _, Data rCon ]+           | isFalseDC rCon -> reduce lArgWHNF+           | otherwise      -> reduce (boolToBoolLiteral tcm ty True)++         _ -> Nothing+   "GHC.Classes.divInt#" | Just (i,j) <- intLiterals args     -> reduce (integerToIntLiteral (i `div` j)) @@ -1072,6 +1137,12 @@      let nTy = snd (splitFunForallTy ty) in      reduce (checkNaturalRange1 nTy w id) +  "GHC.Natural.gcdNatural"+    | Just (i,j) <- naturalLiterals args+    ->+     let nTy = snd (splitFunForallTy ty) in+     reduce (checkNaturalRange2 nTy i j gcd)+   -- GHC.Real.^  -- XXX: Very fragile   --   ^_f, $wf, $wf1 are specialisations of the internal function f in the implementation of (^) in GHC.Real   "GHC.Real.^_f"  -- :: Integer -> Integer -> Integer@@ -1085,11 +1156,17 @@     | [Lit (IntLiteral i), Lit (IntLiteral j)] <- args     -> reduce (integerToIntLiteral $ i ^ j) -  -- XXX: Very fragile. /$s^_f/ is a specialized version of ^_f. That means that-  -- it is type applied to some specific type.-  "Data.Singletons.TypeLits.Internal.$s^_f"-    | Just (i,j) <- naturalLiterals args+  -- Type level ^    -- XXX: Very fragile+  -- These is are specialized versions of ^_f, named by some combination of ghc and singletons.+  "Data.Singletons.TypeLits.Internal.$s^_f"            -- ghc-8.4.4, singletons-2.4.1+    | [i,j] <- naturalLiterals' args     -> reduce (Literal (NaturalLiteral (i ^ j)))+  "Data.Singletons.TypeLits.Internal.$fSingI->^@#@$_f" -- ghc-8.6.5, singletons-2.5.1+    | [i,j] <- naturalLiterals' args+    -> reduce (Literal (NaturalLiteral (i ^ j)))+  "Data.Singletons.TypeLits.Internal.%^_f"             -- ghc-8.8.1, singletons-2.6+    | [i,j] <- naturalLiterals' args+    -> reduce (Literal (NaturalLiteral (i ^ j)))    "GHC.TypeLits.natVal"     | [Lit (NaturalLiteral n), _] <- args@@ -1244,8 +1321,8 @@     -> reduce (Literal (DoubleLiteral (toRational (fromInteger i :: Double))))    "GHC.Base.eqString"-    | [PrimVal _ _ _ [Lit (StringLiteral s1)]-      ,PrimVal _ _ _ [Lit (StringLiteral s2)]+    | [PrimVal _ _ [Lit (StringLiteral s1)]+      ,PrimVal _ _ [Lit (StringLiteral s2)]       ] <- args     -> reduce (boolToBoolLiteral tcm ty (s1 == s2))     | otherwise -> error (show args)@@ -1253,15 +1330,21 @@    "Clash.Class.BitPack.packDouble#" -- :: Double -> BitVector 64     | [DC _ [Left arg]] <- args-    , (h2,[],Literal (DoubleLiteral i)) <- whnf reduceConstant tcm True (h,[],arg)+    , mach2@Machine{mStack=[],mTerm=Literal (DoubleLiteral i)} <- whnf tcm True (setTerm arg $ stackClear mach)     -> let resTyInfo = extractTySizeInfo tcm ty tys-       in  Just (h2,k,mkBitVectorLit' resTyInfo 0 (BitVector.unsafeToInteger $ (pack :: Double -> BitVector 64) $ fromRational i))+        in Just $ mach2+             { mStack = mStack mach+             , mTerm = mkBitVectorLit' resTyInfo 0 (BitVector.unsafeToInteger $ (pack :: Double -> BitVector 64) $ fromRational i)+             }    "Clash.Class.BitPack.packFloat#" -- :: Float -> BitVector 32     | [DC _ [Left arg]] <- args-    , (h2,[],Literal (FloatLiteral i)) <- whnf reduceConstant tcm True (h,[],arg)+    , mach2@Machine{mStack=[],mTerm=Literal (FloatLiteral i)} <- whnf tcm True (setTerm arg $ stackClear mach)     -> let resTyInfo = extractTySizeInfo tcm ty tys-       in  Just (h2,k,mkBitVectorLit' resTyInfo 0 (BitVector.unsafeToInteger $ (pack :: Float -> BitVector 32) $ fromRational i))+        in Just $ mach2+             { mStack = mStack mach+             , mTerm = mkBitVectorLit' resTyInfo 0 (BitVector.unsafeToInteger $ (pack :: Float -> BitVector 32) $ fromRational i)+             }    "Clash.Class.BitPack.unpackFloat#"     | [i] <- bitVectorLiterals' args@@ -1380,6 +1463,12 @@   "Clash.Sized.Internal.BitVector.low"     -> reduce (mkBitLit ty 0 0) +  "Clash.Sized.Internal.BitVector.undefined#"+    | Just (_, kn) <- extractKnownNat tcm tys+    -> let resTyInfo = extractTySizeInfo tcm ty tys+           mask = bit (fromInteger kn) - 1+       in reduce (mkBitVectorLit' resTyInfo mask 0)+ -- Eq   "Clash.Sized.Internal.BitVector.eq##" | [(0,i),(0,j)] <- bitLiterals args     -> reduce (boolToBoolLiteral tcm ty (i == j))@@ -1398,18 +1487,22 @@  -- Bits   "Clash.Sized.Internal.BitVector.and##"-    | [(0,i),(0,j)] <- bitLiterals args-    -> reduce (mkBitLit ty 0 (i .&. j))+    | [i,j] <- bitLiterals args+    -> let Bit msk val = BitVector.and## (toBit i) (toBit j)+       in reduce (mkBitLit ty msk val)   "Clash.Sized.Internal.BitVector.or##"-    | [(0,i),(0,j)] <- bitLiterals args-    -> reduce (mkBitLit ty 0 (i .|. j))+    | [i,j] <- bitLiterals args+    -> let Bit msk val = BitVector.or## (toBit i) (toBit j)+       in reduce (mkBitLit ty msk val)   "Clash.Sized.Internal.BitVector.xor##"-    | [(0,i),(0,j)] <- bitLiterals args-    -> reduce (mkBitLit ty 0 (i `xor` j))+    | [i,j] <- bitLiterals args+    -> let Bit msk val = BitVector.xor## (toBit i) (toBit j)+       in reduce (mkBitLit ty msk val)    "Clash.Sized.Internal.BitVector.complement##"-    | [(0,i)] <- bitLiterals args-    -> reduce (mkBitLit ty 0 (complement i))+    | [i] <- bitLiterals args+    -> let Bit msk val = BitVector.complement## (toBit i)+       in reduce (mkBitLit ty msk val)  -- Pack   "Clash.Sized.Internal.BitVector.pack#"@@ -1473,12 +1566,12 @@   "Clash.Sized.Internal.BitVector.replaceBit#" -- :: :: KnownNat n => BitVector n -> Int -> Bit -> BitVector n     | Just (_, n) <- extractKnownNat tcm tys     , [ _-      , PrimVal bvNm _ _ [_, Lit (IntegerLiteral mskBv), Lit (IntegerLiteral bv)]+      , PrimVal bvP _ [_, Lit (IntegerLiteral mskBv), Lit (IntegerLiteral bv)]       , valArgs -> Just [Literal (IntLiteral i)]-      , PrimVal bNm  _ _ [Lit (IntegerLiteral mskB), Lit (IntegerLiteral b)]+      , PrimVal bP _ [Lit (IntegerLiteral mskB), Lit (IntegerLiteral b)]       ] <- args-    , bvNm == "Clash.Sized.Internal.BitVector.fromInteger#"-    , bNm  == "Clash.Sized.Internal.BitVector.fromInteger##"+    , primName bvP == "Clash.Sized.Internal.BitVector.fromInteger#"+    , primName bP  == "Clash.Sized.Internal.BitVector.fromInteger##"       -> let resTyInfo = extractTySizeInfo tcm ty tys              (mskVal,val) = reifyNat n (op (BV mskBv bv) (fromInteger i) (Bit mskB b))       in reduce (mkBitVectorLit' resTyInfo mskVal val)@@ -1818,8 +1911,8 @@     , Just (i,j) <- indexLiterals args     -> reduce $ catchDivByZero (mkIndexLit ty nTy kn (i `rem` j))   "Clash.Sized.Internal.Index.toInteger#"-    | [PrimVal nm' _ _ [_, Lit (IntegerLiteral i)]] <- args-    , nm' == "Clash.Sized.Internal.Index.fromInteger#"+    | [PrimVal p _ [_, Lit (IntegerLiteral i)]] <- args+    , primName p == "Clash.Sized.Internal.Index.fromInteger#"     -> reduce (integerToIntegerLiteral i)  -- Resize@@ -1955,8 +2048,8 @@     , Just val <- reifyNat kn (liftSigned2 (Signed.mod#) ty tcm tys args)     -> reduce $ catchDivByZero val   "Clash.Sized.Internal.Signed.toInteger#"-    | [PrimVal nm' _ _ [_, Lit (IntegerLiteral i)]] <- args-    , nm' == "Clash.Sized.Internal.Signed.fromInteger#"+    | [PrimVal p _ [_, Lit (IntegerLiteral i)]] <- args+    , primName p == "Clash.Sized.Internal.Signed.fromInteger#"     -> reduce (integerToIntegerLiteral i)  -- Bits@@ -2146,8 +2239,8 @@     , Just val <- reifyNat kn (liftUnsigned2 (Unsigned.rem#) ty tcm tys args)     -> reduce $ catchDivByZero val   "Clash.Sized.Internal.Unsigned.toInteger#"-    | [PrimVal nm' _ _ [_, Lit (IntegerLiteral i)]] <- args-    , nm' == "Clash.Sized.Internal.Unsigned.fromInteger#"+    | [PrimVal p _ [_, Lit (IntegerLiteral i)]] <- args+    , primName p == "Clash.Sized.Internal.Unsigned.fromInteger#"     -> reduce (integerToIntegerLiteral i)  -- Bits@@ -2260,7 +2353,7 @@                          ,Left (mkApps (Data snatDc)                                        [Right k'ty                                        ,Left (Literal (NaturalLiteral (k'-1)))])-                         ,Left (mkApps (Prim nm pInfo)+                         ,Left (mkApps (Prim pInfo)                                        [Right pTy                                        ,Right k'ty                                        ,Right aTy@@ -2270,7 +2363,7 @@                                        ,Left (valToTerm g)                                        ,Left (Either.lefts tArgs !! 1)                                        ])-                         ,Left (mkApps (Prim nm pInfo)+                         ,Left (mkApps (Prim pInfo)                                        [Right pTy                                        ,Right k'ty                                        ,Right aTy@@ -2326,7 +2419,7 @@                       if i' == 0                          then reduceWHNF (Either.lefts vArgs !! 1)                          else reduceWHNF $-                              mkApps (Prim nm pInfo)+                              mkApps (Prim pInfo)                                      [Right (LitTy (NumTy (n'-1)))                                      ,Right aTy                                      ,Left (Literal (NaturalLiteral (n'-1)))@@ -2348,7 +2441,7 @@     -> if n == 0           then reduceWHNF (Either.lefts vArgs !! 1)           else reduceWHNF-                (mkApps (Prim nm pInfo)+                (mkApps (Prim pInfo)                                      [Right (LitTy (NumTy (n-1)))                                      ,Right aTy                                      ,Left (Either.lefts vArgs !! 2)@@ -2368,7 +2461,7 @@           else reduce $                mkVecCons consCon aTy n                   (Either.lefts vArgs !! 1)-                  (mkApps (Prim nm pInfo)+                  (mkApps (Prim pInfo)                                        [Right (LitTy (NumTy (n-1)))                                        ,Right aTy                                        ,Left (Either.lefts vArgs !! 2)])@@ -2403,7 +2496,7 @@                    iAlt   = (tupPat, (Var iId))                in  reduce $                    mkVecCons consCon aTy n' (Either.lefts vArgs !! 1) $-                   mkApps (Prim nm pInfo)+                   mkApps (Prim pInfo)                           [Right (LitTy (NumTy (i'-s')))                           ,Right sTy                           ,Right (LitTy (NumTy (n'-1)))@@ -2433,7 +2526,7 @@                    tupPat = DataPat tupDc [] [fId,iId]                    iAlt   = (tupPat, (Var iId))                in  reduceWHNF $-                   mkApps (Prim nm pInfo)+                   mkApps (Prim pInfo)                      [Right iTy                      ,Right sTy                      ,Right nTy@@ -2470,7 +2563,7 @@            [nilCon,consCon]   = tyConDataCons vecTc            -- Recursive call to @splitAt@            splitAtRec v =-            mkApps (Prim nm pInfo)+            mkApps (Prim pInfo)                    [Right (LitTy (NumTy (m-1)))                    ,Right nTy                    ,Right aTy@@ -2552,7 +2645,7 @@          _ -> reduce $               mkVecCons consCon mVecTy n                 (Case splitAtCall mVecTy [asAlt])-                (mkApps (Prim nm pInfo)+                (mkApps (Prim pInfo)                     [Right (LitTy (NumTy (n-1)))                     ,Right mTy                     ,Right aTy@@ -2585,7 +2678,7 @@             -> -- x : (xs ++ ys)                reduce $                mkVecCons dc aTy (n' + m) (Either.lefts vArgs !! 1)-                 (mkApps (Prim nm pInfo)+                 (mkApps (Prim pInfo)                                       [Right (LitTy (NumTy (n'-1)))                                       ,Right aTy                                       ,Right mTy@@ -2610,7 +2703,7 @@                     ,Right $ mkTyConApp typeNatMul                       [mkTyConApp typeNatSub [nTy,LitTy (NumTy 1)], mTy]                     ,Left h'-                    ,Left $ mkApps (Prim nm pInfo)+                    ,Left $ mkApps (Prim pInfo)                       [ Right (LitTy (NumTy (n-1)))                       , Right mTy                       , Right aTy@@ -2634,7 +2727,7 @@                          then reduce (mkVecCons vecTcNm aTy n' (valToTerm a) (Either.lefts vArgs !! 2))                          else reduce $                               mkVecCons vecTcNm aTy n' (Either.lefts vArgs !! 1)-                                (mkApps (Prim nm pInfo)+                                (mkApps (Prim pInfo)                                         [Right (LitTy (NumTy (n'-1)))                                         ,Right aTy                                         ,Left (Literal (NaturalLiteral (n'-1)))@@ -2668,7 +2761,7 @@                 [Right (LitTy (NumTy (n-1)))                 ,Right aTy                 ,Right (LitTy (NumTy 1))-                ,Left (mkApps (Prim nm pInfo)+                ,Left (mkApps (Prim pInfo)                               [Right (LitTy (NumTy (n-1)))                               ,Right aTy                               ,Left (Either.lefts vArgs !! 2)@@ -2707,7 +2800,7 @@                                        ,Left (primCo consCoTy)                                        ])                        , Left  (Either.lefts vArgs !! 1)-                       , Left  (mkApps (Prim nm pInfo)+                       , Left  (mkApps (Prim pInfo)                                        [ Right nTy                                        , Right (LitTy (NumTy (m'-1)))                                        , Right aTy@@ -2715,6 +2808,7 @@                                        , Left  (Either.lefts vArgs !! 2)                                        ])                        ]+   "Clash.Sized.Vector.rotateLeftS" -- :: KnownNat n => Vec n a -> SNat d -> Vec n a     | nTy : aTy : _ : _ <- tys     , kn : xs : d : _ <- args@@ -2723,14 +2817,14 @@     -> case n of          0  -> reduce (mkVecNil dc aTy)          n' | DC snatDc [_,Left d'] <- d-            , (h2,[],Literal (NaturalLiteral d2)) <- whnf reduceConstant tcm isSubj (h,[],d')+            , mach2@Machine{mStack=[],mTerm=Literal (NaturalLiteral d2)} <- whnf tcm isSubj (setTerm d' $ stackClear mach)             -> case (d2 `mod` n) of                  0  -> reduce (valToTerm xs)                  d3 -> let (_,tyView -> TyConApp vecTcNm _) = splitFunForallTy ty                            (Just vecTc)     = lookupUniqMap vecTcNm tcm                            [nilCon,consCon] = tyConDataCons vecTc-                       in  reduceWHNF' h2 $-                           mkApps (Prim nm pInfo)+                       in  reduceWHNF' mach2 $+                           mkApps (Prim pInfo)                                   [Right nTy                                   ,Right aTy                                   ,Right (LitTy (NumTy (d3-1)))@@ -2746,6 +2840,7 @@                                                 ,Left  (Literal (NaturalLiteral (d3-1)))])                                   ]          _  -> Nothing+   "Clash.Sized.Vector.rotateRightS" -- :: KnownNat n => Vec n a -> SNat d -> Vec n a     | isSubj     , nTy : aTy : _ : _ <- tys@@ -2755,12 +2850,12 @@     -> case n of          0  -> reduce (mkVecNil dc aTy)          n' | DC snatDc [_,Left d'] <- d-            , (h2,[],Literal (NaturalLiteral d2)) <- whnf reduceConstant tcm isSubj (h,[],d')+            , mach2@Machine{mStack=[],mTerm=Literal (NaturalLiteral d2)} <- whnf tcm isSubj (setTerm d' $ stackClear mach)             -> case (d2 `mod` n) of                  0  -> reduce (valToTerm xs)                  d3 -> let (_,tyView -> TyConApp vecTcNm _) = splitFunForallTy ty-                       in  reduceWHNF' h2 $-                           mkApps (Prim nm pInfo)+                       in  reduceWHNF' mach2 $+                           mkApps (Prim pInfo)                                   [Right nTy                                   ,Right aTy                                   ,Right (LitTy (NumTy (d3-1)))@@ -2791,7 +2886,7 @@          n' -> reduce $                mkVecCons dc bTy n'                  (mkApps (valToTerm (args !! 0)) [Left (Either.lefts vArgs !! 1)])-                 (mkApps (Prim nm pInfo)+                 (mkApps (Prim pInfo)                                       [Right aTy                                       ,Right bTy                                       ,Right (LitTy (NumTy (n' - 1)))@@ -2806,8 +2901,7 @@     , Right n <- runExcept (tyNatSize tcm nTy)     , let iLit = mkIndexLit (Either.rights tyArgs' !! 0) nTy n 0     -> reduceWHNF $-       mkApps (Prim "Clash.Sized.Vector.imap_go"-                    (PrimInfo (vecImapGoTy vecTcNm indexTcNm) WorkNever))+       mkApps (Prim (PrimInfo "Clash.Sized.Vector.imap_go" (vecImapGoTy vecTcNm indexTcNm) WorkNever))               [Right nTy               ,Right nTy               ,Right aTy@@ -2831,13 +2925,12 @@                    iLit = mkIndexLit (Either.rights tyArgs !! 0) nTy n' 1                in reduce $ mkVecCons dc bTy m'                  (mkApps (valToTerm f) [Left (valToTerm n),Left (Either.lefts vArgs !! 1)])-                 (mkApps (Prim nm pInfo)+                 (mkApps (Prim pInfo)                          [Right nTy                          ,Right (LitTy (NumTy (m'-1)))                          ,Right aTy                          ,Right bTy-                         ,Left (mkApps (Prim "Clash.Sized.Internal.Index.+#"-                                             (PrimInfo (indexAddTy indexTcNm) WorkVariable))+                         ,Left (mkApps (Prim (PrimInfo "Clash.Sized.Internal.Index.+#" (indexAddTy indexTcNm) WorkVariable))                                        [Right nTy                                        ,Left (Literal (NaturalLiteral n'))                                        ,Left (valToTerm n)@@ -2866,7 +2959,7 @@                                     ,Left  (valToTerm ys)                                     ])                             ])-                 (mkApps (Prim nm pInfo)+                 (mkApps (Prim pInfo)                                       [Right aTy                                       ,Right bTy                                       ,Right cTy@@ -2891,7 +2984,7 @@          _ -> reduceWHNF $               mkApps (valToTerm f)                      [Left (Either.lefts vArgs !! 1)-                     ,Left (mkApps (Prim nm pInfo)+                     ,Left (mkApps (Prim pInfo)                                    [Right aTy                                    ,Right bTy                                    ,Right (LitTy (NumTy (n-1)))@@ -2921,8 +3014,7 @@                   n1mTy  = LitTy (NumTy n1)                   n1m'ty = LitTy (NumTy (n1-1))                   splitAtCall =-                   mkApps (Prim "Clash.Sized.Vector.fold_split"-                                (PrimInfo (foldSplitAtTy vecTcNm) WorkNever))+                   mkApps (Prim (PrimInfo "Clash.Sized.Vector.fold_split" (foldSplitAtTy vecTcNm) WorkNever))                           [Right mTy                           ,Right n1mTy                           ,Right aTy@@ -2941,13 +3033,13 @@                   bsAlt    = (tupPat, (Var bsId))               in  reduceWHNF $                   mkApps (valToTerm f)-                         [Left (mkApps (Prim nm pInfo)+                         [Left (mkApps (Prim pInfo)                                        [Right aTy                                        ,Right m'ty                                        ,Left (valToTerm f)                                        ,Left (Case splitAtCall mVecTy [asAlt])                                        ])-                         ,Left (mkApps (Prim nm pInfo)+                         ,Left (mkApps (Prim pInfo)                                        [Right aTy                                        ,Right n1m'ty                                        ,Left  (valToTerm f)@@ -2971,7 +3063,7 @@            [nilCon,consCon]   = tyConDataCons vecTc            -- Recursive call to @splitAt@            splitAtRec v =-            mkApps (Prim nm pInfo)+            mkApps (Prim pInfo)                    [Right (LitTy (NumTy (m-1)))                    ,Right nTy                    ,Right aTy@@ -3031,7 +3123,7 @@                                        [Right k'ty                                        ,Left (Literal (NaturalLiteral (k'-1)))])                          ,Left (Either.lefts vArgs !! 1)-                         ,Left (mkApps (Prim nm pInfo)+                         ,Left (mkApps (Prim pInfo)                                        [Right pTy                                        ,Right k'ty                                        ,Right aTy@@ -3086,7 +3178,7 @@                          ,Left (mkApps (Data snatDc)                                        [Right k'ty                                        ,Left (Literal (NaturalLiteral (k'-1)))])-                         ,Left (mkApps (Prim nm pInfo)+                         ,Left (mkApps (Prim pInfo)                                        [Right pTy                                        ,Right k'ty                                        ,Right aTy@@ -3095,7 +3187,7 @@                                        ,Left (valToTerm f)                                        ,Left (valToTerm g)                                        ,Left (Case splitAtCall xsSVecTy [asAlt])])-                         ,Left (mkApps (Prim nm pInfo)+                         ,Left (mkApps (Prim pInfo)                                        [Right pTy                                        ,Right k'ty                                        ,Right aTy@@ -3124,7 +3216,7 @@                              , Right aTy                              , Left  (valToTerm xs)                              ])-                     (mkApps (Prim nm pInfo)+                     (mkApps (Prim pInfo)                              [ Right (LitTy (NumTy (n' - 1)))                              , Right aTy                              , Left  (Literal (NaturalLiteral (n'-1)))@@ -3143,7 +3235,7 @@     , Right n <- runExcept (tyNatSize tcm nTy)     -> case n of          0 -> let (pureF,ids') = runPEM (mkSelectorCase $(curLoc) is0 tcm (valToTerm apDict) 1 1) ids-              in  reduceWHNF' (Heap gh gbl h' ids' is0) $+              in  reduceWHNF' (mach { mSupply = ids' }) $                   mkApps pureF                          [Right (mkTyConApp (vecTcNm) [nTy,bTy])                          ,Left  (mkVecNil dc bTy)]@@ -3154,7 +3246,7 @@                     return (fmapF',apF')                   n'ty = LitTy (NumTy (n-1))                   Just (consCoTy : _) = dataConInstArgTys dc [nTy,bTy,n'ty]-              in  reduceWHNF' (Heap gh gbl h' ids' is0) $+              in  reduceWHNF' (mach { mSupply = ids' }) $                   mkApps apF                          [Right (mkTyConApp vecTcNm [n'ty,bTy])                          ,Right (mkTyConApp vecTcNm [nTy,bTy])@@ -3170,7 +3262,7 @@                                        ,Left (mkApps (valToTerm f)                                                      [Left (Either.lefts vArgs !! 1)])                                        ])-                         ,Left (mkApps (Prim nm pInfo)+                         ,Left (mkApps (Prim pInfo)                                        [Right aTy                                        ,Right fTy                                        ,Right bTy@@ -3183,7 +3275,7 @@     where       (tyArgs,_)         = splitFunForallTy ty       TyConApp vecTcNm _ = tyView (Either.rights tyArgs !! 2)-      Heap gh gbl h' ids is0 = h+      (ids, is0) = (mSupply mach, mScopeNames mach)  -- BitPack   "Clash.Sized.Vector.concatBitVector#"@@ -3203,7 +3295,7 @@                  , Right mTy                  , Left (Literal (NaturalLiteral ((n'-1)*m)))                  , Left (Either.lefts vArgs !! 1)-                 , Left (mkApps (Prim nm pInfo)+                 , Left (mkApps (Prim pInfo)                                 [ Right (LitTy (NumTy (n'-1)))                                 , Right mTy                                 , Left (Literal (NaturalLiteral (n'-1)))@@ -3253,7 +3345,7 @@            in  reduce $ mkVecCons consCon (mkTyConApp bvTcNm [mTy]) n'                 (Case splitCall mBVTy [xAlt])-                (mkApps (Prim nm pInfo)+                (mkApps (Prim pInfo)                         [ Right (LitTy (NumTy (n'-1)))                         , Right mTy                         , Left (Literal (NaturalLiteral (n'-1)))@@ -3287,15 +3379,19 @@       else         f (map fromInteger natsAsInts) -    reduce :: Term -> Maybe (Heap, Stack, Term)+    reduce :: Term -> Maybe Machine     reduce e = case isX e of-      Left msg -> trace (unlines ["Warning: Not evaluating constant expression:", show nm, "Because doing so generates an XException:", msg]) Nothing-      Right e' -> Just (h,k,e')-    reduceWHNF e = let (h2,[],e') = whnf reduceConstant tcm isSubj (h,[],e)-                   in  Just (h2,k,e')-    reduceWHNF' h' e = let (h2,[],e') = whnf reduceConstant tcm isSubj (h',[],e)-                       in  Just (h2,k,e')+      Left msg -> trace (unlines ["Warning: Not evaluating constant expression:", show (primName pInfo), "Because doing so generates an XException:", msg]) Nothing+      Right e' -> Just (setTerm e' mach) +    reduceWHNF e =+      let mach1@Machine{mStack=[]} = whnf tcm isSubj (setTerm e $ stackClear mach)+      in Just $ mach1 { mStack = mStack mach }++    reduceWHNF' mach1 e =+      let mach2@Machine{mStack=[]} = whnf tcm isSubj (setTerm e mach1)+       in Just $ mach2 { mStack = mStack mach }+     makeUndefinedIf :: Exception e => (e -> Bool) -> Term -> Term     makeUndefinedIf wantToHandle tm =       case unsafeDupablePerformIO $ tryJust selectException (evaluate $ force tm) of@@ -3306,129 +3402,149 @@         selectException e | wantToHandle e = Just e                           | otherwise = Nothing         msg e = unlines ["Warning: caught exception: \"" ++ show e ++ "\" while trying to evaluate: "-                        , showPpr (mkApps (Prim nm pInfo) (map (Left . valToTerm) args))+                        , showPpr (mkApps (Prim pInfo) (map (Left . valToTerm) args))                         ]      catchDivByZero = makeUndefinedIf (==DivideByZero) -typedLiterals' :: (Value -> Maybe a) -> [Value] -> [a]-typedLiterals' typedLiteral = mapMaybe typedLiteral+-- Helper functions for literals +pairOf :: (Value -> Maybe a) -> [Value] -> Maybe (a, a)+pairOf f [x, y] = (,) <$> f x <*> f y+pairOf _ _ = Nothing++listOf :: (Value -> Maybe a) -> [Value] -> [a]+listOf = mapMaybe++wrapUnsigned :: Integer -> Integer -> Integer+wrapUnsigned n i = i `mod` sz+ where+  sz = 1 `shiftL` fromInteger n++wrapSigned :: Integer -> Integer -> Integer+wrapSigned n i = if mask == 0 then 0 else res+ where+  mask = 1 `shiftL` fromInteger (n - 1)+  res  = case divMod i mask of+           (s,i1) | even s    -> i1+                  | otherwise -> i1 - mask+ doubleLiterals' :: [Value] -> [Rational]-doubleLiterals' = typedLiterals' doubleLiteral-  where-    doubleLiteral x = case x of-      Lit (DoubleLiteral i) -> Just i-      _ -> Nothing+doubleLiterals' = listOf doubleLiteral +doubleLiteral :: Value -> Maybe Rational+doubleLiteral v = case v of+  Lit (DoubleLiteral i) -> Just i+  _ -> Nothing+ floatLiterals' :: [Value] -> [Rational]-floatLiterals' = typedLiterals' floatLiteral-  where-    floatLiteral x = case x of-      Lit (FloatLiteral i) -> Just i-      _ -> Nothing+floatLiterals' = listOf floatLiteral -integerLiterals :: [Value] -> Maybe (Integer, Integer)-integerLiterals args = case integerLiterals' args of-  [i,j] -> Just (i,j)+floatLiteral :: Value -> Maybe Rational+floatLiteral v = case v of+  Lit (FloatLiteral i) -> Just i   _ -> Nothing +integerLiterals :: [Value] -> Maybe (Integer, Integer)+integerLiterals = pairOf integerLiteral++integerLiteral :: Value -> Maybe Integer+integerLiteral v =+  case v of+    Lit (IntegerLiteral i) -> Just i+    DC dc [Left (Literal (IntLiteral i))]+      | dcTag dc == 1+      -> Just i+    DC dc [Left (Literal (ByteArrayLiteral (Vector.Vector _ _ (ByteArray.ByteArray ba))))]+      | dcTag dc == 2+      -> Just (Jp# (BN# ba))+      | dcTag dc == 3+      -> Just (Jn# (BN# ba))+    _ -> Nothing+ naturalLiterals :: [Value] -> Maybe (Integer, Integer)-naturalLiterals args = case naturalLiterals' args of-  [i,j] -> Just (i, j)-  _ -> Nothing+naturalLiterals = pairOf naturalLiteral +naturalLiteral :: Value -> Maybe Integer+naturalLiteral v =+  case v of+    Lit (NaturalLiteral i) -> Just i+    DC dc [Left (Literal (WordLiteral i))]+      | dcTag dc == 1+      -> Just i+    DC dc [Left (Literal (ByteArrayLiteral (Vector.Vector _ _ (ByteArray.ByteArray ba))))]+      | dcTag dc == 2+      -> Just (Jp# (BN# ba))+    _ -> Nothing+ integerLiterals' :: [Value] -> [Integer]-integerLiterals' = typedLiterals' integerLiteral+integerLiterals' = listOf integerLiteral  naturalLiterals' :: [Value] -> [Integer]-naturalLiterals' = typedLiterals' naturalLiteral+naturalLiterals' = listOf naturalLiteral  intLiterals :: [Value] -> Maybe (Integer,Integer)-intLiterals args = case args of-  [Lit (IntLiteral i), Lit (IntLiteral j)] -> Just (i,j)-  _ -> Nothing+intLiterals = pairOf intLiteral  intLiterals' :: [Value] -> [Integer]-intLiterals' = typedLiterals' intLiteral-  where-    intLiteral x = case x of-      Lit (IntLiteral i) -> Just i-      _ -> Nothing+intLiterals' = listOf intLiteral +intLiteral :: Value -> Maybe Integer+intLiteral x = case x of+  Lit (IntLiteral i) -> Just i+  _ -> Nothing+ intCLiteral :: Value -> Maybe Integer-intCLiteral (DC _ [Left (Literal (IntLiteral i))]) = Just i-intCLiteral _                                      = Nothing+intCLiteral v = case v of+  (DC _ [Left (Literal (IntLiteral i))]) -> Just i+  _ -> Nothing  intCLiterals :: [Value] -> Maybe (Integer, Integer)-intCLiterals (a1:a2:_) = liftA2 (,) (intCLiteral a1) (intCLiteral a2)-intCLiterals _         = Nothing+intCLiterals = pairOf intCLiteral -intCLiterals' :: [Value] -> [Integer]-intCLiterals' = catMaybes . map intCLiteral+wordLiterals :: [Value] -> Maybe (Integer,Integer)+wordLiterals = pairOf wordLiteral -mkIntCLiteral-  :: HasCallStack-  => Value-  -- ^ Some existing intC literal. To construct a new intC literal, this-  -- function needs the dataconstructor.-  -> Integer-  -- ^ New value of intC literal-  -> Term-mkIntCLiteral (DC dc [Left (Literal (IntLiteral _))]) i =-  App (Data dc) (Literal (IntLiteral i))-mkIntCLiteral v _i =-  error $ "Report as bug: mkIntCLiteral was called with wrong value: " ++ show v+wordLiterals' :: [Value] -> [Integer]+wordLiterals' = listOf wordLiteral -wordLiterals :: [Value] -> Maybe (Integer,Integer)-wordLiterals args = case args of-  [Lit (WordLiteral i), Lit (WordLiteral j)] -> Just (i,j)+wordLiteral :: Value -> Maybe Integer+wordLiteral x = case x of+  Lit (WordLiteral i) -> Just i   _ -> Nothing-wordLiterals' :: [Value] -> [Integer]-wordLiterals' = typedLiterals' wordLiteral-  where-    wordLiteral x = case x of-      Lit (WordLiteral i) -> Just i-      _ -> Nothing  charLiterals :: [Value] -> Maybe (Char,Char)-charLiterals args = case args of-  [Lit (CharLiteral i), Lit (CharLiteral j)] -> Just (i,j)-  _ -> Nothing+charLiterals = pairOf charLiteral  charLiterals' :: [Value] -> [Char]-charLiterals' = typedLiterals' charLiteral-  where-    charLiteral x = case x of-      Lit (CharLiteral c) -> Just c-      _ -> Nothing+charLiterals' = listOf charLiteral +charLiteral :: Value -> Maybe Char+charLiteral x = case x of+  Lit (CharLiteral c) -> Just c+  _ -> Nothing+ sizedLiterals :: Text -> [Value] -> Maybe (Integer,Integer)-sizedLiterals szCon args-  = case args of-      ([ PrimVal nm  _ _ [_, Lit (IntegerLiteral i)]-       , PrimVal nm' _ _ [_, Lit (IntegerLiteral j)]])-        | nm  == szCon-        , nm' == szCon -> Just (i,j)-      _ -> Nothing+sizedLiterals szCon = pairOf (sizedLiteral szCon)  sizedLiterals' :: Text -> [Value] -> [Integer]-sizedLiterals' szCon = typedLiterals' (sizedLiteral szCon)+sizedLiterals' szCon = listOf (sizedLiteral szCon)  sizedLiteral :: Text -> Value -> Maybe Integer sizedLiteral szCon val = case val of-  PrimVal nm  _ _ [_, Lit (IntegerLiteral i)] | nm == szCon -> Just i+  PrimVal p _ [_, Lit (IntegerLiteral i)]+    | primName p == szCon -> Just i   _ -> Nothing  bitLiterals   :: [Value]   -> [(Integer,Integer)]-bitLiterals = map normalizeBit . typedLiterals' go+bitLiterals = map normalizeBit . mapMaybe go  where   normalizeBit (msk,v) = (msk .&. 1, v .&. 1)   go val = case val of-    PrimVal nm _ _ [Lit (IntegerLiteral m), Lit (IntegerLiteral i)]-      | nm == "Clash.Sized.Internal.BitVector.fromInteger##"+    PrimVal p _ [Lit (IntegerLiteral m), Lit (IntegerLiteral i)]+      | primName p == "Clash.Sized.Internal.BitVector.fromInteger##"       -> Just (m,i)     _ -> Nothing @@ -3438,45 +3554,43 @@ signedLiterals    = sizedLiterals "Clash.Sized.Internal.Signed.fromInteger#" unsignedLiterals  = sizedLiterals "Clash.Sized.Internal.Unsigned.fromInteger#" -bitVectorLiterals-  :: [Value] -> Maybe ((Integer,Integer),(Integer,Integer))-bitVectorLiterals args-  = case args of-      ([ PrimVal nm  _ _ [_, Lit (IntegerLiteral mi), Lit (IntegerLiteral i)]-       , PrimVal nm' _ _ [_, Lit (IntegerLiteral mj), Lit (IntegerLiteral j)]])-        | nm  == "Clash.Sized.Internal.BitVector.fromInteger#"-        , nm' == "Clash.Sized.Internal.BitVector.fromInteger#" -> Just ((mi,i),(mj,j))-      _ -> Nothing- indexLiterals', signedLiterals', unsignedLiterals'   :: [Value] -> [Integer] indexLiterals'     = sizedLiterals' "Clash.Sized.Internal.Index.fromInteger#" signedLiterals'    = sizedLiterals' "Clash.Sized.Internal.Signed.fromInteger#" unsignedLiterals'  = sizedLiterals' "Clash.Sized.Internal.Unsigned.fromInteger#" +bitVectorLiterals+  :: [Value] -> Maybe ((Integer,Integer),(Integer,Integer))+bitVectorLiterals = pairOf bitVectorLiteral+ bitVectorLiterals'   :: [Value] -> [(Integer,Integer)]-bitVectorLiterals' = mapMaybe go- where-  go :: Value -> Maybe (Integer,Integer)-  go val = case val of-    PrimVal nm  _ _ [_, Lit (IntegerLiteral mi), Lit (IntegerLiteral i)]-      | nm == "Clash.Sized.Internal.BitVector.fromInteger#" -> Just (mi, i)-    _ -> Nothing+bitVectorLiterals' = listOf bitVectorLiteral +bitVectorLiteral :: Value -> Maybe (Integer, Integer)+bitVectorLiteral val = case val of+  (PrimVal p _ [_, Lit (IntegerLiteral m), Lit (IntegerLiteral i)])+    | primName p == "Clash.Sized.Internal.BitVector.fromInteger#" -> Just (m, i)+  _ -> Nothing+ toBV :: (Integer,Integer) -> BitVector n toBV = uncurry BV  splitBV :: BitVector n -> (Integer,Integer) splitBV (BV msk val) = (msk,val) +toBit :: (Integer,Integer) -> Bit+toBit = uncurry Bit+ valArgs   :: Value   -> Maybe [Term]-valArgs (PrimVal _ _ _ vs) = Just (map valToTerm vs)-valArgs (DC _ args)        = Just (Either.lefts args)-valArgs _                  = Nothing-+valArgs v =+  case v of+    PrimVal _ _ vs -> Just (fmap valToTerm vs)+    DC _ args -> Just (Either.lefts args)+    _ -> Nothing  -- Tries to match literal arguments to a function like --   (Unsigned.shiftL#  :: forall n. KnownNat n => Unsigned n -> Int -> Unsigned n)@@ -3486,10 +3600,10 @@ sizedLitIntLit szCon tcm tys args   | Just (nTy,kn) <- extractKnownNat tcm tys   , [_-    ,PrimVal nm _ _ [_,Lit (IntegerLiteral i)]+    ,PrimVal p _ [_,Lit (IntegerLiteral i)]     ,valArgs -> Just [Literal (IntLiteral j)]     ] <- args-  , nm == szCon+  , primName p == szCon   = Just (nTy,kn,i,j)   | otherwise   = Nothing@@ -3506,10 +3620,10 @@ bitVectorLitIntLit tcm tys args   | Just (nTy,kn) <- extractKnownNat tcm tys   , [_-    ,PrimVal nm _ _ [_,Lit (IntegerLiteral m),Lit (IntegerLiteral i)]+    ,PrimVal p _ [_,Lit (IntegerLiteral m),Lit (IntegerLiteral i)]     ,valArgs -> Just [Literal (IntLiteral j)]     ] <- args-  , nm == "Clash.Sized.Internal.BitVector.fromInteger#"+  , primName p == "Clash.Sized.Internal.BitVector.fromInteger#"   = Just (nTy,kn,(m,i),j)   | otherwise   = Nothing@@ -3525,20 +3639,14 @@     -> Just (nTy, nInt)   _ -> Nothing -extractKnownNatVal :: TyConMap -> [Type] -> Maybe Integer-extractKnownNatVal tcm tys = fmap snd (extractKnownNat tcm tys)- -- From an argument list to function of type --   forall n m o .. . (KnownNat n, KnownNat m, KnownNat o, ..) => ... -- extract [(nTy,nInt), (mTy,mInt), (oTy,oInt)] -- where nTy is the Type of n -- and   nInt is its value as an Integer extractKnownNats :: TyConMap -> [Type] -> [(Type, Integer)]-extractKnownNats tcm tys =-  catMaybes (map (extractKnownNat tcm . pure)  tys)--extractKnownNatVals :: TyConMap -> [Type] -> [Integer]-extractKnownNatVals tcm tys = map snd (extractKnownNats tcm tys)+extractKnownNats tcm =+  mapMaybe (extractKnownNat tcm . pure)  -- Construct a constant term of a sized type mkSizedLit@@ -3644,26 +3752,6 @@ mkIndexLit rTy nTy kn val =   either id id (mkIndexLitE rTy nTy kn val) --- | Construct a constant term of a sized type-mkSizedLit'-  :: (Type -> Term)-  -- ^ Type constructor?-  -> (Type, Type, Integer)-  -- ^ (result type, forall n., KnownNat n)-  -> Integer-  -- ^ Value to construct-  -> Term-mkSizedLit' conPrim (ty,nTy,kn) = mkSizedLit conPrim ty nTy kn--mkSignedLit', mkUnsignedLit'-  :: (Type, Type, Integer)-  -- ^ (result type, forall n., KnownNat n)-  -> Integer-  -- ^ Value to construct-  -> Term-mkSignedLit'    = mkSizedLit' signedConPrim-mkUnsignedLit'  = mkSizedLit' unsignedConPrim- mkBitVectorLit'   :: (Type, Type, Integer)   -- ^ (result type, forall n., KnownNat n)@@ -3751,14 +3839,14 @@  bConPrim :: Type -> Term bConPrim (tyView -> TyConApp bTcNm _)-  = Prim "Clash.Sized.Internal.BitVector.fromInteger##" (PrimInfo funTy WorkNever)+  = Prim (PrimInfo "Clash.Sized.Internal.BitVector.fromInteger##" funTy WorkNever)   where     funTy      = foldr1 mkFunTy [integerPrimTy,integerPrimTy,mkTyConApp bTcNm []] bConPrim _ = error $ $(curLoc) ++ "called with incorrect type"  bvConPrim :: Type -> Term bvConPrim (tyView -> TyConApp bvTcNm _)-  = Prim "Clash.Sized.Internal.BitVector.fromInteger#" (PrimInfo (ForAllTy nTV funTy) WorkNever)+  = Prim (PrimInfo "Clash.Sized.Internal.BitVector.fromInteger#" (ForAllTy nTV funTy) WorkNever)   where     funTy = foldr1 mkFunTy [naturalPrimTy,integerPrimTy,integerPrimTy,mkTyConApp bvTcNm [nVar]]     nName = mkUnsafeSystemName "n" 0@@ -3768,7 +3856,7 @@  indexConPrim :: Type -> Term indexConPrim (tyView -> TyConApp indexTcNm _)-  = Prim "Clash.Sized.Internal.Index.fromInteger#" (PrimInfo (ForAllTy nTV funTy) WorkNever)+  = Prim (PrimInfo "Clash.Sized.Internal.Index.fromInteger#" (ForAllTy nTV funTy) WorkNever)   where     funTy        = foldr1 mkFunTy [naturalPrimTy,integerPrimTy,mkTyConApp indexTcNm [nVar]]     nName      = mkUnsafeSystemName "n" 0@@ -3778,7 +3866,7 @@  signedConPrim :: Type -> Term signedConPrim (tyView -> TyConApp signedTcNm _)-  = Prim "Clash.Sized.Internal.Signed.fromInteger#" (PrimInfo (ForAllTy nTV funTy) WorkNever)+  = Prim (PrimInfo "Clash.Sized.Internal.Signed.fromInteger#" (ForAllTy nTV funTy) WorkNever)   where     funTy        = foldr1 mkFunTy [naturalPrimTy,integerPrimTy,mkTyConApp signedTcNm [nVar]]     nName      = mkUnsafeSystemName "n" 0@@ -3788,7 +3876,7 @@  unsignedConPrim :: Type -> Term unsignedConPrim (tyView -> TyConApp unsignedTcNm _)-  = Prim "Clash.Sized.Internal.Unsigned.fromInteger#" (PrimInfo (ForAllTy nTV funTy) WorkNever)+  = Prim (PrimInfo "Clash.Sized.Internal.Unsigned.fromInteger#" (ForAllTy nTV funTy) WorkNever)   where     funTy        = foldr1 mkFunTy [naturalPrimTy,integerPrimTy,mkTyConApp unsignedTcNm [nVar]]     nName        = mkUnsafeSystemName "n" 0@@ -3959,15 +4047,15 @@   :: TyConName   -- ^ Vec TyCon name   -> Term-vecHeadPrim vecTcNm = Prim "Clash.Sized.Vector.head"-                           (PrimInfo (vecHeadTy vecTcNm) WorkNever)+vecHeadPrim vecTcNm =+  Prim (PrimInfo "Clash.Sized.Vector.head" (vecHeadTy vecTcNm) WorkNever)  vecLastPrim   :: TyConName   -- ^ Vec TyCon name   -> Term-vecLastPrim vecTcNm = Prim "Clash.Sized.Vector.last"-                           (PrimInfo (vecHeadTy vecTcNm) WorkNever)+vecLastPrim vecTcNm =+  Prim (PrimInfo "Clash.Sized.Vector.last" (vecHeadTy vecTcNm) WorkNever)  vecHeadTy   :: TyConName@@ -3991,15 +4079,15 @@   :: TyConName   -- ^ Vec TyCon name   -> Term-vecTailPrim vecTcNm = Prim "Clash.Sized.Vector.tail"-                           (PrimInfo (vecTailTy vecTcNm) WorkNever)+vecTailPrim vecTcNm =+  Prim (PrimInfo "Clash.Sized.Vector.tail" (vecTailTy vecTcNm) WorkNever)  vecInitPrim   :: TyConName   -- ^ Vec TyCon name   -> Term-vecInitPrim vecTcNm = Prim "Clash.Sized.Vector.init"-                           (PrimInfo (vecTailTy vecTcNm) WorkNever)+vecInitPrim vecTcNm =+  Prim (PrimInfo "Clash.Sized.Vector.init" (vecTailTy vecTcNm) WorkNever)  vecTailTy   :: TyConName@@ -4028,8 +4116,7 @@   -- ^ Vec TyCon name   -> Term splitAtPrim snatTcNm vecTcNm =-  Prim "Clash.Sized.Vector.splitAt"-       (PrimInfo (splitAtTy snatTcNm vecTcNm) WorkNever)+  Prim (PrimInfo "Clash.Sized.Vector.splitAt" (splitAtTy snatTcNm vecTcNm) WorkNever)  splitAtTy   :: TyConName@@ -4095,8 +4182,8 @@   :: TyConName   -- ^ Vec TyCon name   -> Term-vecAppendPrim vecNm = Prim "Clash.Sized.Vector.++"-                           (PrimInfo (vecAppendTy vecNm) WorkNever)+vecAppendPrim vecNm =+  Prim (PrimInfo "Clash.Sized.Vector.++" (vecAppendTy vecNm) WorkNever)  vecAppendTy   :: TyConName@@ -4128,8 +4215,8 @@   :: TyConName   -- ^ Vec TyCon name   -> Term-vecZipWithPrim vecNm = Prim "Clash.Sized.Vector.zipWith"-                            (PrimInfo (vecAppendTy vecNm) WorkNever)+vecZipWithPrim vecNm =+  Prim (PrimInfo "Clash.Sized.Vector.zipWith" (vecZipWithTy vecNm) WorkNever)  vecZipWithTy   :: TyConName@@ -4200,8 +4287,8 @@   :: TyConName   -- ^ BitVector TyCon Name   -> Term-bvAppendPrim bvTcNm = Prim "Clash.Sized.Internal.BitVector.++#"-                           (PrimInfo (bvAppendTy bvTcNm) WorkNever)+bvAppendPrim bvTcNm =+  Prim (PrimInfo "Clash.Sized.Internal.BitVector.++#" (bvAppendTy bvTcNm) WorkNever)  bvAppendTy   :: TyConName@@ -4225,8 +4312,8 @@   :: TyConName   -- ^ BitVector TyCon Name   -> Term-bvSplitPrim bvTcNm = Prim "Clash.Sized.Internal.BitVector.split#"-                          (PrimInfo (bvSplitTy bvTcNm) WorkNever)+bvSplitPrim bvTcNm =+  Prim (PrimInfo "Clash.Sized.Internal.BitVector.split#" (bvSplitTy bvTcNm) WorkNever)  bvSplitTy   :: TyConName@@ -4278,3 +4365,7 @@  svoid :: (State# RealWorld -> State# RealWorld) -> IO () svoid m0 = IO (\s -> case m0 s of s' -> (# s', () #))++isTrueDC,isFalseDC :: DataCon -> Bool+isTrueDC dc  = dcUniq dc == getKey trueDataConKey+isFalseDC dc = dcUniq dc == getKey falseDataConKey
src-ghc/Clash/GHC/GHC2Core.hs view
@@ -6,12 +6,10 @@   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com> -} -{-# LANGUAGE CPP              #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell  #-}-{-# LANGUAGE TupleSections    #-}-{-# LANGUAGE ViewPatterns     #-}+{-# LANGUAGE TemplateHaskell #-}  {-# OPTIONS_GHC -fno-warn-orphans #-} @@ -32,13 +30,13 @@  -- External Modules import           Control.Lens                ((^.), (%~), (&), (%=))-import           Control.Monad.RWS.Lazy      (RWS)-import qualified Control.Monad.RWS.Lazy      as RWS+import           Control.Monad.RWS.Strict    (RWS)+import qualified Control.Monad.RWS.Strict    as RWS import qualified Data.ByteString.Char8       as Char8+import           Data.Char                   (isDigit) import           Data.Hashable               (Hashable (..))-import           Data.HashMap.Lazy           (HashMap)-import qualified Data.HashMap.Lazy           as HashMap-import qualified Data.HashMap.Strict         as HSM+import           Data.HashMap.Strict         (HashMap)+import qualified Data.HashMap.Strict         as HashMap import           Data.Maybe                  (catMaybes,fromMaybe,listToMaybe) #if !MIN_VERSION_base(4,11,0) import           Data.Semigroup@@ -47,6 +45,7 @@ import qualified Data.Text                   as Text import           Data.Text.Encoding          (decodeUtf8) import qualified Data.Traversable            as T+import qualified Text.Read                   as Text  -- GHC API import CoAxiom    (CoAxiom (co_ax_branches), CoAxBranch (cab_lhs,cab_rhs),@@ -131,7 +130,7 @@ makeLenses ''GHC2CoreState  emptyGHC2CoreState :: GHC2CoreState-emptyGHC2CoreState = GHC2CoreState C.emptyUniqMap HSM.empty+emptyGHC2CoreState = GHC2CoreState C.emptyUniqMap HashMap.empty  newtype SrcSpanRB = SrcSpanRB {unSrcSpanRB :: SrcSpan} @@ -335,11 +334,42 @@         go "Clash.Magic.suffixName" args           | [Type nmTy,_aTy,f] <- args           = C.Tick <$> (C.NameMod C.SuffixName <$> coreToType nmTy) <*> term f+        go "Clash.Magic.suffixNameFromNat" args+          | [Type nmTy,_aTy,f] <- args+          = C.Tick <$> (C.NameMod C.SuffixName <$> coreToType nmTy) <*> term f+        go "Clash.Magic.suffixNameP" args+          | [Type nmTy,_aTy,f] <- args+          = C.Tick <$> (C.NameMod C.SuffixNameP <$> coreToType nmTy) <*> term f+        go "Clash.Magic.suffixNameFromNatP" args+          | [Type nmTy,_aTy,f] <- args+          = C.Tick <$> (C.NameMod C.SuffixNameP <$> coreToType nmTy) <*> term f         go "Clash.Magic.setName" args           | [Type nmTy,_aTy,f] <- args           = C.Tick <$> (C.NameMod C.SetName <$> coreToType nmTy) <*> term f-+        go "Clash.Magic.deDup" args+          | [_aTy,f] <- args+          = C.Tick C.DeDup <$> term f+        go "Clash.Magic.noDeDup" args+          | [_aTy,f] <- args+          = C.Tick C.NoDeDup <$> term f+        go nm args+          | Just n <- parseBundle "bundle" nm+            -- length args = domain tyvar + signal arg + number of type vars+          , length args == 2 + n+          = term (last args)+        go nm args+          | Just n <- parseBundle "unbundle" nm+            -- length args = domain tyvar + signal arg + number of type vars+          , length args == 2 + n+          = term (last args)         go _ _ = term' e++    parseBundle :: Text -> Text -> Maybe Int+    parseBundle fNm nm0 = do+      nm1 <- Text.stripPrefix ("Clash.Signal.Bundle." <> fNm) nm0+      nm2 <- Text.stripSuffix "#" nm1+      Text.readMaybe (Text.unpack nm2)+     term' (Var x)                 = var x     term' (Lit l)                 = return $ C.Literal (coreToLiteral l)     term' (App eFun (Type tyArg)) = C.TyApp <$> term eFun <*> coreToType tyArg@@ -368,7 +398,7 @@         x' <- coreToIdSP sp x         return (x',b') -    term' (Case _ _ ty [])  = C.TyApp (C.Prim (pack "EmptyCase") (C.PrimInfo C.undefinedTy C.WorkNever))+    term' (Case _ _ ty [])  = C.TyApp (C.Prim (C.PrimInfo (pack "EmptyCase") C.undefinedTy C.WorkNever))                                 <$> coreToType ty     term' (Case e b ty alts) = do      let usesBndr = any ( not . isEmptyVarSet . exprSomeFreeVars (== b))@@ -396,9 +426,9 @@     term' (Tick (SourceNote rsp _) e) =       C.Tick (C.SrcSpan (RealSrcSpan rsp)) <$> addUsefull (RealSrcSpan rsp) (term e)     term' (Tick _ e)        = term e-    term' (Type t)          = C.TyApp (C.Prim (pack "_TY_") (C.PrimInfo C.undefinedTy C.WorkNever)) <$>+    term' (Type t)          = C.TyApp (C.Prim (C.PrimInfo (pack "_TY_") C.undefinedTy C.WorkNever)) <$>                                 coreToType t-    term' (Coercion co)     = C.TyApp (C.Prim (pack "_CO_") (C.PrimInfo C.undefinedTy C.WorkNever)) <$>+    term' (Coercion co)     = C.TyApp (C.Prim (C.PrimInfo (pack "_CO_") C.undefinedTy C.WorkNever)) <$>                                 coreToType (coercionType co)  @@ -415,7 +445,7 @@         xType  <- coreToType (varType x)         case isDataConId_maybe x of           Just dc -> case lookupPrim xNameS of-            Just p  -> return $ C.Prim xNameS (C.PrimInfo xType (maybe C.WorkVariable workInfo p))+            Just p  -> return $ C.Prim (C.PrimInfo xNameS xType (maybe C.WorkVariable workInfo p))             Nothing -> if isDataConWrapId x && not (isNewTyCon (dataConTyCon dc))               then let xInfo = idInfo x                        unfolding = unfoldingInfo xInfo@@ -428,39 +458,42 @@               else C.Data <$> coreToDataCon dc           Nothing -> case lookupPrim xNameS of             Just (Just (Primitive f wi _))-              | f == pack "Clash.Signal.Internal.mapSignal#" -> return (mapSignalTerm xType)-              | f == pack "Clash.Signal.Internal.signal#"    -> return (signalTerm xType)-              | f == pack "Clash.Signal.Internal.appSignal#" -> return (appSignalTerm xType)-              | f == pack "Clash.Signal.Internal.traverse#"  -> return (traverseTerm xType)-              | f == pack "Clash.Signal.Internal.joinSignal#" -> return (joinTerm xType)-              | f == pack "Clash.Signal.Bundle.vecBundle#"   -> return (vecUnwrapTerm xType)-              | f == pack "GHC.Base.$"                       -> return (dollarTerm xType)-              | f == pack "GHC.Stack.withFrozenCallStack"    -> return (withFrozenCallStackTerm xType)-              | f == pack "GHC.Magic.noinline"               -> return (idTerm xType)-              | f == pack "GHC.Magic.lazy"                   -> return (idTerm xType)-              | f == pack "GHC.Magic.runRW#"                 -> return (runRWTerm xType)-              | f == pack "Clash.Class.BitPack.packXWith"    -> return (packXWithTerm xType)-              | f == pack "Clash.Sized.Internal.BitVector.checkUnpackUndef" -> return (checkUnpackUndefTerm xType)-              | f == pack "Clash.Magic.prefixName"+              | Just n <- parseBundle "bundle" f        -> return (bundleUnbundleTerm (n+1) xType)+              | Just n <- parseBundle "unbundle" f      -> return (bundleUnbundleTerm (n+1) xType)+              | f == "Clash.Signal.Internal.mapSignal#" -> return (mapSignalTerm xType)+              | f == "Clash.Signal.Internal.mapSignal#" -> return (mapSignalTerm xType)+              | f == "Clash.Signal.Internal.signal#"    -> return (signalTerm xType)+              | f == "Clash.Signal.Internal.appSignal#" -> return (appSignalTerm xType)+              | f == "Clash.Signal.Internal.traverse#"  -> return (traverseTerm xType)+              | f == "Clash.Signal.Internal.joinSignal#" -> return (joinTerm xType)+              | f == "Clash.Signal.Bundle.vecBundle#"   -> return (vecUnwrapTerm xType)+              | f == "GHC.Base.$"                       -> return (dollarTerm xType)+              | f == "GHC.Stack.withFrozenCallStack"    -> return (withFrozenCallStackTerm xType)+              | f == "GHC.Magic.noinline"               -> return (idTerm xType)+              | f == "GHC.Magic.lazy"                   -> return (idTerm xType)+              | f == "GHC.Magic.runRW#"                 -> return (runRWTerm xType)+              | f == "Clash.Class.BitPack.packXWith"    -> return (packXWithTerm xType)+              | f == "Clash.Sized.Internal.BitVector.checkUnpackUndef" -> return (checkUnpackUndefTerm xType)+              | f == "Clash.Magic.prefixName"               -> return (nameModTerm C.PrefixName xType)-              | f == pack "Clash.Magic.postfixName"+              | f == "Clash.Magic.postfixName"               -> return (nameModTerm C.SuffixName xType)-              | f == pack "Clash.Magic.setName"+              | f == "Clash.Magic.setName"               -> return (nameModTerm C.SetName xType)-              | otherwise                                    -> return (C.Prim xNameS (C.PrimInfo xType wi))+              | otherwise                                    -> return (C.Prim (C.PrimInfo xNameS xType wi))             Just (Just (BlackBox {workInfo = wi})) ->-              return $ C.Prim xNameS (C.PrimInfo xType wi)+              return $ C.Prim (C.PrimInfo xNameS xType wi)             Just (Just (BlackBoxHaskell {workInfo = wi})) ->-              return $ C.Prim xNameS (C.PrimInfo xType wi)+              return $ C.Prim (C.PrimInfo xNameS xType wi)             Just Nothing ->               -- Was guarded by "DontTranslate". We don't know yet if Clash will               -- actually use it later on, so we don't err here.-              return $ C.Prim xNameS (C.PrimInfo xType C.WorkAlways)+              return $ C.Prim (C.PrimInfo xNameS xType C.WorkVariable)             Nothing               | x `elem` unlocs-              -> return (C.Prim xNameS (C.PrimInfo xType C.WorkAlways))+              -> return (C.Prim (C.PrimInfo xNameS xType C.WorkVariable))               | pack "$cshow" `isInfixOf` xNameS-              -> return (C.Prim xNameS (C.PrimInfo xType C.WorkAlways))+              -> return (C.Prim (C.PrimInfo xNameS xType C.WorkVariable))               | otherwise               -> C.Var <$> coreToId x @@ -840,7 +873,9 @@   ns <- toString (toName v)   let key  = getKey (toUnique v)       locI = getSrcSpan (toName v)-      sort | ns == "ds" || Text.isPrefixOf "$" ns+      -- Is it one of [ds,ds1,ds2,..]+      isDSX = maybe False (maybe True (isDigit . fst) . Text.uncons) . Text.stripPrefix "ds"+      sort | isDSX ns || Text.isPrefixOf "$" ns            = C.System            | otherwise            = C.User@@ -883,6 +918,44 @@  -- | Given the type: --+-- @+--     forall dom a0 a1 .. aN+--   . Signal dom (a0, a1, .., aN)+--  -> (Signal dom a0, Signal dom a1, .., Signal dom aN)+-- @+--+-- or the type+--+-- @+--     forall dom a0 a1 .. aN+--   . (Signal dom a0, Signal dom a1, .., Signal dom aN)+--  -> Signal dom (a0, a1, .., aN)+-- @+--+-- Generate the term:+--+-- @/\dom. /\a0. /\a1. .. /\aN. \x -> x@+--+-- In other words: treat "bundle" and "unbundle" primitives as id.+--+bundleUnbundleTerm :: Int -> C.Type -> C.Term+bundleUnbundleTerm nTyVarsExpected = go []+ where+  go :: [C.TyVar] -> C.Type -> C.Term+  go tvs (C.ForAllTy tv typ) = go (tv:tvs) typ+  go tvs (C.tyView -> C.FunTy argTy _resTy) =+    if length tvs /= nTyVarsExpected then+      -- Internal error: should never happen unless we change the type of+      -- bundle / unbundle.+      error $ $(curLoc) ++ show (length tvs) ++ " vs " ++ show nTyVarsExpected+    else+      let sigName = C.mkLocalId argTy (C.mkUnsafeSystemName "c$s" 0) in+      foldr C.TyLam (C.Lam sigName (C.Var sigName)) (reverse tvs)+  go tvs ty = error $ $(curLoc) ++ show ty ++ " " ++ show tvs+++-- | Given the type:+-- -- @forall a. forall b. forall clk. (a -> b) -> Signal clk a -> Signal clk b@ -- -- Generate the term:@@ -913,42 +986,42 @@  -- | Given the type: ----- @forall a. forall clk. a -> Signal clk a@+-- @forall a. forall dom. a -> Signal dom a@ -- -- Generate the term ----- @/\(a:*)./\(clk:Clock).\(x:Signal clk a).x@+-- @/\(a:*)./\(dom:Domain).\(x:Signal dom a).x@ signalTerm :: C.Type            -> C.Term-signalTerm (C.ForAllTy aTV (C.ForAllTy clkTV funTy)) =+signalTerm (C.ForAllTy aTV (C.ForAllTy domTV funTy)) =     C.TyLam aTV (-    C.TyLam clkTV (+    C.TyLam domTV (     C.Lam   xId (     C.Var   xId)))   where-    (C.FunTy _ aTy) = C.tyView funTy+    (C.FunTy _ saTy) = C.tyView funTy     xName = C.mkUnsafeSystemName "x" 0-    xId   = C.mkLocalId aTy xName+    xId   = C.mkLocalId saTy xName  signalTerm ty = error $ $(curLoc) ++ show ty  -- | Given the type: -- -- @--- forall clk. forall a. forall b. Signal clk (a -> b) -> Signal clk a ->--- Signal clk b+-- forall dom. forall a. forall b. Signal dom (a -> b) -> Signal dom a ->+-- Signal dom b -- @ -- -- Generate the term: -- -- @--- /\(clk:Clock)./\(a:*)./\(b:*).\(f : (Signal clk a -> Signal clk b)).--- \(x : Signal clk a).f x+-- /\(dom:Domain)./\(a:*)./\(b:*).\(f : (Signal dom a -> Signal dom b)).+-- \(x : Signal dom a).f x -- @ appSignalTerm :: C.Type               -> C.Term-appSignalTerm (C.ForAllTy clkTV (C.ForAllTy aTV (C.ForAllTy bTV funTy))) =-    C.TyLam clkTV (+appSignalTerm (C.ForAllTy domTV (C.ForAllTy aTV (C.ForAllTy bTV funTy))) =+    C.TyLam domTV (     C.TyLam aTV (     C.TyLam bTV (     C.Lam   fId (@@ -956,12 +1029,12 @@     C.App (C.Var fId) (C.Var xId))))))   where     (C.FunTy _ funTy'') = C.tyView funTy-    (C.FunTy aTy bTy)   = C.tyView funTy''+    (C.FunTy saTy sbTy)   = C.tyView funTy''     fName = C.mkUnsafeSystemName "f" 0     xName = C.mkUnsafeSystemName "x" 1-    fTy   = C.mkFunTy aTy bTy+    fTy   = C.mkFunTy saTy sbTy     fId   = C.mkLocalId fTy fName-    xId   = C.mkLocalId aTy xName+    xId   = C.mkLocalId saTy xName  appSignalTerm ty = error $ $(curLoc) ++ show ty @@ -975,7 +1048,7 @@ -- Generate the term: -- -- @--- /\(t:Clock)./\(n:Nat)./\(a:*).\(vs:Signal t (Vec n a)).vs+-- /\(t:Domain)./\(n:Nat)./\(a:*).\(vs:Signal t (Vec n a)).vs -- @ vecUnwrapTerm :: C.Type               -> C.Term@@ -995,23 +1068,23 @@ -- | Given the type: -- -- @--- forall f.forall a.forall b.forall clk.Applicative f => (a -> f b) ->--- CSignal clk a -> f (Signal clk b)+-- forall f.forall a.forall b.forall dom.Applicative f => (a -> f b) ->+-- Signal dom a -> f (Signal dom b) -- @ -- -- Generate the term: -- -- @--- /\(f:* -> *)./\(a:*)./\(b:*)./\(clk:Clock).\(dict:Applicative f).--- \(g:a -> f b).\(x:Signal clk a).g x+-- /\(f:* -> *)./\(a:*)./\(b:*)./\(dom:Clock).\(dict:Applicative f).+-- \(g:a -> f b).\(x:Signal dom a).g x -- @ traverseTerm :: C.Type              -> C.Term-traverseTerm (C.ForAllTy fTV (C.ForAllTy aTV (C.ForAllTy bTV (C.ForAllTy clkTV funTy)))) =+traverseTerm (C.ForAllTy fTV (C.ForAllTy aTV (C.ForAllTy bTV (C.ForAllTy domTV funTy)))) =     C.TyLam fTV (     C.TyLam aTV (     C.TyLam bTV (-    C.TyLam clkTV (+    C.TyLam domTV (     C.Lam   dictId (     C.Lam   gId (     C.Lam   xId (@@ -1063,11 +1136,11 @@  -- | Given the type: ----- @forall a. forall clk. Signal clk (Signal clk a) -> Signal clk a@+-- @forall a. forall dom. Signal dom (Signal dom a) -> Signal dom a@ -- -- Generate the term ----- @/\(a:*)./\(clk:Clock).\(x:Signal clk a).x@+-- @/\(a:*)./\(dom:Domain).\(x:Signal dom a).x@ joinTerm :: C.Type          -> C.Term joinTerm ty@(C.ForAllTy {}) = signalTerm ty@@ -1122,7 +1195,7 @@ -- -- @forall (r :: RuntimeRep) (o :: TYPE r).(State# RealWorld -> o) -> o@ ----- Genereate the term:+-- Generate the term: -- -- @/\(r:RuntimeRep)./\(o:TYPE r).\(f:State# RealWord -> o) -> f realWorld#@ runRWTerm@@ -1132,7 +1205,7 @@   C.TyLam rTV (   C.TyLam oTV (   C.Lam   fId (-  (C.App (C.Var fId) (C.Prim rwNm (C.PrimInfo rwTy C.WorkNever))))))+  (C.App (C.Var fId) (C.Prim (C.PrimInfo rwNm rwTy C.WorkNever))))))   where     (C.FunTy fTy _)  = C.tyView funTy     (C.FunTy rwTy _) = C.tyView fTy@@ -1146,7 +1219,7 @@ -- -- @forall (n :: Nat) (a :: Type) .Knownnat n => (a -> BitVector n) -> a -> BitVector n@ ----- Genereate the term:+-- Generate the term: -- -- @/\(n:Nat)./\(a:TYPE r).\(kn:KnownNat n).\(f:a -> BitVector n).f@ packXWithTerm@@ -1172,7 +1245,7 @@ -- -- @forall (n :: Nat) (a :: Type) .Knownnat n => Typeable a => (BitVector n -> a) -> BitVector n -> a@ ----- Genereate the term:+-- Generate the term: -- -- @/\(n:Nat)./\(a:TYPE r).\(kn:KnownNat n).\(f:a -> BitVector n).f@ checkUnpackUndefTerm
src-ghc/Clash/GHC/GenerateBindings.hs view
@@ -5,19 +5,18 @@   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com> -} -{-# LANGUAGE LambdaCase        #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ViewPatterns      #-}  module Clash.GHC.GenerateBindings   (generateBindings) where  import           Control.DeepSeq         (deepseq)-import           Control.Lens            ((%~),(&),view,_1)+import           Control.Lens            ((%~),(&)) import           Control.Monad           (unless) import qualified Control.Monad.State     as State-import qualified Control.Monad.RWS.Lazy  as RWS+import qualified Control.Monad.RWS.Strict as RWS import           Data.Coerce             (coerce) import           Data.Either             (partitionEithers, lefts, rights) import           Data.IntMap.Strict      (IntMap)@@ -42,7 +41,6 @@ import qualified SrcLoc                  as GHC  import           Clash.Annotations.BitRepresentation.Internal (DataRepr')-import           Clash.Annotations.TopEntity (TopEntity) import           Clash.Annotations.Primitive (HDL, extractPrim)  import           Clash.Core.Subst        (extendGblSubstList, mkSubst, substTm)@@ -55,12 +53,13 @@ import           Clash.Core.VarEnv   (InScopeSet, VarEnv, emptyInScopeSet, extendInScopeSet, mkInScopeSet, mkVarEnv, unionVarEnv) import           Clash.Driver            (compilePrimitive)-import           Clash.Driver.Types      (BindingMap)+import           Clash.Driver.Types      (BindingMap, Binding(..)) import           Clash.GHC.GHC2Core   (C2C, GHC2CoreState, tyConMap, coreToId, coreToName, coreToTerm,    makeAllTyCons, qualifiedNameString, emptyGHC2CoreState) import           Clash.GHC.LoadModules   (ghcLibDir, loadModules)-import           Clash.Netlist.BlackBox.Util (usedArguments)+import           Clash.Netlist.BlackBox.Util (getUsedArguments)+import           Clash.Netlist.Types     (TopEntityT(..)) import           Clash.Primitives.Types   (Primitive (..), CompiledPrimMap) import           Clash.Primitives.Util   (generatePrimMap)@@ -86,10 +85,7 @@   -> IO ( BindingMap         , TyConMap         , IntMap TyConName-        , [( Id-           , Maybe TopEntity -- (maybe) TopEntity annotation-           , Maybe Id        -- (maybe) associated testbench-           )]+        , [TopEntityT]         , CompiledPrimMap  -- The primitives found in '.' and 'primDir'         , [DataRepr']         )@@ -117,19 +113,21 @@       tcCache                       = makeAllTyCons tcMap' fiEnvs       allTcCache                    = tysPrimMap `unionUniqMap` tcCache       inScope0 = mkInScopeSet (uniqMapToUniqSet-                      ((mapUniqMap (coerce . view _1) bindingsMap) `unionUniqMap`-                       (mapUniqMap (coerce . view _1) clsMap)))-      clsMap                        = mapUniqMap (\(v,i) -> (v,GHC.noSrcSpan,GHC.Inline,mkClassSelector inScope0 allTcCache (varType v) i)) clsVMap+                      ((mapUniqMap (coerce . bindingId) bindingsMap) `unionUniqMap`+                       (mapUniqMap (coerce . bindingId) clsMap)))+      clsMap                        = mapUniqMap (\(v,i) -> (Binding v GHC.noSrcSpan GHC.Inline (mkClassSelector inScope0 allTcCache (varType v) i))) clsVMap       allBindings                   = bindingsMap `unionVarEnv` clsMap       topEntities'                  =         (\m -> fst (RWS.evalRWS m GHC.noSrcSpan tcMap')) $ mapM (\(topEnt,annM,benchM) -> do           topEnt' <- coreToName GHC.varName GHC.varUnique qualifiedNameString topEnt           benchM' <- traverse coreToId benchM-          return (topEnt',annM,benchM')) topEntities-      topEntities''                 = map (\(topEnt,annM,benchM) -> case lookupUniqMap topEnt allBindings of-                                              Just (v,_,_,_) -> (v,annM,benchM)-                                              Nothing        -> error "This shouldn't happen"-                                          ) topEntities'+          return (topEnt', annM, benchM')) topEntities+      topEntities'' =+        map (\(topEnt, annM, benchM) ->+                case lookupUniqMap topEnt allBindings of+                  Just b -> TopEntityT (bindingId b) annM benchM+                  Nothing -> error "This shouldn't happen"+            ) topEntities'   -- Parsing / compiling primitives:   prepTime  <- startTime `deepseq` primMapC `seq` Clock.getCurrentTime   let prepStartDiff = reportTimeDiff prepTime startTime@@ -162,7 +160,7 @@       tm <- RWS.local (const sp) (coreToTerm primMap unlocatable e)       v' <- coreToId v       checkPrimitive primMap v-      return [(v', (v', sp, inl, tm))]+      return [(v', (Binding v' sp inl tm))]     GHC.Rec bs -> do       tms <- mapM (\(v,e) -> do                     let sp  = GHC.getSrcSpan v@@ -170,15 +168,15 @@                     tm <- RWS.local (const sp) (coreToTerm primMap unlocatable e)                     v' <- coreToId v                     checkPrimitive primMap v-                    return (v',sp,inl,tm)+                    return (Binding v' sp inl tm)                   ) bs       case tms of-        [(v,sp,inl,tm)] -> return [(v, (v, sp, inl, tm))]-        _ -> let vsL   = map (setIdScope LocalId . view _1) tms+        [Binding v sp inl tm] -> return [(v, Binding v sp inl tm)]+        _ -> let vsL   = map (setIdScope LocalId . bindingId) tms                  vsV   = map Var vsL                  subst = extendGblSubstList (mkSubst emptyInScopeSet) (zip vsL vsV)-                 lbs   = zipWith (\(_,_,_,e) vL -> (vL,substTm "mkBindings" subst e)) tms vsL-                 tms1  = zipWith (\(v,sp,inl,_) (_,e) -> (v,(v,sp,inl,Letrec lbs e))) tms lbs+                 lbs   = zipWith (\b vL -> (vL,substTm "mkBindings" subst (bindingTerm b))) tms vsL+                 tms1  = zipWith (\b (_, e) -> (bindingId b, b { bindingTerm = Letrec lbs e })) tms lbs              in  return tms1     ) bindings   clsOpList    <- mapM (\(v,i) -> do@@ -199,7 +197,7 @@ checkPrimitive primMap v = do   nm <- qualifiedNameString (GHC.varName v)   case HashMap.lookup nm primMap of-    Just (extractPrim -> Just (BlackBox _ _ _ _ _ _ _ inc templ)) -> do+    Just (extractPrim -> Just (BlackBox _ _ _ _ _ _ _ _ _ inc r ri templ)) -> do       let         info = GHC.idInfo v         inline = GHC.inlinePragmaSpec $ GHC.inlinePragInfo info@@ -214,7 +212,11 @@         warnIf cond msg = traceIf cond ("\n"++loc++"Warning: "++msg) return ()       qName <- Text.unpack <$> qualifiedNameString (GHC.varName v)       let primStr = "primitive " ++ qName ++ " "-      let usedArgs = usedArguments templ ++ concatMap (usedArguments . snd) inc+      let usedArgs = concat [ maybe [] getUsedArguments r+                            , maybe [] getUsedArguments ri+                            , getUsedArguments templ+                            , concatMap (getUsedArguments . snd) inc+                            ]        let warnArgs [] = return ()           warnArgs (x:xs) = do
src-ghc/Clash/GHC/LoadInterfaceFiles.hs view
@@ -5,12 +5,9 @@   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com> -} -{-# LANGUAGE CPP                 #-}-{-# LANGUAGE RecordWildCards     #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell     #-}-{-# LANGUAGE TupleSections       #-}-{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-}  module Clash.GHC.LoadInterfaceFiles   ( loadExternalExprs@@ -237,9 +234,9 @@   -> m ([Either UnresolvedPrimitive FilePath]) unresolvedPrimitives hdl targetPrim =   case targetPrim of-    (_, Primitive hdl' fp) | hdl == hdl' -> pure [Right fp]+    (_, Primitive hdls fp) | hdl `elem` hdls -> pure [Right fp] -    (target, InlinePrimitive hdl' contentOrFp) | hdl == hdl' ->+    (target, InlinePrimitive hdls contentOrFp) | hdl `elem` hdls ->       case target of         -- Module annotation, can house many primitives         Annotations.ModuleTarget _ ->
src-ghc/Clash/GHC/LoadModules.hs view
@@ -6,17 +6,16 @@   Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com> -} -{-# LANGUAGE CPP                 #-}-{-# LANGUAGE FlexibleContexts    #-}-{-# LANGUAGE RecordWildCards     #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell     #-}-{-# LANGUAGE ViewPatterns        #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}  module Clash.GHC.LoadModules   ( loadModules   , ghcLibDir-  , wantedLanguageExtensions+  , setWantedLanguageExtensions   ) where @@ -31,6 +30,7 @@ import           Clash.Annotations.TopEntity     (TopEntity (..)) import           Clash.Primitives.Types          (UnresolvedPrimitive) import           Clash.Util                      (ClashException(..), pkgIdFromTypeable)+import qualified Clash.Util.Interpolate          as I import           Control.Arrow                   (first, second) import           Control.DeepSeq                 (deepseq) import           Control.Exception               (throw)@@ -94,7 +94,8 @@ import           Clash.GHC.GHC2Core                           (modNameM, qualifiedNameString') import           Clash.GHC.LoadInterfaceFiles                 (loadExternalExprs, unresolvedPrimitives) import           Clash.GHCi.Common                            (checkMonoLocalBindsMod)-import           Clash.Util                                   (curLoc, noSrcSpan, reportTimeDiff)+import           Clash.Util                                   (curLoc, noSrcSpan, reportTimeDiff+                                                              ,wantedLanguageExtensions, unwantedLanguageExtensions) import           Clash.Annotations.BitRepresentation.Internal   (DataRepr', dataReprAnnToDataRepr') @@ -165,7 +166,7 @@ #else                   df <- GHC.getSessionDynFlags #endif-                  let df1 = wantedLanguageExtensions df+                  let df1 = setWantedLanguageExtensions df                   let ghcTyLitNormPlugin = GHC.mkModuleName "GHC.TypeLits.Normalise"                       ghcTyLitExtrPlugin = GHC.mkModuleName "GHC.TypeLits.Extra.Solver"                       ghcTyLitKNPlugin   = GHC.mkModuleName "GHC.TypeLits.KnownNat.Solver"@@ -188,7 +189,7 @@                                     (DynFlags.targetPlatform dflags)                     , DynFlags.reductionDepth = 1000                     }-    let dflags2 = wantedOptimizationFlags dflags1+    let dflags2 = unwantedOptimizationFlags dflags1     let ghcDynamic = case lookup "GHC Dynamic" (DynFlags.compilerInfo dflags) of                       Just "YES" -> True                       _          -> False@@ -212,7 +213,9 @@         -- 'topSortModuleGraph' ensures that modGraph2, and hence tidiedMods         -- are in topological order, i.e. the root module is last.         modGraph2 = Digraph.flattenSCCs (GHC.topSortModuleGraph True modGraph' Nothing)-    tidiedMods <- mapM (\m -> do { pMod  <- parseModule m+    tidiedMods <- mapM (\m -> do { oldDFlags <- GHC.getSessionDynFlags+                                 ; pMod  <- parseModule m+                                 ; _ <- GHC.setSessionDynFlags (GHC.ms_hspp_opts (GHC.pm_mod_summary pMod))                                  ; tcMod <- GHC.typecheckModule (removeStrictnessAnnotations pMod)                                  -- The purpose of the home package table (HPT) is to track                                  -- the already compiled modules, so subsequent modules can@@ -242,6 +245,7 @@                                  ; (tidy_guts,_) <- MonadUtils.liftIO $ TidyPgm.tidyProgram hsc_env simpl_guts                                  ; let pgm        = HscTypes.cg_binds tidy_guts                                  ; let modFamInstEnv = TcRnTypes.tcg_fam_inst_env $ fst $ GHC.tm_internals_ tcMod+                                 ; _ <- GHC.setSessionDynFlags oldDFlags                                  ; return (pgm,modFamInstEnv)                                  }                          ) modGraph2@@ -302,10 +306,15 @@     topEntities' <-       case (topEntities, topSyn) of         ([], []) ->-          Panic.pgmError $ unwords [ "No 'topEntity', nor function with a"-                                   , "'Synthesize' annotation found in root"-                                   , "module:"-                                   , (Outputable.showSDocUnsafe (ppr rootModule)) ]+          let modName1 = Outputable.showSDocUnsafe (ppr rootModule) in+          Panic.pgmError [I.i|+            No top-level function called 'topEntity' found, nor a function with+            a 'Synthesize' annotation in module #{modName1}. Did you forget to+            export them?++            For more information on 'Synthesize' annotations, check out the+            documentation of "Clash.Annotations.TopEntity".+          |]         ([], _) ->           return allSyn'         ([x], _) ->@@ -531,35 +540,16 @@ disableOptimizationsFlags ms@(GHC.ModSummary {..})   = ms {GHC.ms_hspp_opts = dflags}   where-    dflags = wantedOptimizationFlags (ms_hspp_opts+    dflags = unwantedOptimizationFlags (ms_hspp_opts               { DynFlags.optLevel = 2               , DynFlags.reductionDepth = 1000               }) -wantedOptimizationFlags :: GHC.DynFlags -> GHC.DynFlags-wantedOptimizationFlags df =+unwantedOptimizationFlags :: GHC.DynFlags -> GHC.DynFlags+unwantedOptimizationFlags df =   foldl' DynFlags.xopt_unset-    (foldl' DynFlags.gopt_unset-        (foldl' DynFlags.gopt_set df wanted) unwanted) unwantedLang+    (foldl' DynFlags.gopt_unset df unwanted) unwantedLang   where-    wanted = [ Opt_CSE -- CSE-             , Opt_Specialise -- Specialise on types, specialise type-class-overloaded function defined in this module for the types-             , Opt_DoLambdaEtaExpansion -- transform nested series of lambdas into one with multiple arguments, helps us achieve only top-level lambdas-             , Opt_CaseMerge -- We want fewer case-statements-             , Opt_DictsCheap -- Makes dictionaries seem cheap to optimizer: hopefully inline-             , Opt_ExposeAllUnfoldings -- We need all the unfoldings we can get-             , Opt_ForceRecomp -- Force recompilation: never bad-             , Opt_EnableRewriteRules -- Reduce number of functions-             , Opt_SimplPreInlining -- Inlines simple functions, we only care about the major first-order structure-             , Opt_StaticArgumentTransformation -- Turn on the static argument transformation, which turns a recursive function into a non-recursive one with a local recursive loop.-             , Opt_FloatIn -- Moves let-bindings inwards, although it defeats the normal-form with a single top-level let-binding, it helps with other transformations-             , Opt_DictsStrict -- Hopefully helps remove class method selectors-             , Opt_DmdTxDictSel -- I think demand and strictness are related, strictness helps with dead-code, enable-             , Opt_Strictness -- Strictness analysis helps with dead-code analysis. However, see [NOTE: CPR breaks Clash]-             , Opt_SpecialiseAggressively -- Needed to compile Fixed point number functions quickly-             , Opt_CrossModuleSpecialise -- Needed to compile Fixed point number functions quickly-             ]-     unwanted = [ Opt_LiberateCase -- Perform unrolling of recursive RHS: avoid                , Opt_SpecConstr -- Creates local-functions: avoid                , Opt_IgnoreAsserts -- We don't care about assertions@@ -617,45 +607,31 @@ -- everything is done properly, we should enable it again.  -wantedLanguageExtensions :: GHC.DynFlags -> GHC.DynFlags-wantedLanguageExtensions df =-    foldl' DynFlags.xopt_unset-      (foldl' DynFlags.xopt_set df wanted) unwanted-  where-    -- Also update @Test.Tasty.Clash.outputTest'@ when updating this list!-    wanted = [ LangExt.BinaryLiterals-             , LangExt.ConstraintKinds-             , LangExt.DataKinds-             , LangExt.DeriveAnyClass-             , LangExt.DeriveGeneric-             , LangExt.DeriveLift-             , LangExt.DerivingStrategies-             , LangExt.ExplicitForAll-             , LangExt.ExplicitNamespaces-             , LangExt.FlexibleContexts-             , LangExt.FlexibleInstances-             , LangExt.KindSignatures-             , LangExt.MagicHash-             , LangExt.MonoLocalBinds-             , LangExt.QuasiQuotes-             , LangExt.ScopedTypeVariables-             , LangExt.TemplateHaskell-             , LangExt.TemplateHaskellQuotes-             , LangExt.TypeApplications-             , LangExt.TypeFamilies-             , LangExt.TypeOperators-#if __GLASGOW_HASKELL__ < 806-             , LangExt.TypeInType-#endif-             ]-    unwanted = [ LangExt.ImplicitPrelude-               , LangExt.MonomorphismRestriction-#if MIN_VERSION_ghc(8,6,0)-               , LangExt.StarIsType-#endif-               , LangExt.Strict-               , LangExt.StrictData-               ]+setWantedLanguageExtensions :: GHC.DynFlags -> GHC.DynFlags+setWantedLanguageExtensions df =+   foldl' DynFlags.gopt_set+    (foldl' DynFlags.xopt_unset+      (foldl' DynFlags.xopt_set df wantedLanguageExtensions) unwantedLanguageExtensions)+      wantedOptimizations+ where+  wantedOptimizations =+    [ Opt_CSE -- CSE+    , Opt_Specialise -- Specialise on types, specialise type-class-overloaded function defined in this module for the types+    , Opt_DoLambdaEtaExpansion -- transform nested series of lambdas into one with multiple arguments, helps us achieve only top-level lambdas+    , Opt_CaseMerge -- We want fewer case-statements+    , Opt_DictsCheap -- Makes dictionaries seem cheap to optimizer: hopefully inline+    , Opt_ExposeAllUnfoldings -- We need all the unfoldings we can get+    , Opt_ForceRecomp -- Force recompilation: never bad+    , Opt_EnableRewriteRules -- Reduce number of functions+    , Opt_SimplPreInlining -- Inlines simple functions, we only care about the major first-order structure+    , Opt_StaticArgumentTransformation -- Turn on the static argument transformation, which turns a recursive function into a non-recursive one with a local recursive loop.+    , Opt_FloatIn -- Moves let-bindings inwards, although it defeats the normal-form with a single top-level let-binding, it helps with other transformations+    , Opt_DictsStrict -- Hopefully helps remove class method selectors+    , Opt_DmdTxDictSel -- I think demand and strictness are related, strictness helps with dead-code, enable+    , Opt_Strictness -- Strictness analysis helps with dead-code analysis. However, see [NOTE: CPR breaks Clash]+    , Opt_SpecialiseAggressively -- Needed to compile Fixed point number functions quickly+    , Opt_CrossModuleSpecialise -- Needed to compile Fixed point number functions quickly+    ]  -- | Remove all strictness annotations: --
src-ghc/Clash/GHC/NetlistTypes.hs view
@@ -6,9 +6,7 @@ -}  {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell   #-}-{-# LANGUAGE TupleSections     #-}-{-# LANGUAGE ViewPatterns      #-}+{-# LANGUAGE TemplateHaskell #-}  module Clash.GHC.NetlistTypes   (ghcTypeToHWType)@@ -28,7 +26,7 @@ import Clash.Core.Pretty                (showPpr) import Clash.Core.TyCon                 (TyConMap, tyConDataCons) import Clash.Core.Type-  (LitTy (..), Type (..), TypeView (..), coreView, tyView)+  (LitTy (..), Type (..), TypeView (..), coreView, coreView1, tyView) import Clash.Core.Util                  (tyNatSize, substArgTys) import Clash.Netlist.Util               (coreTypeToHWType, stripFiltered) import Clash.Netlist.Types@@ -135,17 +133,27 @@          -- XXX: this is a hack to get a KnownDomain from a KnownConfiguration         "GHC.Classes.(%,%)"-          | [arg0@(tyView -> TyConApp kdNm _), _] <- args+          | [arg0@(tyView -> TyConApp kdNm _), arg1] <- args           , nameOcc kdNm == "Clash.Signal.Internal.KnownDomain"-          -> ExceptT (MaybeT (go reprs m arg0))+          -> case tyView arg1 of+                TyConApp kdNm1 _+                  | nameOcc kdNm1 == "Clash.Signal.Internal.KnownDomain"+                  -> do k1 <- (stripVoid . stripFiltered) <$> ExceptT (MaybeT (go reprs m arg0))+                        k2 <- (stripVoid . stripFiltered) <$> ExceptT (MaybeT (go reprs m arg1))+                        returnN (Void (Just (Product "(%,%)" Nothing [k1,k2])))+                  where+                    stripVoid (Void (Just t)) = t+                    stripVoid t = t+                _ -> ExceptT (MaybeT (go reprs m arg0)) +         "Clash.Signal.Internal.KnownDomain"           -> case tyConDataCons (m `lookupUniqMap'` tc) of                [dc] -> case substArgTys dc args of                  [_,tyView -> TyConApp _ [_,dom]] -> case tyView (coreView m dom) of                    TyConApp _ [tag0, period0, edge0, rstKind0, init0, polarity0] -> do-                     tag1      <- domTag tag0-                     period1   <- domPeriod period0+                     tag1      <- domTag m tag0+                     period1   <- domPeriod m period0                      edge1     <- domEdge m edge0                      rstKind1  <- domResetKind m rstKind0                      init1     <- domInitBehavior m init0@@ -159,13 +167,13 @@         "Clash.Signal.Internal.Clock"           | [tag0] <- args           -> do-            tag1 <- domTag tag0+            tag1 <- domTag m tag0             returnN (Clock (pack tag1))          "Clash.Signal.Internal.Reset"           | [tag0] <- args           -> do-            tag1 <- domTag tag0+            tag1 <- domTag m tag0             returnN (Reset (pack tag1))          "Clash.Sized.Internal.BitVector.Bit" -> returnN Bit@@ -242,6 +250,19 @@         -- never end up being used in the generated HDL.         "GHC.Stack.Types.CallStack" -> returnN (Void Nothing) +        "Clash.Explicit.SimIO.SimIO" ->+          ExceptT $ MaybeT $ Just <$> coreTypeToHWType go reprs m (head args)++        "Clash.Explicit.SimIO.File" -> returnN FileType++        "Clash.Explicit.SimIO.Reg" -> do+          let [aTy] = args+          ExceptT (MaybeT (Just <$> coreTypeToHWType go reprs m aTy))++        "GHC.STRef.STRef" -> do+          let [_,aTy] = args+          ExceptT (MaybeT (Just <$> coreTypeToHWType go reprs m aTy))+         _ -> ExceptT (MaybeT (pure Nothing))      go _ _ _ = pure Nothing@@ -252,13 +273,15 @@   -> ExceptT e (MaybeT m) a liftE = mapExceptT (MaybeT . pure . Just . coerce) -domTag :: Monad m => Type -> ExceptT String (MaybeT m) String-domTag (LitTy (SymTy tag)) = pure tag-domTag ty = throwE $ "Can't translate domain tag" ++ showPpr ty+domTag :: Monad m => TyConMap -> Type -> ExceptT String (MaybeT m) String+domTag m (coreView1 m -> Just ty) = domTag m ty+domTag _ (LitTy (SymTy tag)) = pure tag+domTag _ ty = throwE $ "Internal error. Cannot translate domain tag:\n" ++ showPpr ty -domPeriod :: Monad m => Type -> ExceptT String (MaybeT m) Integer-domPeriod (LitTy (NumTy period)) = pure period-domPeriod ty = throwE $ "Can't translate domain period" ++ showPpr ty+domPeriod :: Monad m => TyConMap -> Type -> ExceptT String (MaybeT m) Integer+domPeriod m (coreView1 m -> Just ty) = domPeriod m ty+domPeriod _ (LitTy (NumTy period)) = pure period+domPeriod _ ty = throwE $ "Internal error. Cannot translate domain period:\n" ++ showPpr ty  fromType   :: Monad m
src-ghc/Clash/GHC/Util.hs view
@@ -1,6 +1,8 @@-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE QuasiQuotes #-}+ module Clash.GHC.Util where +import Outputable         (SDoc) import ErrUtils           (mkPlainErrMsg) import GHC                (GhcMonad(..), printException) import GhcPlugins         (DynFlags, SourceError, ($$), blankLine, empty, isGoodSrcSpan, liftIO, noSrcSpan, text, throwOneError)@@ -10,8 +12,16 @@ import System.Exit        (ExitCode(ExitFailure), exitWith)  import Clash.Util         (ClashException(..))+import Clash.Util.Interpolate (i) import Clash.Driver.Types (ClashOpts(..)) +-- | Like 'lines', but returning a horizontally spaced SDoc instead of a list:+--+-- >>> textLines "a\nb"+-- a $$ b+textLines :: String -> SDoc+textLines s = foldl1 ($$) (map text (lines s))+ handleClashException   :: GhcMonad m   => DynFlags@@ -22,19 +32,22 @@   Just (ClashException sp s eM) -> do     let srcInfo' | isGoodSrcSpan sp = srcInfo                  | otherwise = empty-    throwOneError (mkPlainErrMsg df sp (text s $$ srcInfo' $$ showExtra (opt_errorExtra opts) eM))+    throwOneError (mkPlainErrMsg df sp (blankLine $$ textLines s $$ blankLine $$ srcInfo' $$ showExtra (opt_errorExtra opts) eM))   _ -> case fromException e of-    Just (ErrorCall msg) ->-      throwOneError (mkPlainErrMsg df noSrcSpan (text "Clash error call:" $$ text msg))+    Just (ErrorCallWithLocation _ _) ->+      throwOneError (mkPlainErrMsg df noSrcSpan (text "Clash error call:" $$ textLines (show e)))     _ -> case fromException e of       Just (e' :: SourceError) -> do         GHC.printException e'         liftIO $ exitWith (ExitFailure 1)-      _ -> throwOneError (mkPlainErrMsg df noSrcSpan (text "Other error:" $$ text (displayException e)))+      _ -> throwOneError (mkPlainErrMsg df noSrcSpan (text "Other error:" $$ textLines (displayException e)))   where-    srcInfo = text "NB: The source location of the error is not exact, only indicative, as it is acquired after optimisations." $$-              text "The actual location of the error can be in a function that is inlined." $$-              text "To prevent inlining of those functions, annotate them with a NOINLINE pragma."+    srcInfo = textLines [i|+      The source location of the error is not exact, only indicative, as it+      is acquired after optimizations. The actual location of the error can be+      in a function that is inlined. To prevent inlining of those functions,+      annotate them with a NOINLINE pragma.+    |]      showExtra False (Just _)   =       blankLine $$@@ -42,5 +55,5 @@     showExtra True  (Just msg) =       blankLine $$       text "Additional information:" $$ blankLine $$-      text msg+      textLines msg     showExtra _ _ = empty
src-ghc/Interactive.hs view
@@ -5,6 +5,7 @@    Entry point for the @clashi@ executable. -}+ module Main   ( main -- :: IO ()   ) where