Abbie's Haskell compiler
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.

237 lines
5.9 KiB

  1. {
  2. {-# LANGUAGE FlexibleContexts, FlexibleInstances, ViewPatterns #-}
  3. module Frontend.Autogen.Parser where
  4. import qualified Data.Text as T
  5. import Data.Text (Text)
  6. import Frontend.Lexer.Tokens
  7. import Frontend.Parser.Posn
  8. import Frontend.Syntax
  9. import Frontend.Autogen.Lexer
  10. import Prelude hiding (span)
  11. import Debug.Trace
  12. }
  13. %name parseExp Exp
  14. %name parseMod Module
  15. %name parseType Type
  16. %tokentype { Token }
  17. %monad { Alex }
  18. %lexer { lexer } { Token TokEof _ _ }
  19. %errorhandlertype explist
  20. %error { parseError }
  21. %token
  22. VAR { Token (TokVar _) _ _ }
  23. CON { Token (TokCon _) _ _ }
  24. STRING { Token (TokString _) _ _ }
  25. 'eof' { Token TokEof _ _ }
  26. '(' { Token TokOParen _ _ }
  27. ')' { Token TokCParen _ _ }
  28. '{' { Token TokOBrace _ _ }
  29. '}' { Token TokCBrace _ _ }
  30. START { Token TokLStart _ _ }
  31. END { Token TokLEnd _ _ }
  32. '[' { Token TokOSquare _ _ }
  33. ']' { Token TokCSquare _ _ }
  34. '{-#' { Token TokOPragma _ _ }
  35. '#-}' { Token TokCPragma _ _ }
  36. '\\' { Token TokLambda _ _ }
  37. '->' { Token TokArrow _ _ }
  38. '_' { Token TokUnder _ _ }
  39. '::' { Token TokDoubleColon _ _ }
  40. ';' { Token TokSemi _ _ }
  41. '=' { Token TokEqual _ _ }
  42. ',' { Token TokComma _ _ }
  43. 'let' { Token TokLet _ _ }
  44. 'in' { Token TokIn _ _ }
  45. 'data' { Token TokData _ _ }
  46. 'case' { Token TokCase _ _ }
  47. 'module' { Token TokModule _ _ }
  48. 'where' { Token TokWhere _ _ }
  49. 'import' { Token TokImport _ _ }
  50. 'as' { Token TokAs _ _ }
  51. 'qualified' { Token TokQualified _ _ }
  52. %%
  53. Exp :: { Exp }
  54. : InfixExp '::' Type { span $1 $3 $ Annot $1 $3 }
  55. | InfixExp { $1 }
  56. InfixExp :: { Exp }
  57. : LeftExp {- ... -} { $1 }
  58. -- | LeftExp qop InfixExp { Infix $1 (getVar $2) $3 }
  59. LeftExp :: { Exp }
  60. : '\\' Apat List(Apat) '->' Exp { span $1 $5 (makeLams ($2:$3) $5) }
  61. | 'let' LaidOutList(Decl) 'in' Exp { span $1 $4 $ Let (thd $2) $4 }
  62. | FuncExp { $1 }
  63. FuncExp :: { Exp }
  64. : FuncExp Aexp { span $1 $2 $ App $1 $2 }
  65. | Aexp { $1 }
  66. Aexp :: { Exp }
  67. : qvar { span $1 $1 $ Ref (getVar $1) }
  68. | qcon { span $1 $1 $ Con (getVar $1) }
  69. | '(' CommaList(Exp) ')' { span $1 $3 $ makeTuple $2 }
  70. | STRING { span $1 $1 $ Literal (LitString (getString $1)) }
  71. Type :: { Type }
  72. : Btype '->' Type { span $1 $3 $ Tyarr $1 $3 }
  73. | Btype { $1 }
  74. Btype :: { Type }
  75. : Btype Atype { span $1 $2 $ Tyapp $1 $2 }
  76. | Atype { $1 }
  77. Atype :: { Type }
  78. : qvar { span $1 $1 $ Tyvar (getVar $1) }
  79. | qcon { span $1 $1 $ Tycon (getVar $1) }
  80. | '(' CommaList(Type) ')' { span $1 $3 $ makeTupleType $2 }
  81. Pat :: { Pat }
  82. : Lpat { $1 }
  83. Lpat :: { Pat }
  84. : Apat { $1 }
  85. Apat :: { Pat }
  86. : VAR { span $1 $1 $ Var (getVar $1) }
  87. | '_' { span $1 $1 $ Wildcard }
  88. | '(' CommaList(Pat) ')' { span $1 $3 $ makeTuplePattern $2 }
  89. Decl :: { Decl }
  90. : VAR '::' Type { TySig (getVar $1) $3 }
  91. | VAR Apat List(Apat) Rhs { FunDecl (getVar $1) ($2:$3) $4 }
  92. | Pat Rhs { PatDecl $1 $2 }
  93. Rhs :: { Rhs }
  94. : '=' Exp { BareRhs $2 [] }
  95. | '=' Exp 'where' LaidOutList(Decl) { BareRhs $2 (thd $4) }
  96. LaidOutList(p)
  97. : START Opt(Semis) LOLContents(p, END) { (startPosn $1, lolEnd $3, lolList $3) }
  98. | '{' Opt(Semis) LOLContents(p, '}') { (startPosn $1, lolEnd $3, lolList $3) }
  99. LOLContents(p, End)
  100. : p Semis LOLContents(p,End) { lolCons $1 $3 }
  101. | p Opt(Semis) End { lolCons $1 (emptyLol $3) }
  102. | Opt(Semis) End { emptyLol $2 }
  103. Module :: { Module }
  104. : 'module' CON ImportExportList 'where' LaidOutList(ModItem)
  105. { Module { moduleName = getVar $2
  106. , moduleExports = $3
  107. , moduleItems = thd $5 }
  108. }
  109. ImportExportList :: { Maybe [NamespacedItem Text] }
  110. : {-empty-} { Nothing }
  111. | '(' CommaList(NSItem) ')' { Just $2 }
  112. NSItem :: { NamespacedItem Text }
  113. : VAR { IEVar (getVar $1) }
  114. | CON { IECon (getVar $1) }
  115. | 'module' CON { IEModule (getVar $2) }
  116. ModItem :: { Item }
  117. : Decl { ModDecl $1 }
  118. | Import { ModImport $1 }
  119. Import
  120. : 'import' qcon ImportExportList
  121. { Import (getVar $2) $3 False Nothing }
  122. | 'import' qcon ImportExportList 'as' CON
  123. { Import (getVar $2) $3 False (Just (getVar $5)) }
  124. | 'import' 'qualified' qcon ImportExportList
  125. { Import (getVar $3) $4 True Nothing }
  126. | 'import' 'qualified' qcon ImportExportList 'as' CON
  127. { Import (getVar $3) $4 True (Just (getVar $6)) }
  128. Opt(p)
  129. : { () }
  130. | p { () }
  131. Semis
  132. : ';' Semis { () }
  133. | ';' { () }
  134. -- TODO: qualified names
  135. qvar : VAR { $1 }
  136. qcon : CON { $1 }
  137. List(p)
  138. : {-empty-} { [] }
  139. | p List(p) { $1:$2 }
  140. CommaList(p)
  141. : {-empty-} { [] }
  142. | p { [$1] }
  143. | p ',' CommaList(p) { $1:$3 }
  144. Block(p)
  145. : START p END { (startPosn $1, endPosn $3, $2) }
  146. | '{' p '}' { (startPosn $1, endPosn $3, $2) }
  147. {
  148. type Exp = FeExpr Text
  149. type Pat = FePat Text
  150. type Decl = FeDecl Text
  151. type Type = FeType Text
  152. type Rhs = FeRhs Text
  153. type Module = FeModule Text
  154. type Item = ModuleItem Text
  155. lexer cont = alexMonadScan >>= cont
  156. parseError x = alexError (show x)
  157. makeLams xs b = foldr Lam b xs
  158. getVar (Token (TokVar s) _ _) = s
  159. getVar (Token (TokCon s) _ _) = s
  160. getVar _ = error "getVar non-var"
  161. getString (Token (TokString s) _ _) = s
  162. getString _ = error "getString non-string"
  163. data LOL a = LOL { lolEnd :: Posn, lolList :: [a] }
  164. emptyLol :: HasPosn x => x -> LOL a
  165. emptyLol t = LOL (endPosn t) []
  166. lolCons :: a -> LOL a -> LOL a
  167. lolCons x (LOL p xs) = LOL p (x:xs)
  168. makeTupleType [x] = ParenType x
  169. makeTupleType xs = Tytup xs
  170. makeTuplePattern [x] = ParenPat x
  171. makeTuplePattern xs = TupPat xs
  172. makeTuple [x] = ParenExp x
  173. makeTuple xs = Tuple xs
  174. }