--- | A flattened function application
-data FApp sigid = FApp {
- appFunc :: HsFunction,
- appArgs :: [SignalUseMap sigid],
- appRes :: SignalDefMap sigid
-} deriving (Show, Eq)
-
--- | A conditional signal definition
-data CondDef sigid = CondDef {
- cond :: SignalUse sigid,
- high :: SignalUse sigid,
- low :: SignalUse sigid,
- condRes :: SignalDef sigid
-} deriving (Show, Eq)
+hasState :: HsFunction -> Bool
+hasState hsfunc =
+ any (Foldable.any isStateUse) (hsFuncArgs hsfunc)
+ || Foldable.any isStateUse (hsFuncRes hsfunc)
+
+-- | Something that defines a signal
+data SigDef =
+ -- | A flattened function application
+ FApp {
+ appFunc :: HsFunction,
+ appArgs :: [SignalMap],
+ appRes :: SignalMap
+ }
+ -- | A conditional signal definition
+ | CondDef {
+ cond :: SignalId,
+ high :: SignalId,
+ low :: SignalId,
+ condRes :: SignalId
+ }
+ -- | Unconditional signal definition
+ | UncondDef {
+ defSrc :: Either SignalId SignalExpr,
+ defDst :: SignalId
+ } deriving (Show, Eq)
+
+-- | Is the given SigDef a FApp?
+is_FApp :: SigDef -> Bool
+is_FApp d = case d of
+ (FApp _ _ _) -> True
+ _ -> False
+
+-- | Which signals are used by the given SigDef?
+sigDefUses :: SigDef -> [SignalId]
+sigDefUses (UncondDef (Left id) _) = [id]
+sigDefUses (UncondDef (Right expr) _) = sigExprUses expr
+sigDefUses (CondDef cond true false _) = [cond, true, false]
+sigDefUses (FApp _ args _) = concat $ map Foldable.toList args
+
+-- | An expression on signals
+data SignalExpr =
+ EqLit SignalId String -- ^ Is the given signal equal to the given (VHDL) literal
+ | Literal String (Maybe Type.Type)-- ^ A literal value, with an optional type to cast to
+ | Eq SignalId SignalId -- ^ A comparison between to signals
+ deriving (Show, Eq)
+
+-- Instantiate Eq for Type, so we can derive Eq for SignalExpr.
+instance Eq Type.Type where
+ (==) = Type.coreEqType
+
+-- | Which signals are used by the given SignalExpr?
+sigExprUses :: SignalExpr -> [SignalId]
+sigExprUses (EqLit id _) = [id]
+sigExprUses (Literal _ _) = []
+sigExprUses (Eq a b) = [a, b]
+
+-- Returns the function used by the given SigDef, if any
+usedHsFunc :: SigDef -> Maybe HsFunction
+usedHsFunc (FApp hsfunc _ _) = Just hsfunc
+usedHsFunc _ = Nothing
+
+-- | How is a given signal used in the resulting VHDL?
+data SigUse =
+ SigPortIn -- | Use as an input port
+ | SigPortOut -- | Use as an input port
+ | SigInternal -- | Use as an internal signal
+ | SigStateOld StateId -- | Use as the current internal state
+ | SigStateNew StateId -- | Use as the new internal state
+ | SigSubState -- | Do not use, state variable is used in a subcircuit
+ deriving (Show)
+
+-- | Is this a port signal use?
+isPortSigUse :: SigUse -> Bool
+isPortSigUse SigPortIn = True
+isPortSigUse SigPortOut = True
+isPortSigUse _ = False
+
+-- | Is this a state signal use? Returns false for substate.
+isStateSigUse :: SigUse -> Bool
+isStateSigUse (SigStateOld _) = True
+isStateSigUse (SigStateNew _) = True
+isStateSigUse _ = False
+
+-- | Is this an internal signal use?
+isInternalSigUse :: SigUse -> Bool
+isInternalSigUse SigInternal = True
+isInternalSigUse _ = False
+
+oldStateId :: SigUse -> Maybe StateId
+oldStateId (SigStateOld id) = Just id
+oldStateId _ = Nothing
+
+newStateId :: SigUse -> Maybe StateId
+newStateId (SigStateNew id) = Just id
+newStateId _ = Nothing
+
+-- | Information on a signal definition
+data SignalInfo = SignalInfo {
+ sigName :: Maybe String,
+ sigUse :: SigUse,
+ sigTy :: Type.Type,
+ nameHints :: [String]
+} deriving (Show)