Prototype, extremely bad code implementation of CCHM Cubical Type Theory
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
6.9 KiB

3 years ago
3 years ago
3 years ago
  1. {-# LANGUAGE TupleSections #-}
  2. {-# LANGUAGE BlockArguments #-}
  3. {-# LANGUAGE LambdaCase #-}
  4. {-# LANGUAGE DerivingVia #-}
  5. module Presyntax.Parser where
  6. import Control.Applicative
  7. import Control.Monad.State
  8. import qualified Data.Text as T
  9. import Data.Text (Text)
  10. import Presyntax.Lexer
  11. import Presyntax
  12. data ParseError
  13. = UnexpectedEof Int Int
  14. | Unexpected Token
  15. | Empty
  16. | AltError ParseError ParseError
  17. deriving (Show)
  18. data ParseState
  19. = ParseState { ptTs :: [Token]
  20. , ptLine :: !Int
  21. , ptCol :: !Int
  22. }
  23. newtype Parser a =
  24. Parser { runParser :: ParseState -> Either ParseError (a, ParseState) }
  25. deriving
  26. ( Functor
  27. , Applicative
  28. , Monad
  29. , MonadState ParseState
  30. )
  31. via (StateT ParseState (Either ParseError))
  32. eof :: Parser ()
  33. eof = Parser $ \state ->
  34. case ptTs state of
  35. [] -> Right ((), state)
  36. (x:_) -> Left (Unexpected x)
  37. parseString :: Parser a -> String -> Either (Either LexError ParseError) a
  38. parseString (Parser k) s =
  39. case lexString s of
  40. Left e -> Left (Left e)
  41. Right xs ->
  42. case k (ParseState xs 0 0) of
  43. Left e -> Left (pure e)
  44. Right (x, _) -> Right x
  45. selectToken :: (Token -> Maybe a) -> Parser a
  46. selectToken k = Parser \case
  47. ParseState [] l c -> Left (UnexpectedEof l c)
  48. ParseState (x:xs) _ _ ->
  49. case k x of
  50. Just p -> pure (p, ParseState xs (tokLine x) (tokCol x))
  51. Nothing -> Left (Unexpected x)
  52. expect :: TokenClass -> Parser ()
  53. expect t = selectToken (\x -> if tokClass x == t then Just () else Nothing)
  54. var :: Parser Text
  55. var = selectToken \case
  56. Token _ _ _ _ (Tok_var v) -> pure v
  57. _ -> Nothing
  58. optionally :: Parser a -> Parser (Maybe a)
  59. optionally p = fmap Just p <|> pure Nothing
  60. parens :: Parser a -> Parser a
  61. parens k = do
  62. expect Tok_oparen
  63. x <- k
  64. expect Tok_cparen
  65. pure x
  66. square :: Parser a -> Parser a
  67. square k = do
  68. expect Tok_osquare
  69. x <- k
  70. expect Tok_csquare
  71. pure x
  72. instance Alternative Parser where
  73. empty = Parser \_ -> Left Empty
  74. Parser kx <|> Parser ky = Parser \x ->
  75. case kx x of
  76. Right x -> Right x
  77. Left e ->
  78. case ky x of
  79. Left _ -> Left e
  80. Right y -> Right y
  81. attachPos :: Parser Exp -> Parser Exp
  82. attachPos k = do
  83. start <- gets (\(ParseState ~(x:_) _ _) -> (tokLine x, tokCol x - (tokOff x - tokSOff x)))
  84. x <- k
  85. end <- gets (\(ParseState _ l c) -> (l, c))
  86. pure (Span start end x)
  87. body :: Parser Exp
  88. body = attachPos letExpr <|> attachPos lamExpr <|> attachPos exprPi where
  89. lamExpr = do
  90. expect Tok_lambda
  91. vs <- some arg
  92. expect Tok_arrow
  93. e <- body
  94. pure (foldr Lam e vs)
  95. letExpr = do
  96. expect Tok_let
  97. v <- T.unpack <$> var
  98. expect Tok_colon
  99. t <- body
  100. expect Tok_equal
  101. b <- body
  102. expect Tok_in
  103. Let v t b <$> body
  104. arg = T.unpack <$> var
  105. exprPi :: Parser Exp
  106. exprPi = attachPos $
  107. do
  108. bs <- optionally binder
  109. case bs of
  110. Just k -> foldl (.) id k <$> attachPos exprPi
  111. Nothing -> attachPos exprArr
  112. where
  113. binder = (some (parens bind) <* expect Tok_arrow)
  114. <|> (fmap pure (parens sigma) <* expect Tok_times)
  115. bind = do
  116. names <- some (T.unpack <$> var)
  117. expect Tok_colon
  118. t <- exprPi
  119. pure (foldr (\n k -> Pi n t . k) id names)
  120. sigma = do
  121. names <- some (T.unpack <$> var)
  122. expect Tok_colon
  123. t <- exprPi
  124. pure (foldr (\n k -> Sigma n t . k) id names)
  125. exprArr :: Parser Exp
  126. exprArr = attachPos $ do
  127. t <- attachPos exprConj
  128. c <- optionally (fmap (const True) (expect Tok_arrow) <|> fmap (const False) (expect Tok_times))
  129. case c of
  130. Just True -> Pi "_" t <$> exprPi
  131. Just False -> Sigma "_" t <$> exprPi
  132. Nothing -> pure t
  133. exprApp :: Parser Exp
  134. exprApp = attachPos $
  135. do
  136. head <- atom
  137. spine <- many spineEntry
  138. pure (foldl app head spine)
  139. where
  140. spineEntry = atom
  141. app f s = App f s
  142. exprDisj :: Parser Exp
  143. exprDisj = attachPos $
  144. do
  145. first <- exprApp
  146. rest <- many disjunct
  147. pure (foldl IOr first rest)
  148. where
  149. disjunct = expect Tok_or *> exprApp
  150. exprConj :: Parser Exp
  151. exprConj = attachPos $
  152. do
  153. first <- exprDisj
  154. rest <- many conjunct
  155. pure (foldl IAnd first rest)
  156. where
  157. conjunct = expect Tok_and *> exprDisj
  158. atom0 :: Parser Exp
  159. atom0 = attachPos $
  160. fmap (Var . T.unpack) var
  161. <|> keywords
  162. <|> fmap INot (expect Tok_not *> atom)
  163. <|> parens pair
  164. <|> square (Partial <$> (system <|> pure []))
  165. where
  166. table = [ (Type, Tok_type)
  167. , (Typeω, Tok_typeω)
  168. , (I, Tok_I)
  169. , (I0, Tok_I0)
  170. , (I1, Tok_I1)
  171. , (Path, Tok_path)
  172. , (SubT, Tok_sub)
  173. , (PartialT, Tok_Partial)
  174. , (PartialP, Tok_PartialP)
  175. , (Comp, Tok_comp)
  176. , (SubT, Tok_sub)
  177. , (Comp, Tok_comp)
  178. , (GlueTy, Tok_Glue)
  179. , (Glue, Tok_glue)
  180. , (Unglue, Tok_unglue)
  181. , (Bool, Tok_bool)
  182. , (Tt, Tok_tt)
  183. , (Ff, Tok_ff)
  184. , (If, Tok_if)
  185. ]
  186. keyword (x, y) = fmap (const x) (expect y)
  187. keywords = foldr ((<|>) . keyword) empty table
  188. atom :: Parser Exp
  189. atom = attachPos $
  190. do
  191. e <- atom0
  192. c <- many (selectToken (projection . tokClass))
  193. pure $ case c of
  194. [] -> e
  195. sls -> foldl (flip ($)) e sls
  196. where
  197. projection Tok_p1 = pure Proj1
  198. projection Tok_p2 = pure Proj2
  199. projection _ = Nothing
  200. system :: Parser [(Formula, Exp)]
  201. system =
  202. do
  203. t <- comp
  204. x <- optionally (expect Tok_comma)
  205. case x of
  206. Just () -> (t:) <$> system
  207. Nothing -> pure [t]
  208. where
  209. comp = do
  210. t <- formula
  211. expect Tok_arrow
  212. (t,) <$> body
  213. pair :: Parser Exp
  214. pair = do
  215. t <- body
  216. x <- optionally (expect Tok_comma)
  217. case x of
  218. Just () -> Pair t <$> pair
  219. Nothing -> pure t
  220. statement :: Parser Statement
  221. statement = (assume <|> declare <|> (Eval <$> body)) <* eof where
  222. assume = do
  223. expect Tok_assume
  224. Assume <$> vars
  225. declare = do
  226. expect Tok_let
  227. x <- T.unpack <$> var
  228. expect Tok_colon
  229. ty <- body
  230. expect Tok_equal
  231. Declare x ty <$> body
  232. bind = do
  233. var <- some (T.unpack <$> var)
  234. expect Tok_colon
  235. body <- body
  236. pure $ map ((, body)) var
  237. vars = do
  238. var <- bind
  239. t <- optionally (expect Tok_comma)
  240. case t of
  241. Nothing -> pure var
  242. Just x -> (var ++) <$> vars
  243. formula :: Parser Formula
  244. formula = conjunction where
  245. conjunction, disjunction, atom :: Parser Formula
  246. conjunction = do
  247. d <- disjunction
  248. t <- optionally (expect Tok_and)
  249. case t of
  250. Nothing -> pure d
  251. Just x -> And d <$> conjunction
  252. disjunction = do
  253. d <- atom
  254. t <- optionally (expect Tok_or)
  255. case t of
  256. Nothing -> pure d
  257. Just x -> Or d <$> disjunction
  258. atom = (Is1 . T.unpack) <$> var
  259. <|> (Is0 . T.unpack) <$> (expect Tok_not *> var)
  260. <|> Top <$ expect Tok_I1
  261. <|> Bot <$ expect Tok_I0
  262. <|> parens conjunction