Class: MiniKraken::Composite::ConsCellVisitor

Inherits:
Object
  • Object
show all
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

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]

Parameters:

Returns:

  • (Fiber)

    A Fiber that yields couples



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