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.

283 lines
6.5 KiB

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. <|> fmap (const Type) (expect Tok_type)
  162. <|> fmap (const I) (expect Tok_I)
  163. <|> fmap (const I0) (expect Tok_I0)
  164. <|> fmap (const I1) (expect Tok_I1)
  165. <|> fmap (const Path) (expect Tok_path)
  166. <|> fmap (const SubT) (expect Tok_sub)
  167. <|> fmap (const PartialT) (expect Tok_phi)
  168. <|> fmap (const Comp) (expect Tok_comp)
  169. <|> fmap INot (expect Tok_not *> atom)
  170. <|> parens pair
  171. <|> square (Partial <$> (system <|> pure []))
  172. atom :: Parser Exp
  173. atom = attachPos $
  174. do
  175. e <- atom0
  176. c <- many (selectToken (projection . tokClass))
  177. pure $ case c of
  178. [] -> e
  179. sls -> foldl (flip ($)) e sls
  180. where
  181. projection Tok_p1 = pure Proj1
  182. projection Tok_p2 = pure Proj2
  183. projection _ = Nothing
  184. system :: Parser [(Formula, Exp)]
  185. system =
  186. do
  187. t <- comp
  188. x <- optionally (expect Tok_comma)
  189. case x of
  190. Just () -> (t:) <$> system
  191. Nothing -> pure [t]
  192. where
  193. comp = do
  194. t <- formula
  195. expect Tok_arrow
  196. (t,) <$> body
  197. pair :: Parser Exp
  198. pair = do
  199. t <- body
  200. x <- optionally (expect Tok_comma)
  201. case x of
  202. Just () -> Pair t <$> pair
  203. Nothing -> pure t
  204. statement :: Parser Statement
  205. statement = (assume <|> declare <|> (Eval <$> body)) <* eof where
  206. assume = do
  207. expect Tok_assume
  208. Assume <$> vars
  209. declare = do
  210. expect Tok_let
  211. x <- T.unpack <$> var
  212. expect Tok_colon
  213. ty <- body
  214. expect Tok_equal
  215. Declare x ty <$> body
  216. bind = do
  217. var <- some (T.unpack <$> var)
  218. expect Tok_colon
  219. body <- body
  220. pure $ map ((, body)) var
  221. vars = do
  222. var <- bind
  223. t <- optionally (expect Tok_comma)
  224. case t of
  225. Nothing -> pure var
  226. Just x -> (var ++) <$> vars
  227. formula :: Parser Formula
  228. formula = conjunction where
  229. conjunction, disjunction, atom :: Parser Formula
  230. conjunction = do
  231. d <- disjunction
  232. t <- optionally (expect Tok_and)
  233. case t of
  234. Nothing -> pure d
  235. Just x -> And d <$> conjunction
  236. disjunction = do
  237. d <- atom
  238. t <- optionally (expect Tok_or)
  239. case t of
  240. Nothing -> pure d
  241. Just x -> Or d <$> disjunction
  242. atom = (Is1 . T.unpack) <$> var
  243. <|> (Is0 . T.unpack) <$> (expect Tok_not *> var)
  244. <|> Top <$ expect Tok_I1
  245. <|> Bot <$ expect Tok_I0