summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-01-21 12:14:04 +0100
committerPéter Diviánszky <divipp@gmail.com>2016-01-21 12:20:18 +0100
commitd6777f3fff3c464e126bcfcc2f397472ca839143 (patch)
tree312c1db36d725ee671a18ce57b1cf03ef462ae25
parente17c835b4d3eaf9612c9caf5c1a48cf2e378efcc (diff)
refactor part of parser
-rw-r--r--src/LambdaCube/Compiler/Infer.hs408
-rw-r--r--testdata/language-features/module/Moduledef03.reject.out3
-rw-r--r--testdata/language-features/module/Moduledef04.reject.out3
-rw-r--r--testdata/language-features/module/import03.reject.wip.out2
4 files changed, 199 insertions, 217 deletions
diff --git a/src/LambdaCube/Compiler/Infer.hs b/src/LambdaCube/Compiler/Infer.hs
index 2fbeec92..f0e2e9de 100644
--- a/src/LambdaCube/Compiler/Infer.hs
+++ b/src/LambdaCube/Compiler/Infer.hs
@@ -38,11 +38,12 @@ import Control.Monad.Writer
38import Control.Monad.State 38import Control.Monad.State
39import Control.Monad.Identity 39import Control.Monad.Identity
40import Control.Arrow hiding ((<+>)) 40import Control.Arrow hiding ((<+>))
41import Control.Applicative hiding (optional) 41import Control.Applicative
42import Control.Exception hiding (try) 42import Control.Exception hiding (try)
43 43
44import Text.Parsec hiding (label, Empty, State, (<|>), many, optional) 44import Text.Parsec hiding (label, Empty, State, (<|>), many)
45import qualified Text.Parsec.Token as Pa 45import qualified Text.Parsec.Token as Pa
46import qualified Text.ParserCombinators.Parsec.Language as Pa
46import Text.Parsec.Pos 47import Text.Parsec.Pos
47import Text.Parsec.Indentation hiding (Any) 48import Text.Parsec.Indentation hiding (Any)
48import Text.Parsec.Indentation.Char 49import Text.Parsec.Indentation.Char
@@ -53,6 +54,11 @@ import qualified LambdaCube.Compiler.Pretty as P
53import LambdaCube.Compiler.Pretty hiding (Doc, braces, parens) 54import LambdaCube.Compiler.Pretty hiding (Doc, braces, parens)
54import LambdaCube.Compiler.Token 55import LambdaCube.Compiler.Token
55 56
57-------------------------------------------------------------------------------- utils
58
59(<&>) = flip (<$>)
60
61
56-------------------------------------------------------------------------------- source data 62-------------------------------------------------------------------------------- source data
57 63
58type SName = String 64type SName = String
@@ -197,7 +203,7 @@ data Exp
197 | Con ConName [Exp] 203 | Con ConName [Exp]
198 | TyCon TyConName [Exp] 204 | TyCon TyConName [Exp]
199 | ELit Lit 205 | ELit Lit
200 | Assign !Int Exp Exp -- De Bruijn index decreasing assign operator, only for metavariables (non-recursive) -- TODO: remove 206 | Assign !Int Exp Exp -- De Bruijn index decreasing assign reservedOp, only for metavariables (non-recursive) -- TODO: remove
201 | Label LabelKind Exp{-function alternatives are obeyed during reduction-} Exp{-functions are treated like constants-} 207 | Label LabelKind Exp{-function alternatives are obeyed during reduction-} Exp{-functions are treated like constants-}
202 -- label is used also for getting fixity info 208 -- label is used also for getting fixity info
203 | LabelEnd Exp 209 | LabelEnd Exp
@@ -1356,73 +1362,75 @@ removeHiddenUnit (Pi Hidden Unit (downE 0 -> Just t)) = removeHiddenUnit t
1356removeHiddenUnit (Pi h a b) = Pi h a $ removeHiddenUnit b 1362removeHiddenUnit (Pi h a b) = Pi h a $ removeHiddenUnit b
1357removeHiddenUnit t = t 1363removeHiddenUnit t = t
1358 1364
1359-------------------------------------------------------------------------------- parser 1365---------------------------------------------------------------------------------------
1366-------------------------------------- parser -----------------------------------------
1360 1367
1361addForalls :: Extensions -> [SName] -> SExp -> SExp 1368-- see http://blog.ezyang.com/2014/05/parsec-try-a-or-b-considered-harmful/comment-page-1/#comment-6602
1362addForalls exs defined x = foldl f x [v | v@(vh:_) <- reverse $ freeS x, v `notElem'` defined, isLower vh || NoConstructorNamespace `elem` exs] 1369try' s m = try m <?> s
1363 where
1364 f e v = SPi Hidden (Wildcard SType) $ substSG0 v e
1365 1370
1366defined defs = ("'Type":) $ flip foldMap defs $ \case 1371check msg p m = try' msg $ mfilter p m
1367 TypeAnn (_, x) _ -> [x] 1372
1368 Let (_, x) _ _ _ _ -> [x] 1373-------------------------------------------------------------------------------- parser type
1369 Data (_, x) _ _ _ cs -> x: map (snd . fst) cs
1370 Class (_, x) _ cs -> x: map (snd . fst) cs
1371 TypeFamily (_, x) _ _ -> [x]
1372 x -> error $ unwords ["defined: Impossible", show x, "cann't be here"]
1373 1374
1374type InnerP = Reader GlobalEnv' 1375type P = ParsecT (IndentStream (CharIndentStream String)) SourcePos (Reader GlobalEnv')
1375 1376
1376type P = ParsecT (IndentStream (CharIndentStream String)) SourcePos InnerP
1377 1377
1378lexer :: Pa.GenTokenParser (IndentStream (CharIndentStream String)) SourcePos InnerP 1378-------------------------------------------------------------------------------- lexing
1379
1380lexer :: Pa.GenTokenParser (IndentStream (CharIndentStream String)) SourcePos (Reader GlobalEnv')
1379lexer = makeTokenParser lexeme $ makeIndentLanguageDef style 1381lexer = makeTokenParser lexeme $ makeIndentLanguageDef style
1380 where 1382 where
1381 lexeme p 1383 lexeme p = p <* (getPosition >>= setState >> whiteSpace)
1382 = do{ x <- p; getPosition >>= setState; whiteSpace; return x }
1383 1384
1384 style = Pa.LanguageDef 1385 style = Pa.LanguageDef
1385 { Pa.commentStart = "{-" 1386 { Pa.commentStart = Pa.commentStart Pa.haskellDef
1386 , Pa.commentEnd = "-}" 1387 , Pa.commentEnd = Pa.commentEnd Pa.haskellDef
1387 , Pa.commentLine = "--" 1388 , Pa.commentLine = Pa.commentLine Pa.haskellDef
1388 , Pa.nestedComments = True 1389 , Pa.nestedComments = Pa.nestedComments Pa.haskellDef
1389 , Pa.identStart = letter <|> oneOf "_" 1390 , Pa.identStart = letter <|> char '_' -- '_' is included also
1390 , Pa.identLetter = alphaNum <|> oneOf "_'" 1391 , Pa.identLetter = alphaNum <|> oneOf "_'#"
1391 , Pa.opStart = Pa.opLetter style 1392 , Pa.opStart = Pa.opLetter style
1392 , Pa.opLetter = oneOf ":!#$%&*+./<=>?@\\^|-~" 1393 , Pa.opLetter = oneOf ":!#$%&*+./<=>?@\\^|-~"
1393 , Pa.reservedOpNames= ["->", "=>", "~", "\\", "|", "::", "<-", "=", "@", ".."] 1394 , Pa.reservedOpNames = Pa.reservedOpNames Pa.haskellDef
1394 , Pa.reservedNames = 1395 , Pa.reservedNames = Pa.reservedNames Pa.haskellDef
1395 [ "case", "class", "data", "type", 1396 , Pa.caseSensitive = Pa.caseSensitive Pa.haskellDef
1396 "else", "forall", "if", "import", "infix", "in", "infixl", "infixr",
1397 "instance", "let", "module", "of", "then", "qualified",
1398 "where", "_"
1399 ]
1400 , Pa.caseSensitive = True
1401 } 1397 }
1402 1398
1403position :: P SourcePos 1399parens = Pa.parens lexer
1404position = getPosition 1400braces = Pa.braces lexer
1405 1401brackets = Pa.brackets lexer
1406positionBeforeSpace :: P SourcePos 1402commaSep = Pa.commaSep lexer
1407positionBeforeSpace = getState 1403commaSep1 = Pa.commaSep1 lexer
1404dot = Pa.dot lexer
1405comma = Pa.comma lexer
1406colon = Pa.colon lexer
1407natural = Pa.natural lexer
1408integer = Pa.integer lexer
1409float = Pa.float lexer
1410charLiteral = Pa.charLiteral lexer
1411stringLiteral = Pa.stringLiteral lexer
1412whiteSpace = Pa.whiteSpace lexer
1413operator = Pa.operator lexer
1414reserved = Pa.reserved lexer
1415reservedOp = Pa.reservedOp lexer
1416identifier = Pa.identifier lexer
1417
1418appRange :: P (SI -> a) -> P a
1419appRange p = (\p1 a p2 -> a (Range (p1,p2))) <$> getPosition <*> p <*> getState
1408 1420
1409optional :: P a -> P (Maybe a) 1421withRange :: (SI -> a -> b) -> P a -> P b
1410optional = optionMaybe 1422withRange f p = appRange $ flip f <$> p
1411 1423
1412keyword :: String -> P () 1424infix 9 `withRange`
1413keyword = Pa.reserved lexer
1414 1425
1415operator :: String -> P () 1426-------------------------------------------------------------------------------- namespace handling
1416operator = Pa.reservedOp lexer
1417 1427
1418data Level 1428data Level
1419 = TypeLevel 1429 = TypeLevel
1420 | ExpLevel 1430 | ExpLevel
1421 deriving (Eq, Show) 1431 deriving (Eq, Show)
1422 1432
1423levelElim 1433levelElim typeLevel expLevel = \case
1424 typeLevel
1425 expLevel = \case
1426 TypeLevel -> typeLevel 1434 TypeLevel -> typeLevel
1427 ExpLevel -> expLevel 1435 ExpLevel -> expLevel
1428 1436
@@ -1453,58 +1461,28 @@ tick _ n = n
1453 1461
1454tick' = tick . fromMaybe ExpLevel . namespaceLevel 1462tick' = tick . fromMaybe ExpLevel . namespaceLevel
1455 1463
1456ident = Pa.identifier lexer 1464tickIdent ns = tick' ns <$> identifier
1457tickIdent ns = tick' ns <$> ident
1458
1459lcOps = Pa.operator lexer
1460
1461parens = Pa.parens lexer
1462braces = Pa.braces lexer
1463brackets = Pa.brackets lexer
1464commaSep = Pa.commaSep lexer
1465commaSep1 = Pa.commaSep1 lexer
1466dot = Pa.dot lexer
1467comma = Pa.comma lexer
1468colon = Pa.colon lexer
1469natural = Pa.natural lexer
1470integer = Pa.integer lexer
1471float = Pa.float lexer
1472charLiteral = Pa.charLiteral lexer
1473stringLiteral = Pa.stringLiteral lexer
1474whiteSpace = Pa.whiteSpace lexer
1475
1476data Extension
1477 = NoImplicitPrelude
1478 | NoTypeNamespace
1479 | NoConstructorNamespace
1480 | TraceTypeCheck
1481 deriving (Enum, Eq, Ord, Show)
1482
1483type Name = String
1484type DefinitionR = Stmt
1485
1486data Export = ExportModule Name | ExportId Name
1487type Extensions = [Extension]
1488 1465
1489data ImportItems 1466-------------------------------------------------------------------------------- identifiers
1490 = ImportAllBut [Name]
1491 | ImportJust [Name]
1492
1493data ModuleR
1494 = Module
1495 { extensions :: Extensions
1496 , moduleImports :: [(Name, ImportItems)] -- TODO
1497 , moduleExports :: Maybe [Export]
1498 , definitions :: GlobalEnv' -> Either String [DefinitionR]
1499 , sourceCode :: String
1500 }
1501 1467
1502(<&>) = flip (<$>) 1468--upperCase, lowerCase, symbols, colonSymbols :: P String
1469upperCase NonTypeNamespace = mzero -- todo
1470upperCase ns = (if caseSensitiveNS ns then check "uppercase ident" (isUpper . head') else id) $ tickIdent ns
1471lowerCase ns = (if caseSensitiveNS ns then check "lowercase ident" (isLower . head') else id) identifier <|> try (('_':) <$ char '_' <*> identifier)
1472symbols = check "symbols" ((/=':') . head) operator
1473colonSymbols = "Cons" <$ reservedOp ":" <|> check "symbols" ((==':') . head) operator
1503 1474
1504-------------------------------------------------------------------------------- parser combinators 1475var ns = lowerCase ns
1476patVar ns = lowerCase ns <|> "" <$ reserved "_"
1477qIdent ns = {-qualified_ todo-} (var ns <|> upperCase ns)
1478conOperator = colonSymbols
1479varId ns = var ns <|> parens operatorT
1480backquotedIdent = try' "backquoted" $ char '`' *> ((:) <$> satisfy isAlpha <*> many (satisfy isAlphaNum)) <* char '`' <* whiteSpace
1481operatorT = symbols
1482 <|> conOperator
1483 <|> backquotedIdent
1484moduleName = {-qualified_ todo-} upperCase (Namespace ExpLevel True)
1505 1485
1506-- see http://blog.ezyang.com/2014/05/parsec-try-a-or-b-considered-harmful/comment-page-1/#comment-6602
1507try' s m = try m <?> s
1508{- 1486{-
1509qualified_ id = do 1487qualified_ id = do
1510 q <- try' "qualification" $ upperCase' <* dot 1488 q <- try' "qualification" $ upperCase' <* dot
@@ -1516,60 +1494,49 @@ qualified_ id = do
1516 upperCase' = (:) <$> satisfy isUpper <*> many (satisfy isAlphaNum) 1494 upperCase' = (:) <$> satisfy isUpper <*> many (satisfy isAlphaNum)
1517-} 1495-}
1518 1496
1519optionTry p = optionMaybe (try p)
1520
1521-------------------------------------------------------------------------------- identifiers
1522
1523check msg p m = try' msg $ do
1524 x <- m
1525 if p x then return x else fail $ msg ++ " expected"
1526
1527head' ('\'': c: _) = c 1497head' ('\'': c: _) = c
1528head' (c: _) = c 1498head' (c: _) = c
1529 1499
1530--upperCase, lowerCase, symbols, colonSymbols :: P String
1531upperCase NonTypeNamespace = mzero -- todo
1532upperCase ns = (if caseSensitiveNS ns then check "uppercase ident" (isUpper . head') else id) $ tickIdent ns
1533lowerCase ns = (if caseSensitiveNS ns then check "lowercase ident" (isLower . head') else id) ident <|> try (('_':) <$ char '_' <*> ident)
1534symbols = check "symbols" ((/=':') . head) lcOps
1535colonSymbols = "Cons" <$ operator ":" <|> check "symbols" ((==':') . head) lcOps
1536
1537--------------------------------------------------------------------------------
1538
1539pattern ExpN' :: String -> P.Doc -> String
1540pattern ExpN' s p <- ((,) undefined -> (p, s)) where ExpN' s p = s
1541pattern ExpN s = s
1542
1543var ns = lowerCase ns
1544patVar ns = lowerCase ns <|> "" <$ keyword "_"
1545qIdent ns = {-qualified_ todo-} (var ns <|> upperCase ns)
1546conOperator = colonSymbols
1547varId ns = var ns <|> parens operator'
1548backquotedIdent = try' "backquoted" $ char '`' *> (ExpN <$> ((:) <$> satisfy isAlpha <*> many (satisfy isAlphaNum))) <* char '`' <* whiteSpace
1549operator' = symbols
1550 <|> conOperator
1551 <|> backquotedIdent
1552moduleName = {-qualified_ todo-} upperCase (Namespace ExpLevel True)
1553
1554-------------------------------------------------------------------------------- fixity declarations 1500-------------------------------------------------------------------------------- fixity declarations
1555 1501
1556fixityDef :: P [DefinitionR] 1502fixityDef :: P [Stmt]
1557fixityDef = do 1503fixityDef = do
1558 dir <- Infix <$ keyword "infix" 1504 dir <- Infix <$ reserved "infix"
1559 <|> InfixL <$ keyword "infixl" 1505 <|> InfixL <$ reserved "infixl"
1560 <|> InfixR <$ keyword "infixr" 1506 <|> InfixR <$ reserved "infixr"
1561 localIndentation Gt $ do 1507 localIndentation Gt $ do
1562 i <- fromIntegral <$> natural 1508 i <- fromIntegral <$> natural
1563 ns <- commaSep1 (siName operator') 1509 ns <- commaSep1 (siName operatorT)
1564 return $ PrecDef <$> ns <*> pure (dir, i) 1510 return $ PrecDef <$> ns <*> pure (dir, i)
1565 1511
1566-------------------------------------------------------------------------------- 1512-------------------------------------------------------------------------------- export
1513
1514data Export = ExportModule SName | ExportId SName
1567 1515
1568export :: Namespace -> P Export 1516parseExport :: Namespace -> P Export
1569export ns = 1517parseExport ns =
1570 ExportModule <$ keyword "module" <*> moduleName 1518 ExportModule <$ reserved "module" <*> moduleName
1571 <|> ExportId <$> varId ns 1519 <|> ExportId <$> varId ns
1572 1520
1521-------------------------------------------------------------------------------- import
1522
1523data ImportItems
1524 = ImportAllBut [SName]
1525 | ImportJust [SName]
1526
1527importlist ns = parens (commaSep (varId ns <|> upperCase ns))
1528
1529-------------------------------------------------------------------------------- extensions
1530
1531type Extensions = [Extension]
1532
1533data Extension
1534 = NoImplicitPrelude
1535 | NoTypeNamespace
1536 | NoConstructorNamespace
1537 | TraceTypeCheck
1538 deriving (Enum, Eq, Ord, Show)
1539
1573parseExtensions :: P [Extension] 1540parseExtensions :: P [Extension]
1574parseExtensions 1541parseExtensions
1575 = try (string "{-#") *> simpleSpace *> string "LANGUAGE" *> simpleSpace *> commaSep ext <* simpleSpace <* string "#-}" <* simpleSpace 1542 = try (string "{-#") *> simpleSpace *> string "LANGUAGE" *> simpleSpace *> commaSep ext <* simpleSpace <* string "#-}" <* simpleSpace
@@ -1584,7 +1551,16 @@ parseExtensions
1584 (fail $ "language extension expected instead of " ++ s) 1551 (fail $ "language extension expected instead of " ++ s)
1585 (Map.lookup s extensionMap) 1552 (Map.lookup s extensionMap)
1586 1553
1587importlist ns = parens (commaSep (varId ns <|> upperCase ns)) 1554-------------------------------------------------------------------------------- modules
1555
1556data ModuleR
1557 = Module
1558 { extensions :: Extensions
1559 , moduleImports :: [(SName, ImportItems)]
1560 , moduleExports :: Maybe [Export]
1561 , definitions :: GlobalEnv' -> Either String [Stmt]
1562 , sourceCode :: String
1563 }
1588 1564
1589parseLC :: MonadError ErrorMsg m => FilePath -> String -> m ModuleR 1565parseLC :: MonadError ErrorMsg m => FilePath -> String -> m ModuleR
1590parseLC f str = either (throwError . ErrorMsg . show) return . flip runReader (error "globalenv used") . runParserT p (newPos "" 0 0) f . mkIndentStream 0 infIndentation True Ge . mkCharIndentStream $ str 1566parseLC f str = either (throwError . ErrorMsg . show) return . flip runReader (error "globalenv used") . runParserT p (newPos "" 0 0) f . mkIndentStream 0 infIndentation True Ge . mkCharIndentStream $ str
@@ -1597,10 +1573,10 @@ parseLC f str = either (throwError . ErrorMsg . show) return . flip runReader (e
1597 then NonTypeNamespace 1573 then NonTypeNamespace
1598 else Namespace ExpLevel (not $ NoConstructorNamespace `elem` exts) 1574 else Namespace ExpLevel (not $ NoConstructorNamespace `elem` exts)
1599 whiteSpace 1575 whiteSpace
1600 header <- optional $ do 1576 header <- optionMaybe $ do
1601 modn <- keyword "module" *> moduleName 1577 modn <- reserved "module" *> moduleName
1602 exps <- optional (parens $ commaSep $ export ns) 1578 exps <- optionMaybe (parens $ commaSep $ parseExport ns)
1603 keyword "where" 1579 reserved "where"
1604 return (modn, exps) 1580 return (modn, exps)
1605 let mkIDef _ n i h _ = (n, f i h) 1581 let mkIDef _ n i h _ = (n, f i h)
1606 where 1582 where
@@ -1608,11 +1584,11 @@ parseLC f str = either (throwError . ErrorMsg . show) return . flip runReader (e
1608 f (Just h) Nothing = ImportAllBut h 1584 f (Just h) Nothing = ImportAllBut h
1609 f Nothing (Just i) = ImportJust i 1585 f Nothing (Just i) = ImportJust i
1610 idefs <- many $ 1586 idefs <- many $
1611 mkIDef <$> (keyword "import" *> (optionTry $ keyword "qualified")) 1587 mkIDef <$> (reserved "import" *> (optionMaybe $ try $ reserved "qualified"))
1612 <*> moduleName 1588 <*> moduleName
1613 <*> (optionTry $ keyword "hiding" *> importlist ns) 1589 <*> (optionMaybe $ try $ reserved "hiding" *> importlist ns)
1614 <*> (optionTry $ importlist ns) 1590 <*> (optionMaybe $ try $ importlist ns)
1615 <*> (optionTry $ keyword "as" *> moduleName) 1591 <*> (optionMaybe $ try $ reserved "as" *> moduleName)
1616 st <- getParserState 1592 st <- getParserState
1617 1593
1618 let defs ge = (show +++ id) . flip runReader ge . runParserT p (newPos "" 0 0) f . mkIndentStream 0 infIndentation True Ge . mkCharIndentStream $ "" 1594 let defs ge = (show +++ id) . flip runReader ge . runParserT p (newPos "" 0 0) f . mkIndentStream 0 infIndentation True Ge . mkCharIndentStream $ ""
@@ -1630,7 +1606,9 @@ parseLC f str = either (throwError . ErrorMsg . show) return . flip runReader (e
1630 , sourceCode = str 1606 , sourceCode = str
1631 } 1607 }
1632 1608
1633parseType ns mb vs = maybe id option mb $ operator "::" *> parseTTerm ns PrecLam vs 1609--------------------------------------------------------------------------------
1610
1611parseType ns mb vs = maybe id option mb $ reservedOp "::" *> parseTTerm ns PrecLam vs
1634typedIds ns mb vs = (,) <$> commaSep1 (siName (varId ns <|> patVar ns <|> upperCase ns)) 1612typedIds ns mb vs = (,) <$> commaSep1 (siName (varId ns <|> patVar ns <|> upperCase ns))
1635 <*> localIndentation Gt {-TODO-} (parseType ns mb vs) 1613 <*> localIndentation Gt {-TODO-} (parseType ns mb vs)
1636 1614
@@ -1642,7 +1620,7 @@ telescope ns mb vs = (map removeSI *** id) <$> telescopeSI ns mb (map addSI vs)
1642telescopeSI :: Namespace -> Maybe SExp -> [SIName] -> P ([SIName], [(Visibility, SExp)]) -- todo: refactor to [(SIName, (Visibility, SExp))] 1620telescopeSI :: Namespace -> Maybe SExp -> [SIName] -> P ([SIName], [(Visibility, SExp)]) -- todo: refactor to [(SIName, (Visibility, SExp))]
1643telescopeSI ns mb vs = option (vs, []) $ do 1621telescopeSI ns mb vs = option (vs, []) $ do
1644 (si, (x, vt)) <- withSI 1622 (si, (x, vt)) <- withSI
1645 ( operator "@" *> (maybe empty (\x -> flip (,) (Hidden, x) <$> patVar ns) mb <|> parens (typedId Hidden)) 1623 ( reservedOp "@" *> (maybe empty (\x -> flip (,) (Hidden, x) <$> patVar ns) mb <|> parens (typedId Hidden))
1646 <|> try (parens $ typedId Visible) 1624 <|> try (parens $ typedId Visible)
1647 <|> maybe ((,) "" . (,) Visible <$> parseTerm ns PrecAtom (map removeSI vs)) 1625 <|> maybe ((,) "" . (,) Visible <$> parseTerm ns PrecAtom (map removeSI vs))
1648 (\x -> flip (,) (Visible, x) <$> patVar ns) 1626 (\x -> flip (,) (Visible, x) <$> patVar ns)
@@ -1658,7 +1636,7 @@ telescopeSI ns mb vs = option (vs, []) $ do
1658parseClause ns e = do 1636parseClause ns e = do
1659 (fe, p) <- pattern' ns e 1637 (fe, p) <- pattern' ns e
1660 localIndentation Gt $ do 1638 localIndentation Gt $ do
1661 x <- operator "->" *> parseETerm ns PrecLam fe 1639 x <- reservedOp "->" *> parseETerm ns PrecLam fe
1662 f <- parseWhereBlock ns fe 1640 f <- parseWhereBlock ns fe
1663 return (p, f x) 1641 return (p, f x)
1664 1642
@@ -1692,7 +1670,7 @@ mkTupPat ns ps = PCon (debugSI "", tick' ns $ "Tuple" ++ show (length ps)) (ParP
1692pattern' ns vs = 1670pattern' ns vs =
1693 pCon <$> (siName $ upperCase ns) <*> patterns ns vs 1671 pCon <$> (siName $ upperCase ns) <*> patterns ns vs
1694 <|> pCon <$> try (withSI (char '\'' *> upperCase (switchNS ns))) <*> patterns ns vs 1672 <|> pCon <$> try (withSI (char '\'' *> upperCase (switchNS ns))) <*> patterns ns vs
1695 <|> (patternAtom ns vs >>= \(vs, p) -> option (vs, p) ((id *** (\p' -> PCon (debugSI "pattern'","Cons") (ParPat . (:[]) <$> [p, p']))) <$ operator ":" <*> pattern' ns vs)) 1673 <|> (patternAtom ns vs >>= \(vs, p) -> option (vs, p) ((id *** (\p' -> PCon (debugSI "pattern'","Cons") (ParPat . (:[]) <$> [p, p']))) <$ reservedOp ":" <*> pattern' ns vs))
1696 1674
1697pCon i (vs, x) = (vs, PCon i x) 1675pCon i (vs, x) = (vs, PCon i x)
1698 1676
@@ -1713,7 +1691,7 @@ commaSepUnfold p vs = commaSepUnfold1 p vs <|> pure (vs, [])
1713 1691
1714telescope' ns vs = option (vs, []) $ do 1692telescope' ns vs = option (vs, []) $ do
1715 (vs', vt) <- 1693 (vs', vt) <-
1716 operator "@" *> (f Hidden <$> patternAtom ns vs) 1694 reservedOp "@" *> (f Hidden <$> patternAtom ns vs)
1717 <|> f Visible <$> patternAtom ns vs 1695 <|> f Visible <$> patternAtom ns vs
1718 (id *** (vt:)) <$> telescope' ns vs' 1696 (id *** (vt:)) <$> telescope' ns vs'
1719 where 1697 where
@@ -1770,7 +1748,7 @@ compileGuardTrees True ulend lend ge alts = foldr1 SParEval $ compileGuardTree u
1770 1748
1771parseDef :: Namespace -> DBNames -> P [Stmt] 1749parseDef :: Namespace -> DBNames -> P [Stmt]
1772parseDef ns e = 1750parseDef ns e =
1773 do keyword "data" 1751 do reserved "data"
1774 localIndentation Gt $ do 1752 localIndentation Gt $ do
1775 (si,x) <- siName $ upperCase (typeNS ns) 1753 (si,x) <- siName $ upperCase (typeNS ns)
1776 (nps, ts) <- telescopeSI (typeNS ns) (Just SType) (dbToSINames "parseDef data" e) 1754 (nps, ts) <- telescopeSI (typeNS ns) (Just SType) (dbToSINames "parseDef data" e)
@@ -1780,58 +1758,58 @@ parseDef ns e =
1780 ( if mk then Just $ diffDBNames nps' npsd else Nothing 1758 ( if mk then Just $ diffDBNames nps' npsd else Nothing
1781 , foldr (uncurry SPi) (foldl SAppV (SGlobal (si,x)) $ downToS (length ts') $ length ts) ts') 1759 , foldr (uncurry SPi) (foldl SAppV (SGlobal (si,x)) $ downToS (length ts') $ length ts) ts')
1782 (af, cs) <- 1760 (af, cs) <-
1783 do (,) True <$ keyword "where" <*> localIndentation Ge (localAbsoluteIndentation $ many $ 1761 do (,) True <$ reserved "where" <*> localIndentation Ge (localAbsoluteIndentation $ many $
1784 (id *** (,) Nothing) <$> typedIds ns Nothing npsd) 1762 (id *** (,) Nothing) <$> typedIds ns Nothing npsd)
1785 <|> do (,) False <$ operator "=" <*> 1763 <|> do (,) False <$ reservedOp "=" <*>
1786 sepBy1 ((,) <$> (pure <$> siName (upperCase ns)) 1764 sepBy1 ((,) <$> (pure <$> siName (upperCase ns))
1787 <*> ( braces (mkConTy True <$> (telescopeDataFields (typeNS ns) nps)) 1765 <*> ( braces (mkConTy True <$> (telescopeDataFields (typeNS ns) nps))
1788 <|> (mkConTy False <$> telescopeSI (typeNS ns) Nothing nps)) ) 1766 <|> (mkConTy False <$> telescopeSI (typeNS ns) Nothing nps)) )
1789 (operator "|") 1767 (reservedOp "|")
1790 <|> pure (True, []) 1768 <|> pure (True, [])
1791 ge <- ask 1769 ge <- ask
1792 return $ mkData ge (si,x) ts t af $ concatMap (\(vs, t) -> (,) <$> vs <*> pure t) $ cs 1770 return $ mkData ge (si,x) ts t af $ concatMap (\(vs, t) -> (,) <$> vs <*> pure t) $ cs
1793 <|> do keyword "class" 1771 <|> do reserved "class"
1794 localIndentation Gt $ do 1772 localIndentation Gt $ do
1795 x <- siName $ upperCase (typeNS ns) 1773 x <- siName $ upperCase (typeNS ns)
1796 (nps, ts) <- telescope (typeNS ns) (Just SType) e 1774 (nps, ts) <- telescope (typeNS ns) (Just SType) e
1797 cs <- 1775 cs <-
1798 do keyword "where" *> localIndentation Ge (localAbsoluteIndentation $ many $ typedIds ns Nothing nps) 1776 do reserved "where" *> localIndentation Ge (localAbsoluteIndentation $ many $ typedIds ns Nothing nps)
1799 <|> pure [] 1777 <|> pure []
1800 return $ pure $ Class x (map snd ts) (concatMap (\(vs, t) -> (,) <$> vs <*> pure t) cs) 1778 return $ pure $ Class x (map snd ts) (concatMap (\(vs, t) -> (,) <$> vs <*> pure t) cs)
1801 <|> do keyword "instance" 1779 <|> do reserved "instance"
1802 let ns' = typeNS ns 1780 let ns' = typeNS ns
1803 localIndentation Gt $ do 1781 localIndentation Gt $ do
1804 constraints <- option [] $ try $ getTTuple' <$> parseTerm ns' PrecEq e <* operator "=>" 1782 constraints <- option [] $ try $ getTTuple' <$> parseTerm ns' PrecEq e <* reservedOp "=>"
1805 (si,x) <- siName $ upperCase ns' 1783 (si,x) <- siName $ upperCase ns'
1806 (nps, args) <- telescope' ns' e 1784 (nps, args) <- telescope' ns' e
1807 cs <- option [] $ keyword "where" *> localIndentation Ge (localAbsoluteIndentation $ some $ 1785 cs <- option [] $ reserved "where" *> localIndentation Ge (localAbsoluteIndentation $ some $
1808 funAltDef (varId ns) ns nps) 1786 funAltDef (varId ns) ns nps)
1809 <|> pure [] 1787 <|> pure []
1810 ge <- ask 1788 ge <- ask
1811 return $ pure $ Instance (si,x) ({-todo-}map snd args) (deBruinify (diffDBNames nps e ++ [x]) <$> constraints) $ compileFunAlts' id{-TODO-} ge cs 1789 return $ pure $ Instance (si,x) ({-todo-}map snd args) (deBruinify (diffDBNames nps e ++ [x]) <$> constraints) $ compileFunAlts' id{-TODO-} ge cs
1812 <|> do try (keyword "type" >> keyword "family") 1790 <|> do try (reserved "type" >> reserved "family")
1813 let ns' = typeNS ns 1791 let ns' = typeNS ns
1814 localIndentation Gt $ do 1792 localIndentation Gt $ do
1815 (si, x) <- siName $ upperCase ns' 1793 (si, x) <- siName $ upperCase ns'
1816 (nps, ts) <- telescope ns' (Just SType) e 1794 (nps, ts) <- telescope ns' (Just SType) e
1817 t <- parseType ns' (Just SType) nps 1795 t <- parseType ns' (Just SType) nps
1818 option {-open type family-}[TypeFamily (si, x) ts t] $ do 1796 option {-open type family-}[TypeFamily (si, x) ts t] $ do
1819 cs <- keyword "where" *> localIndentation Ge (localAbsoluteIndentation $ many $ 1797 cs <- reserved "where" *> localIndentation Ge (localAbsoluteIndentation $ many $
1820 funAltDef (upperCase ns' >>= \x' -> guard (x == x') >> return x') ns' e) 1798 funAltDef (upperCase ns' >>= \x' -> guard (x == x') >> return x') ns' e)
1821 ge <- ask 1799 ge <- ask
1822 -- closed type family desugared here 1800 -- closed type family desugared here
1823 return $ compileFunAlts False id SLabelEnd ge [TypeAnn (si, x) $ addParamsS ts t] cs 1801 return $ compileFunAlts False id SLabelEnd ge [TypeAnn (si, x) $ addParamsS ts t] cs
1824 <|> do keyword "type" 1802 <|> do reserved "type"
1825 let ns' = typeNS ns 1803 let ns' = typeNS ns
1826 localIndentation Gt $ do 1804 localIndentation Gt $ do
1827 (si, x) <- siName $ upperCase ns' 1805 (si, x) <- siName $ upperCase ns'
1828 let addSI n = (debugSI "type telescope", n) 1806 let addSI n = (debugSI "type telescope", n)
1829 (nps, ts) <- telescopeSI ns' (Just (Wildcard SType)) (map addSI{-todo: remove-} e) 1807 (nps, ts) <- telescopeSI ns' (Just (Wildcard SType)) (map addSI{-todo: remove-} e)
1830 operator "=" 1808 reservedOp "="
1831 rhs <- parseTerm ns' PrecLam $ map snd nps 1809 rhs <- parseTerm ns' PrecLam $ map snd nps
1832 ge <- ask 1810 ge <- ask
1833 return $ compileFunAlts False id SLabelEnd ge [{-TypeAnn (si, x) $ addParamsS ts $ SType-}{-todo-}] [FunAlt (si, x) (reverse $ zip (reverse ts) $ map PVar nps) Nothing rhs] 1811 return $ compileFunAlts False id SLabelEnd ge [{-TypeAnn (si, x) $ addParamsS ts $ SType-}{-todo-}] [FunAlt (si, x) (reverse $ zip (reverse ts) $ map PVar nps) Nothing rhs]
1834 <|> do try (keyword "type" >> keyword "instance") 1812 <|> do try (reserved "type" >> reserved "instance")
1835 let ns' = typeNS ns 1813 let ns' = typeNS ns
1836 pure <$> localIndentation Gt (funAltDef (upperCase ns') ns' e) 1814 pure <$> localIndentation Gt (funAltDef (upperCase ns') ns' e)
1837 <|> do (vs, t) <- try $ typedIds ns Nothing [] 1815 <|> do (vs, t) <- try $ typedIds ns Nothing []
@@ -1842,7 +1820,7 @@ parseDef ns e =
1842 where 1820 where
1843 telescopeDataFields ns vs = option (vs, []) $ do 1821 telescopeDataFields ns vs = option (vs, []) $ do
1844 (x, vt) <- do name <- siName $ var (expNS ns) 1822 (x, vt) <- do name <- siName $ var (expNS ns)
1845 operator "::" 1823 reservedOp "::"
1846 term <- parseTerm ns PrecLam (siToDBNames vs) 1824 term <- parseTerm ns PrecLam (siToDBNames vs)
1847 return (name, (Visible, term)) 1825 return (name, (Visible, term))
1848 (id *** (vt:)) <$> (comma *> telescopeDataFields ns (x: vs) <|> pure (vs, [])) 1826 (id *** (vt:)) <$> (comma *> telescopeDataFields ns (x: vs) <|> pure (vs, []))
@@ -1852,18 +1830,18 @@ funAltDef parseName ns e = do -- todo: use ns to determine parseName
1852 do try' "operator definition" $ do 1830 do try' "operator definition" $ do
1853 (e', a1) <- patternAtom ns ("": e) 1831 (e', a1) <- patternAtom ns ("": e)
1854 localIndentation Gt $ do 1832 localIndentation Gt $ do
1855 (si,n) <- siName $ operator' 1833 (si,n) <- siName $ operatorT
1856 (e'', a2) <- patternAtom ns $ init (diffDBNames e' e) ++ n: e 1834 (e'', a2) <- patternAtom ns $ init (diffDBNames e' e) ++ n: e
1857 lookAhead $ operator "=" <|> operator "|" 1835 lookAhead $ reservedOp "=" <|> reservedOp "|"
1858 return ((si, n), (e'', (,) (Visible, Wildcard SType) <$> [a1, a2])) 1836 return ((si, n), (e'', (,) (Visible, Wildcard SType) <$> [a1, a2]))
1859 <|> do try $ do 1837 <|> do try $ do
1860 (si,n) <- siName $ parseName 1838 (si,n) <- siName $ parseName
1861 localIndentation Gt $ (,) (si, n) <$> telescope' ns (n: e) <* (lookAhead $ operator "=" <|> operator "|") 1839 localIndentation Gt $ (,) (si, n) <$> telescope' ns (n: e) <* (lookAhead $ reservedOp "=" <|> reservedOp "|")
1862 localIndentation Gt $ do 1840 localIndentation Gt $ do
1863 gu <- option Nothing $ do 1841 gu <- option Nothing $ do
1864 operator "|" 1842 reservedOp "|"
1865 Just <$> parseTerm ns PrecOp fe 1843 Just <$> parseTerm ns PrecOp fe
1866 operator "=" 1844 reservedOp "="
1867 rhs <- parseTerm ns PrecLam []--fe 1845 rhs <- parseTerm ns PrecLam []--fe
1868 f <- parseWhereBlock ns fe 1846 f <- parseWhereBlock ns fe
1869 return $ FunAlt n ts gu $ deBruinify' fe {-hack-} $ f rhs 1847 return $ FunAlt n ts gu $ deBruinify' fe {-hack-} $ f rhs
@@ -1877,7 +1855,7 @@ mkData ge x ts t af cs = [Data x ts t af $ (id *** snd) <$> cs] ++ concatMap mkP
1877 mkProj _ = [] 1855 mkProj _ = []
1878 1856
1879parseWhereBlock ns fe = option id $ do 1857parseWhereBlock ns fe = option id $ do
1880 keyword "where" 1858 reserved "where"
1881 dcls <- localIndentation Ge (localAbsoluteIndentation $ parseDefs id ns fe) 1859 dcls <- localIndentation Ge (localAbsoluteIndentation $ parseDefs id ns fe)
1882 ge <- ask 1860 ge <- ask
1883 return $ mkLets ge dcls 1861 return $ mkLets ge dcls
@@ -1892,7 +1870,7 @@ type DBNames = [SName] -- De Bruijn variable names
1892 1870
1893valueDef :: Namespace -> DBNames -> P ((DBNames, Pat), SExp) 1871valueDef :: Namespace -> DBNames -> P ((DBNames, Pat), SExp)
1894valueDef ns e = do 1872valueDef ns e = do
1895 (e', p) <- try $ pattern' ns e <* operator "=" 1873 (e', p) <- try $ pattern' ns e <* reservedOp "="
1896 localIndentation Gt $ do 1874 localIndentation Gt $ do
1897 ex <- parseETerm ns PrecLam e 1875 ex <- parseETerm ns PrecLam e
1898 return ((diffDBNames e' e, p), ex) 1876 return ((diffDBNames e' e, p), ex)
@@ -1904,39 +1882,38 @@ parseETerm ns = parseTerm $ expNS ns
1904 1882
1905parseTerm :: Namespace -> Prec -> DBNames -> P SExp 1883parseTerm :: Namespace -> Prec -> DBNames -> P SExp
1906parseTerm ns PrecLam e = 1884parseTerm ns PrecLam e =
1907 mkIf `withRange` ((,,) <$ keyword "if" <*> parseTerm ns PrecLam e <* keyword "then" <*> parseTerm ns PrecLam e <* keyword "else" <*> parseTerm ns PrecLam e) 1885 mkIf `withRange` ((,,) <$ reserved "if" <*> parseTerm ns PrecLam e <* reserved "then" <*> parseTerm ns PrecLam e <* reserved "else" <*> parseTerm ns PrecLam e)
1908 <|> do (tok, ns) <- (SPi . const Hidden <$ operator "." <|> SPi . const Visible <$ operator "->", typeNS ns) <$ keyword "forall" 1886 <|> do (tok, ns) <- (SPi . const Hidden <$ reservedOp "." <|> SPi . const Visible <$ reservedOp "->", typeNS ns) <$ reserved "forall"
1909 (fe, ts) <- telescope ns (Just $ Wildcard SType) e 1887 (fe, ts) <- telescope ns (Just $ Wildcard SType) e
1910 f <- tok 1888 f <- tok
1911 t' <- parseTerm ns PrecLam fe 1889 t' <- parseTerm ns PrecLam fe
1912 return $ foldr (uncurry f) t' ts 1890 return $ foldr (uncurry f) t' ts
1913 <|> do sPos <- position 1891 <|> do appRange $ do
1914 (tok, ns) <- (asks (\a r -> patLam_ r id a) <* operator "->", expNS ns) <$ operator "\\" 1892 (tok, ns) <- (asks (\a r -> patLam_ r id a) <* reservedOp "->", expNS ns) <$ reservedOp "\\"
1915 (fe, ts) <- telescope' ns e 1893 (fe, ts) <- telescope' ns e
1916 f <- tok 1894 f <- tok
1917 t' <- parseTerm ns PrecLam fe 1895 t' <- parseTerm ns PrecLam fe
1918 ePos <- positionBeforeSpace 1896 return $ \r -> foldr (uncurry (f r)) t' ts
1919 return $ foldr (uncurry (f $ Range (sPos,ePos))) t' ts 1897 <|> do (asks compileCase) <* reserved "case" <*> parseETerm ns PrecLam e
1920 <|> do (asks compileCase) <* keyword "case" <*> parseETerm ns PrecLam e 1898 <* reserved "of" <*> localIndentation Ge (localAbsoluteIndentation $ some $ parseClause ns e)
1921 <* keyword "of" <*> localIndentation Ge (localAbsoluteIndentation $ some $ parseClause ns e)
1922 <|> do (asks $ \ge -> compileGuardTree id id ge . Alts) <*> parseSomeGuards ns (const True) e 1899 <|> do (asks $ \ge -> compileGuardTree id id ge . Alts) <*> parseSomeGuards ns (const True) e
1923 <|> do t <- parseTerm ns PrecEq e 1900 <|> do t <- parseTerm ns PrecEq e
1924 option t $ mkPi <$> (Visible <$ operator "->" <|> Hidden <$ operator "=>") <*> pure t <*> parseTTerm ns PrecLam e 1901 option t $ mkPi <$> (Visible <$ reservedOp "->" <|> Hidden <$ reservedOp "=>") <*> pure t <*> parseTTerm ns PrecLam e
1925parseTerm ns PrecEq e = parseTerm ns PrecAnn e >>= \t -> option t $ SCstr t <$ operator "~" <*> parseTTerm ns PrecAnn e 1902parseTerm ns PrecEq e = parseTerm ns PrecAnn e >>= \t -> option t $ SCstr t <$ reservedOp "~" <*> parseTTerm ns PrecAnn e
1926parseTerm ns PrecAnn e = parseTerm ns PrecOp e >>= \t -> option t $ SAnn t <$> parseType ns Nothing e 1903parseTerm ns PrecAnn e = parseTerm ns PrecOp e >>= \t -> option t $ SAnn t <$> parseType ns Nothing e
1927parseTerm ns PrecOp e = (asks $ \dcls -> calculatePrecs dcls e) <*> p' where 1904parseTerm ns PrecOp e = (asks $ \dcls -> calculatePrecs dcls e) <*> p' where
1928 p' = ((\si (t, xs) -> (mkNat ns si 0, ("-!", t): xs)) `withRange` (operator "-" *> p_)) 1905 p' = ((\si (t, xs) -> (mkNat ns si 0, ("-!", t): xs)) `withRange` (reservedOp "-" *> p_))
1929 <|> p_ 1906 <|> p_
1930 p_ = (,) <$> parseTerm ns PrecApp e <*> (option [] $ operator' >>= p) 1907 p_ = (,) <$> parseTerm ns PrecApp e <*> (option [] $ operatorT >>= p)
1931 p op = do (exp, op') <- try ((,) <$> parseTerm ns PrecApp e <*> operator') 1908 p op = do (exp, op') <- try ((,) <$> parseTerm ns PrecApp e <*> operatorT)
1932 ((op, exp):) <$> p op' 1909 ((op, exp):) <$> p op'
1933 <|> pure . (,) op <$> parseTerm ns PrecLam e 1910 <|> pure . (,) op <$> parseTerm ns PrecLam e
1934parseTerm ns PrecApp e = 1911parseTerm ns PrecApp e =
1935 try {- TODO: adjust try for better error messages e.g. don't use braces -} 1912 try {- TODO: adjust try for better error messages e.g. don't use braces -}
1936 (foldl sapp <$> (sVar e `withRange` upperCase ns) <*> braces (commaSep $ lowerCase ns *> operator "=" *> ((,) Visible <$> parseTerm ns PrecLam e))) <|> 1913 (foldl sapp <$> (sVar e `withRange` upperCase ns) <*> braces (commaSep $ lowerCase ns *> reservedOp "=" *> ((,) Visible <$> parseTerm ns PrecLam e))) <|>
1937 (foldl sapp <$> parseTerm ns PrecSwiz e <*> many 1914 (foldl sapp <$> parseTerm ns PrecSwiz e <*> many
1938 ( (,) Visible <$> parseTerm ns PrecSwiz e 1915 ( (,) Visible <$> parseTerm ns PrecSwiz e
1939 <|> (,) Hidden <$ operator "@" <*> parseTTerm ns PrecSwiz e)) 1916 <|> (,) Hidden <$ reservedOp "@" <*> parseTTerm ns PrecSwiz e))
1940parseTerm ns PrecSwiz e = do 1917parseTerm ns PrecSwiz e = do
1941 t <- parseTerm ns PrecProj e 1918 t <- parseTerm ns PrecProj e
1942 try (mkSwizzling t `withRange` (char '%' *> manyNM 1 4 (satisfy (`elem` ("xyzwrgba" :: [Char]))) <* whiteSpace)) <|> pure t 1919 try (mkSwizzling t `withRange` (char '%' *> manyNM 1 4 (satisfy (`elem` ("xyzwrgba" :: [Char]))) <* whiteSpace)) <|> pure t
@@ -1949,20 +1926,20 @@ parseTerm ns PrecAtom e =
1949 <|> sLit `withRange` (LFloat <$> try float) 1926 <|> sLit `withRange` (LFloat <$> try float)
1950 <|> sLit `withRange` (LInt . fromIntegral <$ char '#' <*> natural) 1927 <|> sLit `withRange` (LInt . fromIntegral <$ char '#' <*> natural)
1951 <|> mkNat ns `withRange` natural 1928 <|> mkNat ns `withRange` natural
1952 <|> Wildcard (Wildcard SType) <$ keyword "_" 1929 <|> Wildcard (Wildcard SType) <$ reserved "_"
1953 <|> char '\'' *> parseTerm (switchNS ns) PrecAtom e 1930 <|> char '\'' *> parseTerm (switchNS ns) PrecAtom e
1954 <|> sVar e `withRange` (try (varId ns) <|> upperCase ns) 1931 <|> sVar e `withRange` (try (varId ns) <|> upperCase ns)
1955 <|> mkDotDot <$> try (operator "[" *> parseTerm ns PrecLam e <* operator ".." ) <*> parseTerm ns PrecLam e <* operator "]" 1932 <|> mkDotDot <$> try (reservedOp "[" *> parseTerm ns PrecLam e <* reservedOp ".." ) <*> parseTerm ns PrecLam e <* reservedOp "]"
1956 <|> listCompr ns e 1933 <|> listCompr ns e
1957 <|> mkList ns `withRange` brackets (commaSep $ parseTerm ns PrecLam e) 1934 <|> mkList ns `withRange` brackets (commaSep $ parseTerm ns PrecLam e)
1958 <|> mkLeftSection `withRange` try{-todo: better try-} (parens $ (,) <$> withRange (,) (guardM (/= "-") operator') <*> parseTerm ns PrecLam e) 1935 <|> mkLeftSection `withRange` try{-todo: better try-} (parens $ (,) <$> siName (guardM (/= "-") operatorT) <*> parseTerm ns PrecLam e)
1959 <|> mkRightSection `withRange` try{-todo: better try!-} (parens $ (,) <$> parseTerm ns PrecApp e <*> withRange (,) operator') 1936 <|> mkRightSection `withRange` try{-todo: better try!-} (parens $ (,) <$> parseTerm ns PrecApp e <*> siName operatorT)
1960 <|> mkTuple ns `withRange` parens (commaSep $ parseTerm ns PrecLam e) 1937 <|> mkTuple ns `withRange` parens (commaSep $ parseTerm ns PrecLam e)
1961 <|> mkRecord `withRange` braces (commaSep $ ((,) <$> lowerCase ns <* colon <*> parseTerm ns PrecLam e)) 1938 <|> mkRecord `withRange` braces (commaSep $ ((,) <$> lowerCase ns <* colon <*> parseTerm ns PrecLam e))
1962 <|> do keyword "let" 1939 <|> do reserved "let"
1963 dcls <- localIndentation Ge (localAbsoluteIndentation $ parseDefs id ns e) 1940 dcls <- localIndentation Ge (localAbsoluteIndentation $ parseDefs id ns e)
1964 ge <- ask 1941 ge <- ask
1965 mkLets ge dcls <$ keyword "in" <*> parseTerm ns PrecLam e 1942 mkLets ge dcls <$ reserved "in" <*> parseTerm ns PrecLam e
1966 1943
1967guardM p m = m >>= \x -> if p x then return x else fail "guardM" 1944guardM p m = m >>= \x -> if p x then return x else fail "guardM"
1968 1945
@@ -2011,11 +1988,6 @@ mkList _ si xs = error "mkList"
2011mkNat (Namespace ExpLevel _) si n = SGlobal (noSI,"fromInt") `SAppV` sLit si (LInt $ fromIntegral n) 1988mkNat (Namespace ExpLevel _) si n = SGlobal (noSI,"fromInt") `SAppV` sLit si (LInt $ fromIntegral n)
2012mkNat _ _ n = toNat n 1989mkNat _ _ n = toNat n
2013 1990
2014infix 9 `withRange`
2015
2016withRange :: (SI -> a -> b) -> P a -> P b
2017withRange f p = (\p1 a p2 -> f (Range (p1,p2)) a) <$> position <*> p <*> positionBeforeSpace
2018
2019siName :: P SName -> P SIName 1991siName :: P SName -> P SIName
2020siName = withSI 1992siName = withSI
2021 1993
@@ -2038,7 +2010,7 @@ manyNM n m p = do
2038 2010
2039generator, letdecl, boolExpression :: Namespace -> DBNames -> P (DBNames, SExp -> SExp) 2011generator, letdecl, boolExpression :: Namespace -> DBNames -> P (DBNames, SExp -> SExp)
2040generator ns dbs = do 2012generator ns dbs = do
2041 (dbs', pat) <- try $ pattern' ns dbs <* operator "<-" 2013 (dbs', pat) <- try $ pattern' ns dbs <* reservedOp "<-"
2042 exp <- parseTerm ns PrecLam dbs 2014 exp <- parseTerm ns PrecLam dbs
2043 ge <- ask 2015 ge <- ask
2044 return $ (,) dbs' $ \e -> application 2016 return $ (,) dbs' $ \e -> application
@@ -2050,7 +2022,7 @@ generator ns dbs = do
2050 , exp 2022 , exp
2051 ] 2023 ]
2052 2024
2053letdecl ns dbs = ask >>= \ge -> keyword "let" *> ((\((dbs', p), e) -> (dbs, \exp -> mkLets ge [ValueDef (dbs', p) e] exp)) <$> valueDef ns dbs) 2025letdecl ns dbs = ask >>= \ge -> reserved "let" *> ((\((dbs', p), e) -> (dbs, \exp -> mkLets ge [ValueDef (dbs', p) e] exp)) <$> valueDef ns dbs)
2054 2026
2055boolExpression ns dbs = do 2027boolExpression ns dbs = do
2056 pred <- parseTerm ns PrecLam dbs 2028 pred <- parseTerm ns PrecLam dbs
@@ -2060,8 +2032,8 @@ application = foldl1 SAppV
2060 2032
2061listCompr :: Namespace -> DBNames -> P SExp 2033listCompr :: Namespace -> DBNames -> P SExp
2062listCompr ns dbs = (\e (dbs', fs) -> foldr ($) (deBruinify (diffDBNames dbs' dbs) e) fs) 2034listCompr ns dbs = (\e (dbs', fs) -> foldr ($) (deBruinify (diffDBNames dbs' dbs) e) fs)
2063 <$> try' "List comprehension" ((SGlobal (noSI, "singleton") `SAppV`) <$ operator "[" <*> parseTerm ns PrecLam dbs <* operator "|") 2035 <$> try' "List comprehension" ((SGlobal (noSI, "singleton") `SAppV`) <$ reservedOp "[" <*> parseTerm ns PrecLam dbs <* reservedOp "|")
2064 <*> commaSepUnfold (liftA2 (<|>) (generator ns) $ liftA2 (<|>) (letdecl ns) (boolExpression ns)) dbs <* operator "]" 2036 <*> commaSepUnfold (liftA2 (<|>) (generator ns) $ liftA2 (<|>) (letdecl ns) (boolExpression ns)) dbs <* reservedOp "]"
2065 2037
2066-- todo: make it more efficient 2038-- todo: make it more efficient
2067diffDBNames xs ys = take (length xs - length ys) xs 2039diffDBNames xs ys = take (length xs - length ys) xs
@@ -2171,15 +2143,15 @@ patLam_ :: SI -> (SExp -> SExp) -> GlobalEnv' -> (Visibility, SExp) -> Pat -> SE
2171patLam_ si f ge (v, t) p e = SLam_ si v t $ compileGuardTree f f ge $ compilePatts [(p, 0)] Nothing e 2143patLam_ si f ge (v, t) p e = SLam_ si v t $ compileGuardTree f f ge $ compilePatts [(p, 0)] Nothing e
2172 2144
2173parseSomeGuards ns f e = do 2145parseSomeGuards ns f e = do
2174 pos <- sourceColumn <$> getPosition <* operator "|" 2146 pos <- sourceColumn <$> getPosition <* reservedOp "|"
2175 guard $ f pos 2147 guard $ f pos
2176 (e', f) <- 2148 (e', f) <-
2177 do (e', PCon (_, p) vs) <- try $ pattern' ns e <* operator "<-" 2149 do (e', PCon (_, p) vs) <- try $ pattern' ns e <* reservedOp "<-"
2178 x <- parseETerm ns PrecEq e 2150 x <- parseETerm ns PrecEq e
2179 return (e', \gs' gs -> GuardNode x p vs (Alts gs'): gs) 2151 return (e', \gs' gs -> GuardNode x p vs (Alts gs'): gs)
2180 <|> do x <- parseETerm ns PrecEq e 2152 <|> do x <- parseETerm ns PrecEq e
2181 return (e, \gs' gs -> [GuardNode x "True" [] $ Alts gs', GuardNode x "False" [] $ Alts gs]) 2153 return (e, \gs' gs -> [GuardNode x "True" [] $ Alts gs', GuardNode x "False" [] $ Alts gs])
2182 f <$> (parseSomeGuards ns (> pos) e' <|> (:[]) . GuardLeaf <$ operator "->" <*> parseETerm ns PrecLam e') 2154 f <$> (parseSomeGuards ns (> pos) e' <|> (:[]) . GuardLeaf <$ reservedOp "->" <*> parseETerm ns PrecLam e')
2183 <*> (parseSomeGuards ns (== pos) e <|> pure []) 2155 <*> (parseSomeGuards ns (== pos) e <|> pure [])
2184 2156
2185toNat 0 = SGlobal (debugSI "toNat","Zero") 2157toNat 0 = SGlobal (debugSI "toNat","Zero")
@@ -2189,6 +2161,18 @@ toNatP si = run where
2189 run 0 = PCon (si, "Zero") [] 2161 run 0 = PCon (si, "Zero") []
2190 run n | n > 0 = PCon (si, "Succ") [ParPat [run $ n-1]] 2162 run n | n > 0 = PCon (si, "Succ") [ParPat [run $ n-1]]
2191 2163
2164addForalls :: Extensions -> [SName] -> SExp -> SExp
2165addForalls exs defined x = foldl f x [v | v@(vh:_) <- reverse $ freeS x, v `notElem'` defined, isLower vh || NoConstructorNamespace `elem` exs]
2166 where
2167 f e v = SPi Hidden (Wildcard SType) $ substSG0 v e
2168
2169defined defs = ("'Type":) $ flip foldMap defs $ \case
2170 TypeAnn (_, x) _ -> [x]
2171 Let (_, x) _ _ _ _ -> [x]
2172 Data (_, x) _ _ _ cs -> x: map (snd . fst) cs
2173 Class (_, x) _ cs -> x: map (snd . fst) cs
2174 TypeFamily (_, x) _ _ -> [x]
2175 x -> error $ unwords ["defined: Impossible", show x, "cann't be here"]
2192-------------------------------------------------------------------------------- 2176--------------------------------------------------------------------------------
2193 2177
2194class SourceInfo si where 2178class SourceInfo si where
@@ -2230,7 +2214,7 @@ patSI = \case
2230 PatType ps e -> sourceInfo ps <> sourceInfo e 2214 PatType ps e -> sourceInfo ps <> sourceInfo e
2231 2215
2232data GuardTree 2216data GuardTree
2233 = GuardNode SExp Name [ParPat] GuardTree -- _ <- _ 2217 = GuardNode SExp SName [ParPat] GuardTree -- _ <- _
2234 | Alts [GuardTree] -- _ | _ 2218 | Alts [GuardTree] -- _ | _
2235 | GuardLeaf SExp -- _ -> e 2219 | GuardLeaf SExp -- _ -> e
2236 deriving Show 2220 deriving Show
diff --git a/testdata/language-features/module/Moduledef03.reject.out b/testdata/language-features/module/Moduledef03.reject.out
index f1713b40..60fa01a7 100644
--- a/testdata/language-features/module/Moduledef03.reject.out
+++ b/testdata/language-features/module/Moduledef03.reject.out
@@ -1,4 +1,3 @@
1"testdata/language-features/module/Moduledef03.reject.lc" (line 1, column 20): 1"testdata/language-features/module/Moduledef03.reject.lc" (line 1, column 20):
2unexpected "w" 2unexpected "w"
3expecting uppercase ident 3expecting uppercase ident \ No newline at end of file
4uppercase ident expected \ No newline at end of file
diff --git a/testdata/language-features/module/Moduledef04.reject.out b/testdata/language-features/module/Moduledef04.reject.out
index b81c5571..53486f84 100644
--- a/testdata/language-features/module/Moduledef04.reject.out
+++ b/testdata/language-features/module/Moduledef04.reject.out
@@ -1,4 +1,3 @@
1"testdata/language-features/module/Moduledef04.reject.lc" (line 3, column 1): 1"testdata/language-features/module/Moduledef04.reject.lc" (line 3, column 1):
2unexpected "h" 2unexpected "h"
3expecting uppercase ident 3expecting uppercase ident \ No newline at end of file
4uppercase ident expected \ No newline at end of file
diff --git a/testdata/language-features/module/import03.reject.wip.out b/testdata/language-features/module/import03.reject.wip.out
index f9d205e5..e72840a5 100644
--- a/testdata/language-features/module/import03.reject.wip.out
+++ b/testdata/language-features/module/import03.reject.wip.out
@@ -1 +1 @@
can't find module Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/comment/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/pragma/Hello02.lc testdata/language-features/pragma/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc \ No newline at end of file can't find module Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/comment/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/pragma/Hello02.lc testdata/language-features/pragma/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/basic-values/Hello02.lc testdata/language-features/module/Hello02.lc testdata/language-features/module/Hello02.lc testdata/Hello02.lc \ No newline at end of file