module Blanks.Conversion
  ( locScopeForget
  , scopeAnno
  ) where

import Blanks.LocScope (LocScope, pattern LocScopeBinder, pattern LocScopeBound, pattern LocScopeEmbed,
                        pattern LocScopeFree)
import Blanks.Scope (Scope, pattern ScopeBinder, pattern ScopeBound, pattern ScopeEmbed, pattern ScopeFree)

-- | Forget all the annotations and yield a plain 'Scope'.
locScopeForget :: Functor f => LocScope l n f a -> Scope n f a
locScopeForget :: LocScope l n f a -> Scope n f a
locScopeForget ls :: LocScope l n f a
ls =
  case LocScope l n f a
ls of
    LocScopeBound _ b :: Int
b -> Int -> Scope n f a
forall n (f :: * -> *) a. Int -> Scope n f a
ScopeBound Int
b
    LocScopeFree _ a :: a
a -> a -> Scope n f a
forall a n (f :: * -> *). a -> Scope n f a
ScopeFree a
a
    LocScopeBinder _ r :: Int
r x :: n
x e :: LocScope l n f a
e -> Int -> n -> Scope n f a -> Scope n f a
forall n (f :: * -> *) a. Int -> n -> Scope n f a -> Scope n f a
ScopeBinder Int
r n
x (LocScope l n f a -> Scope n f a
forall (f :: * -> *) l n a.
Functor f =>
LocScope l n f a -> Scope n f a
locScopeForget LocScope l n f a
e)
    LocScopeEmbed _ fe :: f (LocScope l n f a)
fe -> f (Scope n f a) -> Scope n f a
forall (f :: * -> *) n a. f (Scope n f a) -> Scope n f a
ScopeEmbed ((LocScope l n f a -> Scope n f a)
-> f (LocScope l n f a) -> f (Scope n f a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap LocScope l n f a -> Scope n f a
forall (f :: * -> *) l n a.
Functor f =>
LocScope l n f a -> Scope n f a
locScopeForget f (LocScope l n f a)
fe)

-- | Annotate every location in the 'Scope' with a given value as a 'LocScope'.
scopeAnno :: Functor f => l -> Scope n f a -> LocScope l n f a
scopeAnno :: l -> Scope n f a -> LocScope l n f a
scopeAnno l :: l
l = Scope n f a -> LocScope l n f a
go where
  go :: Scope n f a -> LocScope l n f a
go s :: Scope n f a
s =
    case Scope n f a
s of
      ScopeBound b :: Int
b -> l -> Int -> LocScope l n f a
forall l n (f :: * -> *) a. l -> Int -> LocScope l n f a
LocScopeBound l
l Int
b
      ScopeFree a :: a
a -> l -> a -> LocScope l n f a
forall l a n (f :: * -> *). l -> a -> LocScope l n f a
LocScopeFree l
l a
a
      ScopeBinder r :: Int
r x :: n
x e :: Scope n f a
e -> l -> Int -> n -> LocScope l n f a -> LocScope l n f a
forall l n (f :: * -> *) a.
l -> Int -> n -> LocScope l n f a -> LocScope l n f a
LocScopeBinder l
l Int
r n
x (Scope n f a -> LocScope l n f a
go Scope n f a
e)
      ScopeEmbed fe :: f (Scope n f a)
fe -> l -> f (LocScope l n f a) -> LocScope l n f a
forall l (f :: * -> *) n a.
l -> f (LocScope l n f a) -> LocScope l n f a
LocScopeEmbed l
l ((Scope n f a -> LocScope l n f a)
-> f (Scope n f a) -> f (LocScope l n f a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Scope n f a -> LocScope l n f a
go f (Scope n f a)
fe)