Skip to content

Commit 7b396dc

Browse files
committed
Switch to TraversableTerm in Lower and Optimize too.
Passing around the traversal defs explicitly is getting painful and it's a source of bugs. I think it makes to have higher level APIs on top of TraversableTerm that carry it in a monad. I'll try that next.
1 parent ea3a2c3 commit 7b396dc

File tree

6 files changed

+301
-553
lines changed

6 files changed

+301
-553
lines changed

dex.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ library
5555
, Core
5656
, Err
5757
, Export
58-
, GenericTraversal
5958
, Generalize
6059
, Imp
6160
, ImpToLLVM

src/lib/Builder.hs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,21 @@ type ForallTraversalDef m r = forall i o. TraversalDef (m i o) r i o
14641464
type ExprTraversalDef m r = forall i o. Expr r i -> m i o (Expr r o)
14651465
type BlockTraversalDef m r = forall i o. Block r i -> m i o (Block r o)
14661466

1467+
traverseExprs
1468+
:: (IRRep r, TraversableTerm e r, EnvExtender2 m, SubstReader Name m)
1469+
=> e i -> ExprTraversalDef m r -> m i o (e o)
1470+
traverseExprs e f = traverseTerm (exprTraversal f) e where
1471+
1472+
exprTraversal
1473+
:: (IRRep r, EnvExtender2 m, SubstReader Name m)
1474+
=> ExprTraversalDef m r -> ForallTraversalDef m r
1475+
exprTraversal f = TraversalDef
1476+
{ handleName = renameM
1477+
, handleType = traverseTypeRename (exprTraversal f)
1478+
, handleAtom = traverseAtomRename (exprTraversal f)
1479+
, handleLam = traverseLam (exprTraversal f) (traverseBlock (exprTraversal f) f)
1480+
, handlePi = traversePi (exprTraversal f) }
1481+
14671482
traverseBlock
14681483
:: (IRRep r, FromName v, SubstReader v m, EnvExtender2 m)
14691484
=> ForallTraversalDef m r
@@ -1474,6 +1489,25 @@ traverseBlock f fExpr (Block _ decls result) = do
14741489
result' <- handleAtom f result
14751490
return $ Abs decls' result'
14761491

1492+
traverseAtomRename
1493+
:: (IRRep r, SubstReader Name m, EnvExtender2 m)
1494+
=> ForallTraversalDef m r
1495+
-> Atom r i -> m i o (Atom r o)
1496+
traverseAtomRename f = \case
1497+
Var v -> Var <$> renameM v
1498+
SimpInCore x -> SimpInCore <$> renameM x
1499+
ProjectElt i x -> ProjectElt i <$> traverseAtomRename f x
1500+
x -> traverseAtom f x
1501+
1502+
traverseTypeRename
1503+
:: (IRRep r, SubstReader Name m, EnvExtender2 m)
1504+
=> ForallTraversalDef m r
1505+
-> Type r i -> m i o (Type r o)
1506+
traverseTypeRename f = \case
1507+
TyVar v -> TyVar <$> renameM v
1508+
ProjectEltTy i x -> ProjectEltTy i <$> traverseAtomRename f x
1509+
x -> traverseType f x
1510+
14771511
traverseLam
14781512
:: (IRRep r, FromName v, SubstReader v m, EnvExtender2 m)
14791513
=> ForallTraversalDef m r
@@ -1520,6 +1554,79 @@ traverseDecls f (Nest (Let b (DeclBinding ann _ expr)) decls) cont = do
15201554
traverseDecls f decls \decls' ->
15211555
cont $ Nest decl' decls'
15221556

1557+
-- === traversal helpers that allow emissions ===
1558+
1559+
type ExprEmitTraversalDef m r = forall i o. Emits o => Expr r i -> m i o (Atom r o)
1560+
1561+
liftAtomSubstBuilder :: (IRRep r, EnvReader m) => AtomSubstBuilder r n n a -> m n a
1562+
liftAtomSubstBuilder cont = liftBuilder $ runSubstReaderT idSubst cont
1563+
1564+
type AtomSubstBuilder r = SubstReaderT AtomSubstVal (BuilderM r)
1565+
1566+
exprEmitTraversal
1567+
:: (IRRep r, ScopableBuilder2 r m, SubstReader AtomSubstVal m)
1568+
=> ExprEmitTraversalDef m r -> ForallTraversalDef m r
1569+
exprEmitTraversal f = TraversalDef
1570+
{ handleName = substM
1571+
, handleType = traverseTypeSubst (exprEmitTraversal f)
1572+
, handleAtom = traverseAtomSubst (exprEmitTraversal f)
1573+
, handleLam = traverseLamEmit (exprEmitTraversal f) f
1574+
, handlePi = traversePi (exprEmitTraversal f) }
1575+
1576+
traverseLamEmit
1577+
:: (IRRep r, SubstReader AtomSubstVal m, ScopableBuilder2 r m)
1578+
=> ForallTraversalDef m r
1579+
-> ExprEmitTraversalDef m r
1580+
-> LamExpr r i -> m i o (LamExpr r o)
1581+
traverseLamEmit f fExpr lam =
1582+
traverseLam f (\b -> buildBlock $ traverseBlockEmit f fExpr b) lam
1583+
1584+
traverseBlockEmit
1585+
:: (Emits o, IRRep r, SubstReader AtomSubstVal m, EnvExtender2 m)
1586+
=> ForallTraversalDef m r
1587+
-> ExprEmitTraversalDef m r
1588+
-> Block r i -> m i o (Atom r o)
1589+
traverseBlockEmit f fExpr (Block _ decls result) = do
1590+
traverseDeclsEmit fExpr decls do
1591+
handleAtom f result
1592+
1593+
traverseDeclsEmit
1594+
:: (IRRep r, SubstReader AtomSubstVal m, EnvExtender2 m, Emits o)
1595+
=> ExprEmitTraversalDef m r
1596+
-> Nest (Decl r) i i'
1597+
-> m i' o a
1598+
-> m i o a
1599+
traverseDeclsEmit _ Empty cont = cont
1600+
traverseDeclsEmit f (Nest (Let b (DeclBinding _ _ expr)) decls) cont = do
1601+
x <- f expr
1602+
extendSubst (b@>SubstVal x) do
1603+
traverseDeclsEmit f decls cont
1604+
1605+
traverseExprsEmit
1606+
:: (IRRep r, ScopableBuilder2 r m, SubstReader AtomSubstVal m
1607+
, TraversableTerm e r)
1608+
=> e i -> ExprEmitTraversalDef m r -> m i o (e o)
1609+
traverseExprsEmit e f = traverseTerm (exprEmitTraversal f) e where
1610+
1611+
traverseAtomSubst
1612+
:: (IRRep r, SubstReader AtomSubstVal m, EnvExtender2 m)
1613+
=> ForallTraversalDef m r
1614+
-> Atom r i -> m i o (Atom r o)
1615+
traverseAtomSubst f = \case
1616+
Var v -> substM $ Var v
1617+
SimpInCore x -> SimpInCore <$> substM x
1618+
ProjectElt i x -> ProjectElt i <$> traverseAtomSubst f x
1619+
x -> traverseAtom f x
1620+
1621+
traverseTypeSubst
1622+
:: (IRRep r, SubstReader AtomSubstVal m, EnvExtender2 m)
1623+
=> ForallTraversalDef m r
1624+
-> Type r i -> m i o (Type r o)
1625+
traverseTypeSubst f = \case
1626+
TyVar v -> substM $ TyVar v
1627+
ProjectEltTy i x -> ProjectEltTy i <$> traverseAtomSubst f x
1628+
x -> traverseType f x
1629+
15231630
-- === Helpers for function evaluation over fixed-width types ===
15241631

15251632
applyIntBinOp' :: (forall a. (Eq a, Ord a, Num a, Integral a)

src/lib/CheapReduction.hs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,17 @@ instance IRRep r => TraversableTerm (Expr r) r where
558558
traverseTerm f = \case
559559
TopApp v xs -> TopApp <$> handleName f v <*> mapM (ha f) xs
560560
TabApp tab xs -> TabApp <$> ha f tab <*> mapM (ha f) xs
561-
Case x alts t effs -> Case <$> ha f x <*> mapM (handleAlt f) alts <*> handleType f t <*> tt f effs
561+
Case x alts t _ -> do
562+
x' <- ha f x
563+
t' <- handleType f t
564+
alts' <- mapM (handleAlt f) alts
565+
let effs' = foldMap altEffects alts'
566+
return $ Case x' alts' t' effs'
567+
where
568+
altEffects :: Alt r n -> EffectRow r n
569+
altEffects (Abs bs (Block ann _ _)) = case ann of
570+
NoBlockAnn -> Pure
571+
BlockAnn _ effs -> ignoreHoistFailure $ hoist bs effs
562572
Atom x -> Atom <$> ha f x
563573
TabCon Nothing t xs -> TabCon Nothing <$> handleType f t <*> mapM (ha f) xs
564574
TabCon (Just (WhenIRE d)) t xs -> TabCon <$> (Just . WhenIRE <$> ha f d) <*> handleType f t <*> mapM (ha f) xs

0 commit comments

Comments
 (0)