Class: Hexp::MutableTreeWalk

Inherits:
Object
  • Object
show all
Defined in:
lib/hexp/mutable_tree_walk.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ MutableTreeWalk

Returns a new instance of MutableTreeWalk.



5
6
7
8
9
10
# File 'lib/hexp/mutable_tree_walk.rb', line 5

def initialize(root)
  @root = root
  @path = [root]
  @replacements = [{}]
  @result = nil
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



3
4
5
# File 'lib/hexp/mutable_tree_walk.rb', line 3

def path
  @path
end

#resultObject (readonly)

Returns the value of attribute result.



3
4
5
# File 'lib/hexp/mutable_tree_walk.rb', line 3

def result
  @result
end

#rootObject (readonly)

Returns the value of attribute root.



3
4
5
# File 'lib/hexp/mutable_tree_walk.rb', line 3

def root
  @root
end

Instance Method Details

#at_rightmost_child?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/hexp/mutable_tree_walk.rb', line 55

def at_rightmost_child?
  current.equal? parent.children.last
end

#backtrack_and_right!Object



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/hexp/mutable_tree_walk.rb', line 24

def backtrack_and_right!
  while at_rightmost_child?
    @path.pop
    handle_replacements!
    if @path.length == 1 #back at start, we're done
      @result = @path.pop
      return
    end
  end
  go_right!
end

#currentObject



71
72
73
# File 'lib/hexp/mutable_tree_walk.rb', line 71

def current
  @path.last
end

#current_idxObject



63
64
65
# File 'lib/hexp/mutable_tree_walk.rb', line 63

def current_idx
  parent.children.find_index { |ch| current.equal?(ch) }
end

#end?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/hexp/mutable_tree_walk.rb', line 75

def end?
  @path.empty?
end

#go_right!Object



59
60
61
# File 'lib/hexp/mutable_tree_walk.rb', line 59

def go_right!
  @path[-1] = parent.children[current_idx + 1]
end

#handle_replacements!Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/hexp/mutable_tree_walk.rb', line 40

def handle_replacements!
  replacements = @replacements.pop
  return if replacements.empty?
  new_children = [*current.children]
  replacements.each do |idx, val|
    new_children[idx..idx] = val
  end
  new_node = current.set_children(new_children)
  if @path.length == 1
    @path = [new_node]
  else
    @replacements.last[current_idx] = new_node
  end
end

#next!Object



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/hexp/mutable_tree_walk.rb', line 12

def next!
  return if end?
  if current.children.any?
    @path << current.children.first
    @replacements << {}
  elsif @path.length == 1
    @result = @path.pop
  else
    backtrack_and_right!
  end
end

#parentObject



67
68
69
# File 'lib/hexp/mutable_tree_walk.rb', line 67

def parent
  @path[-2]
end

#replace!(val) ⇒ Object



36
37
38
# File 'lib/hexp/mutable_tree_walk.rb', line 36

def replace!(val)
  @replacements.last[current_idx] = val
end