/* $Id: stack.c,v 1.2 2009/01/04 15:49:32 kiesling Exp $ */

/*
  This file is part of Ctalk.
  Copyright © 2005-2009 Robert Kiesling, ctalk@ctalklang.org.
  Permission is granted to copy this software provided that this copyright
  notice is included in all source code modules.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation, 
  Inc., 51 Franklin St., Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <stdio.h>
#include <string.h>
#include "object.h"
#include "message.h"
#include "ctalk.h"

/*
 *  These are leftovers from the versions of ctalk which had
 *  the preprocessor in the same program.
 */

MESSAGE *p_messages[P_MESSAGES+1]; /* Preprocess message stack.        */
int p_message_ptr = P_MESSAGES;    /* Preprocess stack pointer.        */



int p_message_push (MESSAGE *m) {
  if (p_message_ptr == 0) {
    _warning (_("p_message_push: stack overflow.\n"));
    return ERROR;
  }
#ifdef MACRO_STACK_TRACE
  debug (_("p_message_push %d. %s."), p_message_ptr, m -> name);
#endif
  p_messages[p_message_ptr--] = m;
  return p_message_ptr + 1;
}

MESSAGE *p_message_pop (void) {
  MESSAGE *m;
  if (p_message_ptr == P_MESSAGES) {
    _warning (_("p_message_pop: stack underflow.\n"));
    return (MESSAGE *)NULL;
  }
#ifdef MACRO_STACK_TRACE
  debug (_("p_message_pop %d. %s."), p_message_ptr, 
	 p_messages[p_message_ptr+1] -> name);
#endif
  if (p_messages[p_message_ptr + 1] && 
      IS_MESSAGE(p_messages[p_message_ptr + 1])) {
    m = p_messages[p_message_ptr + 1];
    p_messages[++p_message_ptr] = NULL;
    return m;
  } else {
    p_messages[++p_message_ptr] = NULL;
    return NULL;
  }
}

int stack_start (MESSAGE_STACK messages) {
  if (messages == p_messages)
    return P_MESSAGES;
  if (messages == message_stack ())
    return P_MESSAGES;
  if (messages == fn_message_stack ())
    return P_MESSAGES;
  if (messages == method_message_stack ())
    return N_MESSAGES;
  if (messages == method_buf_message_stack ())
    return P_MESSAGES;
  if (messages == tmpl_message_stack ())
    return N_MESSAGES;
  if (messages == c_message_stack ())
    return N_MESSAGES;
  if (messages == var_message_stack ())
    return N_MESSAGES;
  _error (_("stack_start: unimplemented message stack."));
  /* Avoid warning message. */
  return ERROR;
}

/*
 *  Return the index of the next stack entry.
 */
int get_stack_top (MESSAGE_STACK messages) {
  if (messages == p_messages)
    return p_message_ptr;
  if (messages == message_stack ())
    return get_messageptr ();
  if (messages == fn_message_stack ())
    return get_fn_messageptr ();
  if (messages == method_buf_message_stack ())
    return get_method_buf_message_ptr ();
  if (messages == c_message_stack ())
    return get_c_message_ptr ();
  if (messages == method_message_stack ())
    return get_method_message_ptr ();
  if (messages == tmpl_message_stack ())
    return get_tmpl_messageptr ();
  if (messages == var_message_stack ())
    return get_var_messageptr ();
  _error (_("get_stack_top: unimplemented message stack."));
  /* Avoid warning message. */
  return ERROR;
}

