1717module Codec.CBOR.Cuddle.Huddle
1818 ( -- * Core Types
1919 Huddle ,
20+ HuddleItem (.. ),
2021 Rule ,
2122 Named ,
2223 IsType0 (.. ),
@@ -70,14 +71,17 @@ module Codec.CBOR.Cuddle.Huddle
7071 tag ,
7172
7273 -- * Generics
74+ GRef ,
75+ GRuleDef ,
7376 GRuleCall ,
7477 binding ,
7578 binding2 ,
79+ callToDef ,
7680
7781 -- * Conversion to CDDL
7882 collectFrom ,
7983 toCDDL ,
80- toCDDLNoRoot
84+ toCDDLNoRoot ,
8185 )
8286where
8387
@@ -93,12 +97,12 @@ import Data.List.NonEmpty qualified as NE
9397import Data.Map.Strict qualified as HaskMap
9498import Data.String (IsString (fromString ))
9599import Data.Text qualified as T
96- import Data.Tuple.Optics (Field1 ( .. ), Field2 ( .. ), Field3 (.. ))
100+ import Data.Tuple.Optics (Field2 (.. ))
97101import Data.Void (Void )
98102import Data.Word (Word64 )
99103import GHC.Exts (IsList (Item , fromList , toList ))
100104import GHC.Generics (Generic )
101- import Optics.Core (over , view , (%~) , (&) , (.~) )
105+ import Optics.Core (view , (%~) , (&) , (.~) )
102106import Prelude hiding ((/) )
103107
104108data Named a = Named
@@ -117,23 +121,22 @@ instance Show (Named a) where
117121
118122type Rule = Named Type0
119123
124+ data HuddleItem
125+ = HIRule Rule
126+ | HIGRule GRuleDef
127+ | HIGroup (Named Group )
128+ deriving (Generic , Show )
129+
120130-- | Top-level Huddle type is a list of rules.
121131data Huddle = Huddle
122132 { -- | Root elements
123133 roots :: [Rule ],
124- rules :: NE. NonEmpty Rule ,
125- groups :: [Named Group ],
126- gRules :: [GRuleDef ]
134+ items :: [HuddleItem ]
127135 }
128136 deriving (Generic , Show )
129137
130- -- | This instance is mostly used for testing
131- instance IsList Huddle where
132- type Item Huddle = Rule
133- fromList [] = error " Huddle: Cannot have empty ruleset"
134- fromList (x : xs) = Huddle mempty (x NE. :| xs) mempty mempty
135-
136- toList = NE. toList . rules
138+ instance Default Huddle where
139+ def = Huddle [] []
137140
138141data Choice a
139142 = NoChoice a
@@ -826,19 +829,17 @@ collectFrom topRs =
826829 toHuddle $
827830 execState
828831 (traverse goRule topRs)
829- ( HaskMap. empty, HaskMap. empty, HaskMap. empty)
832+ HaskMap. empty
830833 where
831- toHuddle (rules, groups, gRules) =
834+ toHuddle items =
832835 Huddle
833836 { roots = topRs,
834- rules = NE. fromList $ view _2 <$> HaskMap. toList rules,
835- groups = view _2 <$> HaskMap. toList groups,
836- gRules = view _2 <$> HaskMap. toList gRules
837+ items = view _2 <$> HaskMap. toList items
837838 }
838839 goRule r@ (Named n t0 _) = do
839- (rules, _, _) <- get
840- when (HaskMap. notMember n rules ) $ do
841- modify (over _1 $ HaskMap. insert n r )
840+ items <- get
841+ when (HaskMap. notMember n items ) $ do
842+ modify (HaskMap. insert n ( HIRule r) )
842843 goT0 t0
843844 goChoice f (NoChoice x) = f x
844845 goChoice f (ChoiceOf x xs) = f x >> goChoice f xs
@@ -848,14 +849,14 @@ collectFrom topRs =
848849 goT2 (T2Tagged (Tagged _ t0)) = goT0 t0
849850 goT2 (T2Ref n) = goRule n
850851 goT2 (T2Group r@ (Named n g _)) = do
851- (_, groups, _) <- get
852- when (HaskMap. notMember n groups ) $ do
853- modify (over _2 $ HaskMap. insert n r )
852+ items <- get
853+ when (HaskMap. notMember n items ) $ do
854+ modify (HaskMap. insert n ( HIGroup r) )
854855 goGroup g
855856 goT2 (T2Generic r@ (Named n g _)) = do
856- (_, _, gRules) <- get
857- when (HaskMap. notMember n gRules ) $ do
858- modify (over _3 $ HaskMap. insert n (fmap callToDef r))
857+ items <- get
858+ when (HaskMap. notMember n items ) $ do
859+ modify (HaskMap. insert n (HIGRule $ fmap callToDef r))
859860 goT0 (body g)
860861 -- Note that the parameters here may be different, so this doesn't live
861862 -- under the guard
@@ -872,13 +873,14 @@ collectFrom topRs =
872873--------------------------------------------------------------------------------
873874-- Conversion to CDDL
874875--------------------------------------------------------------------------------
875- -- | Convert from Huddle to CDDL, generating a top level root element.
876- toCDDL :: Huddle -> CDDL
876+
877+ -- | Convert from Huddle to CDDL, generating a top level root element.
878+ toCDDL :: Huddle -> CDDL
877879toCDDL = toCDDL' True
878880
879881-- | Convert from Huddle to CDDL, skipping a root element.
880- toCDDLNoRoot :: Huddle -> CDDL
881- toCDDLNoRoot = toCDDL' False
882+ toCDDLNoRoot :: Huddle -> CDDL
883+ toCDDLNoRoot = toCDDL' False
882884
883885-- | Convert from Huddle to CDDL for the purpose of pretty-printing.
884886toCDDL' :: Bool -> Huddle -> CDDL
@@ -888,19 +890,16 @@ toCDDL' mkPseudoRoot hdl =
888890 then (toTopLevelPseudoRoot (roots hdl) NE. <| )
889891 else id
890892 )
891- $ fmap toCDDLRule (rules hdl)
892- `appendList` fmap toCDDLGroup (groups hdl)
893- `appendList` fmap toGenRuleDef (gRules hdl)
893+ $ fmap toCDDLItem (NE. fromList $ items hdl)
894894 where
895+ toCDDLItem (HIRule r) = toCDDLRule r
896+ toCDDLItem (HIGroup g) = toCDDLGroup g
897+ toCDDLItem (HIGRule g) = toGenRuleDef g
895898 toTopLevelPseudoRoot :: [Rule ] -> C. WithComments C. Rule
896899 toTopLevelPseudoRoot topRs =
897900 toCDDLRule $
898901 comment " Pseudo-rule introduced by Cuddle to collect root elements" $
899902 " huddle_root_defs" =:= arr (fromList (fmap a topRs))
900- -- This function is missing from NonEmpty prior to 4.16, so we temporarily
901- -- add it here.
902- appendList :: NE. NonEmpty a -> [a ] -> NE. NonEmpty a
903- appendList (x NE. :| xs) ys = x NE. :| xs <> ys
904903 toCDDLRule :: Rule -> C. WithComments C. Rule
905904 toCDDLRule (Named n t0 c) =
906905 C. WithComments
0 commit comments