summaryrefslogtreecommitdiff
path: root/src/LambdaCube
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-02-12 13:41:13 +0100
committerPéter Diviánszky <divipp@gmail.com>2016-02-12 13:50:51 +0100
commit7588f4a16f8e72afbb42e0c5365e73a6d0eafa8e (patch)
tree5246912357b92b58aa8a21d72ff329678221e572 /src/LambdaCube
parent3376d76a631e5e53118b3d86cbd21a415543f593 (diff)
refactoring (use RWS)
Diffstat (limited to 'src/LambdaCube')
-rw-r--r--src/LambdaCube/Compiler/Lexer.hs181
-rw-r--r--src/LambdaCube/Compiler/Parser.hs27
2 files changed, 93 insertions, 115 deletions
diff --git a/src/LambdaCube/Compiler/Lexer.hs b/src/LambdaCube/Compiler/Lexer.hs
index 9c75c675..2cbef453 100644
--- a/src/LambdaCube/Compiler/Lexer.hs
+++ b/src/LambdaCube/Compiler/Lexer.hs
@@ -22,41 +22,17 @@ import qualified Data.Set as Set
22import qualified Data.Map as Map 22import qualified Data.Map as Map
23 23
24import Control.Monad.Except 24import Control.Monad.Except
25import Control.Monad.Reader 25import Control.Monad.RWS
26import Control.Monad.Writer
27import Control.Arrow hiding ((<+>)) 26import Control.Arrow hiding ((<+>))
28import Control.Applicative 27import Control.Applicative
29import Control.DeepSeq 28import Control.DeepSeq
30 29
31import LambdaCube.Compiler.Pretty hiding (Doc, braces, parens)
32
33import Control.Monad.State
34import Text.Megaparsec 30import Text.Megaparsec
35import Text.Megaparsec.Lexer hiding (lexeme, symbol, space, negate, symbol', indentBlock) 31import Text.Megaparsec.Lexer hiding (lexeme, symbol, space, negate, symbol', indentBlock)
36import Text.Megaparsec as Pr hiding (try, label, Message) 32import Text.Megaparsec as Pr hiding (try, label, Message)
37import Text.Megaparsec.Pos 33import Text.Megaparsec.Pos
38 34
39runParserT'' p f = flip evalStateT (initialPos f) . runParserT p f 35import LambdaCube.Compiler.Pretty hiding (Doc, braces, parens)
40
41runPT' p st = snd <$> flip evalStateT (initialPos ".....") (runParserT' p st)
42
43type P = ParsecT String (StateT SourcePos InnerP)
44
45indentMany' p = indentMS True p
46indentMany s p = reserved s >> indentMS True p
47indentSome s p = reserved s >> indentMS False p
48
49indentMS null p = (if null then option [] else id) $ do
50 checkIndent
51 lvl <- indentLevel
52 (if null then many else some) $ do
53 pos <- getPosition
54 guard (sourceColumn pos == lvl)
55 local (second $ const (sourceLine pos, sourceColumn pos)) p
56
57lexeme' sp p = checkIndent *> p <* (getPosition >>= put) <* sp
58
59checkIndent = asks snd >>= \(r, c) -> getPosition >>= \pos -> when (sourceColumn pos <= c && sourceLine pos /= r) $ fail "wrong indentation"
60 36
61-------------------------------------------------------------------------------- parser utils 37-------------------------------------------------------------------------------- parser utils
62 38
@@ -70,7 +46,7 @@ manyNM k n p = (:) <$> p <*> manyNM (k-1) (n-1) p
70 46
71-------------------------------------------------------------------------------- parser type 47-------------------------------------------------------------------------------- parser type
72 48
73type InnerP = WriterT [PostponedCheck] (Reader ((DesugarInfo, Namespace), (Int, Int){-indentation level-})) 49type P = ParsecT String (RWS ((DesugarInfo, Namespace), (Int, Int){-indentation level-}) [PostponedCheck] SourcePos)
74 50
75type PostponedCheck = Maybe String 51type PostponedCheck = Maybe String
76 52
@@ -86,6 +62,11 @@ dsInfo = asks $ fst . fst
86namespace :: P Namespace 62namespace :: P Namespace
87namespace = asks $ snd . fst 63namespace = asks $ snd . fst
88 64
65runP_ r f p = (\(a, s, w) -> (a, w)) $ runRWS p (r, (0, 0)) (initialPos f)
66
67runP r f p s = runP_ r f $ runParserT p f s
68
69runP' r f p st = runP_ r f $ runParserT' p st
89 70
90-------------------------------------------------------------------------------- literals 71-------------------------------------------------------------------------------- literals
91 72
@@ -178,7 +159,7 @@ _ `validate` _ = mempty
178 159
179sourceNameSI (RangeSI (Range a _)) = sourceName a 160sourceNameSI (RangeSI (Range a _)) = sourceName a
180 161
181sameSource r@(RangeSI {}) q@(RangeSI {}) = sourceNameSI r == sourceNameSI q 162sameSource r@RangeSI{} q@RangeSI{} = sourceNameSI r == sourceNameSI q
182sameSource _ _ = True 163sameSource _ _ = True
183 164
184class SourceInfo si where 165class SourceInfo si where
@@ -315,6 +296,77 @@ getFixity :: DesugarInfo -> SName -> Fixity
315getFixity (fm, _) n = fromMaybe (InfixL, 9) $ Map.lookup n fm 296getFixity (fm, _) n = fromMaybe (InfixL, 9) $ Map.lookup n fm
316 297
317 298
299----------------------------------------------------------- operators and identifiers
300
301reservedOp name = lexeme $ try $ string name *> notFollowedBy opLetter
302
303reserved name = lexeme $ try $ string name *> notFollowedBy identLetter
304
305expect msg p i = i >>= \n -> if (p n) then unexpected (msg ++ " " ++ show n) else return n
306
307identifier ident = lexeme $ try $ expect "reserved word" (`Set.member` theReservedNames) ident
308
309operator oper = lexeme $ try $ trCons <$> expect "reserved operator" (`Set.member` theReservedOpNames) oper
310 where
311 trCons ":" = "Cons"
312 trCons x = x
313
314theReservedOpNames = Set.fromList ["::","..","=","\\","|","<-","->","@","~","=>"]
315
316theReservedNames = Set.fromList $
317 ["let","in","case","of","if","then","else"
318 ,"data","type"
319 ,"class","default","deriving","do","import"
320 ,"infix","infixl","infixr","instance","module"
321 ,"newtype","where"
322 ,"primitive"
323 -- "as","qualified","hiding"
324 ] ++
325 ["foreign","import","export","primitive"
326 ,"_ccall_","_casm_"
327 ,"forall"
328 ]
329
330----------------------------------------------------------- indentation, white space, symbols
331
332checkIndent = asks snd >>= \(r, c) -> getPosition >>= \pos -> when (sourceColumn pos <= c && sourceLine pos /= r) $ fail "wrong indentation"
333
334indentMS null p = (if null then option [] else id) $ do
335 checkIndent
336 lvl <- indentLevel
337 (if null then many else some) $ do
338 pos <- getPosition
339 guard (sourceColumn pos == lvl)
340 local (second $ const (sourceLine pos, sourceColumn pos)) p
341
342lexeme' sp p = checkIndent *> p <* (getPosition >>= put) <* sp
343
344lexeme = lexeme' whiteSpace
345
346symbol = symbol' whiteSpace
347
348symbol' sp name
349 = lexeme' sp (string name)
350
351whiteSpace = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "")
352
353simpleSpace
354 = skipSome (satisfy isSpace)
355
356oneLineComment
357 = try (string "--" >> many (char '-') >> notFollowedBy opLetter)
358 >> skipMany (satisfy (/= '\n'))
359
360multiLineComment = try (string "{-") *> inCommentMulti
361
362inCommentMulti
363 = try (() <$ string "-}")
364 <|> multiLineComment *> inCommentMulti
365 <|> skipSome (noneOf "{}-") *> inCommentMulti
366 <|> oneOf "{}-" *> inCommentMulti
367 <?> "end of comment"
368
369
318---------------------------------------------------------------------- 370----------------------------------------------------------------------
319---------------------------------------------------------------------- 371----------------------------------------------------------------------
320-- modified version of 372-- modified version of
@@ -491,77 +543,4 @@ parseLit = lexeme $ charLiteral <|> stringLiteral <|> natFloat
491 ; seq n (return n) 543 ; seq n (return n)
492 } 544 }
493 545
494-----------------------------------------------------------
495-- Operators & reserved ops
496-----------------------------------------------------------
497reservedOp name =
498 lexeme $ try $
499 do{ string name
500 ; notFollowedBy opLetter <?> ("end of " ++ show name)
501 }
502
503operator oper =
504 lexeme $ try $ trCons <$> expect "reserved operator" (`Set.member` theReservedOpNames) oper
505 where
506 trCons ":" = "Cons"
507 trCons x = x
508
509theReservedOpNames = Set.fromList ["::","..","=","\\","|","<-","->","@","~","=>"]
510
511expect msg p i = i >>= \n -> if (p n) then unexpected (msg ++ " " ++ show n) else return n
512
513-----------------------------------------------------------
514-- Identifiers & Reserved words
515-----------------------------------------------------------
516reserved name =
517 lexeme $ try $
518 do{ string name
519 ; notFollowedBy identLetter <?> ("end of " ++ show name)
520 }
521
522identifier ident =
523 lexeme $ try $ expect "reserved word" (`Set.member` theReservedNames) ident
524
525theReservedNames = Set.fromList $
526 ["let","in","case","of","if","then","else"
527 ,"data","type"
528 ,"class","default","deriving","do","import"
529 ,"infix","infixl","infixr","instance","module"
530 ,"newtype","where"
531 ,"primitive"
532 -- "as","qualified","hiding"
533 ] ++
534 ["foreign","import","export","primitive"
535 ,"_ccall_","_casm_"
536 ,"forall"
537 ]
538
539-----------------------------------------------------------
540-- White space & symbols
541-----------------------------------------------------------
542
543lexeme = lexeme' whiteSpace
544
545symbol = symbol' whiteSpace
546
547symbol' sp name
548 = lexeme' sp (string name)
549
550whiteSpace = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "")
551
552simpleSpace
553 = skipSome (satisfy isSpace)
554
555oneLineComment
556 = try (string "--" >> many (char '-') >> notFollowedBy opLetter)
557 >> skipMany (satisfy (/= '\n'))
558
559multiLineComment = try (string "{-") *> inCommentMulti
560
561inCommentMulti
562 = try (() <$ string "-}")
563 <|> multiLineComment *> inCommentMulti
564 <|> skipSome (noneOf "{}-") *> inCommentMulti
565 <|> oneOf "{}-" *> inCommentMulti
566 <?> "end of comment"
567 546
diff --git a/src/LambdaCube/Compiler/Parser.hs b/src/LambdaCube/Compiler/Parser.hs
index 3b2ab687..b69fe7a4 100644
--- a/src/LambdaCube/Compiler/Parser.hs
+++ b/src/LambdaCube/Compiler/Parser.hs
@@ -354,8 +354,8 @@ parseTerm prec = withRange setSI $ case prec of
354 t' <- dbf' fe <$> parseTerm PrecLam 354 t' <- dbf' fe <$> parseTerm PrecLam
355 ge <- dsInfo 355 ge <- dsInfo
356 return $ foldr (uncurry (patLam id ge)) t' ts 356 return $ foldr (uncurry (patLam id ge)) t' ts
357 <|> compileCase <$ reserved "case" <*> dsInfo <*> parseETerm PrecLam <*> do 357 <|> compileCase <$ reserved "case" <*> dsInfo <*> parseETerm PrecLam <* reserved "of" <*> do
358 indentSome "of" $ do 358 indentMS False $ do
359 (fe, p) <- longPattern 359 (fe, p) <- longPattern
360 (,) p <$> parseRHS (dbf' fe) "->" 360 (,) p <$> parseRHS (dbf' fe) "->"
361-- <|> compileGuardTree id id <$> dsInfo <*> (Alts <$> parseSomeGuards (const True)) 361-- <|> compileGuardTree id id <$> dsInfo <*> (Alts <$> parseSomeGuards (const True))
@@ -383,7 +383,7 @@ parseTerm prec = withRange setSI $ case prec of
383 ) <|> mkList <$> namespace <*> pure []) 383 ) <|> mkList <$> namespace <*> pure [])
384 <|> mkTuple <$> namespace <*> parens (commaSep $ parseTerm PrecLam) 384 <|> mkTuple <$> namespace <*> parens (commaSep $ parseTerm PrecLam)
385 <|> mkRecord <$> braces (commaSep $ (,) <$> lowerCase <* symbol ":" <*> parseTerm PrecLam) 385 <|> mkRecord <$> braces (commaSep $ (,) <$> lowerCase <* symbol ":" <*> parseTerm PrecLam)
386 <|> mkLets True <$> dsInfo <*> parseDefs xSLabelEnd (indentMany "let") <* reserved "in" <*> parseTerm PrecLam 386 <|> mkLets True <$ reserved "let" <*> dsInfo <*> parseDefs xSLabelEnd <* reserved "in" <*> parseTerm PrecLam
387 where 387 where
388 level pr f = parseTerm pr >>= \t -> option t $ f t 388 level pr f = parseTerm pr >>= \t -> option t $ f t
389 389
@@ -758,7 +758,7 @@ parseDef =
758 ( if mk then Just nps' else Nothing 758 ( if mk then Just nps' else Nothing
759 , foldr (uncurry SPi) (foldl SAppV (SGlobal x) $ downToS (length ts') $ length ts) ts') 759 , foldr (uncurry SPi) (foldl SAppV (SGlobal x) $ downToS (length ts') $ length ts) ts')
760 (af, cs) <- option (True, []) $ 760 (af, cs) <- option (True, []) $
761 do fmap ((,) True) $ indentMany "where" $ second ((,) Nothing . dbf' npsd) <$> typedIds Nothing 761 do fmap ((,) True) $ (reserved "where" >>) $ indentMS True $ second ((,) Nothing . dbf' npsd) <$> typedIds Nothing
762 <|> (,) False <$ reservedOp "=" <*> 762 <|> (,) False <$ reservedOp "=" <*>
763 sepBy1 ((,) <$> (pure <$> parseSIName upperCase) 763 sepBy1 ((,) <$> (pure <$> parseSIName upperCase)
764 <*> do do braces $ mkConTy True . second (zipWith (\i (v, e) -> (v, dbf_ i npsd e)) [0..]) 764 <*> do do braces $ mkConTy True . second (zipWith (\i (v, e) -> (v, dbf_ i npsd e)) [0..])
@@ -771,21 +771,21 @@ parseDef =
771 <|> do indentation (reserved "class") $ do 771 <|> do indentation (reserved "class") $ do
772 x <- parseSIName $ typeNS upperCase 772 x <- parseSIName $ typeNS upperCase
773 (nps, ts) <- telescope (Just SType) 773 (nps, ts) <- telescope (Just SType)
774 cs <- option [] $ indentMany "where" $ typedIds Nothing 774 cs <- option [] $ (reserved "where" >>) $ indentMS True $ typedIds Nothing
775 return $ pure $ Class x (map snd ts) (concatMap (\(vs, t) -> (,) <$> vs <*> pure (dbf' nps t)) cs) 775 return $ pure $ Class x (map snd ts) (concatMap (\(vs, t) -> (,) <$> vs <*> pure (dbf' nps t)) cs)
776 <|> do indentation (reserved "instance") $ typeNS $ do 776 <|> do indentation (reserved "instance") $ typeNS $ do
777 constraints <- option [] $ try "constraint" $ getTTuple' <$> parseTerm PrecOp <* reservedOp "=>" 777 constraints <- option [] $ try "constraint" $ getTTuple' <$> parseTerm PrecOp <* reservedOp "=>"
778 x <- parseSIName upperCase 778 x <- parseSIName upperCase
779 (nps, args) <- telescopePat 779 (nps, args) <- telescopePat
780 checkPattern nps 780 checkPattern nps
781 cs <- expNS $ option [] $ indentSome "where" $ dbFunAlt nps <$> funAltDef varId 781 cs <- expNS $ option [] $ reserved "where" *> indentMS False (dbFunAlt nps <$> funAltDef varId)
782 pure . Instance x ({-todo-}map snd args) (dbff (nps <> [x]) <$> constraints) <$> compileFunAlts' id{-TODO-} cs 782 pure . Instance x ({-todo-}map snd args) (dbff (nps <> [x]) <$> constraints) <$> compileFunAlts' id{-TODO-} cs
783 <|> do indentation (try "type family" $ reserved "type" >> reserved "family") $ typeNS $ do 783 <|> do indentation (try "type family" $ reserved "type" >> reserved "family") $ typeNS $ do
784 x <- parseSIName upperCase 784 x <- parseSIName upperCase
785 (nps, ts) <- telescope (Just SType) 785 (nps, ts) <- telescope (Just SType)
786 t <- dbf' nps <$> parseType (Just SType) 786 t <- dbf' nps <$> parseType (Just SType)
787 option {-open type family-}[TypeFamily x ts t] $ do 787 option {-open type family-}[TypeFamily x ts t] $ do
788 cs <- indentMany "where" $ funAltDef $ mfilter (== snd x) upperCase 788 cs <- (reserved "where" >>) $ indentMS True $ funAltDef $ mfilter (== snd x) upperCase
789 -- closed type family desugared here 789 -- closed type family desugared here
790 compileFunAlts False id SLabelEnd [TypeAnn x $ addParamsS ts t] cs 790 compileFunAlts False id SLabelEnd [TypeAnn x $ addParamsS ts t] cs
791 <|> do indentation (try "type instance" $ reserved "type" >> reserved "instance") $ typeNS $ pure <$> funAltDef upperCase 791 <|> do indentation (try "type instance" $ reserved "type" >> reserved "instance") $ typeNS $ pure <$> funAltDef upperCase
@@ -817,10 +817,10 @@ parseRHS fe tok = fmap (fmap (fe *** fe) +++ fe) $ do
817 <|> do 817 <|> do
818 reservedOp tok 818 reservedOp tok
819 rhs <- parseTerm PrecLam 819 rhs <- parseTerm PrecLam
820 f <- option id $ mkLets True <$> dsInfo <*> parseDefs xSLabelEnd (indentMany "where") 820 f <- option id $ mkLets True <$ reserved "where" <*> dsInfo <*> parseDefs xSLabelEnd
821 return $ Right $ f rhs 821 return $ Right $ f rhs
822 822
823parseDefs lend p = p parseDef >>= compileFunAlts' lend . concat 823parseDefs lend = indentMS True parseDef >>= compileFunAlts' lend . concat
824 824
825funAltDef parseName = do -- todo: use ns to determine parseName 825funAltDef parseName = do -- todo: use ns to determine parseName
826 (n, (fee, tss)) <- 826 (n, (fee, tss)) <-
@@ -1084,16 +1084,15 @@ parseModule f str = do
1084 { extensions = exts 1084 { extensions = exts
1085 , moduleImports = [("Prelude", ImportAllBut []) | NoImplicitPrelude `notElem` exts] ++ idefs 1085 , moduleImports = [("Prelude", ImportAllBut []) | NoImplicitPrelude `notElem` exts] ++ idefs
1086 , moduleExports = join $ snd <$> header 1086 , moduleExports = join $ snd <$> header
1087 , definitions = \ge -> first (show +++ id) $ flip runReader ((ge, ns), (0,0)) . runWriterT $ runPT' (parseDefs SLabelEnd indentMany' <* eof) st 1087 , definitions = \ge -> first ((show +++ id) . snd) $ runP' (ge, ns) f (parseDefs SLabelEnd <* eof) st
1088 , sourceCode = str 1088 , sourceCode = str
1089 } 1089 }
1090 1090
1091parseLC :: MonadError ErrorMsg m => FilePath -> String -> m Module 1091parseLC :: MonadError ErrorMsg m => FilePath -> String -> m Module
1092parseLC f str 1092parseLC f str
1093 = either (throwError . ErrorMsg . show) return 1093 = either (throwError . ErrorMsg . show) return
1094 . flip runReader ((error "globalenv used", Namespace (Just ExpLevel) True), (0,0)) 1094 . fst
1095 . fmap fst . runWriterT 1095 . runP (error "globalenv used", Namespace (Just ExpLevel) True) f (parseModule f str)
1096 . runParserT'' (parseModule f str) f
1097 $ str 1096 $ str
1098 1097
1099-------------------------------------------------------------------------------- pretty print 1098-------------------------------------------------------------------------------- pretty print