diff options
author | Péter Diviánszky <divipp@gmail.com> | 2015-12-09 17:08:34 +0100 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2015-12-09 17:08:34 +0100 |
commit | 2d1b06325c999450c09abfcfed474e1316030f60 (patch) | |
tree | 0c0c79eb59ea08467735d2ec12bf67f77d6b17dd /prototypes | |
parent | a1877248068e958c5207dd272465237838f87526 (diff) |
support list comprehensions (buggy)
Diffstat (limited to 'prototypes')
-rw-r--r-- | prototypes/Infer.hs | 99 |
1 files changed, 91 insertions, 8 deletions
diff --git a/prototypes/Infer.hs b/prototypes/Infer.hs index b26db29c..636665af 100644 --- a/prototypes/Infer.hs +++ b/prototypes/Infer.hs | |||
@@ -67,7 +67,7 @@ data SExp | |||
67 | = SGlobal SName | 67 | = SGlobal SName |
68 | | SBind Binder SExp SExp | 68 | | SBind Binder SExp SExp |
69 | | SApp Visibility SExp SExp | 69 | | SApp Visibility SExp SExp |
70 | | SLet SExp SExp | 70 | | SLet SExp SExp -- let x = e in f --> SLet e f{-x is Var 0-} |
71 | | SVar !Int | 71 | | SVar !Int |
72 | | STyped ExpType | 72 | | STyped ExpType |
73 | | SPreExp PreExp -- eliminated at the end of parsing | 73 | | SPreExp PreExp -- eliminated at the end of parsing |
@@ -1335,7 +1335,7 @@ patternAtom ns vs = | |||
1335 | eqPP = ParPat [PCon "EQ" []] | 1335 | eqPP = ParPat [PCon "EQ" []] |
1336 | truePP = ParPat [PCon "True" []] | 1336 | truePP = ParPat [PCon "True" []] |
1337 | 1337 | ||
1338 | patlist ns vs = commaSep' (\vs -> (\(vs, p) t -> (vs, patType p t)) <$> pattern' ns vs <*> parseType ns (Just $ Wildcard SType) vs) vs | 1338 | patlist ns vs = commaSep1' (\vs -> (\(vs, p) t -> (vs, patType p t)) <$> pattern' ns vs <*> parseType ns (Just $ Wildcard SType) vs) vs |
1339 | 1339 | ||
1340 | mkListPat (p: ps) = PCon "Cons" $ map (ParPat . (:[])) [p, mkListPat ps] | 1340 | mkListPat (p: ps) = PCon "Cons" $ map (ParPat . (:[])) [p, mkListPat ps] |
1341 | mkListPat [] = PCon "Nil" [] | 1341 | mkListPat [] = PCon "Nil" [] |
@@ -1358,10 +1358,16 @@ mkTupPat :: [Pat] -> Pat | |||
1358 | mkTupPat [x] = x | 1358 | mkTupPat [x] = x |
1359 | mkTupPat ps = PCon ("Tuple" ++ show (length ps)) (ParPat . (:[]) <$> ps) | 1359 | mkTupPat ps = PCon ("Tuple" ++ show (length ps)) (ParPat . (:[]) <$> ps) |
1360 | 1360 | ||
1361 | commaSep' p vs = | 1361 | commaSep1' :: (t -> P (t, a)) -> t -> P (t, [a]) |
1362 | p vs >>= \(vs, x) -> (\(vs, xs) -> (vs, x: xs)) <$ comma <*> commaSep' p vs | 1362 | commaSep1' p vs = |
1363 | p vs >>= \(vs, x) -> (\(vs, xs) -> (vs, x: xs)) <$ comma <*> commaSep1' p vs | ||
1363 | <|> pure (vs, [x]) | 1364 | <|> pure (vs, [x]) |
1364 | 1365 | ||
1366 | commaSep' :: (t -> P (t, a)) -> t -> P (t, [a]) | ||
1367 | commaSep' p vs = | ||
1368 | commaSep1' p vs | ||
1369 | <|> pure (vs, []) | ||
1370 | |||
1365 | telescope' ns vs = option (vs, []) $ do | 1371 | telescope' ns vs = option (vs, []) $ do |
1366 | (vs', vt) <- | 1372 | (vs', vt) <- |
1367 | operator "@" *> (f Hidden <$> patternAtom ns vs) | 1373 | operator "@" *> (f Hidden <$> patternAtom ns vs) |
@@ -1430,10 +1436,16 @@ parseStmt ns e = | |||
1430 | dcls <- localIndentation Ge (localAbsoluteIndentation $ parseStmts ns fe) | 1436 | dcls <- localIndentation Ge (localAbsoluteIndentation $ parseStmts ns fe) |
1431 | return $ mkLets' dcls | 1437 | return $ mkLets' dcls |
1432 | return $ pure $ FunAlt n ts gu $ f rhs | 1438 | return $ pure $ FunAlt n ts gu $ f rhs |
1433 | <|> do (e', p) <- try $ pattern' ns e <* keyword "=" | 1439 | <|> pure . uncurry ValueDef <$> valueDef ns e |
1434 | localIndentation Gt $ do | 1440 | |
1435 | ex <- parseETerm ns PrecLam e' | 1441 | type DBNames = [SName] -- De Bruijn variable names |
1436 | return $ pure $ ValueDef (take (length e' - length e) e', p) ex | 1442 | |
1443 | valueDef :: Namespace -> DBNames -> P ((DBNames, Pat), SExp) | ||
1444 | valueDef ns e = do | ||
1445 | (e', p) <- try $ pattern' ns e <* keyword "=" | ||
1446 | localIndentation Gt $ do | ||
1447 | ex <- parseETerm ns PrecLam e' | ||
1448 | return ((take (length e' - length e) e', p), ex) | ||
1437 | 1449 | ||
1438 | pattern TPVar t = ParPat [PatType (ParPat [PVar]) t] | 1450 | pattern TPVar t = ParPat [PatType (ParPat [PVar]) t] |
1439 | 1451 | ||
@@ -1486,6 +1498,7 @@ parseTerm ns PrecAtom e = | |||
1486 | <|> Wildcard (Wildcard SType) <$ keyword "_" | 1498 | <|> Wildcard (Wildcard SType) <$ keyword "_" |
1487 | <|> sVar e <$> (lcIdents ns <|> try (varId ns)) | 1499 | <|> sVar e <$> (lcIdents ns <|> try (varId ns)) |
1488 | <|> mkDotDot <$> try (operator "[" *> parseTerm ns PrecLam e <* operator ".." ) <*> parseTerm ns PrecLam e <* operator "]" | 1500 | <|> mkDotDot <$> try (operator "[" *> parseTerm ns PrecLam e <* operator ".." ) <*> parseTerm ns PrecLam e <* operator "]" |
1501 | <|> listCompr ns e | ||
1489 | <|> mkList ns <$> brackets (commaSep $ parseTerm ns PrecLam e) | 1502 | <|> mkList ns <$> brackets (commaSep $ parseTerm ns PrecLam e) |
1490 | <|> mkTuple ns <$> parens (commaSep $ parseTerm ns PrecLam e) | 1503 | <|> mkTuple ns <$> parens (commaSep $ parseTerm ns PrecLam e) |
1491 | <|> do keyword "let" | 1504 | <|> do keyword "let" |
@@ -1498,6 +1511,75 @@ mkIf b t f = SGlobal "PrimIfThenElse" `SAppV` b `SAppV` t `SAppV` f | |||
1498 | 1511 | ||
1499 | mkDotDot e f = SGlobal "fromTo" `SAppV` e `SAppV` f | 1512 | mkDotDot e f = SGlobal "fromTo" `SAppV` e `SAppV` f |
1500 | 1513 | ||
1514 | -------------------------------------------------------------------------------- list comprehensions | ||
1515 | {- example | ||
1516 | |||
1517 | dbs<<[ x | y <- [1..10], let x = y * y]>> | ||
1518 | --> | ||
1519 | dbs<<[ _ | y <- [1..10], let x = y * y]>> $ dbs<<x>> | ||
1520 | --> | ||
1521 | (\exp -> SGlobal "concatMap" `SAppV` | ||
1522 | SLam | ||
1523 | | PVar <- Var 0 = y:dbs<<[ _ | let x = y * y]>> $ exp | ||
1524 | | _ = <<[]>> | ||
1525 | <<[1..10]>> | ||
1526 | ) (SGlobal "x") | ||
1527 | --> | ||
1528 | (\exp -> SGlobal "concatMap" `SAppV` | ||
1529 | SLam | ||
1530 | | PVar <- Var 0 = SLet (y:dbs<<y * y>>) ((x:y:dbs<<[ _ ]>>) $ exp) | ||
1531 | | _ = <<[]>> | ||
1532 | <<[1..10]>> | ||
1533 | ) (SGlobal "x") | ||
1534 | --> | ||
1535 | (\exp -> SGlobal "concatMap" `SAppV` | ||
1536 | SLam | ||
1537 | | PVar <- Var 0 = SLet (y:dbs<<y * y>>) ((x:y:dbs<<[ _ ]>>) $ exp) | ||
1538 | | _ = <<[]>> | ||
1539 | <<[1..10]>> | ||
1540 | ) (SGlobal "x") | ||
1541 | --> | ||
1542 | SGlobal "concatMap" `SAppV` | ||
1543 | SLam | ||
1544 | | PVar <- Var 0 = SLet (Var 0 * Var 0) (Var 0) | ||
1545 | | _ = <<[]>> | ||
1546 | <<[1..10]>> | ||
1547 | --> | ||
1548 | -} | ||
1549 | |||
1550 | generator, letdecl, boolExpression :: Namespace -> DBNames -> P (DBNames, SExp -> SExp) | ||
1551 | |||
1552 | generator ns dbs = do | ||
1553 | (dbs', pat) <- try $ pattern' ns dbs <* operator "<-" | ||
1554 | exp <- parseTerm ns PrecLam dbs | ||
1555 | return $ (,) (join traceShow dbs') $ \e -> application | ||
1556 | [ SGlobal "concatMap" | ||
1557 | , SLam Visible (Wildcard SType) $ compileGuardTree' $ Alts | ||
1558 | [ compilePatts [(pat, 0)] Nothing $ preExp $ \dcls -> upS $ removePreExpsE dcls e | ||
1559 | , GuardLeaf $ SGlobal "Nil" | ||
1560 | ] | ||
1561 | , exp | ||
1562 | ] | ||
1563 | |||
1564 | letdecl ns dbs = keyword "let" *> ((\((dbs', p), e) -> (join traceShow dbs' ++ dbs, \exp -> mkLets' [ValueDef (dbs', p) e] exp)) <$> valueDef ns dbs) | ||
1565 | |||
1566 | boolExpression ns dbs = do | ||
1567 | pred <- parseTerm ns PrecLam dbs | ||
1568 | return (dbs, \e -> application [SGlobal "PrimIfThenElse", pred, e, SGlobal "Nil"]) | ||
1569 | |||
1570 | application = foldl1 SAppV | ||
1571 | |||
1572 | listCompr :: Namespace -> DBNames -> P SExp | ||
1573 | listCompr ns dbs = (\e (dbs', fs) -> foldr ($) (preExp $ \dcls -> deBruinify (take (length dbs' - length dbs) dbs') $ removePreExpsE dcls e) fs) <$> | ||
1574 | try' "List comprehension" ((SGlobal "singleton" `SAppV`) <$ operator "[" <*> parseTerm ns PrecLam dbs <* operator "|") <*> | ||
1575 | commaSep' (liftA2 (<|>) (generator ns) $ liftA2 (<|>) (letdecl ns) (boolExpression ns)) dbs <* operator "]" | ||
1576 | |||
1577 | deBruinify :: DBNames -> SExp -> SExp | ||
1578 | deBruinify [] e = e | ||
1579 | deBruinify (n: ns) e = substSG n (SVar 0) $ upS $ deBruinify ns e | ||
1580 | |||
1581 | -- deBruinify ["a","b"] <<a * b>> --> Var 0 * Var 1 | ||
1582 | |||
1501 | -------------------------------------------------------------------------------- | 1583 | -------------------------------------------------------------------------------- |
1502 | 1584 | ||
1503 | calculatePrecs :: [SName] -> (SExp, [(SName, SExp)]) -> SExp | 1585 | calculatePrecs :: [SName] -> (SExp, [(SName, SExp)]) -> SExp |
@@ -1577,6 +1659,7 @@ getTTuple _ = Nothing | |||
1577 | 1659 | ||
1578 | mkLets' ss e = preExp $ \ge -> mkLets (removePreExps ge ss) (removePreExpsE ge e) | 1660 | mkLets' ss e = preExp $ \ge -> mkLets (removePreExps ge ss) (removePreExpsE ge e) |
1579 | 1661 | ||
1662 | mkLets :: [Stmt] -> SExp -> SExp | ||
1580 | mkLets [] e = e | 1663 | mkLets [] e = e |
1581 | mkLets (Let n _ Nothing (downS 0 -> Just x): ds) e = SLet x (substSG n (SVar 0) $ upS $ mkLets ds e) | 1664 | mkLets (Let n _ Nothing (downS 0 -> Just x): ds) e = SLet x (substSG n (SVar 0) $ upS $ mkLets ds e) |
1582 | mkLets (ValueDef (ns, p) x: ds) e = patLam p (foldl (\e n -> substSG n (SVar 0) $ upS e) (mkLets ds e) ns) `SAppV` x | 1665 | mkLets (ValueDef (ns, p) x: ds) e = patLam p (foldl (\e n -> substSG n (SVar 0) $ upS e) (mkLets ds e) ns) `SAppV` x |