-- Implementation of stack when the length of the stack
-- and the list are stored both in a tree #stack_abstract.

#STACKS
 $S:=#NEWSTACK(T);
 #PUSH(A $S);

  #PUSH(B $S);
   PRINT #TOP($S);
  #POP($S);

  #PUSH(C $S);
  #POP($S);

 #POP($S);
 PRINT $S;
##


#stack_abstract
<. size: #NUMBER,
   [ list : (. (+ $ELEMENT +) .) ]
.>
##


#NEWSTACK
/ RETURN 'stack'::<.size:0.> /
-- This 'stack' is added for better understanding of printouts
-- only.
##

#PUSH  $EL
$STACK:=
 <. size : $size / $size+:=1 /,
  [ list : $list
    /IF #LEN($list)>=$size -> $list[$size]:=$EL   
     ELSIF T -> $list!.:=$EL
     FI;
     RETURN T/
   ]
 .>
/ $STACK++:=<.list:(.$EL.).> /
##

#PUSH2  $EL $S -- The same as push, without patterns
/$S.size+:=1;
 IF $S.list ->
    IF #LEN($S.list)>=$S.size -> $S.list[$S.size]:=$EL   
    ELSIF T -> $S.list!.:=$EL
    FI;
  ELSIF T->$S++:=<.list:(.$EL.).>
  FI;
/##


#POP $S
/ IF $S.size>0 -> $S.size+:=-1; FI; /
##

#TOP $S
/ RETURN $S.list[$S.size] /
##     
