def missing is public, readable = object{
method asString->String{"-"}
}
type Iterator = {
reset->Void
hasNext->Boolean
get->T
next->T}
type Stack = {
push(_:T)->Void
pop->T
peek->T
size->Number
isEmpty->Boolean
isFull->Boolean
asString->String
iterator->Iterator}
method withSize(capacity:Number)->Stack is public{StackArray.new(capacity)}
class StackArray.new(capacity:Number){
// index to top element of stack
var top:Number is readable := -1
// Array of value references. Top is higher in array.
var data is readable := PrimitiveArray.new(capacity)
// @post removes all elements from stack
method clear->Void is public{top := -1}
// Add a value to top of stack
// @post adds an element to stack
// @param item the value to be added
method push(item)->Void is public{
if(!isFull) then{
top := top + 1
data[top] := item}
else{print "Stack is full; can't push"}
}
// Remove value from top of stack
// @pre stack is not empty
// @post removes and returns top element
// @return value removed
method pop->Dynamic is public{
if(!isEmpty) then {
var result := data[top]
data[top] := None
top := top - 1
result}
else{
print "Stack is empty"
missing}
}
// Get reference to top value in stack
// @pre stack not empty
// @post @return top element
method peek->Dynamic is public{
if(!isEmpty) then {data[top]}
else{
print "Stack is empty"
missing}
}
// @post @return number of elements in stack
method size->Number is public{top + 1}
// @post @return true iff stack is empty
method isEmpty->Boolean is public{size == 0}
// @post @return true iff stack is full
method isFull->Boolean is public{top == (data.size - 1)}
// @post @return string representation of stack
method asString->String is public{
var str:String := "= 0} do {
str := str ++ " {data[i]}"
i := i - 1}
return str ++ ">"}
// @post @return iterator to traverse stack
method iterator->Iterator is public{StackIterator.new(data, top)}
}
class StackIterator.new(source, start:Number){
var data is readable := source
var current:Number is readable := start
var remaining:Number is readable := start + 1
method reset->Void is public{
current := start
remaining := start + 1}
method hasNext->Boolean is public{remaining > 0}
method next->Dynamic is public{
var temp:Dynamic := data[current]
current := (current - 1) % data.size
remaining := remaining - 1
temp}
method get->Dynamic is public{data[current]}
}