less prototype, less bad code implementation of CCHM 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.

289 lines
8.6 KiB

  1. {
  2. {-# LANGUAGE FlexibleContexts, FlexibleInstances, ViewPatterns #-}
  3. module Presyntax.Parser where
  4. import qualified Data.Text as T
  5. import Data.Text (Text)
  6. import Presyntax.Presyntax
  7. import Presyntax.Tokens
  8. import Presyntax.Lexer
  9. import Prelude hiding (span)
  10. import Debug.Trace
  11. }
  12. %name parseExp Exp
  13. %name parseStmt Statement
  14. %name parseProg Program
  15. %name parseRepl ReplStatement
  16. %tokentype { Token }
  17. %monad { Alex }
  18. %lexer { lexer } { Token TokEof _ _ }
  19. %errorhandlertype explist
  20. %error { parseError }
  21. %token
  22. var { Token (TokVar _) _ _ }
  23. 'eof' { Token TokEof _ _ }
  24. '(' { Token TokOParen _ _ }
  25. ')' { Token TokCParen _ _ }
  26. '{' { Token TokOBrace _ _ }
  27. '}' { Token TokCBrace _ _ }
  28. START { Token TokLStart _ _ }
  29. END { Token TokLEnd _ _ }
  30. '[' { Token TokOSquare _ _ }
  31. ']' { Token TokCSquare _ _ }
  32. '{-#' { Token TokOPragma _ _ }
  33. '#-}' { Token TokCPragma _ _ }
  34. '\\' { Token TokLambda _ _ }
  35. '->' { Token TokArrow _ _ }
  36. '_' { Token TokUnder _ _ }
  37. ':' { Token TokColon _ _ }
  38. ';' { Token TokSemi _ _ }
  39. '=' { Token TokEqual _ _ }
  40. ',' { Token TokComma _ _ }
  41. '*' { Token TokStar _ _ }
  42. 'as' { Token TokAs _ _ }
  43. 'let' { Token TokLet _ _ }
  44. 'in' { Token TokIn _ _ }
  45. 'data' { Token TokData _ _ }
  46. 'case' { Token TokCase _ _ }
  47. 'where' { Token TokWhere _ _ }
  48. '&&' { Token TokAnd _ _ }
  49. '||' { Token TokOr _ _ }
  50. '.1' { Token TokPi1 _ _ }
  51. '.2' { Token TokPi2 _ _ }
  52. 'PRIMITIVE' { Token TokPrim _ _ }
  53. 'postulate' { Token TokPostulate _ _ }
  54. ':let' { Token TokReplLet _ _ }
  55. ':t' { Token (TokReplT _) _ _ }
  56. %%
  57. Exp :: { Expr }
  58. Exp
  59. : '\\' LambdaList '->' Exp { span $1 $4 $ makeLams $2 $4 }
  60. | '\\' MaybeLambdaList '[' Faces ']' { span $1 $5 $ makeLams $2 $ LamSystem $4 }
  61. | '\\' 'case' Block(CaseList) { span $1 $3 $ LamCase (thd $3) }
  62. | '(' var ':' Exp ')' ProdTail { span $1 $6 $ Pi Ex (getVar $2) $4 $6 }
  63. | '{' var ':' Exp '}' ProdTail { span $1 $6 $ Pi Im (getVar $2) $4 $6 }
  64. | ExpApp '->' Exp { span $1 $3 $ Pi Ex (T.singleton '_') $1 $3 }
  65. | '(' var ':' Exp ')' '*' Exp { span $1 $7 $ Sigma (getVar $2) $4 $7 }
  66. | ExpApp '*' Exp { span $1 $3 $ Sigma (T.singleton '_') $1 $3 }
  67. | 'let' Block(LetList) 'in' Exp { span $1 $4 $ Let (thd $2) $4 }
  68. | ExpApp { $1 }
  69. ExpApp :: { Expr }
  70. : ExpApp ExpProj { span $1 $2 $ App Ex $1 $2 }
  71. | ExpApp '{' Exp '}' { span $1 $4 $ App Im $1 $3 }
  72. | ExpProj { $1 }
  73. ExpProj :: { Expr }
  74. : ExpProj '.1' { span $1 $2 $ Proj1 $1 }
  75. | ExpProj '.2' { span $1 $2 $ Proj2 $1 }
  76. | Atom { $1 }
  77. Tuple :: { Expr }
  78. : Exp { $1 }
  79. | Exp ',' Tuple { span $1 $3 $ Pair $1 $3 }
  80. Atom :: { Expr }
  81. : var { span $1 $1 $ Var (getVar $1) }
  82. | '_' { span $1 $1 $ Hole }
  83. | '(' Tuple ')' { span $1 $3 $ $2 }
  84. ProdTail :: { Expr }
  85. : '(' VarList ':' Exp ')' ProdTail { span $1 $6 $ makePis Ex (thd $2) $4 $6 }
  86. | '{' VarList ':' Exp '}' ProdTail { span $1 $6 $ makePis Im (thd $2) $4 $6 }
  87. | '->' Exp { span $2 $2 $ $2 }
  88. MaybeLambdaList :: { [(Plicity, Text)] }
  89. : {- empty -} { [] }
  90. | LambdaList { $1 }
  91. LambdaList :: { [(Plicity, Text)] }
  92. : var { [(Ex, getVar $1)] }
  93. | '_' { [(Ex, T.singleton '_')] }
  94. | var LambdaList { (Ex, getVar $1):$2 }
  95. | '_' LambdaList { (Ex, T.singleton '_'):$2 }
  96. | '{'var'}' { [(Im, getVar $2)] }
  97. | '{'var'}' LambdaList { (Im, getVar $2):$4 }
  98. LhsList :: { [(Plicity, Text)] }
  99. : { [] }
  100. | LambdaList { $1 }
  101. VarList :: { (Posn, Posn, [Text]) }
  102. : var { (startPosn $1, endPosn $1, [getVar $1]) }
  103. | var ',' VarList { case $3 of (_, end, xs) -> (startPosn $1, end, getVar $1:xs) }
  104. LetItem :: { LetItem }
  105. : var ':' Exp { LetDecl (getVar $1) $3 }
  106. | var LhsList '=' Rhs { LetBind (getVar $1) (makeLams $2 $4) }
  107. LetList :: { [LetItem] }
  108. : { [] }
  109. | LetItem { [$1] }
  110. | LetItem ';' LetList { $1:$3 }
  111. CaseItem :: { (Pattern, Expr) }
  112. : Pattern '->' Exp { ($1, $3) }
  113. CaseList :: { [(Pattern, Expr)] }
  114. : { [] }
  115. | CaseItem { [$1] }
  116. | CaseItem Semis CaseList { $1:$3 }
  117. Pattern :: { Pattern }
  118. : PatVarList { makePattern $1 }
  119. PatVarList :: { (Posn, Posn, [Text]) }
  120. : var { (startPosn $1, endPosn $1, [getVar $1]) }
  121. | var PatVarList { case $2 of (_, end, xs) -> (startPosn $1, end, getVar $1:xs) }
  122. Statement :: { Statement }
  123. : VarList ':' Exp { spanSt $1 $3 $ Decl (thd $1) $3 }
  124. | var LhsList '=' Rhs { spanSt $1 $4 $ Defn (getVar $1) (makeLams $2 $4) }
  125. | '{-#' Pragma '#-}' { spanSt $1 $3 $ $2 }
  126. | 'postulate' Block(Postulates) { spanSt $1 $2 $ Postulate (thd $2) }
  127. | 'data' var Parameters ':' Exp 'where' Block(Constructors)
  128. { spanSt $1 $7 $ Data (getVar $2) $3 $5 (thd $7) }
  129. Constructors :: { [(Posn, Posn, Constructor)] }
  130. : { [] }
  131. | var ':' Exp { [(startPosn $1, endPosn $3, Point (getVar $1) $3)] }
  132. | var PatVarList ':' Exp '[' Faces ']' { [(startPosn $1, endPosn $7, Path (getVar $1) (thd $2) $4 $6)] }
  133. | var ':' Exp Semis Constructors { (startPosn $1, endPosn $3, Point (getVar $1) $3):$5 }
  134. | var PatVarList ':' Exp '[' Faces ']' Semis Constructors
  135. { (startPosn $1, endPosn $7, Path (getVar $1) (thd $2) $4 $6):$9 }
  136. Parameters :: { [(Text, Plicity, Expr)] }
  137. : {- empty -} { [] }
  138. | '(' var ':' Exp ')' Parameters { (getVar $2, Ex, $4):$6 }
  139. | '{' var ':' Exp '}' Parameters { (getVar $2, Im, $4):$6 }
  140. Rhs :: { Expr }
  141. : Exp { $1 }
  142. | Exp 'where' START LetList END { span $1 $5 $ Let $4 $1 }
  143. ReplStatement :: { Statement }
  144. : Exp { spanSt $1 $1 $ ReplNf $1 }
  145. | ':t' Exp { spanSt $1 $2 $ ReplTy $2 }
  146. | ':let' VarList ':' Exp { spanSt $1 $4 $ Decl (thd $2) $4 }
  147. | ':let' var LhsList '=' Exp { spanSt $1 $5 $ Defn (getVar $2) (makeLams $3 $5) }
  148. | '{-#' Pragma '#-}' { spanSt $1 $3 $ $2 }
  149. Postulates :: { [(Text, Expr)] }
  150. : var ':' Exp { [(getVar $1, $3)] }
  151. | var ':' Exp Semis Postulates { (getVar $1, $3):$5 }
  152. StatementSeq :: { [Statement] }
  153. : Statement { [$1] }
  154. | Statement Semis { [$1] }
  155. | Statement Semis Program { $1:$3 }
  156. Program :: { [Statement] }
  157. : { [] }
  158. | Semis { [] }
  159. | StatementSeq { $1 }
  160. | Semis StatementSeq { $2 }
  161. Semis :: { () }
  162. : ';' { () }
  163. | ';' Semis { () }
  164. Pragma :: { Statement }
  165. : 'PRIMITIVE' var var { Builtin (getVar $2) (getVar $3) }
  166. | 'PRIMITIVE' var { Builtin (getVar $2) (getVar $2) }
  167. Faces :: { [(Formula, Expr)] }
  168. : {- empty system -} { [] }
  169. | NeFaces { $1 }
  170. NeFaces :: { [(Formula, Expr) ]}
  171. : Formula '->' Exp { [($1, $3)] }
  172. | Formula '->' Exp ',' NeFaces { ($1, $3):$5 }
  173. Formula :: { Formula }
  174. : Disjn { $1 }
  175. | Disjn '&&' Disjn { $1 `FAnd` $3 }
  176. Disjn :: { Formula }
  177. : FAtom { $1 }
  178. | FAtom '||' FAtom { $1 `FOr` $3 }
  179. FAtom :: { Formula }
  180. : '(' var '=' var ')' {%
  181. case $4 of
  182. Token (TokVar x) _ _
  183. | x == T.pack "i0" -> pure (FIs0 (getVar $2))
  184. | x == T.pack "i1" -> pure (FIs1 (getVar $2))
  185. x -> parseError (x, ["i0", "i1"])
  186. }
  187. Block(p)
  188. : START p END { (startPosn $1, endPosn $3, $2) }
  189. | '{' p '}' { (startPosn $1, endPosn $3, $2) }
  190. {
  191. lexer cont = alexMonadScan >>= cont
  192. parseError x = alexError (show x)
  193. makeLams xs b = foldr (uncurry Lam) b xs
  194. makePis p xs t b = foldr (flip (Pi p) t) b xs
  195. makeSigmas xs t b = foldr (flip Sigma t) b xs
  196. class HasPosn a where
  197. startPosn :: a -> Posn
  198. endPosn :: a -> Posn
  199. instance HasPosn Token where
  200. startPosn (Token _ l c) = Posn l c
  201. endPosn (Token t l c) = Posn l (c + tokSize t)
  202. instance HasPosn Expr where
  203. startPosn (Span _ s _) = s
  204. startPosn _ = error "no start posn in parsed expression?"
  205. endPosn (Span _ _ e) = e
  206. endPosn _ = error "no end posn in parsed expression?"
  207. instance HasPosn (Posn, Posn, a) where
  208. startPosn (s, _, _) = s
  209. endPosn (_, e, _) = e
  210. thd :: (a, b, c) -> c
  211. thd (x, y, z) = z
  212. span s e ex = Span ex (startPosn s) (endPosn e)
  213. spanSt s e ex = SpanSt ex (startPosn s) (endPosn e)
  214. getVar (Token (TokVar s) _ _) = s
  215. getVar _ = error "getVar non-var"
  216. makePattern (_, _, [x]) = PCap x
  217. makePattern (_, _, (x:xs)) = PCon x xs
  218. }