Class: Stupidedi::Zipper::EditedCursor

Inherits:
AbstractCursor show all
Defined in:
lib/stupidedi/zipper/edited_cursor.rb

Instance Attribute Summary collapse

Querying the Tree Location collapse

Traversing the Tree collapse

Editing the Tree collapse

Instance Method Summary collapse

Methods inherited from AbstractCursor

#append_child, #between, #child, #children, #dangle, #depth, #descendant, #down, #first?, #flatten, #insert_left, #insert_right, #last?, #prepend_child, #root

Constructor Details

#initialize(node, path, parent) ⇒ EditedCursor

Returns a new instance of EditedCursor.



17
18
19
20
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 17

def initialize(node, path, parent)
  @node, @path, @parent =
    node, path, parent
end

Instance Attribute Details

#nodeObject (readonly)

Returns the value of attribute node.



9
10
11
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 9

def node
  @node
end

#parentAbstractCursor (readonly)

Returns:



15
16
17
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 15

def parent
  @parent
end

#pathHole (readonly)

Returns:



12
13
14
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 12

def path
  @path
end

Instance Method Details

#append(node) ⇒ AbstractCursor, EditedCursor

Navigate to the last (rightmost) sibling node



111
112
113
114
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 111

def append(node)
  EditedCursor.new(node,
    Hole.new(@node.cons(@path.left), @path.parent, @path.right), @parent)
end

#deleteAbstractCursor, EditedCursor

Navigate to the last (rightmost) sibling node



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 131

def delete
  if not last?
    # Move to `next`
    head, *tail = @path.right

    EditedCursor.new(head,
      Hole.new(@path.left, @path.parent, tail), @parent)
  elsif not first?
    # Move to `prev`
    head, *tail = @path.left

    EditedCursor.new(head,
      Hole.new(tail, @path.parent, @path.right), @parent)
  else
    # Deleting the only child
    parent =
      @parent.node.copy(:children =>
        @path.left.reverse.concat(@path.right))

    EditedCursor.new(parent, @path.parent, @parent.parent).dangle
  end
end

#firstAbstractCursor, EditedCursor

Navigate to the first (leftmost) sibling node



82
83
84
85
86
87
88
89
90
91
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 82

def first
  if first?
    return self
  end

  right = @path.left.init.reverse.concat(@node.cons(@path.right))

  EditedCursor.new(@path.left.last,
    Hole.new([], @path.parent, right), @parent)
end

#lastAbstractCursor, EditedCursor

Navigate to the last (rightmost) sibling node



95
96
97
98
99
100
101
102
103
104
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 95

def last
  if last?
    return self
  end

  left = @node.cons(@path.right.init.reverse).concat(@path.left)

  EditedCursor.new(@path.right.last,
    Hole.new(left, @path.parent, []), @parent)
end

#leaf?Boolean

Returns:

  • (Boolean)


26
27
28
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 26

def leaf?
  @node.leaf? or @node.children.empty?
end

#nextAbstractCursor, EditedCursor

Navigate to the next (rightward) sibling node



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 54

def next
  if last?
    raise Exceptions::ZipperError,
      "cannot move to next after last node"
  end

  head, *tail = @path.right

  EditedCursor.new(head,
    Hole.new(@node.cons(@path.left), @path.parent, tail), @parent)
end

#prepend(node) ⇒ AbstractCursor, EditedCursor

Navigate to the last (rightmost) sibling node



118
119
120
121
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 118

def prepend(node)
  EditedCursor.new(node,
    Hole.new(@path.left, @path.parent, @node.cons(@path.right)), @parent)
end

#prevAbstractCursor, EditedCursor

Navigate to the previous (leftward) sibling node



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 68

def prev
  if first?
    raise Exceptions::ZipperError,
      "cannot move to prev before first node"
  end

  head, *tail = @path.left

  EditedCursor.new(head,
    Hole.new(tail, @path.parent, @node.cons(@path.right)), @parent)
end

#replace(node) ⇒ AbstractCursor, EditedCursor

Navigate to the last (rightmost) sibling node



125
126
127
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 125

def replace(node)
  EditedCursor.new(node, @path, @parent)
end

#root?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 31

def root?
  false
end

#upAbstractCursor

Navigate to the parent node



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/stupidedi/zipper/edited_cursor.rb', line 40

def up
  node =
    @parent.node.copy(:children =>
      @path.left.reverse.concat(@node.cons(@path.right)))

  if parent.root?
    RootCursor.new(node)
  else
    EditedCursor.new(node, @path.parent, @parent.parent)
  end
end