This commit is contained in:
2026-07-22 23:47:33 -06:00
parent 81a136fcf2
commit 1c7322614c
2 changed files with 54 additions and 25 deletions
+53 -24
View File
@@ -3,6 +3,7 @@
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FunctionalDependencies #-}
module Gyehoek.CPS.Syntax
( Val(..)
, Kappa(..)
@@ -19,6 +20,11 @@ module Gyehoek.CPS.Syntax
, _ExpPrim
, _ExpLetRec
, _ExpApply
, binders
, body
, op
, args
, cont
, cps
, pattern AbsLambda'
, pattern AbsKappa'
@@ -48,6 +54,7 @@ import Data.HashSet (HashSet)
import qualified Data.HashSet as HS
import Data.Hashable (Hashable)
import Data.Monoid (Endo)
import Data.Containers.ListUtils (nubOrd)
-- Data types
@@ -56,10 +63,10 @@ data Val
| ValLit Lit
deriving (Show, Generic, Data, Eq)
data Kappa = MkKappa (List Name) Exp
data Kappa = MkKappa { binders :: List Name, body :: Exp }
deriving (Show, Generic, Data, Eq)
data Lambda = MkLambda (List Name) Name Exp
data Lambda = MkLambda { binders :: List Name, ktail :: Name, body :: Exp }
deriving (Show, Generic, Data, Eq)
data Abs
@@ -72,7 +79,7 @@ pattern AbsLambda' xs e ktail = AbsLambda (MkLambda xs e ktail)
data Exp
= ExpPrim (Prim Val) Kappa
| ExpLetRec (NonEmpty (Name, Abs)) Exp
| ExpLetRec { binders :: NonEmpty (Name, Abs), body :: Exp }
| ExpContinue Name (List Val)
| ExpIf Val Exp Exp
| ExpApply
@@ -97,7 +104,24 @@ data Program = MkProgram
deriving (Show, Generic, Data)
makePrisms ''Kappa
-- makeLenses ''Kappa
makePrisms ''Exp
-- makeLenses ''Exp
-- makeFieldsNoPrefix ''Exp
-- makeFieldsNoPrefix ''Kappa
-- makeLensesWith abbreviatedFields ''Exp
-- makeLensesFor [("binders", "_binders"), ("body", "_body")] ''Exp
makeFieldsId ''Exp
makeFieldsId ''Kappa
makeFieldsId ''Lambda
instance HasBinders Abs (List Name) where
binders k (AbsKappa kap) = AbsKappa <$> binders k kap
binders k (AbsLambda lam) = AbsLambda <$> binders k lam
instance HasBody Abs Exp where
body k (AbsKappa kap) = AbsKappa <$> body k kap
body k (AbsLambda lam) = AbsLambda <$> body k lam
-- SexpIso instances
@@ -230,24 +254,29 @@ free = go where
-- | Free variables given in the order of their appearance.
free' :: Exp -> List Name
free' = go HS.empty where
gokap bound (MkKappa xs m) = go (bound & insertFrom xs) m
golam bound (MkLambda xs k m) = go (bound & insertFrom (k:xs)) m
goabs bound = \case
AbsKappa kap -> gokap bound kap
AbsLambda lam -> golam bound lam
go :: HashSet Name -> Exp -> List Name
go bound = \case
ExpPrim p k ->
p & toListOf (folded . #ValVar . filtered (`notElem` bound))
& (<> gokap bound k)
ExpLetRec bs m ->
foldMapOf (each . _2) (goabs bound') bs <> go bound' m
where bound' = bound & insertFrom (bs ^.. each . _1)
ExpContinue k xs -> filter (`notElem` bound) (k : xs ^.. each . #ValVar)
ExpIf c t f ->
(c ^.. #ValVar . filtered (`notElem` bound))
<> go bound t <> go bound f
ExpApply f xs k ->
(f:xs) ^.. (each . #ValVar . filtered (`notElem` bound))
<> (k ^.. filtered (`notElem` bound))
free' = nubOrd . goFree HS.empty where
goFreeKap bound (MkKappa xs m) = goFree (bound & insertFrom xs) m
goFreeLam bound (MkLambda xs k m) = goFree (bound & insertFrom (k:xs)) m
goFreeAbs bound = \case
AbsKappa kap -> goFreeKap bound kap
AbsLambda lam -> goFreeLam bound lam
goFree :: HashSet Name -> Exp -> List Name
goFree bound = \case
ExpPrim p k ->
p & toListOf (folded . #ValVar . filtered (`notElem` bound))
& (<> goFreeKap bound k)
ExpLetRec bs m ->
foldMapOf (each . _2) (goFreeAbs bound') bs <> goFree bound' m
where bound' = bound & insertFrom (bs ^.. each . _1)
ExpContinue k xs -> filter (`notElem` bound) (k : xs ^.. each . #ValVar)
ExpIf c t f ->
(c ^.. #ValVar . filtered (`notElem` bound))
<> goFree bound t <> goFree bound f
ExpApply f xs k ->
(f:xs) ^.. (each . #ValVar . filtered (`notElem` bound))
<> (k ^.. filtered (`notElem` bound))
freeLambda :: Lambda -> List Name
freeLambda (MkLambda {binders,ktail,body}) = _
+1 -1
View File
@@ -52,7 +52,7 @@ import Language.Haskell.TH.Quote (QuasiQuoter)
newtype Name = MkName { inner :: Text }
deriving newtype (Show, Eq, IsString, Gen, Hashable)
deriving newtype (Show, Eq, Ord, IsString, Gen, Hashable)
deriving stock (Generic, Data)
getName :: Name -> Text