{-# LANGUAGE Safe #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Cryptol.Parser.Selector
( Selector(..)
, ppSelector
, ppNestedSels
, selName
) where
import GHC.Generics (Generic)
import Control.DeepSeq
import Data.List(intersperse)
import Cryptol.Utils.Ident
import Cryptol.Utils.PP
data Selector = TupleSel Int (Maybe Int)
| RecordSel Ident (Maybe [Ident])
| ListSel Int (Maybe Int)
deriving (Eq, Show, Ord, Generic, NFData)
instance PP Selector where
ppPrec _ sel =
case sel of
TupleSel x sig -> int x <+> ppSig tupleSig sig
RecordSel x sig -> pp x <+> ppSig recordSig sig
ListSel x sig -> int x <+> ppSig listSig sig
where
tupleSig n = int n
recordSig xs = braces $ fsep $ punctuate comma $ map pp xs
listSig n = int n
ppSig f = maybe empty (\x -> text "/* of" <+> f x <+> text "*/")
ppSelector :: Selector -> Doc
ppSelector sel =
case sel of
TupleSel x _ -> ordinal (x+1) <+> text "field"
RecordSel x _ -> text "field" <+> pp x
ListSel x _ -> ordinal x <+> text "element"
selName :: Selector -> Ident
selName s =
case s of
RecordSel i _ -> i
TupleSel n _ -> packIdent ("_" ++ show n)
ListSel n _ -> packIdent ("__" ++ show n)
ppNestedSels :: [Selector] -> Doc
ppNestedSels = hcat . intersperse "." . map ppS
where ppS s = case s of
RecordSel i _ -> text (unpackIdent i)
TupleSel n _ -> int n
ListSel n _ -> brackets (int n)