@@ -1464,6 +1464,21 @@ type ForallTraversalDef m r = forall i o. TraversalDef (m i o) r i o
14641464type ExprTraversalDef m r = forall i o . Expr r i -> m i o (Expr r o )
14651465type 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+
14671482traverseBlock
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+
14771511traverseLam
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
15251632applyIntBinOp' :: (forall a . (Eq a , Ord a , Num a , Integral a )
0 commit comments