summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCsaba Hruska <csaba.hruska@gmail.com>2017-05-28 21:21:48 -0600
committerCsaba Hruska <csaba.hruska@gmail.com>2017-05-28 21:21:48 -0600
commit233f1b8d67f3d5158792cb3f5b2cb17a03fdaf5b (patch)
tree39f02a54d7c6c386328a73b9bb5db7feea7f54ef /src
parentedf778d9ea460e515d3cb65440808b4aa6023b6f (diff)
add type signatures
Diffstat (limited to 'src')
-rw-r--r--src/LambdaCube/Compiler/Lexer.hs28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/LambdaCube/Compiler/Lexer.hs b/src/LambdaCube/Compiler/Lexer.hs
index 66179853..ac7f7f71 100644
--- a/src/LambdaCube/Compiler/Lexer.hs
+++ b/src/LambdaCube/Compiler/Lexer.hs
@@ -34,11 +34,13 @@ import LambdaCube.Compiler.DesugaredSource
34 34
35-- try with error handling 35-- try with error handling
36-- see http://blog.ezyang.com/2014/05/parsec-try-a-or-b-considered-harmful/comment-page-1/#comment-6602 36-- see http://blog.ezyang.com/2014/05/parsec-try-a-or-b-considered-harmful/comment-page-1/#comment-6602
37try_ :: String -> Parse r w a -> Parse r w a
37try_ s m = try m <?> s 38try_ s m = try m <?> s
38 39
39toSPos :: SourcePos -> SPos 40toSPos :: SourcePos -> SPos
40toSPos p = SPos (fromIntegral $ unPos $ sourceLine p) (fromIntegral $ unPos $ sourceColumn p) 41toSPos p = SPos (fromIntegral $ unPos $ sourceLine p) (fromIntegral $ unPos $ sourceColumn p)
41 42
43getSPos :: Parse r w SPos
42getSPos = toSPos <$> getPosition 44getSPos = toSPos <$> getPosition
43 45
44-------------------------------------------------------------------------------- literals 46-------------------------------------------------------------------------------- literals
@@ -130,12 +132,14 @@ getParseState = (,) <$> ask <*> getParserState
130 132
131----------------------------------------------------------- indentation, white space, symbols 133----------------------------------------------------------- indentation, white space, symbols
132 134
135getCheckedSPos :: Parse r w SPos
133getCheckedSPos = do 136getCheckedSPos = do
134 p <- getSPos 137 p <- getSPos
135 p' <- asks indentationLevel 138 p' <- asks indentationLevel
136 when (p /= p' && column p <= column p') $ fail "wrong indentation" 139 when (p /= p' && column p <= column p') $ fail "wrong indentation"
137 return p 140 return p
138 141
142identation :: Bool -> Parse r w t -> Parse r w [t]
139identation allowempty p = (if allowempty then option [] else id) $ do 143identation allowempty p = (if allowempty then option [] else id) $ do
140 pos' <- getCheckedSPos 144 pos' <- getCheckedSPos
141 (if allowempty then many else some) $ do 145 (if allowempty then many else some) $ do
@@ -143,6 +147,7 @@ identation allowempty p = (if allowempty then option [] else id) $ do
143 guard (column pos == column pos') 147 guard (column pos == column pos')
144 local (\e -> e {indentationLevel = pos}) p 148 local (\e -> e {indentationLevel = pos}) p
145 149
150lexemeWithoutSpace :: Parse r w t -> Parse r w (SI, t)
146lexemeWithoutSpace p = do 151lexemeWithoutSpace p = do
147 p1 <- getCheckedSPos 152 p1 <- getCheckedSPos
148 x <- p 153 x <- p
@@ -155,8 +160,10 @@ lexemeWithoutSpace p = do
155appRange :: Parse r w (SI -> a) -> Parse r w a 160appRange :: Parse r w (SI -> a) -> Parse r w a
156appRange p = (\fi p1 a p2 -> a $ RangeSI $ Range fi p1 p2) <$> asks fileInfo <*> getSPos <*> p <*> getLexemeEnd 161appRange p = (\fi p1 a p2 -> a $ RangeSI $ Range fi p1 p2) <$> asks fileInfo <*> getSPos <*> p <*> getLexemeEnd
157 162
163--getLexemeEnd :: _
158getLexemeEnd = get 164getLexemeEnd = get
159 165
166--noSpaceBefore :: _ --Parse r w a -> Parse r w a
160noSpaceBefore p = try $ do 167noSpaceBefore p = try $ do
161 pos <- getLexemeEnd 168 pos <- getLexemeEnd
162 x <- p 169 x <- p
@@ -164,19 +171,25 @@ noSpaceBefore p = try $ do
164 RangeSI (Range _ pos' _) -> pos == pos' 171 RangeSI (Range _ pos' _) -> pos == pos'
165 return x 172 return x
166 173
174lexeme_ :: Parse r w a -> Parse r w (SI, a)
167lexeme_ p = lexemeWithoutSpace p <* whiteSpace 175lexeme_ p = lexemeWithoutSpace p <* whiteSpace
168 176
169lexeme :: Parse r w a -> Parse r w a 177lexeme :: Parse r w a -> Parse r w a
170lexeme p = snd <$> lexeme_ p 178lexeme p = snd <$> lexeme_ p
171 179
180lexemeName :: Parse r w SName -> Parse r w SIName
172lexemeName p = uncurry SIName <$> lexeme_ p 181lexemeName p = uncurry SIName <$> lexeme_ p
173 182
183symbolWithoutSpace :: String -> Parse r w (SI, String)
174symbolWithoutSpace = lexemeWithoutSpace . string 184symbolWithoutSpace = lexemeWithoutSpace . string
175 185
186symbol :: String -> Parse r w (SI, String)
176symbol name = symbolWithoutSpace name <* whiteSpace 187symbol name = symbolWithoutSpace name <* whiteSpace
177 188
189simpleSpace :: Parse r w ()
178simpleSpace = skipSome (satisfy isSpace) 190simpleSpace = skipSome (satisfy isSpace)
179 191
192whiteSpace :: Parse r w ()
180whiteSpace = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "") 193whiteSpace = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "")
181 where 194 where
182 oneLineComment 195 oneLineComment
@@ -192,10 +205,12 @@ whiteSpace = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "
192 <|> oneOf "{}-" *> inCommentMulti 205 <|> oneOf "{}-" *> inCommentMulti
193 <?> "end of comment" 206 <?> "end of comment"
194 207
208parens, braces, brackets :: Parse r w a -> Parse r w a
195parens = between (symbol "(") (symbol ")") 209parens = between (symbol "(") (symbol ")")
196braces = between (symbol "{") (symbol "}") 210braces = between (symbol "{") (symbol "}")
197brackets = between (symbol "[") (symbol "]") 211brackets = between (symbol "[") (symbol "]")
198 212
213commaSep, commaSep1 :: Parse r w a -> Parse r w [a]
199commaSep p = sepBy p $ symbol "," 214commaSep p = sepBy p $ symbol ","
200commaSep1 p = sepBy1 p $ symbol "," 215commaSep1 p = sepBy1 p $ symbol ","
201 216
@@ -208,8 +223,10 @@ tick c = f <$> asks namespace
208 where 223 where
209 f = \case TypeNS -> switchTick c; _ -> c 224 f = \case TypeNS -> switchTick c; _ -> c
210 225
226switchNamespace :: Namespace -> Namespace
211switchNamespace = \case ExpNS -> TypeNS; TypeNS -> ExpNS 227switchNamespace = \case ExpNS -> TypeNS; TypeNS -> ExpNS
212 228
229modifyLevel :: (Namespace -> Namespace) -> Parse r w a -> Parse r w a
213modifyLevel f = local $ \e -> e {namespace = f $ namespace e} 230modifyLevel f = local $ \e -> e {namespace = f $ namespace e}
214 231
215typeNS, expNS :: Parse r w a -> Parse r w a 232typeNS, expNS :: Parse r w a -> Parse r w a
@@ -217,7 +234,7 @@ typeNS = modifyLevel $ const TypeNS
217expNS = modifyLevel $ const ExpNS 234expNS = modifyLevel $ const ExpNS
218 235
219-------------------------------------------------------------------------------- identifiers 236-------------------------------------------------------------------------------- identifiers
220 237lowerLetter, upperLetter, identStart, identLetter, lowercaseOpLetter, opLetter :: Parse r w Char
221lowerLetter = satisfy $ (||) <$> isLower <*> (== '_') 238lowerLetter = satisfy $ (||) <$> isLower <*> (== '_')
222upperLetter = satisfy isUpper 239upperLetter = satisfy isUpper
223identStart = satisfy $ (||) <$> isLetter <*> (== '_') 240identStart = satisfy $ (||) <$> isLetter <*> (== '_')
@@ -225,9 +242,10 @@ identLetter = satisfy $ (||) <$> isAlphaNum <*> (`elem` ("_\'#" :: [Char])
225lowercaseOpLetter = oneOf "!#$%&*+./<=>?@\\^|-~" 242lowercaseOpLetter = oneOf "!#$%&*+./<=>?@\\^|-~"
226opLetter = lowercaseOpLetter <|> char ':' 243opLetter = lowercaseOpLetter <|> char ':'
227 244
245maybeStartWith :: (Char -> Bool) -> Parse r w String -> Parse r w String
228maybeStartWith p i = i <|> (:) <$> satisfy p <*> i 246maybeStartWith p i = i <|> (:) <$> satisfy p <*> i
229 247
230upperCase, upperCase_, lowerCase :: Parse r w SIName 248upperCase, upperCase_, lowerCase, backquotedIdent, symbols, lcSymbols, colonSymbols, moduleName, patVar, lhsOperator, rhsOperator, varId, upperLower :: Parse r w SIName
231upperCase = identifier (tick =<< (:) <$> upperLetter <*> many identLetter) <?> "uppercase ident" 249upperCase = identifier (tick =<< (:) <$> upperLetter <*> many identLetter) <?> "uppercase ident"
232upperCase_ = identifier (tick =<< maybeStartWith (=='\'') ((:) <$> upperLetter <*> many identLetter)) <?> "uppercase ident" 250upperCase_ = identifier (tick =<< maybeStartWith (=='\'') ((:) <$> upperLetter <*> many identLetter)) <?> "uppercase ident"
233lowerCase = identifier ((:) <$> lowerLetter <*> many identLetter) <?> "lowercase ident" 251lowerCase = identifier ((:) <$> lowerLetter <*> many identLetter) <?> "lowercase ident"
@@ -247,8 +265,10 @@ upperLower = lowerCase <|> upperCase_ <|> parens symbols
247 265
248----------------------------------------------------------- operators and identifiers 266----------------------------------------------------------- operators and identifiers
249 267
268reservedOp :: String -> Parse r w SI
250reservedOp name = fst <$> lexeme_ (try $ string name *> notFollowedBy opLetter) 269reservedOp name = fst <$> lexeme_ (try $ string name *> notFollowedBy opLetter)
251 270
271reserved :: String -> Parse r w SI
252reserved name = fst <$> lexeme_ (try $ string name *> notFollowedBy identLetter) 272reserved name = fst <$> lexeme_ (try $ string name *> notFollowedBy identLetter)
253 273
254expect :: String -> (String -> Bool) -> Parse r w String -> Parse r w String 274expect :: String -> (String -> Bool) -> Parse r w String -> Parse r w String
@@ -260,8 +280,10 @@ identifier name = lexemeName $ try $ expect "reserved word" (`Set.member` theRes
260operator :: Parse r w String -> Parse r w SIName 280operator :: Parse r w String -> Parse r w SIName
261operator name = lexemeName $ try $ expect "reserved operator" (`Set.member` theReservedOpNames) name 281operator name = lexemeName $ try $ expect "reserved operator" (`Set.member` theReservedOpNames) name
262 282
283theReservedOpNames :: Set.Set String
263theReservedOpNames = Set.fromList ["::","..","=","\\","|","<-","->","@","~","=>"] 284theReservedOpNames = Set.fromList ["::","..","=","\\","|","<-","->","@","~","=>"]
264 285
286theReservedNames :: Set.Set String
265theReservedNames = Set.fromList $ 287theReservedNames = Set.fromList $
266 ["let","in","case","of","if","then","else" 288 ["let","in","case","of","if","then","else"
267 ,"data","type" 289 ,"data","type"