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.

249 lines
6.5 KiB

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