diff options
author | Csaba Hruska <csaba.hruska@gmail.com> | 2017-05-28 21:21:48 -0600 |
---|---|---|
committer | Csaba Hruska <csaba.hruska@gmail.com> | 2017-05-28 21:21:48 -0600 |
commit | 233f1b8d67f3d5158792cb3f5b2cb17a03fdaf5b (patch) | |
tree | 39f02a54d7c6c386328a73b9bb5db7feea7f54ef /src | |
parent | edf778d9ea460e515d3cb65440808b4aa6023b6f (diff) |
add type signatures
Diffstat (limited to 'src')
-rw-r--r-- | src/LambdaCube/Compiler/Lexer.hs | 28 |
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 |
37 | try_ :: String -> Parse r w a -> Parse r w a | ||
37 | try_ s m = try m <?> s | 38 | try_ s m = try m <?> s |
38 | 39 | ||
39 | toSPos :: SourcePos -> SPos | 40 | toSPos :: SourcePos -> SPos |
40 | toSPos p = SPos (fromIntegral $ unPos $ sourceLine p) (fromIntegral $ unPos $ sourceColumn p) | 41 | toSPos p = SPos (fromIntegral $ unPos $ sourceLine p) (fromIntegral $ unPos $ sourceColumn p) |
41 | 42 | ||
43 | getSPos :: Parse r w SPos | ||
42 | getSPos = toSPos <$> getPosition | 44 | getSPos = 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 | ||
135 | getCheckedSPos :: Parse r w SPos | ||
133 | getCheckedSPos = do | 136 | getCheckedSPos = 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 | ||
142 | identation :: Bool -> Parse r w t -> Parse r w [t] | ||
139 | identation allowempty p = (if allowempty then option [] else id) $ do | 143 | identation 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 | ||
150 | lexemeWithoutSpace :: Parse r w t -> Parse r w (SI, t) | ||
146 | lexemeWithoutSpace p = do | 151 | lexemeWithoutSpace p = do |
147 | p1 <- getCheckedSPos | 152 | p1 <- getCheckedSPos |
148 | x <- p | 153 | x <- p |
@@ -155,8 +160,10 @@ lexemeWithoutSpace p = do | |||
155 | appRange :: Parse r w (SI -> a) -> Parse r w a | 160 | appRange :: Parse r w (SI -> a) -> Parse r w a |
156 | appRange p = (\fi p1 a p2 -> a $ RangeSI $ Range fi p1 p2) <$> asks fileInfo <*> getSPos <*> p <*> getLexemeEnd | 161 | appRange p = (\fi p1 a p2 -> a $ RangeSI $ Range fi p1 p2) <$> asks fileInfo <*> getSPos <*> p <*> getLexemeEnd |
157 | 162 | ||
163 | --getLexemeEnd :: _ | ||
158 | getLexemeEnd = get | 164 | getLexemeEnd = get |
159 | 165 | ||
166 | --noSpaceBefore :: _ --Parse r w a -> Parse r w a | ||
160 | noSpaceBefore p = try $ do | 167 | noSpaceBefore 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 | ||
174 | lexeme_ :: Parse r w a -> Parse r w (SI, a) | ||
167 | lexeme_ p = lexemeWithoutSpace p <* whiteSpace | 175 | lexeme_ p = lexemeWithoutSpace p <* whiteSpace |
168 | 176 | ||
169 | lexeme :: Parse r w a -> Parse r w a | 177 | lexeme :: Parse r w a -> Parse r w a |
170 | lexeme p = snd <$> lexeme_ p | 178 | lexeme p = snd <$> lexeme_ p |
171 | 179 | ||
180 | lexemeName :: Parse r w SName -> Parse r w SIName | ||
172 | lexemeName p = uncurry SIName <$> lexeme_ p | 181 | lexemeName p = uncurry SIName <$> lexeme_ p |
173 | 182 | ||
183 | symbolWithoutSpace :: String -> Parse r w (SI, String) | ||
174 | symbolWithoutSpace = lexemeWithoutSpace . string | 184 | symbolWithoutSpace = lexemeWithoutSpace . string |
175 | 185 | ||
186 | symbol :: String -> Parse r w (SI, String) | ||
176 | symbol name = symbolWithoutSpace name <* whiteSpace | 187 | symbol name = symbolWithoutSpace name <* whiteSpace |
177 | 188 | ||
189 | simpleSpace :: Parse r w () | ||
178 | simpleSpace = skipSome (satisfy isSpace) | 190 | simpleSpace = skipSome (satisfy isSpace) |
179 | 191 | ||
192 | whiteSpace :: Parse r w () | ||
180 | whiteSpace = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "") | 193 | whiteSpace = 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 | ||
208 | parens, braces, brackets :: Parse r w a -> Parse r w a | ||
195 | parens = between (symbol "(") (symbol ")") | 209 | parens = between (symbol "(") (symbol ")") |
196 | braces = between (symbol "{") (symbol "}") | 210 | braces = between (symbol "{") (symbol "}") |
197 | brackets = between (symbol "[") (symbol "]") | 211 | brackets = between (symbol "[") (symbol "]") |
198 | 212 | ||
213 | commaSep, commaSep1 :: Parse r w a -> Parse r w [a] | ||
199 | commaSep p = sepBy p $ symbol "," | 214 | commaSep p = sepBy p $ symbol "," |
200 | commaSep1 p = sepBy1 p $ symbol "," | 215 | commaSep1 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 | ||
226 | switchNamespace :: Namespace -> Namespace | ||
211 | switchNamespace = \case ExpNS -> TypeNS; TypeNS -> ExpNS | 227 | switchNamespace = \case ExpNS -> TypeNS; TypeNS -> ExpNS |
212 | 228 | ||
229 | modifyLevel :: (Namespace -> Namespace) -> Parse r w a -> Parse r w a | ||
213 | modifyLevel f = local $ \e -> e {namespace = f $ namespace e} | 230 | modifyLevel f = local $ \e -> e {namespace = f $ namespace e} |
214 | 231 | ||
215 | typeNS, expNS :: Parse r w a -> Parse r w a | 232 | typeNS, expNS :: Parse r w a -> Parse r w a |
@@ -217,7 +234,7 @@ typeNS = modifyLevel $ const TypeNS | |||
217 | expNS = modifyLevel $ const ExpNS | 234 | expNS = modifyLevel $ const ExpNS |
218 | 235 | ||
219 | -------------------------------------------------------------------------------- identifiers | 236 | -------------------------------------------------------------------------------- identifiers |
220 | 237 | lowerLetter, upperLetter, identStart, identLetter, lowercaseOpLetter, opLetter :: Parse r w Char | |
221 | lowerLetter = satisfy $ (||) <$> isLower <*> (== '_') | 238 | lowerLetter = satisfy $ (||) <$> isLower <*> (== '_') |
222 | upperLetter = satisfy isUpper | 239 | upperLetter = satisfy isUpper |
223 | identStart = satisfy $ (||) <$> isLetter <*> (== '_') | 240 | identStart = satisfy $ (||) <$> isLetter <*> (== '_') |
@@ -225,9 +242,10 @@ identLetter = satisfy $ (||) <$> isAlphaNum <*> (`elem` ("_\'#" :: [Char]) | |||
225 | lowercaseOpLetter = oneOf "!#$%&*+./<=>?@\\^|-~" | 242 | lowercaseOpLetter = oneOf "!#$%&*+./<=>?@\\^|-~" |
226 | opLetter = lowercaseOpLetter <|> char ':' | 243 | opLetter = lowercaseOpLetter <|> char ':' |
227 | 244 | ||
245 | maybeStartWith :: (Char -> Bool) -> Parse r w String -> Parse r w String | ||
228 | maybeStartWith p i = i <|> (:) <$> satisfy p <*> i | 246 | maybeStartWith p i = i <|> (:) <$> satisfy p <*> i |
229 | 247 | ||
230 | upperCase, upperCase_, lowerCase :: Parse r w SIName | 248 | upperCase, upperCase_, lowerCase, backquotedIdent, symbols, lcSymbols, colonSymbols, moduleName, patVar, lhsOperator, rhsOperator, varId, upperLower :: Parse r w SIName |
231 | upperCase = identifier (tick =<< (:) <$> upperLetter <*> many identLetter) <?> "uppercase ident" | 249 | upperCase = identifier (tick =<< (:) <$> upperLetter <*> many identLetter) <?> "uppercase ident" |
232 | upperCase_ = identifier (tick =<< maybeStartWith (=='\'') ((:) <$> upperLetter <*> many identLetter)) <?> "uppercase ident" | 250 | upperCase_ = identifier (tick =<< maybeStartWith (=='\'') ((:) <$> upperLetter <*> many identLetter)) <?> "uppercase ident" |
233 | lowerCase = identifier ((:) <$> lowerLetter <*> many identLetter) <?> "lowercase ident" | 251 | lowerCase = 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 | ||
268 | reservedOp :: String -> Parse r w SI | ||
250 | reservedOp name = fst <$> lexeme_ (try $ string name *> notFollowedBy opLetter) | 269 | reservedOp name = fst <$> lexeme_ (try $ string name *> notFollowedBy opLetter) |
251 | 270 | ||
271 | reserved :: String -> Parse r w SI | ||
252 | reserved name = fst <$> lexeme_ (try $ string name *> notFollowedBy identLetter) | 272 | reserved name = fst <$> lexeme_ (try $ string name *> notFollowedBy identLetter) |
253 | 273 | ||
254 | expect :: String -> (String -> Bool) -> Parse r w String -> Parse r w String | 274 | expect :: 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 | |||
260 | operator :: Parse r w String -> Parse r w SIName | 280 | operator :: Parse r w String -> Parse r w SIName |
261 | operator name = lexemeName $ try $ expect "reserved operator" (`Set.member` theReservedOpNames) name | 281 | operator name = lexemeName $ try $ expect "reserved operator" (`Set.member` theReservedOpNames) name |
262 | 282 | ||
283 | theReservedOpNames :: Set.Set String | ||
263 | theReservedOpNames = Set.fromList ["::","..","=","\\","|","<-","->","@","~","=>"] | 284 | theReservedOpNames = Set.fromList ["::","..","=","\\","|","<-","->","@","~","=>"] |
264 | 285 | ||
286 | theReservedNames :: Set.Set String | ||
265 | theReservedNames = Set.fromList $ | 287 | theReservedNames = Set.fromList $ |
266 | ["let","in","case","of","if","then","else" | 288 | ["let","in","case","of","if","then","else" |
267 | ,"data","type" | 289 | ,"data","type" |