module Cryptol.Parser.Names where
import Cryptol.Parser.AST
import Data.Set (Set)
import qualified Data.Set as Set
tnamesNT :: Newtype name -> ([Located name], ())
tnamesNT x = ([ nName x ], ())
namesDs :: Ord name => [Decl name] -> ([Located name], Set name)
namesDs ds = (defs, boundNames defs (Set.unions frees))
where
defs = concat defss
(defss,frees) = unzip (map namesD ds)
namesD :: Ord name => Decl name -> ([Located name], Set name)
namesD decl =
case decl of
DBind b -> namesB b
DPatBind p e -> (namesP p, namesE e)
DSignature {} -> ([],Set.empty)
DFixity{} -> ([],Set.empty)
DPragma {} -> ([],Set.empty)
DType {} -> ([],Set.empty)
DProp {} -> ([],Set.empty)
DLocated d _ -> namesD d
allNamesD :: Ord name => Decl name -> [Located name]
allNamesD decl =
case decl of
DBind b -> fst (namesB b)
DPatBind p _ -> namesP p
DSignature ns _ -> ns
DFixity _ ns -> ns
DPragma ns _ -> ns
DType ts -> [tsName ts]
DProp ps -> [psName ps]
DLocated d _ -> allNamesD d
tsName :: TySyn name -> Located name
tsName (TySyn lqn _ _) = lqn
psName :: PropSyn name -> Located name
psName (PropSyn lqn _ _) = lqn
namesB :: Ord name => Bind name -> ([Located name], Set name)
namesB b = ([bName b], boundNames (namesPs (bParams b)) (namesDef (thing (bDef b))))
namesDef :: Ord name => BindDef name -> Set name
namesDef DPrim = Set.empty
namesDef (DExpr e) = namesE e
namesE :: Ord name => Expr name -> Set name
namesE expr =
case expr of
EVar x -> Set.singleton x
ELit _ -> Set.empty
ENeg e -> namesE e
EComplement e -> namesE e
ETuple es -> Set.unions (map namesE es)
ERecord fs -> Set.unions (map (namesE . value) fs)
ESel e _ -> namesE e
EList es -> Set.unions (map namesE es)
EFromTo _ _ _ -> Set.empty
EInfFrom e e' -> Set.union (namesE e) (maybe Set.empty namesE e')
EComp e arms -> let (dss,uss) = unzip (map namesArm arms)
in Set.union (boundNames (concat dss) (namesE e))
(Set.unions uss)
EApp e1 e2 -> Set.union (namesE e1) (namesE e2)
EAppT e _ -> namesE e
EIf e1 e2 e3 -> Set.union (namesE e1) (Set.union (namesE e2) (namesE e3))
EWhere e ds -> let (bs,xs) = namesDs ds
in Set.union (boundNames bs (namesE e)) xs
ETyped e _ -> namesE e
ETypeVal _ -> Set.empty
EFun ps e -> boundNames (namesPs ps) (namesE e)
ELocated e _ -> namesE e
EParens e -> namesE e
EInfix a o _ b-> Set.insert (thing o) (Set.union (namesE a) (namesE b))
namesPs :: [Pattern name] -> [Located name]
namesPs = concatMap namesP
namesP :: Pattern name -> [Located name]
namesP pat =
case pat of
PVar x -> [x]
PWild -> []
PTuple ps -> namesPs ps
PRecord fs -> namesPs (map value fs)
PList ps -> namesPs ps
PTyped p _ -> namesP p
PSplit p1 p2 -> namesPs [p1,p2]
PLocated p _ -> namesP p
namesM :: Ord name => Match name -> ([Located name], Set name)
namesM (Match p e) = (namesP p, namesE e)
namesM (MatchLet b) = namesB b
namesArm :: Ord name => [Match name] -> ([Located name], Set name)
namesArm = foldr combine ([],Set.empty) . map namesM
where combine (ds1,fs1) (ds2,fs2) =
( filter ((`notElem` map thing ds2) . thing) ds1 ++ ds2
, Set.union fs1 (boundNames ds1 fs2)
)
boundNames :: Ord name => [Located name] -> Set name -> Set name
boundNames bs xs = Set.difference xs (Set.fromList (map thing bs))
namesT :: Ord name => Set name -> Type name -> Set name
namesT vs = go
where
go ty =
case ty of
TWild -> Set.empty
TFun t1 t2 -> Set.union (go t1) (go t2)
TSeq t1 t2 -> Set.union (go t1) (go t2)
TBit -> Set.empty
TNum _ -> Set.empty
TChar _ -> Set.empty
TApp _ ts -> Set.unions (map go ts)
TTuple ts -> Set.unions (map go ts)
TRecord fs -> Set.unions (map (go . value) fs)
TLocated t _ -> go t
TUser x [] | x `Set.member` vs
-> Set.empty
TUser x ts -> Set.insert x (Set.unions (map go ts))
TParens t -> namesT vs t
TInfix a _ _ b-> Set.union (namesT vs a) (namesT vs b)
namesC :: Ord name => Set name -> Prop name -> Set name
namesC vs prop =
case prop of
CFin t -> namesT vs t
CEqual t1 t2 -> Set.union (namesT vs t1) (namesT vs t2)
CNeq t1 t2 -> Set.union (namesT vs t1) (namesT vs t2)
CGeq t1 t2 -> Set.union (namesT vs t1) (namesT vs t2)
CZero t -> namesT vs t
CLogic t -> namesT vs t
CArith t -> namesT vs t
CCmp t -> namesT vs t
CSignedCmp t -> namesT vs t
CLiteral t1 t2-> Set.union (namesT vs t1) (namesT vs t2)
CUser x ts -> Set.insert x (Set.unions (map (namesT vs) ts))
CLocated p _ -> namesC vs p
CType t -> namesT vs t
tnamesDs :: Ord name => [Decl name] -> ([Located name], Set name)
tnamesDs ds = (defs, boundNames defs (Set.unions frees))
where
defs = concat defss
(defss,frees) = unzip (map tnamesD ds)
tnamesD :: Ord name => Decl name -> ([Located name], Set name)
tnamesD decl =
case decl of
DSignature _ s -> ([], tnamesS s)
DFixity {} -> ([], Set.empty)
DPragma {} -> ([], Set.empty)
DBind b -> ([], tnamesB b)
DPatBind _ e -> ([], tnamesE e)
DLocated d _ -> tnamesD d
DType (TySyn n ps t) -> ([n], Set.difference (tnamesT t) (Set.fromList (map tpName ps)))
DProp (PropSyn n ps cs)
-> ([n], Set.difference (Set.unions (map tnamesC cs))
(Set.fromList (map tpName ps)))
tnamesB :: Ord name => Bind name -> Set name
tnamesB b = Set.unions [setS, setP, setE]
where
setS = maybe Set.empty tnamesS (bSignature b)
setP = Set.unions (map tnamesP (bParams b))
setE = tnamesDef (thing (bDef b))
tnamesDef :: Ord name => BindDef name -> Set name
tnamesDef DPrim = Set.empty
tnamesDef (DExpr e) = tnamesE e
tnamesE :: Ord name => Expr name -> Set name
tnamesE expr =
case expr of
EVar _ -> Set.empty
ELit _ -> Set.empty
ENeg e -> tnamesE e
EComplement e -> tnamesE e
ETuple es -> Set.unions (map tnamesE es)
ERecord fs -> Set.unions (map (tnamesE . value) fs)
ESel e _ -> tnamesE e
EList es -> Set.unions (map tnamesE es)
EFromTo a b c -> Set.union (tnamesT a)
(Set.union (maybe Set.empty tnamesT b) (maybe Set.empty tnamesT c))
EInfFrom e e' -> Set.union (tnamesE e) (maybe Set.empty tnamesE e')
EComp e mss -> Set.union (tnamesE e) (Set.unions (map tnamesM (concat mss)))
EApp e1 e2 -> Set.union (tnamesE e1) (tnamesE e2)
EAppT e fs -> Set.union (tnamesE e) (Set.unions (map tnamesTI fs))
EIf e1 e2 e3 -> Set.union (tnamesE e1) (Set.union (tnamesE e2) (tnamesE e3))
EWhere e ds -> let (bs,xs) = tnamesDs ds
in Set.union (boundNames bs (tnamesE e)) xs
ETyped e t -> Set.union (tnamesE e) (tnamesT t)
ETypeVal t -> tnamesT t
EFun ps e -> Set.union (Set.unions (map tnamesP ps)) (tnamesE e)
ELocated e _ -> tnamesE e
EParens e -> tnamesE e
EInfix a _ _ b-> Set.union (tnamesE a) (tnamesE b)
tnamesTI :: Ord name => TypeInst name -> Set name
tnamesTI (NamedInst f) = tnamesT (value f)
tnamesTI (PosInst t) = tnamesT t
tnamesP :: Ord name => Pattern name -> Set name
tnamesP pat =
case pat of
PVar _ -> Set.empty
PWild -> Set.empty
PTuple ps -> Set.unions (map tnamesP ps)
PRecord fs -> Set.unions (map (tnamesP . value) fs)
PList ps -> Set.unions (map tnamesP ps)
PTyped p t -> Set.union (tnamesP p) (tnamesT t)
PSplit p1 p2 -> Set.union (tnamesP p1) (tnamesP p2)
PLocated p _ -> tnamesP p
tnamesM :: Ord name => Match name -> Set name
tnamesM (Match p e) = Set.union (tnamesP p) (tnamesE e)
tnamesM (MatchLet b) = tnamesB b
tnamesS :: Ord name => Schema name -> Set name
tnamesS (Forall params props ty _) =
Set.difference (Set.union (Set.unions (map tnamesC props)) (tnamesT ty))
(Set.fromList (map tpName params))
tnamesC :: Ord name => Prop name -> Set name
tnamesC prop =
case prop of
CFin t -> tnamesT t
CEqual t1 t2 -> Set.union (tnamesT t1) (tnamesT t2)
CNeq t1 t2 -> Set.union (tnamesT t1) (tnamesT t2)
CGeq t1 t2 -> Set.union (tnamesT t1) (tnamesT t2)
CZero t -> tnamesT t
CLogic t -> tnamesT t
CArith t -> tnamesT t
CCmp t -> tnamesT t
CSignedCmp t -> tnamesT t
CLiteral t1 t2 -> Set.union (tnamesT t1) (tnamesT t2)
CUser x ts -> Set.insert x (Set.unions (map tnamesT ts))
CLocated p _ -> tnamesC p
CType t -> tnamesT t
tnamesT :: Ord name => Type name -> Set name
tnamesT ty =
case ty of
TWild -> Set.empty
TFun t1 t2 -> Set.union (tnamesT t1) (tnamesT t2)
TSeq t1 t2 -> Set.union (tnamesT t1) (tnamesT t2)
TBit -> Set.empty
TNum _ -> Set.empty
TChar __ -> Set.empty
TApp _ ts -> Set.unions (map tnamesT ts)
TTuple ts -> Set.unions (map tnamesT ts)
TRecord fs -> Set.unions (map (tnamesT . value) fs)
TLocated t _ -> tnamesT t
TUser x ts -> Set.insert x (Set.unions (map tnamesT ts))
TParens t -> tnamesT t
TInfix a _ _ c-> Set.union (tnamesT a) (tnamesT c)