require_relative 'mixins'
module Oppen
class ScanStack
extend Mixins
def initialize(size, config)
@bottom = 0
@config = config
@empty = true
@stack = Array.new(size)
@top = 0
end
def empty?
@empty
end
def length
@stack.length
end
def top
if empty?
raise 'Accessing empty stack from top'
end
@stack[@top]
end
def bottom
if empty?
raise 'Accessing empty stack from bottom'
end
@stack[@bottom]
end
def increment(index)
(index + 1) % length
end
def decrement(index)
(index - 1) % length
end
def push(value)
if empty?
@empty = false
else
@top = increment(@top)
if @top == @bottom
raise 'Stack full' if !@config.upsize_stack?
@stack, @bottom, @top = ScanStack.upsize_circular_array(@stack, @bottom)
end
end
@stack[@top] = value
end
def pop
if empty?
raise 'Popping empty stack from top'
end
res = top
if @top == @bottom
@empty = true
else
@top = decrement(@top)
end
res
end
def pop_bottom
if empty?
raise 'Popping empty stack from bottom'
end
res = bottom
if @top == @bottom
@empty = true
else
@bottom = increment(@bottom)
end
res
end
def update_indexes(offset)
@stack = @stack.map { |val|
(val + offset) % length if val
}
end
end
end