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.

165 lines
4.6 KiB

  1. {
  2. {-# LANGUAGE FlexibleInstances #-}
  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. }
  11. %name parseExp Exp
  12. %name parseStmt Statement
  13. %name parseProg Program
  14. %name parseRepl ReplStatement
  15. %tokentype { Token }
  16. %monad { Alex }
  17. %lexer { lexer } { Token TokEof _ _ }
  18. %errorhandlertype explist
  19. %error { parseError }
  20. %token
  21. var { Token (TokVar _) _ _ }
  22. '(' { Token TokOParen _ _ }
  23. ')' { Token TokCParen _ _ }
  24. '{' { Token TokOBrace _ _ }
  25. '}' { Token TokCBrace _ _ }
  26. '{-#' { Token TokOPragma _ _ }
  27. '#-}' { Token TokCPragma _ _ }
  28. '\\' { Token TokLambda _ _ }
  29. '->' { Token TokArrow _ _ }
  30. ':' { Token TokColon _ _ }
  31. ';' { Token TokSemi _ _ }
  32. '=' { Token TokEqual _ _ }
  33. ',' { Token TokComma _ _ }
  34. '*' { Token TokStar _ _ }
  35. '.1' { Token TokPi1 _ _ }
  36. '.2' { Token TokPi2 _ _ }
  37. 'PRIMITIVE' { Token TokPrim _ _ }
  38. ':let' { Token TokReplLet _ _ }
  39. ':t' { Token (TokReplT _) _ _ }
  40. %%
  41. Exp :: { Expr }
  42. Exp
  43. : '\\' LambdaList '->' Exp { span $1 $4 $ makeLams $2 $4 }
  44. | '(' var ':' Exp ')' ProdTail { span $1 $6 $ Pi Ex (getVar $2) $4 $6 }
  45. | '{' var ':' Exp '}' ProdTail { span $1 $6 $ Pi Im (getVar $2) $4 $6 }
  46. | ExpApp '->' Exp { span $1 $3 $ Pi Ex (T.singleton '_') $1 $3 }
  47. | '(' var ':' Exp ')' '*' Exp { span $1 $7 $ Sigma (getVar $2) $4 $7 }
  48. | ExpApp '*' Exp { span $1 $3 $ Sigma (T.singleton '_') $1 $3 }
  49. | ExpApp { $1 }
  50. ExpApp :: { Expr }
  51. : ExpApp ExpProj { span $1 $2 $ App Ex $1 $2 }
  52. | ExpApp '{' Exp '}' { span $1 $4 $ App Im $1 $3 }
  53. | ExpProj { $1 }
  54. ExpProj :: { Expr }
  55. : ExpProj '.1' { span $1 $2 $ Proj1 $1 }
  56. | ExpProj '.2' { span $1 $2 $ Proj2 $1 }
  57. | Atom { $1 }
  58. Tuple :: { Expr }
  59. : Exp { $1 }
  60. | Exp ',' Tuple { span $1 $3 $ Pair $1 $3 }
  61. Atom :: { Expr }
  62. : var { span $1 $1 $ Var (getVar $1) }
  63. | '(' Tuple ')' { span $1 $3 $ $2 }
  64. ProdTail :: { Expr }
  65. : '(' VarList ':' Exp ')' ProdTail { span $1 $6 $ makePis Ex (thd $2) $4 $6 }
  66. | '{' VarList ':' Exp '}' ProdTail { span $1 $6 $ makePis Im (thd $2) $4 $6 }
  67. | '->' Exp { span $2 $2 $ $2 }
  68. LambdaList :: { [(Plicity, Text)] }
  69. : var { [(Ex, getVar $1)] }
  70. | var LambdaList { (Ex, getVar $1):$2 }
  71. | '{'var'}' { [(Im, getVar $2)] }
  72. | '{'var'}' LambdaList { (Im, getVar $2):$4 }
  73. LhsList :: { [(Plicity, Text)] }
  74. : { [] }
  75. | LambdaList { $1 }
  76. VarList :: { (Posn, Posn, [Text]) }
  77. : var { (startPosn $1, endPosn $1, [getVar $1]) }
  78. | var ',' VarList { case $3 of (_, end, xs) -> (startPosn $1, end, getVar $1:xs) }
  79. Statement :: { Statement }
  80. : VarList ':' Exp { spanSt $1 $3 $ Decl (thd $1) $3 }
  81. | var LhsList '=' Exp { spanSt $1 $4 $ Defn (getVar $1) (makeLams $2 $4) }
  82. | '{-#' Pragma '#-}' { spanSt $1 $3 $ $2 }
  83. ReplStatement :: { Statement }
  84. : Exp { spanSt $1 $1 $ ReplNf $1 }
  85. | ':t' Exp { spanSt $1 $2 $ ReplTy $2 }
  86. | ':let' VarList ':' Exp { spanSt $1 $4 $ Decl (thd $2) $4 }
  87. | ':let' var LhsList '=' Exp { spanSt $1 $5 $ Defn (getVar $2) (makeLams $3 $5) }
  88. | '{-#' Pragma '#-}' { spanSt $1 $3 $ $2 }
  89. Program :: { [Statement] }
  90. : Statement { [$1] }
  91. | Statement ';' Program { $1:$3 }
  92. Pragma :: { Statement }
  93. : 'PRIMITIVE' var var { Builtin (getVar $2) (getVar $3) }
  94. | 'PRIMITIVE' var { Builtin (getVar $2) (getVar $2) }
  95. {
  96. lexer cont = alexMonadScan >>= cont
  97. parseError x = alexError (show x)
  98. makeLams xs b = foldr (uncurry Lam) b xs
  99. makePis p xs t b = foldr (flip (Pi p) t) b xs
  100. makeSigmas xs t b = foldr (flip Sigma t) b xs
  101. class HasPosn a where
  102. startPosn :: a -> Posn
  103. endPosn :: a -> Posn
  104. instance HasPosn Token where
  105. startPosn (Token _ l c) = Posn l c
  106. endPosn (Token t l c) = Posn l (c + tokSize t)
  107. instance HasPosn Expr where
  108. startPosn (Span _ s _) = s
  109. startPosn _ = error "no start posn in parsed expression?"
  110. endPosn (Span _ _ e) = e
  111. endPosn _ = error "no end posn in parsed expression?"
  112. instance HasPosn (Posn, Posn, a) where
  113. startPosn (s, _, _) = s
  114. endPosn (_, e, _) = e
  115. thd :: (a, b, c) -> c
  116. thd (x, y, z) = z
  117. span s e ex = Span ex (startPosn s) (endPosn e)
  118. spanSt s e ex = SpanSt ex (startPosn s) (endPosn e)
  119. getVar (Token (TokVar s) _ _) = s
  120. getVar _ = error "getVar non-var"
  121. }