code: def traverse(fn, expr, type=ir.Expr, container=Stack):
      
      args = expr if isinstance(expr, collections.abc.Iterable) else [expr]
      todo = container(arg for arg in args if isinstance(arg, type))
      seen = set()
  
      while todo:
          expr = todo.get()
          op = expr.op()
          if op in seen:
              continue
          else:
              seen.add(op)
  
          control, result = fn(expr)
          if result is not None:
              yield result
  
          if control is not halt:
              if control is proceed:
                  args = op.flat_args()
              elif isinstance(control, collections.abc.Iterable):
                  args = control
              else:
                  raise TypeError(
                      'First item of the returned tuple must be '
                      'an instance of boolean or iterable'
                  )
  
              todo.extend(
                  arg for arg in todo.visitor(args) if isinstance(arg, type)
              )
docs: Utility for generic expression tree traversal
  
      Parameters
      ----------
      fn : Callable[[ir.Expr], Tuple[Union[Boolean, Iterable], Any]]
          This function will be applied on each expressions, it must
          return a tuple. The first element of the tuple controls the
          traversal, and the second is the result if its not None.
      expr: ir.Expr
          The traversable expression or a list of expressions.
      type: Type
          Only the instances if this type are traversed.
      container: Union[Stack, Queue], default Stack
          Defines the traversing order.