import vector

type Iterator = {
    reset->Void
    hasNext->Boolean
    get->T
    next->T}

type Vector = {
    size->Number
    isEmpty->Boolean
    clear->Void
    contains(_:T)->Boolean
    addFirst(_:T)->Void
    addLast(_:T)->Void
    firstElement->T
    lastElement->T
    removeFirst->T
    removeLast->T
    removeValue(_:T)->T
    indexOf(_:T)->Number
    at(_:Number)->T
    setValue(_:T)at(_:Number)->T
    add(_:T)at(_:Number)->Void
    removeFromIndex(_:Number)->T
    iterator->Iterator
    asString->String
    forEachDo(_:Block)->Void
    map(_:Block)->Vector
    ensureCapacity(_:Number)->Void
    capacity->Number
    copyInto(_)->Void
    indexOf(_:T)startingFrom(_:Number)->Number
    setSize(_:Number)->Void
    trimToSize->Void}

type Stack = {
    push(_:T)->Void
    pop->T
    peek->T
    isEmpty->Boolean
    size->Number
    clear->Void
    iterator->Iterator
    asString->String}

method new->Stack is public{StackVector.new(vector.defaultCapacity)}

method withSize(cap:Number)->Stack is public{StackVector.new(cap)}

class StackVector.new(capacity:Number){

    // vector containing stack data
    var data:Vector is readable := vector.withSize(capacity)
     
    // Add element to top of stack
    // @post item added to stack
    // @param item element to be added
    method push(item)->Void is public{data.addLast(item)}
     
    // Remove element from top of stack
    // @pre stack is not empty
    // @post most recently added item removed
    // @return item removed from top of stack
    method pop->Dynamic is public{data.removeFromIndex(size)}

    // Fetch reference to top element of stack
    // @pre stack is not empty
    // @post @return top value
    method peek->Dynamic is public{data.at(size)}

    // @return true iff stack is empty
    method isEmpty->Boolean is public{size == 0}

    // @post @return number of elements in stack
    method size->Number is public{data.size}

    // @post removes all elements from stack
    method clear->Void is public{data.clear}

    // @post @return iterator to traverse stack--INCORRECT ORDER
    method iterator->Iterator is public{data.iterator}

    // @post @return string representation of stack
    method asString->String is public{
        var str:String := " 0} do {
            str := str ++ " {data.at(i)}"
            i := i - 1}
        return str ++ ">"}
}