|
{-# LANGUAGE PatternSynonyms #-}
|
|
module Syntax where
|
|
|
|
import Data.Function (on)
|
|
import Data.Text (Text)
|
|
|
|
import Presyntax.Presyntax (Plicity(..))
|
|
import qualified Data.Text as T
|
|
import Data.IORef (IORef)
|
|
import Data.Set (Set)
|
|
import qualified Data.Set as Set
|
|
|
|
data WiredIn
|
|
= WiType
|
|
| WiPretype
|
|
| WiInterval
|
|
| WiI0
|
|
| WiI1
|
|
| WiIAnd
|
|
| WiIOr
|
|
| WiINot
|
|
deriving (Eq, Show, Ord)
|
|
|
|
data Term
|
|
= Ref Name
|
|
| App Plicity Term Term
|
|
| Lam Plicity Text Term
|
|
| Pi Plicity Text Term Term
|
|
| Meta MV
|
|
| Type
|
|
| Typeω
|
|
|
|
| Sigma Text Term Term
|
|
| Pair Term Term
|
|
| Proj1 Term
|
|
| Proj2 Term
|
|
|
|
| I
|
|
| I0 | I1
|
|
| IAnd Term Term
|
|
| IOr Term Term
|
|
| INot Term
|
|
deriving (Eq, Show, Ord)
|
|
|
|
data MV =
|
|
MV { mvName :: Text
|
|
, mvCell :: {-# UNPACK #-} !(IORef (Maybe Value))
|
|
}
|
|
|
|
instance Eq MV where
|
|
(==) = (==) `on` mvName
|
|
instance Ord MV where
|
|
(<=) = (<=) `on` mvName
|
|
instance Show MV where
|
|
show = ('?':) . T.unpack . mvName
|
|
|
|
data Name
|
|
= Bound Text
|
|
| Defined Text
|
|
deriving (Eq, Show, Ord)
|
|
|
|
type NFType = Value
|
|
|
|
data Value
|
|
= VNe Head [Projection]
|
|
| VLam Plicity Closure
|
|
| VPi Plicity Value Closure
|
|
| VSigma Value Closure
|
|
| VPair Value Value
|
|
|
|
| VType | VTypeω
|
|
|
|
| VI
|
|
| VI0 | VI1
|
|
| VIAnd Value Value
|
|
| VIOr Value Value
|
|
| VINot Value
|
|
deriving (Eq, Show, Ord)
|
|
|
|
pattern VVar :: Name -> Value
|
|
pattern VVar x = VNe (HVar x) []
|
|
|
|
quoteWith :: Set Text -> Value -> Term
|
|
quoteWith names (VNe h sp) = foldl goSpine (goHead h) (reverse sp) where
|
|
goHead (HVar v) = Ref v
|
|
goHead (HMeta m) = Meta m
|
|
|
|
goSpine t (PApp p v) = App p t (quoteWith names v)
|
|
goSpine t PProj1 = Proj1 t
|
|
goSpine t PProj2 = Proj2 t
|
|
|
|
quoteWith names (VLam p (Closure n k)) =
|
|
let n' = refresh names n
|
|
in Lam p n' (quoteWith (Set.insert n' names) (k (VVar (Bound n'))))
|
|
|
|
quoteWith names (VPi p d (Closure n k)) =
|
|
let n' = refresh names n
|
|
in Pi p n' (quoteWith names d) (quoteWith (Set.insert n' names) (k (VVar (Bound n'))))
|
|
|
|
quoteWith names (VSigma d (Closure n k)) =
|
|
let n' = refresh names n
|
|
in Sigma n' (quoteWith names d) (quoteWith (Set.insert n' names) (k (VVar (Bound n'))))
|
|
|
|
quoteWith names (VPair a b) = Pair (quoteWith names a) (quoteWith names b)
|
|
quoteWith _ VType = Type
|
|
quoteWith _ VTypeω = Typeω
|
|
quoteWith _ VI = I
|
|
quoteWith _ VI0 = I0
|
|
quoteWith _ VI1 = I1
|
|
quoteWith names (VIAnd x y) = IAnd (quoteWith names x) (quoteWith names y)
|
|
quoteWith names (VIOr x y) = IOr (quoteWith names x) (quoteWith names y)
|
|
quoteWith names (VINot x) = INot (quoteWith names x)
|
|
|
|
refresh :: Set Text -> Text -> Text
|
|
refresh s n
|
|
| T.singleton '_' == n = n
|
|
| n `Set.notMember` s = n
|
|
| otherwise = refresh s (n <> T.singleton '\'')
|
|
|
|
quote :: Value -> Term
|
|
quote = quoteWith mempty
|
|
|
|
data Closure
|
|
= Closure
|
|
{ clArgName :: Text
|
|
, clCont :: Value -> Value
|
|
}
|
|
|
|
instance Show Closure where
|
|
show (Closure n c) = "Closure \\" ++ show n ++ " -> " ++ show (c (VVar (Bound n)))
|
|
|
|
instance Eq Closure where
|
|
Closure _ k == Closure _ k' =
|
|
k (VVar (Bound (T.pack "_"))) == k' (VVar (Bound (T.pack "_")))
|
|
|
|
instance Ord Closure where
|
|
Closure _ k <= Closure _ k' =
|
|
k (VVar (Bound (T.pack "_"))) <= k' (VVar (Bound (T.pack "_")))
|
|
|
|
data Head
|
|
= HVar Name
|
|
| HMeta MV
|
|
deriving (Eq, Show, Ord)
|
|
|
|
data Projection
|
|
= PApp Plicity Value
|
|
| PProj1
|
|
| PProj2
|
|
deriving (Eq, Show, Ord)
|