17
17
module Codec.CBOR.Cuddle.Huddle
18
18
( -- * Core Types
19
19
Huddle ,
20
+ HuddleItem (.. ),
20
21
Rule ,
21
22
Named ,
22
23
IsType0 (.. ),
@@ -70,14 +71,17 @@ module Codec.CBOR.Cuddle.Huddle
70
71
tag ,
71
72
72
73
-- * Generics
74
+ GRef ,
75
+ GRuleDef ,
73
76
GRuleCall ,
74
77
binding ,
75
78
binding2 ,
79
+ callToDef ,
76
80
77
81
-- * Conversion to CDDL
78
82
collectFrom ,
79
83
toCDDL ,
80
- toCDDLNoRoot
84
+ toCDDLNoRoot ,
81
85
)
82
86
where
83
87
@@ -93,12 +97,12 @@ import Data.List.NonEmpty qualified as NE
93
97
import Data.Map.Strict qualified as HaskMap
94
98
import Data.String (IsString (fromString ))
95
99
import Data.Text qualified as T
96
- import Data.Tuple.Optics (Field1 ( .. ), Field2 ( .. ), Field3 (.. ))
100
+ import Data.Tuple.Optics (Field2 (.. ))
97
101
import Data.Void (Void )
98
102
import Data.Word (Word64 )
99
103
import GHC.Exts (IsList (Item , fromList , toList ))
100
104
import GHC.Generics (Generic )
101
- import Optics.Core (over , view , (%~) , (&) , (.~) )
105
+ import Optics.Core (view , (%~) , (&) , (.~) )
102
106
import Prelude hiding ((/) )
103
107
104
108
data Named a = Named
@@ -117,23 +121,22 @@ instance Show (Named a) where
117
121
118
122
type Rule = Named Type0
119
123
124
+ data HuddleItem
125
+ = HIRule Rule
126
+ | HIGRule GRuleDef
127
+ | HIGroup (Named Group )
128
+ deriving (Generic , Show )
129
+
120
130
-- | Top-level Huddle type is a list of rules.
121
131
data Huddle = Huddle
122
132
{ -- | Root elements
123
133
roots :: [Rule ],
124
- rules :: NE. NonEmpty Rule ,
125
- groups :: [Named Group ],
126
- gRules :: [GRuleDef ]
134
+ items :: [HuddleItem ]
127
135
}
128
136
deriving (Generic , Show )
129
137
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 [] []
137
140
138
141
data Choice a
139
142
= NoChoice a
@@ -826,19 +829,17 @@ collectFrom topRs =
826
829
toHuddle $
827
830
execState
828
831
(traverse goRule topRs)
829
- ( HaskMap. empty, HaskMap. empty, HaskMap. empty)
832
+ HaskMap. empty
830
833
where
831
- toHuddle (rules, groups, gRules) =
834
+ toHuddle items =
832
835
Huddle
833
836
{ 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
837
838
}
838
839
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) )
842
843
goT0 t0
843
844
goChoice f (NoChoice x) = f x
844
845
goChoice f (ChoiceOf x xs) = f x >> goChoice f xs
@@ -848,14 +849,14 @@ collectFrom topRs =
848
849
goT2 (T2Tagged (Tagged _ t0)) = goT0 t0
849
850
goT2 (T2Ref n) = goRule n
850
851
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) )
854
855
goGroup g
855
856
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))
859
860
goT0 (body g)
860
861
-- Note that the parameters here may be different, so this doesn't live
861
862
-- under the guard
@@ -872,13 +873,14 @@ collectFrom topRs =
872
873
--------------------------------------------------------------------------------
873
874
-- Conversion to CDDL
874
875
--------------------------------------------------------------------------------
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
877
879
toCDDL = toCDDL' True
878
880
879
881
-- | 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
882
884
883
885
-- | Convert from Huddle to CDDL for the purpose of pretty-printing.
884
886
toCDDL' :: Bool -> Huddle -> CDDL
@@ -888,19 +890,16 @@ toCDDL' mkPseudoRoot hdl =
888
890
then (toTopLevelPseudoRoot (roots hdl) NE. <| )
889
891
else id
890
892
)
891
- $ fmap toCDDLRule (rules hdl)
892
- `appendList` fmap toCDDLGroup (groups hdl)
893
- `appendList` fmap toGenRuleDef (gRules hdl)
893
+ $ fmap toCDDLItem (NE. fromList $ items hdl)
894
894
where
895
+ toCDDLItem (HIRule r) = toCDDLRule r
896
+ toCDDLItem (HIGroup g) = toCDDLGroup g
897
+ toCDDLItem (HIGRule g) = toGenRuleDef g
895
898
toTopLevelPseudoRoot :: [Rule ] -> C. WithComments C. Rule
896
899
toTopLevelPseudoRoot topRs =
897
900
toCDDLRule $
898
901
comment " Pseudo-rule introduced by Cuddle to collect root elements" $
899
902
" 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
904
903
toCDDLRule :: Rule -> C. WithComments C. Rule
905
904
toCDDLRule (Named n t0 c) =
906
905
C. WithComments
0 commit comments