Class: MiniKraken::Composite::ConsCellVisitor
- Inherits:
-
Object
- Object
- MiniKraken::Composite::ConsCellVisitor
- Defined in:
- lib/mini_kraken/composite/cons_cell_visitor.rb
Overview
Factory class. Purpose: to create Fiber specialized in the visit of cons cells.
Class Method Summary collapse
-
.df_visitor(aCell) ⇒ Fiber
Build a depth-first in-order expression tree visitor.
Class Method Details
.df_visitor(aCell) ⇒ Fiber
Build a depth-first in-order expression tree visitor. The visitor is implemented as a Fiber. The Fiber yields couples of the form: [member, visitee] where member is one of :car, :cdr The end of visit is signalled with the couple [:stop, nil]
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/mini_kraken/composite/cons_cell_visitor.rb', line 18 def self.df_visitor(aCell) first = aCell # The visit will start from the provided cons cell # puts "#{__callee__} called with #{aCell.object_id.to_s(16)}" visitor = Fiber.new do |skipping| # Initialization part: will run once visitees = Set.new # Keep track of the conscell already visited visit_stack = first.nil? ? [] : [[:car, first]] # The LIFO queue of cells to visit until visit_stack.empty? # Traversal part (as a loop) side, cell = visit_stack.pop next if visitees.include?(cell) && side == :car visitees << cell if cell.kind_of?(ConsCell) skip_children = Fiber.yield [side, cell] next if skip_children || skipping skipping = false if cell.is_a?(ConsCell) && !cell.null? visit_stack.push([:cdr, cell.cdr]) visit_stack.push([:car, cell.car]) end end # Send stop mark Fiber.yield [:stop, nil] end return visitor end |