/*
 * Routines de gestions de piles
 * (c)1991 par Denis GOUNELLE
 *
 * long Push( type , val )
 *	empile la valeur "val" avec "type" comme type
 *	retourne 0 si ok, -1 sinon
 *
 * long Pop( type , indic )
 *	depile la derniere valeur de type "type" et retourne cette valeur
 *	si indic = 1, provoque une erreur si pas de valeur a depiler,
 *      sinon retourne -1 
 *
 * void FlushStack( type )
 *	vide toutes les valeurs de type  indique
 */

#include "aroff.h"
#include "pile.h"

static long sp = 0 ;
extern long *Pile, TaillePile ;

/***********************************************************************/

void FlushStack( type )
long type ;

{
  register long k, l ;

  for ( k = l = 0 ; k < sp ; k += 2 )
  {
    if ( Pile[k] == type )
    {
      if ( type == TE_CONTEXT ) free( Pile[k+1] ) ;
      continue ;
    }

    if ( Pile[k] != TE_VIDE )
    {
      Pile[l] = Pile[k]   ; l++ ;
      Pile[l] = Pile[k+1] ; l++ ;
    }
  }

  sp = l ;
}

/***********************************************************************/

long Push( type , val )
long type, val ;

{
  if ( sp >= TaillePile ) FlushStack( TE_VIDE ) ;
  if ( sp >= TaillePile ) Fatal( ERR_PILEP ) ;

  Pile[sp] = type ; sp++ ;
  Pile[sp] = val  ; sp++ ;
  return( 0 ) ;
}

/***********************************************************************/

long Pop( type , indic )
long type, indic ;

{
  register long k, l ;

  l = sp - 2 ;

  for ( k = l ; k >= 0 ; k -= 2 )
    if ( Pile[k] == type )
    {
      if ( k == l ) sp = l ;
      else Pile[k] = TE_VIDE ;
      return( Pile[k+1] ) ;
    }

  if ( indic ) Fatal( ERR_PILEV ) ;
  return( -1 ) ;
}

